Skip to main content
Glama

rustok-mcp

CI License: MIT-0

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:

rustok-wallet (agent edition)

rustok-wallet-tui (this repo)

Who signs

the agent, unrestricted

you, in a separate terminal (rustok-console, y/N + PIN)

Where

rustokwallet.com · ClawHub · image ghcr.io/rustok-org/rustok-wallet

this repo (main) · ClawHub · image ghcr.io/rustok-org/rustok-wallet-tui

Line

0.4.x (maintained from the wallet-v0.4.0 tag)

0.5.x+

Related MCP server: seashail

Install (rustok-wallet-tui, self-custody)

curl --proto '=https' --tlsv1.2 -fsSL \
  https://raw.githubusercontent.com/rustok-org/mcp/wallet-tui-v0.11.0/scripts/install.sh | sh

rustok init             # creates the wallet — you choose a PIN, it prints the 12 words once
rustok connect claude   # registers it with your agent (or: cursor / hermes / openclaw)

The console image is published by version only — there is no latest tag to pull, on purpose: the installer pins the exact digest of the release it ships with, and a floating tag would quietly undo that.

The installer verifies the wallet image's cosign signature before anything touches disk, pulls it by digest, and installs the rustok command — it never touches a secret, a keystore or your wallet. Requires podman (or docker) and cosign; you can read the script before running it. Full walkthrough, including the by-hand setup without the shim: Installation Guide.

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-tui

Both 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 package ghcr.io/rustok-org/rustok-wallet, stdio). A TUI-edition registry entry ships separately as io.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-stdio

Docker

docker build -t rustok-mcp .
docker run -p 127.0.0.1:3001:3001 -e RUSTOK_MCP_HOST=0.0.0.0 rustok-mcp

To 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 send Authorization: Bearer <token> to reach /mcp/sse and /mcp/message. Distinct from the outbound RUSTOK_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 EventSource API cannot set headers and is not a supported client; use an MCP client that sends request headers.

  • /health is 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/meta deploy 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 is process-trusted (all by default; restrict with RUSTOK_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. txguard surfaces a risk level on preview but does not block. Opt-in limits may come later.

  • Chains: RUSTOK_ALLOWED_CHAINS decides which ones are shown (default 1,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_transaction returns 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

6 tools
execute_transactionA

Submit a previewed transaction for execution. What happens next has three cases, and policy_mode + policy_origin from get_wallet_context tell you which one you are in: a supervised wallet parks it for the human to release in the wallet console; an autonomous wallet whose owner has NOT yet confirmed that mode parks it exactly the same way; an autonomous wallet whose owner confirmed the mode at the console releases it without asking again. Before calling, show the human a summary card of the preview (recipient, decoded call, amount, estimated cost, risk level) — in the third case that card is the last moment anyone sees it. On a 'pending' result, relay next_step: the human opens a SEPARATE terminal and runs rustok console — or, without the installer's shim, the label-discovery form spelled out in next_step. Never run or offer to run that command yourself, and never ask for the approval PIN in chat. Then poll get_execution_status for the outcome.

ParametersJSON Schema
NameRequiredDescriptionDefault
preview_idYesUUID returned by preview_transaction

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does so richly. It discloses the three distinct execution paths based on wallet policies, warns that the summary card is 'the last moment anyone sees it' in the third case (irreversibility), and includes security constraints about not running console commands or asking for PINs.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but every sentence carries necessary information. It is front-loaded with the purpose, then structured logically through cases, pre-call actions, pending handling, and security constraints. Slightly wordy in places but appropriately sized for the tool's complexity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no output schema and a complex execution flow, the description covers most essential context: three cases, pre-call requirements, pending-result handling, and post-call polling. It falls short of specifying the immediate response structure (e.g., success vs. error fields), which would make it fully complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The only parameter, preview_id, is already fully described in the schema as 'UUID returned by preview_transaction' (100% coverage). The description adds no new parameter-level meaning beyond restating that the transaction was previewed, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with 'Submit a previewed transaction for execution', which is a specific verb+resource statement. It clearly distinguishes from siblings like preview_transaction and get_execution_status by focusing on the execution step.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides detailed when-to-use guidance: it references get_wallet_context to determine policy_mode and policy_origin, explains the three cases, instructs to show a summary card before calling, and specifies to poll get_execution_status afterward. It also explicitly states 'Never run or offer to run that command yourself' and 'never ask for the approval PIN', giving clear exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_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.

ParametersJSON Schema
NameRequiredDescriptionDefault
addressNoOptional address to query instead of the active wallet (requires chain_id)
chain_idNoChain ID: optional filter for the active wallet, required with address

TDQS

A4.1/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines4/5

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_execution_statusA

Poll the outcome of a parked execution. States: 'pending' (human has not decided yet), 'executed' (done, tx_hash present), 'denied' (human said no — respect it, do not re-submit), 'expired' (approval deadline passed), 'failed' (error_reason explains). An 'unknown' state is NOT terminal — the wallet core reported something this client does not recognize; keep polling until the deadline. Poll when the human asks, or every ~15-30 seconds until not_after_unix (if null, only on request); stop on any terminal state. A not_found error means the id is unknown or no longer retained — stop polling.

ParametersJSON Schema
NameRequiredDescriptionDefault
preview_idYesUUID from preview_transaction / execute_transaction

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations provided, but the description fully discloses behavior: polling strategy, state definitions, handling of 'unknown' as non-terminal, and error handling for not_found. Completely transparent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Every sentence serves a purpose—states, polling logic, error handling. Well-structured and front-loaded with purpose, then states, then usage guidelines. No redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple tool (1 param, no output schema, no annotations), the description is exceptionally complete, covering all behaviors, actions, and edge cases. Nothing essential is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% with a clear description for preview_id. The tool description does not add additional context beyond the schema, meeting the baseline but not exceeding.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description explicitly states the tool polls the outcome of a parked execution and lists all possible states. It clearly distinguishes from siblings like preview_transaction and execute_transaction by focusing on status polling.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit guidance on when to poll (on human request or every 15-30 seconds until deadline), when to stop (terminal states or not_found), and how to handle each state (e.g., do not re-submit on 'denied').

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
addressNoOptional address to query instead of the active wallet

TDQS

A3.7/5.0
Behavior3/5

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.

Conciseness4/5

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.

Completeness2/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.3/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines3/5

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.

preview_transactionA

Preview an arbitrary transaction (native value + optional calldata) before executing. Returns the decoded call (who/what is authorized), a pre-sign simulation (revert check), gas, and a risk level.

ParametersJSON Schema
NameRequiredDescriptionDefault
toYesRecipient / contract address
dataNoCalldata as 0x-hex; empty for a native value transfer
valueYesNative value in wei
chain_idYesChain ID

TDQS

A4.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description bears full responsibility. It describes outputs but does not explicitly state that the operation is read-only or non-destructive. It mentions 'preview... before executing', implying no state change, but lacks direct confirmation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with no wasted words. The action is stated first, followed by a concise list of return values. Front-loaded and efficient.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no output schema, the description adequately lists return items (decoded call, simulation, gas, risk). It could benefit from an example output or more detail on risk level, but is sufficient for an agent to understand the tool's behavior.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so baseline is 3. The description adds context for 'data' (calldata vs native transfer) and 'value' (in wei), which adds value beyond the schema definitions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool previews an arbitrary transaction before execution, specifying the inputs (native value + optional calldata) and outputs (decoded call, simulation, gas, risk). It distinguishes itself from sibling 'execute_transaction' by the word 'before executing'.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage before executing a transaction, but does not explicitly state when to use alternatives like 'get_positions' or 'sign_message'. However, the purpose is clear enough for an AI agent to infer usage context.

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.

  1. 1 tool updatev0.8.4
    • Removedsign_message
  2. 7 tool updatesv0.8.2
    • First observedexecute_transaction
    • First observedget_balances
    • First observedget_execution_status
    • First observedget_positions
    • First observedget_wallet_context
    • First observedpreview_transaction
    • First observedsign_message

TDQS

A4.2/5.0

Scored across 6 tools

Disambiguation4/5

The transaction lifecycle tools (preview, execute, status) are clearly distinct. get_wallet_context and get_balances have some overlap around asset holdings, but the descriptions make their different scopes reasonably clear.

Naming Consistency5/5

All tool names follow a consistent snake_case verb_noun pattern: preview_transaction, execute_transaction, get_execution_status, get_wallet_context, get_balances, get_positions. There are no mixed conventions or vague verbs.

Tool Count5/5

Six tools is a well-scoped set for a wallet-focused MCP server. Each tool covers a necessary aspect of transaction preview/execution and wallet state inspection without unnecessary bloat.

Completeness4/5

The server covers the core transaction workflow: preview, execute, and poll status, plus wallet context, balances, and DeFi positions. Minor gaps such as transaction history or explicit cancellation are absent, but the primary wallet operations are well supported.

Maintenance

ActivityMaintained
ResponsivenessUnresponsive

Related MCP Connectors

Related MCP Servers