Read-only Sui analytics: fund tracing, protocol-aware tx decoding, no API keys or wallet.
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.
67 tools. It also does the ordinary things well — wallet overviews, DeFi positions, NFTs, prices, Move package analysis — but the reason to pick this one is the forensics.
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.
Doing investigative work? Start with the forensics tools loaded:
"env": { "SUI_TOOLS": "core,forensics" }
Ranking a lending protocol's wallets for a day, then testing whether a cluster is coordinated — six calls:
aggregate_events(module: <package>, from: "2026-08-07T00:00:00Z", to: "now")
→ every event type it emits, with counts and the numeric fields available
(user actions are usually far rarer than bookkeeping events)
aggregate_events(event_type: <DepositEvent>, value_field: "event.deposit_value", value_scale: 100)
→ wallets ranked by USD deposited, truncated: false
find_funding_sources(addresses: [...25], depth: "first_hop")
→ 23 of 25 share one funder, funded in three bursts of under a minute
get_address_fanout(<that funder>)
→ 1,623 recipients — "distributor", so co-funding alone proves nothing;
the second-level timing clustering is what carries it
That last step is the point. Several wallets tracing to one funder looks decisive until you measure the funder. Every funding result carries that measurement so a coincidence doesn't get reported as a link.
Fan-out reports shape as well as size, because size alone doesn't separate the cases that matter. Measured on the same day, a known exchange and a sybil funder had almost identical counterparty counts — 399 and 431 — and completely different flow: the exchange ran balanced at 0.73 out/in (deposits in, withdrawals out) while the funder ran 9.78 (it pays many and is paid by few). One is noise in an investigation; the other is the thing you're looking for.
A Sui address is the hash of whatever authenticates it. For a multisig, the threshold, every member key and every weight are part of that hash, so the committee can be read off the address and checked — derive it, confirm it reproduces the address.
Identify a wallet and its committee. identify_address returns the shape, every member address, and each member resolved to its own name, labels and SuiNS history.
identify_address(0x045dadba…)
→ authentication: multisig, 4-of-7, verified: true
committee_members: 7, each with name/label/kind
See which keys are actually used. The committee never changes, but who signs varies per transaction. analyze_multisig reads that across the wallet's history.
analyze_multisig(0x045dadba…, max_transactions: 200)
→ transactions_examined: 8
signer_sets: [0,1,3,4] x4, [1,2,3,4] x2, [0,2,3,4] x2
always_present: [3, 4]
dormant_members: [5, 6]
active_signers_meet_threshold: true
dormant_members are keys that hold weight and have never used it. always_present are keys the wallet currently cannot move without. Both are reported against transactions_examined, since the claim is only as good as the window.
See who authorised one transaction. get_transaction returns an authorization block naming the keys that signed and the members that did not, plus the gas sponsor when there is one.
get_transaction(oxrJ3Bppuk…)
→ authorization[0]: sender, multisig 4-of-7
signed_by: [0, 1, 3, 4]
did_not_sign: [2, 5, 6]
Search backwards from keys to a treasury. Given addresses a trace has already linked, find_shared_multisig derives every committee they could form and returns the ones that exist on chain. This finds multisigs that never appeared in the trace, since a wallet is only visible if it transacted with something you looked at.
find_shared_multisig([0xafe2fafa…, 0xc848c5cc…])
→ candidates_checked: 4, found: 1
0xcf4e7b88… 1-of-2, evidence_tier: chain-derived
Clustering. build_wallet_edges emits a co_signer edge for any key that can spend a wallet on its own, and marks clusters built only from those chain-derived rather than heuristic. Keys sitting on more committees than the limit are treated as custody or wallet-provider keys and listed under excluded_co_signers instead of linking everyone who uses that provider.
Limits, also stated in the tool output. Member order is part of the address, so find_shared_multisig is factorial in committee size and refuses past five keys; it covers equal-weight committees only, so a nil result is not a negative finding. A wallet that has never sent a transaction cannot be classified at all — it has produced no signature — and comes back as unknown rather than as an ordinary wallet.
zkLogin and passkey wallets go through the same path. zkLogin reports its OAuth issuer, which is all the chain discloses about the account.
Several tools now qualify their own answers, because a confident-looking number is worse than an absent one.
Is this coin the one you meant? A symbol is not an identifier on Sui — 8,008
mainnet coins share one with another, and imitators are named to be mistaken.
analyze_token reports verified, and every balance change in a trace carries
coin_verified:
-850 MAGMA (unverified, assumed scale) coin_verified=false
+202.361728 USDC coin_verified=true
Two separate marks. unverified is about which coin. assumed scale is about
whether the number is right at all — decimals for an unknown coin are a guess,
and 47 of 289 imitators declare a different scale from the coin they imitate.
An ambiguous symbol returns candidates rather than a coin. USDC matches seven
legitimate verified coins on Sui (Circle's, Wormhole's, Celer's), so picking one
would misreport which asset moved.
Why did it fail? get_transaction returns the abort code with the package,
module and function that raised it, and a clever error's constant name where the
author defined one.
Who deployed this, and can they still change it? analyze_package and
identify_address report publisher — the address that created the package,
attributed to the lineage root. The UpgradeCap carries holder_status:
burned means upgrade rights were renounced, which reduces risk, and is what
27 of every 30 departing caps did.
Has an issuer frozen this address? check_coin_restrictions reads the
on-chain deny list in both directions. A frozen address usually holds none of
the coin that froze it, so it checks every configured coin type rather than the
ones it holds.
What moved that was not a coin? trace_funds reports object_flow.
Sui is object-based, so a balance change only covers Coin<T> — an NFT, a
Kiosk or a capability changes hands without producing one:
--- Hop 1 (2025-01-10 10:25:31 UTC) ---
Sender: 0x8c4f…5ee8
Action: Transfer to recipient
Objects:
package::UpgradeCap ⚠ 0x8c4f…5ee8 -> 0xeda2…6c2b
Whoever holds this can publish new code for the package.
Kiosk moves count: a kiosk-held NFT is owned by the Kiosk object, so the
ordinary NFT trade reads object -> object and is reported as a custody
change. A DeFi position is named by its protocol (position::Position (Cetus)) rather than lumped in with pictures.
Transfers of UpgradeCap, TreasuryCap, DenyCap, DenyCapV2 and
Publisher are marked as carrying control. A capability sent to an unspendable
address is reported as renounced_capabilities — rights given up, the opposite
of a handover.
What has happened since I last looked? watch_addresses records a set of
addresses and where it last looked; poll_watch returns only what is new:
{ "watched": 20, "active": 0, "hits": [], "requests": 1 }
That empty answer is 13 tokens and one request, which is what makes it callable
on a loop — nothing triggers a poll on its own, so the caller drives it. A hit
names the address, digest, checkpoint and why it fired — never the transaction
itself, which stays a get_transaction call away:
| reason | |
|---|---|
value_in / value_out | coin moved, with per-coin nets |
capability_moved | mint, upgrade, freeze or publish rights changed hands |
object_moved | an NFT, kiosk item or DeFi position changed hands |
sink_reached | a counterparty carries a sink label |
lookalike_appeared | a new counterparty renders like a watched address |
appeared | something happened that moved no coin and no named object |
Watching starts from the current checkpoint, so adding an address does not
replay its history. min_amount filters coin movements only: a labelled sink
or a transfer that moves no coin is reported whatever its size. An address busy
enough to fill the per-poll cap is listed in more_pending rather than being
silently truncated. Requires SUI_STORE_PATH.
Are these really the top holders? Only when complete_ranking is true.
get_top_holders walks coin objects in object-id order, which is unrelated to
balance, so a scan that stops early returns the largest holder it saw. On SUI
the reported top holder goes from 66 SUI at max_scan 200 to 3,454 at 800,
with no overlap in the top five. A truncated scan therefore returns
sampled_holders — no rank, no percentage of supply — and says so. Raise
max_scan until truncated is false for a real ranking, which is only
feasible for coins few enough to enumerate. analyze_token makes the same
distinction.
Is this address the one it looks like? get_transaction_history and
trace_funds compare every address they touch and report address_poisoning
when two of them are close enough to be mistaken for one another:
⚠ Addresses in this trace close enough to be mistaken for one another:
0xd649a4d5…57127127 vs 0xd642ef27…c75d7127
An attacker generates an address sharing the leading and trailing characters of one you already deal with, sends dust from it, and waits for someone to copy the wrong row out of their own history. The check runs over senders, balance-change recipients and the branches a trace declined to follow — a poisoning wallet sends, so it never appears as a counterparty, and the lookalike is usually several hops from the address it imitates.
A pair is reported when at least three characters match at each end — about one collision in seventeen million pairs by chance. They do not render identically at every width; what they share is both ends, which is what defeats a glance and a short truncation.
The address with the larger footprint is named as the established side, and only
when the gap is wide enough to mean something — dust repeating inside one page
is the normal shape of this attack, so a small margin is not evidence. Otherwise
the pair is reported with direction_known: false rather than guessing.
Does this address pay other people's gas? get_address_fanout reports
sponsor_shape — invisible to value fan-out, since sponsoring moves none of
the sponsor's own money. relayer is proven; private_sponsor off a truncated
scan is flagged provisional, because breadth only grows with the window.
The server gives Claude chain access. It does not, on its own, give it method — which tool answers which question, what a control group is for, or which conclusions to refuse. That lives in a skill shipped alongside it.
mkdir -p ~/.claude/skills
cp -r "$(npm root -g)/sui-analytics-mcp/.claude/skills/sui-forensics" ~/.claude/skills/
Or copy .claude/skills/sui-forensics/ out of this repo. It loads automatically
once present; there is nothing to configure.
It covers the evidence tiers and what each licenses you to claim, the order to work in, the base-rate check that stops shared ancestry reading as collusion, and the conclusions to refuse — "no edge found, so they are unrelated" being the one that costs most.
All 67 tools loaded at once cost about 14k tokens of context on every request, and a large flat tool list makes models pick the wrong tool. So the server starts with a core set of 17 and keeps the rest one call away.
When you ask for something outside the current set — "trace where these funds went" — the model calls enable_tools and the tracing tools appear immediately, no restart. You never have to pick a profile.
To start with more, set SUI_TOOLS:
"env": { "SUI_TOOLS": "core,forensics" }
| Profile | Tools | Contents |
|---|---|---|
core (default) | 18 | Wallets, balances, transactions (single and batched), tokens, NFTs, DeFi positions, staking, pools, names |
forensics | 29 | Fund tracing, funding-source attribution, cross-chain bridge resolution, wallet-edge clustering, package analysis, control-group sampling, timelines, object provenance, labels, events, oracle-vs-market deviation, live address watching |
developer | 18 | Move packages, disassembly, decompilation, upgrade diffing, dependency graphs, PTB decoding, unsigned transaction building, Move Registry |
market | 6 | DeepBook order book and fills, pool stats, token search, validators |
all | 59 | Everything |
Runtime switching relies on notifications/tools/list_changed. Claude Code and Claude Desktop honour it; some clients cache the tool list and will only see the change after a restart. SUI_TOOLS always works, so set it explicitly if your client doesn't refresh.
Upgrading from 1.1.x, where every tool loaded at startup? Set SUI_TOOLS=all to keep that behaviour.
The server has no credentials and no ability to move funds:
build_transfer and build_staking return unsigned BCS bytes that you sign and broadcast somewhere else; simulate_transaction dry-runs bytes against a fullnode without executing them.Supply-chain scanners report the capabilities a package uses, without the reason. Here is the full list for this one:
| Capability | Where it's used |
|---|---|
| Network | Public Sui RPC and GraphQL, plus Pyth, Aftermath and the Move Registry for prices and name resolution. Hosts are listed in src/config.ts. |
| Filesystem | Temp files for decompile_module, and reading SUI_LABELS_FILE if you set it. |
| Subprocess | One call, in src/tools/decompiler.ts, to the decompiler binary you build and point at. execFile with array arguments, so no shell is involved and nothing is interpolated into a command string. |
| Environment | The SUI_-prefixed variables in .env.example, plus two optional price-provider keys (PYTH_API_KEY, CMC_API_KEY). Nothing else is read. |
There is no eval, no dynamic require, no minified or obfuscated code, and no telemetry. Inputs that come from the chain are treated as untrusted: decompile_module validates module names before they reach a filesystem path, and bounds how many modules one call will process.
Most of the dependency tree is the MCP SDK. This server speaks stdio only and imports just server/mcp.js and server/stdio.js, so the SDK's HTTP-transport dependencies are installed but never loaded.
Releases are published from CI with npm provenance, so every tarball carries a signed attestation tying it to the commit and workflow run that produced it:
npm audit signatures
network arg (mainnet / testnet / devnet); query multiple networks in one session (e.g. compare a testnet value to mainnet). SUI_NETWORK sets only the default.@deepbook/core to package addresses, and backAll environment variables are optional. See .env.example for the full list; the common ones are SUI_NETWORK (default network), SUI_FULLNODE_URL / SUI_GRAPHQL_URL (custom RPC endpoints), and SUI_LABELS_FILE (address attribution labels for fund tracing).
Current USD prices come from Aftermath, which is free and needs no key — that is the default path and it covers everything except historical pricing.
Two paid sources are opt-in and engage only when their key is set, so nobody is billed by accident and nothing degrades if you set neither:
| Variable | Enables |
|---|---|
PYTH_API_KEY | Historical prices (get_token_prices with at), oracle-vs-market comparison. Pyth's Hermes endpoint began requiring authentication for price values; feed discovery is still open. |
CMC_API_KEY | CoinMarketCap as an additional current-price source. Note it keys on ticker symbols, which are not unique on-chain, so it is only consulted for symbols already mapped to a coin type. |
Without a key, tools that need a paid source say so explicitly rather than returning a null price — a missing price and a price of zero are different claims.
Set SUI_STORE_PATH to keep address labels and fan-out measurements across sessions. It uses Node's built-in node:sqlite, so it adds no dependency and no native build. Unset by default — nothing is written to disk unless you ask for it, which matters because an investigation store is a record of which addresses you looked at.
"env": { "SUI_STORE_PATH": "/Users/you/.local/share/sui-mcp/store.db" }
Fund traces are deliberately not cached: a trace is a function of your labels, so a stored one would silently disagree with a fresh run the moment a label changed.
{
"mcpServers": {
"sui": {
"command": "npx",
"args": ["-y", "sui-analytics-mcp"],
"env": { "SUI_NETWORK": "testnet" }
}
}
}
64 of the 67 tools need nothing beyond the install above. Only decompile_module requires an external binary, and there are lighter options before you reach for it:
disassemble_module returns Move bytecode assembly via the GraphQL endpoint.analyze_package summarizes a package's API and runs a heuristic risk scan.diff_package_upgrade diffs two versions of a package.Use the decompiler when you want higher-level, source-like Move output instead of bytecode.
The binary is Revela's move-decompiler, built from Rust. It is not bundled in the npm package because a published tarball could only carry one platform's build, so you compile it once yourself and point the server at it with SUI_DECOMPILER_PATH. This works the same whether you installed via npx or from source. You need a Rust toolchain (rustup.rs); the build takes a few minutes.
git clone --depth 1 https://github.com/verichains/revela_sui.git
cd revela_sui/external-crates/move
cargo build --release --bin move-decompiler
# binary lands at target/release/move-decompiler
Then add its absolute path to your client config:
{
"mcpServers": {
"sui": {
"command": "npx",
"args": ["-y", "sui-analytics-mcp"],
"env": {
"SUI_DECOMPILER_PATH": "/absolute/path/to/revela_sui/external-crates/move/target/release/move-decompiler"
}
}
}
}
If you already cloned this repo, npm run build:decompiler does the same clone and build and copies the result to bin/move-decompiler.
Without SUI_DECOMPILER_PATH the server falls back to looking for move-decompiler on PATH. Prefer the absolute path: desktop clients often launch servers with a minimal environment that doesn't include your shell's PATH, so a binary you can run in a terminal may still be invisible to the server. If it's found in neither place, decompile_module returns an error explaining how to fix it, and the other 56 tools are unaffected.
For development, or to run a version you've modified:
git clone https://github.com/0xfreak0/sui-mcp.git
cd sui-mcp
npm install
npm run build
Then point your client at the build output instead of npx:
{
"mcpServers": {
"sui": {
"command": "node",
"args": ["/absolute/path/to/sui-mcp/dist/index.js"]
}
}
}
See CONTRIBUTING.md for the development and release workflow.
| Tool | Description |
|---|---|
identify_address | Identify what a Sui address is: wallet, package, validator, or object |
get_wallet_overview | Comprehensive wallet overview: balances, SuiNS name, staking, kiosks, recent txs |
get_transaction_history | Decoded activity feed with protocol names and human-readable actions |
analyze_token | Full token analysis: metadata, price, 24h change, supply, top holders |
| Tool | Description |
|---|---|
get_chain_info | Current chain ID, epoch, checkpoint height, timestamp, gas price |
get_checkpoint | Checkpoint details by sequence number or digest |
| Tool | Description |
|---|---|
get_object | Object by ID with type, owner, JSON content, and display metadata |
list_owned_objects | List objects owned by an address with optional type filter |
list_dynamic_fields | Dynamic fields of an object (tables, kiosk contents, etc.) |
| Tool | Description |
|---|---|
get_balance | Balance of a coin type for an address (defaults to SUI) |
get_coin_info | Token metadata: name, symbol, decimals, description, supply |
search_token | Search tokens by name/symbol, with Aftermath Finance fallback |
get_token_prices | USD prices for tokens — current (Aftermath + Pyth), or historical via Pyth when at is set |
| Tool | Description |
|---|---|
get_transactions | Reads up to 50 transactions in ONE call given their digests — sender, timing, balance changes, Move calls, and events with decoded fields. Ten digests go from ten round trips to one. Malformed digests are rejected before the request, because the server refuses a whole batch over one bad key |
get_transaction | Transaction by digest with protocol-decoded actions |
query_transactions | Filter transactions by sender, address, object, or function |
query_events | Filter events by type, sender, module, or checkpoint range |
| Tool | Description |
|---|---|
get_defi_positions | DeFi positions across Suilend, Cetus, NAVI, Scallop, Bluefin, Bucket |
find_pools | Discover liquidity pools by token pair (Cetus, DeepBook, Turbos) |
get_pool_stats | Pool reserves, fees, and prices for a given pool object ID (AMMs; see below for DeepBook) |
DeepBook v3 is a central limit order book, so it has no reserves — depth, spread and traded price come from the DeepBook indexer rather than from a pool object. Mainnet and testnet only.
| Tool | Description |
|---|---|
deepbook_orderbook | Live bid/ask depth, spread, mid price and resting-liquidity imbalance. Omit pool_name to list pools. |
deepbook_trades | Recent fills with maker/taker balance manager IDs — attribute trading to an account during an incident window |
compare_oracle_price | (Security) Pyth oracle price vs the price DeepBook actually traded at, over a window — detects stale feeds, manipulation windows, and liquidations priced at levels the market never printed |
| Tool | Description |
|---|---|
list_nfts | List NFTs owned by a wallet, including kiosk-stored NFTs |
list_nft_collections | Lightweight collection summary with counts |
get_top_holders | Holders of an NFT collection or token — a ranking only when the scan completes |
| Tool | Description |
|---|---|
get_validators | List validators (stake, commission, voting power), or full detail for one when address is set |
get_staking_summary | Wallet's staking positions and pools |
| Tool | Description |
|---|---|
resolve_name | SuiNS name resolution (forward and reverse) |
The Move Registry maps human-readable package names like @suins/core or @deepbook/core to on-chain package addresses. Backed by mainnet.mvr.mystenlabs.com/v1 (or testnet.mvr... when SUI_NETWORK=testnet).
| Tool | Description |
|---|---|
mvr_resolve | Resolve one or many MVR names → package IDs. Accepts version-pinned names like @suins/core/3. |
mvr_reverse_resolve | Reverse-lookup: package addresses → MVR names. Useful for enriching raw addresses anywhere. |
mvr_get_package_info | Full record for a name: metadata, version, package_address, package_info ID, git source. |
mvr_search | Browse / search the registry. Supports substring search, pagination, and an is_linked filter for published packages. |
mvr_resolve_struct | Resolve @org/app::module::Type → canonical type tag at the type's defining-package address. |
Typical flows:
@deepbook/core?" → mvr_resolve(['@deepbook/core']) → 0x4874e1.... Hand the address to get_package for module/function details.0xf22f…?" → mvr_reverse_resolve(['0xf22f…']) → @suins/core.mvr_search('deepbook', limit=20, is_linked=true) → paginated list.mvr_resolve(['@suins/core/3']) returns the v3 package address rather than the latest.| Tool | Description |
|---|---|
get_package | Move package modules, structs (with ordered fields), and functions |
get_move_function | Specific Move function signature and parameters |
get_package_dependency_graph | Package dependency analysis with recursive traversal |
analyze_package | Summarize a package's API + heuristic risk scan (no binary; accepts 0x id or MVR name) |
disassemble_module | Disassemble Move bytecode via GraphQL (no binary; accepts 0x id or MVR name) |
decompile_module | Decompile Move bytecode to source (requires decompiler binary) |
diff_package_upgrade | (Security) Diff two package versions to spot what an upgrade changed — malicious-upgrade / backdoor detection |
| Tool | Description |
|---|---|
build_transfer | Build an unsigned transfer of SUI or any coin (auto coin selection); returns BCS for simulate_transaction |
build_staking | Build an unsigned stake/unstake transaction (action: stake|unstake) |
simulate_transaction | Dry-run a transaction to preview effects and gas cost |
| Tool | Description |
|---|---|
decode_ptb | Decode a Programmable Transaction Block from BCS bytes |
check_activity | Monitor address or object for new activity since a checkpoint |
| Tool | Description |
|---|---|
trace_funds | Swap-aware, USD-valued multi-hop fund tracing that stops at labeled sinks (forward or backward) |
resolve_bridge_transfer | Follow funds across a bridge, in either direction. Resolves Wormhole (VAA identity (emitter chain, emitter address, sequence)), Sui's native bridge and Circle CCTP — the latter two carry the destination chain and recipient in their own events, so their far side needs no indexer at all. Detects Mayan MCTP and any package the registry types as a bridge. Inbound claims resolve to their origin chain and transfer id rather than being mistaken for exits. Every result is tiered: chain-derived trusts nobody, indexer-attested is a lead to confirm |
find_funding_source | Walk an address back to its funding source(s) for attribution; stops at labeled exchanges/bridges |
find_funding_sources | Same, for up to 100 addresses in one call — shares work across converging chains, reports shared funders with flow shape, addresses paid by one transaction (weighed against that transaction's full recipient count), subjects that funded each other, and sub-minute funding bursts |
sample_control_addresses | Draw a random, reproducible control group from the same protocol and window, so a cohort's rate can be compared against chance |
resolve_protocol_packages | Find which of a protocol's package versions are actually emitting now — the bundled registry is a decode map full of historical IDs, and querying one returns nothing |
get_address_fanout | How many distinct addresses a funder pays. Tells an exchange hot wallet apart from a real common origin |
build_wallet_edges | Finds addresses that may share an operator with the ones you give it, and shows the evidence. Multisig co-signature (read from the address hash, not inferred), shared first funder, direct funding, shared gas sponsor, or a third party paying both. Exchanges and relayers are measured and discarded first |
analyze_multisig | For a multisig wallet, which committee keys are actually live and which have never signed, across its history. The committee is fixed for the life of the address; only who signs varies |
find_shared_multisig | Given addresses you suspect are related, derive every committee they could form and find the multisig they jointly control — a hit is proof, since the address IS the hash of its committee |
check_coin_restrictions | Read a regulated coin's on-chain deny list — which addresses its issuer froze, or whether a given address is frozen for the coins it holds. Chain-derived: it is the issuer's own decision, reversible by whoever holds the DenyCap |
save_finding | Record a conclusion against a named case, so an investigation outlives its session |
list_findings | List findings in a case, or every case with its count |
export_case | Render a case as a Markdown report, highest-confidence findings first |
delete_finding | Retract a finding that turned out to be wrong |
aggregate_events | Rank wallets or event types by activity/value over a time window — "top wallets on this protocol today" in one call |
build_timeline | Merge multiple addresses' activity into one checkpoint-ordered, protocol-decoded timeline |
trace_object_history | Object provenance: version history + ownership transitions (who created/held an object when) |
manage_labels | Address-label registry (exchanges, bridges, mixers, malicious wallets) used by the tracing tools |
diff_package_upgrade | Diff two package versions to detect malicious upgrades / backdoors |
Source-derived launch command. Check the maintainer’s required arguments and credentials before running:
npx -y sui-analytics-mcpMerge this template into ~/Library/Application Support/Claude/claude_desktop_config.json. Keep existing servers. Add any arguments, credentials, and permissions required by the maintainer; this template has not been install-tested.
{
"mcpServers": {
"io-github-0xfreak0-sui-mcp": {
"command": "npx",
"args": [
"-y",
"sui-analytics-mcp"
]
}
}
}Restart Claude Desktop completely for changes to take effect. Confirm the server appears connected in the client’s tool list, then try a read-only example from its documentation.
Claude Desktop setup referenceSui Analytics works with any MCP-compatible client. Copy the config snippet from the Configuration section above and add it to the file shown for your client, then restart the application.
~/Library/Application Support/Claude/claude_desktop_config.jsonRestart Claude Desktop completely for changes to take effect.~/.cursor/mcp.jsonRestart Cursor for changes to take effect..vscode/mcp.jsonReload VS Code window for changes to take effect.~/.codeium/windsurf/mcp_config.jsonRestart Windsurf for changes to take effect..mcp.jsonSave at the project root, then start Claude Code in that project and review the MCP server approval prompt. Keep real credentials out of shared files.