Atlas / MCP servers / 0xfreak0 / sui-mcp

sui-mcpBLOCK

mcp/0xfreak0/sui-mcp

Read-only MCP server for investigating activity on Sui — fund tracing, funding-source attribution, address fan-out, multi-address timelines. No API keys or wallet.

Verdict
BLOCK
Grade
D
Trust score
69 /100
Exposed tools
86 70r · 14w · 2d
Transport
stdio
License
MIT
Stars
0
01

Overview

From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.

Documentation: [sui-mcp.vercel.app](https://sui-mcp.vercel.app/)

[](https://github.com/0xfreak0/sui-mcp/actions/workflows/ci.yml)

Read-only MCP server for investigating activity on Sui. Trace where funds went, attribute wallets to their funding sources, rank addresses by protocol flow, work out who can actually sign for a multisig treasury, and tell a coordinated cluster from a crowd, then reconstruct it all on a timeline.

It also covers the ordinary things: wallet overviews, DeFi positions, NFTs, prices and Move package analysis. USD totals are provider-based estimates; see How USD values are calculated.

Install

Add this to your MCP client config (Claude Code, Claude Desktop, Cursor, or anything else that speaks MCP over stdio):

{
"mcpServers": {
"sui": {
"command": "npx",
"args": ["-y", "sui-analytics-mcp"]
}
}
}

No account, API key, or config file is required. The server reads public Sui endpoints and defaults to mainnet. Requires Node.js >= 22.13.

For investigative work, start with the forensics tools loaded:

"env": { "SUI_TOOLS": "core,forensics" }

What an investigation looks like

The first two steps on the 22 May 2025 Cetus CLMM exploit, starting from the attacker wallet:

get_transaction_history(0xe28b50cef1d633ea43d3296a3f6b67ff0312a5f1a99f0af753c85b8b5de8ff06, order: "oldest")
→ funded once with 9.98 SUI, one failed transaction, then the first
success: DVMG3B2kocLEnVMDuQzTYRgjwuuFSfciawPvXXheB3x at 10:30:50 UTC

analyze_attack_tx(DVMG3B2kocLEnVMDuQzTYRgjwuuFSfciawPvXXheB3x)
→ attacker gained 10,024,321.28 haSUI and 5,765,124.46 SUI
haSUI/SUI pool price moved -99.9999%
anomalies: outsized-mint (high), shared-state-jump (high), ...

Every value can be checked on chain. The [full example](https://sui-mcp.vercel.app/examples/protocol-ex

Read from source at commit c3e898dcaddfOBSERVED · 2026-10-11
02

Connect

Built from this server's own package name, version and transport as found in its source — not copied from anyone's documentation, so it cannot drift against a page we do not control. Replace the environment placeholders with a token scoped to the least it needs.

claude-code (npm)
claude mcp add sui-analytics-mcp -- npx -y [email protected]
03

Exposed tools (86)

70 read · 14 write · 2 destructive. Blast radius: 2 tools can delete or overwrite — an agent that can be talked into calling a tool can be talked into calling this one.

ToolRiskDescription
addressreadThe address (0x...) or SuiNS name to investigate.
addressesreadAddresses to assess, comma-separated.
aggregate_eventsread(Incident investigation) Rank senders or event types by event count, or by a summed event field, across a window in one call instead of paging query_events.
analyze_attack_txread(Incident investigation) Investigate one exploit transaction: gains and losses per address and coin in USD at block time, attacker profit or a signing victim
analyze_multisigread(Multisig investigation) Read which of a multisig wallet
analyze_packagewriteScan a Move package
analyze_tokenread(Recommended for token research) Get a comprehensive analysis of a Sui token in one call: metadata, current price, 24h change, total supply, and top 5 holders. Accepts either a coin type (e.g.
build_stakingreadBuild an unsigned transaction to stake or unstake SUI. action=
build_timelineread(Incident investigation) Reconstruct an incident across up to 10 wallets or objects as one decoded timeline, deduplicated and ordered by checkpoint. from/to accept ISO times or checkpoints and bound the chain query. With from, reads forward from the start; otherwise reads each address
build_transferwriteBuild an unsigned transaction to transfer a coin (SUI or any coin type) from one address to another. For SUI it splits from the gas coin; for other coins it draws the amount from the sender
build_wallet_edgesread
case_namereadCase to record findings under.
check_activityread(Monitoring/polling) Stateless one-shot check for new activity on a Sui address or object since a known checkpoint, timestamp, cursor or version. Address mode with a baseline returns the transactions after it, oldest first;
check_coin_restrictionsread(Incident investigation) Read issuer freezes and whole-coin pauses from regulated coins
classify_deposit_addressread
coin_typereadThe coin type (0x...::module::NAME). A symbol works but may match several coins.
compare_oracle_priceread
decode_ptbread
decompile_moduleread
deepbook_orderbookwrite(DeepBook) Live order book depth for a DeepBook v3 pool: bids, asks, spread, mid price and resting-liquidity imbalance. DeepBook is a central limit order book, so this, not pool reserves, is its real liquidity picture. Omit pool_name to list available pools.
deepbook_tradesread(DeepBook) Recent fills for a DeepBook v3 pool, with the maker and taker balance manager IDs behind each trade. Filter by balance manager to attribute trading activity to one account during an incident window, or by time range to reconstruct what traded when.
delete_findingdestructive(Incident investigation) Remove a finding by id, for retracting something that turned out to be wrong. Use list_findings to get ids. Requires SUI_STORE_PATH.
diff_package_upgraderead
digestreadThe digest of the transaction you suspect.
disassemble_moduleread
enable_toolswrite
export_caseread(Incident investigation) Render a case
find_flow_pathread(Incident investigation) Find value paths from one address to another. Searches forward from
find_funding_sourceread(Incident investigation) Follow a wallet
find_funding_sourcesread
find_poolsreadFind liquidity pools for a token pair across Cetus, DeepBook v2/v3, Turbos and BlueMove v1. Searches both token orders and every Turbos fee tier. Each result reports the pool
find_shared_multisigread
get_address_fanoutread
get_balancereadRead one coin
get_chain_inforeadGet current Sui network info: chain ID, epoch, checkpoint height, timestamp, and reference gas price. Optionally pass an epoch number to get details for a specific epoch.
get_checkpointreadGet a Sui checkpoint by sequence number, digest or timestamp, or the latest if none is given. Returns its timestamp, epoch and network transaction count. Use it to turn a checkpoint number into a time, or a time into a checkpoint: with
get_coin_inforeadGet on-chain metadata for a token/coin given its exact coin type string (e.g.
get_defi_positionsreadFind and value a wallet
get_move_functionwrite(Developer) Get a specific Move function signature from a Sui package. Returns parameters, type parameters, return type, and visibility.
get_nft_salesreadNFT marketplace sales over a recent window, with volume and per-marketplace totals. Reads TradePort, BlueMove and OriginByte sale events. Also records which wallet holds which kiosk, which is what makes get_top_holders able to name a real owner for a kiosk-held NFT.
get_objectreadGet a Sui object by its ID. Returns type, owner, version, content (JSON), and digest. Automatically extracts display metadata (name, description, image_url) for NFTs. For the LATEST version it also lists
get_packagewrite(Developer) Get a Sui Move package by its ID. By default returns a per-module summary: function and struct counts, entry and public function names. Pass
get_package_dependency_graphwrite(Developer) Get the dependency graph of a Sui Move package from its linkage table: every package it is linked against, with the exact version linked (
get_pool_statsreadGet stats for a DeFi liquidity pool on Sui given its object ID. Auto-detects the protocol (Cetus, DeepBook, Turbos, etc.) and returns token pair, reserves, fees, and current prices.
get_staking_summaryreadGet directly held StakedSui positions and principal, now or at as_of. Historical budget stops return a continuation; totals stay null until replay finishes. Excludes wrapped stakes and liquid-staking tokens.
get_token_pricesreadGet USD prices for Sui coins by full coin type, current by default or at a past moment when
get_top_holdersreadScan objects of a given type and return top holders. The scan is slow and paginated. Works for NFT collections (ranked by count) or tokens (ranked by balance, counting both Coin<T> objects and address balances, with the split and the holder
get_transactionreadRead one Sui transaction
get_transaction_historyread(Recommended for wallet activity) Read a wallet
get_transactionsread
get_upgrade_historyread(Incident investigation) Read upgrade governance across a package lineage: each version
get_validatorsreadList current Sui validators, or return detailed info for one
get_wallet_overviewread(Recommended first tool for wallets) Overview of a Sui wallet: every coin balance, SuiNS name, staked SUI and kiosk counts, 50 newest transactions with an older-history continuation, and a time-bounded scan of package versions it published or upgraded in the first 20 sent transactions (
get_wallet_packageswriteList package versions created by publish or upgrade transactions sent from this wallet address. Scans 20 sent transactions per call, oldest first;
identify_addressread
list_dynamic_fieldsread(Developer) List dynamic fields of a Sui object. Returns field names, types, and values. Useful for inspecting on-chain tables, kiosk contents, or other dynamic collections.
list_findingsread(Incident investigation) List recorded findings, or every case with its finding count. Call with no arguments to see what cases exist. Requires SUI_STORE_PATH.
list_nft_collectionsreadSummary of the NFT collections a wallet holds: every kiosk plus directly owned objects, one row per collection type with its count. Each collection carries an estimated value (tier heuristic): per item, the lower of the collection
list_nftsread(Recommended for NFTs) List NFTs owned by a wallet, including kiosk-stored NFTs. Each row has an object id,
list_owned_objectsreadList raw objects owned by a Sui address with optional type filter and pagination.
manage_labelsread
mvr_get_package_infowriteGet the full Move Registry record for a single package name: metadata (description, homepage, icon), current version, on-chain package_address, the package_info object ID, and git source info (repo, branch, path) when registered.
mvr_resolvewriteResolve one or more Move Registry (MVR) names to their on-chain package IDs. Names use the form
mvr_resolve_structwriteResolve fully-qualified Move struct names (e.g.
mvr_reverse_resolvereadReverse-lookup MVR names from one or more package addresses. Useful for enriching raw addresses (e.g. from get_package or transaction decoders) with their canonical
mvr_searchwriteBrowse or search the Move Registry for packages. Searches name and description; returns one page (default 20 results) with a cursor for pagination. Pass
poll_watchreadReturn what has happened to watched addresses since the last poll, and nothing else. Cheap to call repeatedly: an empty result is a few dozen tokens. Each hit names a digest and why it fired; read the ones that matter with get_transaction.
protocolreadA package ID (0x...), an MVR name (@org/app), or a protocol name such as Cetus.
query_eventsreadQuery events by type, sender, emitting module or time/checkpoint range. Event fields are decoded; no hand-written GraphQL is needed. Use a protocol
query_transactionsread
resolve_bridge_transferwrite
resolve_namereadResolve a SuiNS name (.sui domain) to an address, or reverse-lookup an address to its SuiNS name. At least one of
resolve_protocol_packagesread
sample_control_addressesread
save_findingwrite
screen_addressread
search_tokenreadFind a Sui coin type by name or symbol for get_balance, get_coin_info or get_token_prices. Verified types rank first, then exact symbol matches; verified means a curated list vouches for that exact type, not its copyable name. Mainnet
simulate_transactionread
subjectreadAn attack transaction digest, or the attacker
summarize_address_flowsread(Incident investigation) Summarize an address
summarize_incident_lossesread(Incident investigation) Total an attacker
trace_flow_graphread
trace_fundsread(Incident investigation) Follow a fund-flow path from a transaction. Forward traces a recipient
trace_object_historyread(Incident investigation) Trace an object
v59readValidator v59
watch_addressesdestructiveAdd, remove or list addresses watched for new activity during an investigation. A watch records where it last looked, so poll_watch returns only what is new. Requires SUI_STORE_PATH.
04

Trust audit

BLOCKgrade D · trust 69/100 Do not install this without reading the findings. The audit found something that could harm you or your machine.

LayerWhat it checksResult
L0Provenance & inventoryPASS
L1Static analysis of the codeFAIL
L2Instruction surface (what it tells the agent)PASS
L3Class-specific surfaceWARN
L4Behavioural (sandbox)SKIPPED

What the source does

Filesystem
declared (7 observation(s))
Network
declared (5 observation(s))
Shell
declared (2 observation(s))
Dependencies
not all pinned
Secrets in source
found

Findings (25)

HIGHCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
src/utils/store.ts:81
exec(sql: string): void;
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
MEDIUMObfuscation / stealth · obf.homoglyph · CWE-506, CWE-94
scripts/probe/adversarial.mjs:239
const UNICODE = "Ωmega 🚀 名前 \u202e";
MEDIUMHard-coded secrets · secret.generic · CWE-798, CWE-321
test/valuers-amm-lp.test.ts:30
const TOKEN = "0x00000000000000000000000000000000000000000000000000000000000000b1";
MEDIUMFilesystem / path · mcp.destructive_tools · CWE-22, CWE-59
delete_finding, watch_addresses
Why it matters. 2 tool(s) can delete or overwrite
Fix. prefer a read-only mode or scoped tokens; the page states the blast radius
LOWInventory / provenance · inv.binary · CWE-1104
test/decompiler-safety.test.ts
decompiler-safety.test.ts
Why it matters. a compiled or binary member cannot be reviewed from source
Fix. ship source, or explain the binary in the README
LOWInventory / provenance · inv.suspicious_name · CWE-1104
site/src/content/docs/examples/protocol-exploit.md
protocol-exploit.md
Why it matters. member named after an attack tool
Fix. remove or justify
LOWInventory / provenance · inv.suspicious_name · CWE-1104
test/fixtures/cetus-exploit-grpc.json
cetus-exploit-grpc.json
Why it matters. member named after an attack tool
Fix. remove or justify
LOWInventory / provenance · inv.suspicious_name · CWE-1104
test/fixtures/scallop-exploit-ptb.json
scallop-exploit-ptb.json
Why it matters. member named after an attack tool
Fix. remove or justify
LOWCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
test/store.test.ts:577
exec(sql: string): void;
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
scripts/probe/consistency-pass2.mjs:10
import { registerTransactionTools } from "../../dist/tools/transactions.js";
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
scripts/probe/consistency-pass2.mjs:11
import { registerAnalyzePackageTools } from "../../dist/tools/analyze-package.js";
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
scripts/probe/consistency-pass2.mjs:12
import { registerFundingTools } from "../../dist/tools/funding.js";
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
scripts/probe/consistency-pass2.mjs:13
import { registerHistoryTools } from "../../dist/tools/history.js";
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
scripts/probe/consistency-pass2.mjs:14
import { runWithNetwork } from "../../dist/config.js";
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
test/tools/ptb.test.ts:34
const client = new SuiGrpcClient({ network: "mainnet", baseUrl: "http://127.0.0.1:9" });
LOWObfuscation / stealth · obf.base64_blob · CWE-506, CWE-94
test/bridge-beneficiary.test.ts:28
"0100000000000000000000000000000000000000000000000000000e1104194d802a62e389553ae6f061970ce1be2607c7f918154532e4296512d5a2c773424ff5001500000000000000000000000063186b34c809cca9f3825a3592082e1f1549fa5b0
LOWObfuscation / stealth · obf.base64_blob · CWE-506, CWE-94
test/bridge-beneficiary.test.ts:39
"0100000000000000000000000000000000000000000000000000000000d7e5a5ac9258181f5ceac8dbffb7030890243caed69a9599d2886d957a9cb7656af3bdb30015e6c373f66273e9f86d0f4b0f77ad11ed7f3f8da1855e88116c689ad2de4d808e0
LOWObfuscation / stealth · obf.base64_blob · CWE-506, CWE-94
test/bridge-beneficiary.test.ts:47
"03000000000000000000000000000000000000000000000000000000293ca6226f069b8857feab8184fb687f634618c035dac439dc1aeb3b5598a0f000000000010001000000000000000000000000cafd2f0a35a4459fa40c0517e17e6fa2939441ca0
LOWObfuscation / stealth · obf.base64_blob · CWE-506, CWE-94
test/bridge-beneficiary.test.ts:58
"9945ff104b6aede12bf98dce51cd92a157e13e89bf2dd7c5e2cfe47e91ad315505a46ac50bc1525f6607fce6db3f8cd1e2a6163e839dd7f8429dbf30b164406217ccfad7009100000000000000000000000000000000000000000000000000000000000
LOWObfuscation / stealth · obf.base64_blob · CWE-506, CWE-94
test/cctp.test.ts:12
"AAAAAAAAAAgAAAADAAAAAAAGfaSv3Hksea0RIV1mYcwGMg1IuffdRvTp1JAcRZhvpDDjyAAAAAAAAAAAAAAAABkzDRDZzIdRIY6vUeiIXQWGQuCKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPy4o0WPiUEKsfJVDwVZ1r1ql08J9vGVqZ/N/QpO
LOWSupply chain · supply.unpinned · CWE-829, CWE-1357
package.json
@grpc/grpc-js, @modelcontextprotocol/sdk, @mysten/sui, @protobuf-ts/grpc-transport, graphql-request, zod, typescript, vitest
Why it matters. 8 dependency range(s) float
Fix. pin exact versions or ship a lockfile
LOWSupply chain · supply.unpinned · CWE-829, CWE-1357
site/package.json
@astrojs/starlight, astro, starlight-links-validator
Why it matters. 3 dependency range(s) float
Fix. pin exact versions or ship a lockfile
LOWPrompt injection · prompt.transfer_instruction · CWE-94, CWE-1427
scripts/probe/README.md:21
| `case-pass.mjs` | Replays every case in `cases/incidents/` (and in `$SUI_CASES_DIR` when set): each check's tool call through the built server, its answer against the value the incident's post-morte
Why it matters. an instruction to move sensitive data to an outside destination
Fix. remove; a skill never needs the user's secrets off the machine
INFOInventory / provenance · inv.oversize · CWE-1104
src/data/coin-symbols.json
src/data/coin-symbols.json
Why it matters. 12784932 bytes not read
INFOInventory / provenance · inv.oversize · CWE-1104
src/data/guardians-blocklist.json
src/data/guardians-blocklist.json
Why it matters. 1981986 bytes not read

Gates applied: no_behavioural_pass.

Audited 2026-10-11 · audit v0.4.1 · source sha c3e898dcaddffull audit observations/trust-audit/mcp-server/0xfreak0__sui-mcp.json · Report an issue / request a re-scan
05

Audit history

Every audit this server has had. A grade with a past is a grade somebody is still checking.

DateSourceVerdictGradeScoreChange
2026-10-11c3e898dcaddfBLOCKD69first audit
06

Questions

What is the sui-mcp MCP server?

Read-only MCP server for investigating activity on Sui — fund tracing, funding-source attribution, address fan-out, multi-address timelines. No API keys or wallet.

What tools does sui-mcp expose?

86 in total: 70 read-only, 14 that write, and 2 that can delete or overwrite (delete_finding, watch_addresses). Every one is listed on this page with its risk.

Is sui-mcp safe to connect to an agent?

No — not without reading the findings first. The audit graded it D (69/100) and found 1 critical or high issue in the source. Each one is listed on this page with the file and line it is on. Separately from the audit: 2 of its tools can destroy data, so scope the token you give it to what you actually need.

What credentials does sui-mcp need?

It reads PYTH_API_KEY from the environment. Give it a token scoped to the least it needs — an agent that can be talked into calling a tool can be talked into calling it with your credentials.

How does sui-mcp run?

It speaks stdio, so it runs as a local process your client starts. It is published on npm as sui-mcp-docs at 1.27.0.

How current is this page?

The grade is for one exact copy of the source (c3e898dcaddf), read on 2026-10-11. The repository is watched and re-audited when it changes.

Advertisement