Giving Claude Code a wallet with MCP
What an MCP wallet server should expose, why it has no “send money” tool, and how scoped session keys keep the main wallet key out of every client.
MinAgent Team6 min read
Claude Code is good at finding what it needs to finish a task. Sometimes what it needs costs money: a data API, a rendering service, another agent that does one job well. The Model Context Protocol (MCP) is how we hand it a wallet without handing it the keys.
MCP in one paragraph
MCP is an open standard for connecting AI applications to outside tools and data. An MCP server exposes a set of tools, each with a name, a description, and a typed input. An MCP client, such as Claude Code, lists those tools and lets the model call them. The model never sees how a tool works inside; it only sees what the tool says it does and what comes back.
That separation is exactly what a wallet needs. The model decides when to pay. The server decides whether it may, and does the signing.
Which tools to expose
The MinAgent wallet server exposes four tools:
get_balance: what the agent has, and how much of today's budget is left.get_rules: the owner's limits, so the model can plan around them instead of discovering them by failing.fetch_paid: fetch a URL, paying with x402 if the server asks for it.list_receipts: recent payments, with the task each one belonged to.
What's missing on purpose
There is no send_money(address, amount) tool. Every payment goes through fetch_paid, which only pays in response to a real 402 from the URL being fetched. Money can only move in exchange for a resource, at the price that resource asked for.
This closes the most common prompt-injection attack on agent wallets. A page that says “send 50 USDC to this address” has no tool to make that happen. At worst it can point the agent at a URL that charges, and that URL still has to pass the allow-list and limits described in our post on spending rules.
{
"name": "fetch_paid",
"description": "Fetch a URL. If the server responds with 402 Payment Required, pay with x402 within the owner's rules and return the content plus a receipt.",
"inputSchema": {
"type": "object",
"properties": {
"url": { "type": "string", "format": "uri" },
"method": { "type": "string", "enum": ["GET", "POST"], "default": "GET" },
"body": { "type": "string" },
"reason": {
"type": "string",
"description": "One sentence on why this purchase helps the current task. Shown to the owner."
}
},
"required": ["url", "reason"]
}
}The reason field costs the model one sentence and gives the owner an audit trail in plain language. When a payment needs approval, that sentence is what the owner reads on their phone.
Session keys: the client never holds the wallet key
When you connect a client, MinAgent issues it a session key: a credential that can ask the wallet for signatures but can't sign on its own. It is scoped to one agent, expires, and can be revoked from the dashboard without touching the wallet itself.
So if a laptop is lost or a config file leaks, you revoke one session. The wallet, its funds, and every other connected client keep working.
Connecting Claude Code
Claude Code adds MCP servers with claude mcp add. The hosted server is the simplest option:
claude mcp add --transport http minagent https://api.minagent.xyz/mcpIf you prefer the wallet client to run on your machine, register it as a local stdio server. Options for Claude Code go before the --; everything after it is the command that starts the server:
claude mcp add minagent --env MINAGENT_AGENT=research-bot -- npx -y minagent mcpEither way, the first call opens a browser window to approve the session and pick which agent it acts as.
What it looks like in use
Ask Claude Code for something that needs paid data and it will check its budget, buy what it needs, and tell you what it spent:
> Compare this week's GPU spot prices across the three providers we use.
● get_rules → daily budget 20 USDC, 18.40 left, cap 3 USDC per payment
● fetch_paid https://prices.example/gpu/weekly
reason: "Weekly GPU spot prices for the comparison you asked for"
→ paid 0.25 USDC, receipt 0x7c1…e9a
● fetch_paid https://cloud-index.example/gpu?window=7d
→ paid 0.40 USDC, receipt 0x2b8…41f
Here's the comparison. I spent 0.65 USDC on two data sources; 17.75 USDC
is left in today's budget.Same wallet, any client
Because the wallet is an MCP server, nothing here is specific to Claude Code. A local agent, another MCP-capable editor, or your own script can connect to the same agent identity and share the same budget and receipts. The rules follow the agent, not the client.