rustok-mcp
OfficialThis MCP server lets an agent read a Rustok self-custody wallet's state and preview/execute transactions subject to human approval.
get_wallet_context — read the active wallet's address, held assets, and any assets that could not be read (with reasons), including policy_mode and policy_origin that determine how executions are handled.
get_balances — read per-asset balances for the active wallet (raw units + formatted, with
unavailabledistinguishing unknown from zero), or the native balance of an explicit address (requireschain_id).get_positions — read on-chain DeFi positions (Aave v3, ERC-4626) for the active wallet or a given address.
preview_transaction — preview an arbitrary transaction (native value + optional calldata), returning the decoded call, a pre-sign simulation/revert check, gas, and a risk level.
execute_transaction — submit a previewed transaction by
preview_id; a supervised (or unconfirmed autonomous) wallet parks it for a human to release in a separaterustok console, while a confirmed autonomous wallet releases it immediately.get_execution_status — poll a parked execution's outcome: pending, executed, denied, expired, failed, or non-terminal unknown.
Note: signing keys never leave Core, funds-moving approvals must be given by the human in a separate terminal, and the agent must never run the console command or ask for the PIN.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@rustok-mcpshow my wallet balance"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
rustok-mcp
MCP Server for Rustok — connects Claude Desktop, Cursor, and cloud agents to the Rustok wallet via Gateway.
Two editions
Rustok ships two wallet products — pick the trust model you want:
|
| |
Who signs | the agent, unrestricted | you, in a separate terminal ( |
Where | rustokwallet.com · ClawHub · image | this repo ( |
Line | 0.4.x (maintained from the | 0.5.x+ |
Related MCP server: seashail
Install (rustok-wallet-tui, self-custody)
Install trusted cosign 3+ independently, then use the verify-before-execute bootstrap in the published release skill. It downloads over --proto '=https' --tlsv1.2, verifies the manifest signature and installer hash before running the installer. There is no pipe-to-shell path. The repository skill is an unfilled source template; install wallet binaries only from the generated release/listing package.
rustok init # you choose a 6-digit PIN; the recovery phrase prints once
rustok connect claude # read-only; also cursor / hermes / openclawrustok connect claude --force --capabilities read_wallet,preview_tx,execute_tx requires confirmation in the user's own terminal before expanding rights. Core policy and PIN remain separate from the capability grant. rustok update verifies a signed release and preserves explicit subsets; live sessions retain their old image/grants until a human restart. There are no hard-coded spending limits after the user acknowledges unlimited autonomy.
The wallet is one self-contained image (Core + Gateway + MCP over stdio + the
human-approval console); keys live only in a local container volume and never
leave your machine. Transactions that move funds are approved by a human in a
second terminal with rustok console — the agent cannot drive it.
Install as an agent skill
The wallet skill (skills/rustok-wallet-tui/)
installs straight from this repo:
# skills CLI (Claude Code, Cursor, and other agents) — https://skills.sh
npx skills add rustok-org/mcp
# Hermes Agent
hermes skills tap add rustok-org/mcp
hermes skills install rustok-org/mcp/rustok-wallet-tuiBoth editions are on ClawHub as separate listings: the agent edition at
@temrjan/rustok-wallet, and the
console edition — the maintained one — at
@rustok/wallet, published as
Rustok Agentic Wallet.
Registries
Official MCP Registry — the agent edition is published as
io.github.rustok-org/rustok-wallet(OCI packageghcr.io/rustok-org/rustok-wallet, stdio). A TUI-edition registry entry ships separately asio.github.rustok-org/rustok-wallet-tui.ClawHub — two listings: the console edition (maintained) at
@rustok/wallet, and the agent edition at@temrjan/rustok-wallet.
Quick Start (Development)
# Install dependencies
uv sync --dev
# Run the server
uv run rustok-mcp
# Or run stdio transport
uv run rustok-mcp-stdioDocker
docker build -t rustok-mcp .
docker run -p 127.0.0.1:3001:3001 -e RUSTOK_MCP_HOST=0.0.0.0 rustok-mcpTo run the full stack (MCP → Gateway → Core + Redis), use the compose file
in rustok-org/meta.
Authentication
The network-facing SSE transport is gated by a shared bearer token.
Inbound (
RUSTOK_MCP_INBOUND_API_KEY) — clients must sendAuthorization: Bearer <token>to reach/mcp/sseand/mcp/message. Distinct from the outboundRUSTOK_MCP_API_KEY(MCP → Gateway).Dev: leave it empty — the loopback flow stays open and the server logs a warning at startup.
Prod: required. The token must travel in the request header, never in a query string (query strings leak into access logs). Generate one with
openssl rand -hex 32.The browser
EventSourceAPI cannot set headers and is not a supported client; use an MCP client that sends request headers./healthis always public (used by the container healthcheck).The local stdio transport is process-trusted and not gated.
⚠️ The MCP has no built-in brute-force / rate-limit protection. Terminate it behind the edge proxy (Caddy) with host-level rate limiting (see the
rustok-org/metadeploy docs); do not expose it to the internet directly.
What is Rustok?
Rustok is a self-custody AI-native crypto wallet. The MCP Server is a thin bridge between LLM agents and the Rustok Gateway — private keys never leave the Core service (they stay in the local keystore volume).
Self-custody: keys are encrypted at rest (Argon2id + AES-256-GCM) and only decrypted inside Core on your machine.
Capability-gated tools (
read_wallet/preview_tx/execute_tx): the stdio transport defaults to read-only (explicit grants useRUSTOK_MCP_CAPABILITIES); the network-facing SSE transport is bearer-gated.No spending policy by design: no hard-coded limits, budgets, or blocklists — you consciously accept the risk of funds on the agent wallet.
txguardsurfaces a risk level on preview but does not block. Opt-in limits may come later.Chains:
RUSTOK_ALLOWED_CHAINSdecides which ones are shown (default1,8453,42161— Ethereum, Base, Arbitrum). Those read out of the box: the build carries two public nodes for each. Naming your own (RUSTOK_RPC_URLS_<id>, or an Alchemy key) replaces the carried list rather than joining it. Any node that reads a balance learns the address and the IP that asked — that is true of ours, yours, and your provider's alike.Informed preview:
preview_transactionreturns the decoded call (who/what is authorized), a pre-sign simulation (revert check), gas, and a txguard risk level. Execution is not exposed as an MCP tool.Audit logging: every action is append-only logged to SQLite in Core.
Documentation
License
This repository is licensed under MIT-0.
The warranty and liability terms it carries, and the limit of every safeguard this wallet advertises, are stated in full here: https://github.com/rustok-org/mcp/blob/main/DISCLAIMER.md
The Rustok Core wallet engine is a proprietary artifact built from the private rustok-org/core repository.
Available Tools
3 toolsget_balancesA
Get the balances of the active wallet, or the native balance of an explicit address.
Active wallet (no address): one row per asset — balance is in that asset's own raw units and balance_formatted is the same amount with decimals applied, so show that one. balance_eth appears only on a native-coin row, where it equals balance_formatted; a token never has it, because the amount is not in ETH. token_address is empty for the native coin and is what tells two tokens with the same symbol apart.
unavailable comes back beside balances and lists what could NOT be read, with a reason. An asset missing from balances while unavailable is empty holds zero; if it is named in unavailable, the balance is unknown, not zero — do not report it as empty.
With an explicit address the answer is different and smaller: one native row carrying balance (wei) and balance_eth, with no balance_formatted, decimals or token_address. The token registry describes this wallet's own holdings, so tokens are never reported for somebody else's address.
| Name | Required | Description | Default |
|---|---|---|---|
| address | No | Optional address to query instead of the active wallet (requires chain_id) | |
| chain_id | No | Chain ID: optional filter for the active wallet, required with address |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Since no annotations are provided, the description carries full transparency burden and meets it thoroughly. It explains field semantics (`balance_formatted`, `balance_eth` only on native rows, `token_address` disambiguates tokens), the `unavailable` list, the zero-vs-unknown distinction, and that tokens are never reported for other addresses. This is detailed behavioral disclosure beyond a simple 'returns balances'.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but entirely informative, systematically covering field meanings, edge cases, and mode differences. It could be trimmed, but every sentence contributes to correct interpretation, so it earns a 4 rather than a lower score.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description must explain the return value and does so comprehensively: row structure, which fields appear in which mode, how to handle `unavailable`, and the zero/unknown distinction. The tool's complexity justifies this depth.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Both parameters are already fully described in the input schema (100% coverage), so the description adds no new parameter-level semantics beyond what's in the schema. It does reinforce the relationship between `address` and `chain_id`, but the schema already states that; per the rubric, baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb-resource statement ('Get the balances of the active wallet, or the native balance of an explicit address'), making the tool's function unmistakable. It further clarifies scope with two distinct modes, but it does not explicitly contrast this with sibling tools like get_positions or get_wallet_context.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly delineates when to use each mode: 'Active wallet (no `address`)' vs 'With an explicit `address` the answer is different and smaller,' including parameter dependencies. It lacks explicit guidance on when to prefer this tool over alternatives, but the usage context is well-defined.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_positionsA
Get on-chain DeFi positions (Aave v3, ERC-4626) for the active wallet, or for an explicit address.
| Name | Required | Description | Default |
|---|---|---|---|
| address | No | Optional address to query instead of the active wallet |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided; description states 'get' implying read-only. Does not declare lack of side effects, rate limits, or auth requirements. Adequate but minimal behavioral disclosure beyond what is obvious.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single sentence, concise and front-loaded with core action and scope. Could be slightly improved by separating the address override clause, but remains efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists. Description does not describe return format (e.g., array of position objects, fields like protocol, asset, amount). Missing key information for an AI agent to interpret results.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%; parameter description in schema is clear ('Optional address to query instead of the active wallet'). Main description reinforces this but adds no new semantic details beyond schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Purpose is explicit: retrieves on-chain DeFi positions (Aave v3, ERC-4626) for the active wallet or a given address. Clearly distinguishes from siblings like get_balances (token balances) and get_wallet_context.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
States when to use (to get DeFi positions) and the option to specify an address. No explicit when-not-to-use or alternatives, but the context of sibling tools makes this clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_wallet_contextA
Get the active wallet: its address, the assets it holds, and the assets it could not read. A balance row carries symbol, balance (the asset's own raw units), decimals, balance_formatted (the amount to show) and token_address (empty for the chain's native coin). unavailable lists what could not be read and why — so a row missing from balances while unavailable is empty means the balance is zero, not unknown.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It thoroughly explains the balance row structure, the meaning of `unavailable`, and how to interpret missing balances. This goes beyond a basic summary, but it does not cover potential errors or rate limits, which are less critical here.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise yet informative. The first sentence gives the overview, and the following sentences clarify the field structure and the interpretation of `unavailable`. Every sentence adds value without unnecessary repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description must explain return values, and it does so in sufficient detail. It covers the main fields, the meaning of `unavailable`, and the balance interpretation logic, making the tool's behavior predictable and complete for an agent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There are zero parameters, so the description does not need to add parameter-level detail. The schema coverage is 100% by default, and the description focuses on return semantics, which is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool gets the active wallet and its details: address, balances, and unreadable assets. This distinguishes it from siblings like get_balances and get_positions by adding the unreadable-assets feature and the focus on 'active wallet'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use the tool by explaining its output and the meaning of the `unavailable` field, but it does not explicitly compare with alternatives or state exclusions. It is not misleading, but usage guidance is only implicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
3 tool updates
v0.8.6- Removed
execute_transaction - Removed
get_execution_status - Removed
preview_transaction
1 tool update
v0.8.4- Removed
sign_message
7 tool updates
v0.8.2- First observed
execute_transaction - First observed
get_balances - First observed
get_execution_status - First observed
get_positions - First observed
get_wallet_context - First observed
preview_transaction - First observed
sign_message
TDQS
Scored across 3 tools
get_balances and get_wallet_context substantially overlap: both return balance rows, `unavailable` entries, and the same asset metadata, with get_wallet_context essentially adding the wallet address. An agent can distinguish get_positions easily, but the boundary between the other two is fuzzy and could cause misselection.
All three tools follow a uniform `get_<noun>` snake_case pattern (get_balances, get_positions, get_wallet_context), which is highly predictable and readable.
Three tools is on the thin side for a wallet/DeFi server; the surface feels minimal and only covers reading, with no clear separation of concerns to justify the small count.
Coverage is read-only: balances, DeFi positions, and wallet context are present, but there are no transaction, transfer, approval, or history operations, leaving notable gaps in the wallet lifecycle an agent might need.
Maintenance
Related MCP Connectors
MCP server for Boson Protocol — on-chain agentic commerce for physical & digital goods.
MCP server for your apps' tools and custom tools, plus hosted AI agents and approval-gated workflows
MCP server for the Z1N Protocol - on-chain identity for AI agents on Polygon
Tenzro Network MCP server: wallet, identity, payments, inference, staking, bridges, verification.
Related MCP Servers
- AlicenseNot gradedqualityFmaintenanceA lightweight, fast MCP server that provides onchain capabilities for the LLMs and Agents.62 npm255MIT
- AlicenseNot gradedqualityDmaintenanceAgent-native, self-hosted MCP server for crypto trading and DeFi management. Enables agents to query balances, execute trades, and manage positions with a policy engine and secure key storage.7Apache 2.0
- AlicenseNot gradedqualityCmaintenanceSelf-hosted MCP server enabling AI agents to manage EVM wallets, check balances, swap tokens, and securely execute transactions via 1Claw Intents without exposing private keys.50 PyPIMIT
- AlicenseCqualityDmaintenanceMCP server enabling LLMs to interact with a Cardano node by wrapping cardano-cli/torsten-cli, supporting queries, transactions, staking, and governance operations.64MIT