sui-mcpBLOCK
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.
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
c3e898dcaddfOBSERVED · 2026-10-11Connect
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 mcp add sui-analytics-mcp -- npx -y [email protected]
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.
| Tool | Risk | Description |
|---|---|---|
address | read | The address (0x...) or SuiNS name to investigate. |
addresses | read | Addresses to assess, comma-separated. |
aggregate_events | read | (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_tx | read | (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_multisig | read | (Multisig investigation) Read which of a multisig wallet |
analyze_package | write | Scan a Move package |
analyze_token | read | (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_staking | read | Build an unsigned transaction to stake or unstake SUI. action= |
build_timeline | read | (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_transfer | write | Build 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_edges | read | |
case_name | read | Case to record findings under. |
check_activity | read | (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_restrictions | read | (Incident investigation) Read issuer freezes and whole-coin pauses from regulated coins |
classify_deposit_address | read | |
coin_type | read | The coin type (0x...::module::NAME). A symbol works but may match several coins. |
compare_oracle_price | read | |
decode_ptb | read | |
decompile_module | read | |
deepbook_orderbook | write | (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_trades | read | (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_finding | destructive | (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_upgrade | read | |
digest | read | The digest of the transaction you suspect. |
disassemble_module | read | |
enable_tools | write | |
export_case | read | (Incident investigation) Render a case |
find_flow_path | read | (Incident investigation) Find value paths from one address to another. Searches forward from |
find_funding_source | read | (Incident investigation) Follow a wallet |
find_funding_sources | read | |
find_pools | read | Find 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_multisig | read | |
get_address_fanout | read | |
get_balance | read | Read one coin |
get_chain_info | read | Get 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_checkpoint | read | Get 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_info | read | Get on-chain metadata for a token/coin given its exact coin type string (e.g. |
get_defi_positions | read | Find and value a wallet |
get_move_function | write | (Developer) Get a specific Move function signature from a Sui package. Returns parameters, type parameters, return type, and visibility. |
get_nft_sales | read | NFT 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_object | read | Get 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_package | write | (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_graph | write | (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_stats | read | Get 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_summary | read | Get 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_prices | read | Get USD prices for Sui coins by full coin type, current by default or at a past moment when |
get_top_holders | read | Scan 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_transaction | read | Read one Sui transaction |
get_transaction_history | read | (Recommended for wallet activity) Read a wallet |
get_transactions | read | |
get_upgrade_history | read | (Incident investigation) Read upgrade governance across a package lineage: each version |
get_validators | read | List current Sui validators, or return detailed info for one |
get_wallet_overview | read | (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_packages | write | List package versions created by publish or upgrade transactions sent from this wallet address. Scans 20 sent transactions per call, oldest first; |
identify_address | read | |
list_dynamic_fields | read | (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_findings | read | (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_collections | read | Summary 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_nfts | read | (Recommended for NFTs) List NFTs owned by a wallet, including kiosk-stored NFTs. Each row has an object id, |
list_owned_objects | read | List raw objects owned by a Sui address with optional type filter and pagination. |
manage_labels | read | |
mvr_get_package_info | write | Get 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_resolve | write | Resolve one or more Move Registry (MVR) names to their on-chain package IDs. Names use the form |
mvr_resolve_struct | write | Resolve fully-qualified Move struct names (e.g. |
mvr_reverse_resolve | read | Reverse-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_search | write | Browse or search the Move Registry for packages. Searches name and description; returns one page (default 20 results) with a cursor for pagination. Pass |
poll_watch | read | Return 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. |
protocol | read | A package ID (0x...), an MVR name (@org/app), or a protocol name such as Cetus. |
query_events | read | Query events by type, sender, emitting module or time/checkpoint range. Event fields are decoded; no hand-written GraphQL is needed. Use a protocol |
query_transactions | read | |
resolve_bridge_transfer | write | |
resolve_name | read | Resolve a SuiNS name (.sui domain) to an address, or reverse-lookup an address to its SuiNS name. At least one of |
resolve_protocol_packages | read | |
sample_control_addresses | read | |
save_finding | write | |
screen_address | read | |
search_token | read | Find 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_transaction | read | |
subject | read | An attack transaction digest, or the attacker |
summarize_address_flows | read | (Incident investigation) Summarize an address |
summarize_incident_losses | read | (Incident investigation) Total an attacker |
trace_flow_graph | read | |
trace_funds | read | (Incident investigation) Follow a fund-flow path from a transaction. Forward traces a recipient |
trace_object_history | read | (Incident investigation) Trace an object |
v59 | read | Validator v59 |
watch_addresses | destructive | Add, 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. |
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.
| Layer | What it checks | Result |
|---|---|---|
| L0 | Provenance & inventory | PASS |
| L1 | Static analysis of the code | FAIL |
| L2 | Instruction surface (what it tells the agent) | PASS |
| L3 | Class-specific surface | WARN |
| L4 | Behavioural (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)
exec(sql: string): void;
const UNICODE = "Ωmega 🚀 名前 \u202e";
const TOKEN = "0x00000000000000000000000000000000000000000000000000000000000000b1";
delete_finding, watch_addresses
decompiler-safety.test.ts
protocol-exploit.md
cetus-exploit-grpc.json
scallop-exploit-ptb.json
exec(sql: string): void;
import { registerTransactionTools } from "../../dist/tools/transactions.js";import { registerAnalyzePackageTools } from "../../dist/tools/analyze-package.js";import { registerFundingTools } from "../../dist/tools/funding.js";import { registerHistoryTools } from "../../dist/tools/history.js";import { runWithNetwork } from "../../dist/config.js";const client = new SuiGrpcClient({ network: "mainnet", baseUrl: "http://127.0.0.1:9" });"0100000000000000000000000000000000000000000000000000000e1104194d802a62e389553ae6f061970ce1be2607c7f918154532e4296512d5a2c773424ff5001500000000000000000000000063186b34c809cca9f3825a3592082e1f1549fa5b0
"0100000000000000000000000000000000000000000000000000000000d7e5a5ac9258181f5ceac8dbffb7030890243caed69a9599d2886d957a9cb7656af3bdb30015e6c373f66273e9f86d0f4b0f77ad11ed7f3f8da1855e88116c689ad2de4d808e0
"03000000000000000000000000000000000000000000000000000000293ca6226f069b8857feab8184fb687f634618c035dac439dc1aeb3b5598a0f000000000010001000000000000000000000000cafd2f0a35a4459fa40c0517e17e6fa2939441ca0
"9945ff104b6aede12bf98dce51cd92a157e13e89bf2dd7c5e2cfe47e91ad315505a46ac50bc1525f6607fce6db3f8cd1e2a6163e839dd7f8429dbf30b164406217ccfad7009100000000000000000000000000000000000000000000000000000000000
"AAAAAAAAAAgAAAADAAAAAAAGfaSv3Hksea0RIV1mYcwGMg1IuffdRvTp1JAcRZhvpDDjyAAAAAAAAAAAAAAAABkzDRDZzIdRIY6vUeiIXQWGQuCKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPy4o0WPiUEKsfJVDwVZ1r1ql08J9vGVqZ/N/QpO
@grpc/grpc-js, @modelcontextprotocol/sdk, @mysten/sui, @protobuf-ts/grpc-transport, graphql-request, zod, typescript, vitest
@astrojs/starlight, astro, starlight-links-validator
| `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
src/data/coin-symbols.json
src/data/guardians-blocklist.json
Gates applied: no_behavioural_pass.
c3e898dcaddffull audit observations/trust-audit/mcp-server/0xfreak0__sui-mcp.json · Report an issue / request a re-scanAudit history
Every audit this server has had. A grade with a past is a grade somebody is still checking.
| Date | Source | Verdict | Grade | Score | Change |
|---|---|---|---|---|---|
| 2026-10-11 | c3e898dcaddf | BLOCK | D | 69 | first audit |
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.