About 16ane sandbox wallet
16ane sandbox wallet is an MCP server for agents using the 16ane testnet to discover services, inspect budgets, and make bounded tANE payments. Its tools also support publishing services and preparing refund requests; it handles simulated tokens with no cash value.
Key features
- 01Discover services and prices
- 02Fetch quotes without payment
- 03Inspect vault balance and payment records
- 04Purchase within vault and call limits
- 05Publish services and prepare refund requests
Use cases
- 01Find available testnet services and their prices
- 02Check a delegated budget before purchasing
- 03Pay for a service call with capped tANE
- 04Register an agent service or prepare a refund request
MCP support
Exposes seven wallet and service tools to MCP clients over stdio or Streamable HTTP. The server verifies its delegated agent key and applies call, server, and vault spending limits.
Configuration
Local server config is the same for every client. Copy it into your client’s MCP config file.
npx -y @16ane/mcp-serverANE_VAULT_ADDRESSThe vault whose owner delegated a budget to this agent (see `npx -y @16ane/mcp-server init`)ANE_AGENT_PRIVATE_KEYSecretThe delegated agent key, never an owner key. Optional: by default the key from `init` is readLocal servers need a runtime on your machine (e.g. Node.js 18+). Config file locations differ by client; see your client’s docs.
Tools
Local servers expose tools only once running on your machine, and the maintainer has not provided a tool list.
Details
From the project README@16ane/mcp-server — 16ane sandbox wallet adapter for MCP hosts
Exposes the 16ane testnet sandbox to MCP-compatible LLM hosts (Claude Desktop,
Cursor, MCP clients) as seven constrained tools: service discovery, quoting,
balance inspection and bounded purchasing. Speaks MCP 2026-07-28
(spec, checked
2026-10-22) over stdio and Streamable HTTP. No runtime dependencies.
TEST TOKENS (tANE) - NO CASH VALUE. This adapter moves simulated testnet tokens only. It never handles INR, redemptions or real value of any kind.
Quick start: the public sandbox in two steps (#147)
Needs Node.js 24 or newer. Nothing to clone, and no ETH for the agent.
1. Make the agent's key. This creates only an agent key (~/.config/16ane/agent.key, mode 0600) and prints
its address. Run it again and it keeps the same key.
npx -y @16ane/mcp-server init
2. Delegate a budget to that address, as the vault owner, from your own wallet. Open the link init prints
(https://app.16ane.com/#/delegate?agent=0x…). Create a vault, fund it with free tANE, and sign a fixed budget for
the agent. The owner's transactions need a little Base Sepolia ETH; the agent's payments do not. The owner key stays
in your wallet: this server has no owner-key option at all.
3. Add the server to your MCP host with the vault address. All other settings default to the public Base Sepolia
sandbox and https://api.16ane.com.
claude mcp add 16ane -e ANE_VAULT_ADDRESS=0xYourVault -- npx -y @16ane/mcp-server # Claude Code
{ "mcpServers": { "16ane": { "command": "npx", "args": ["-y", "@16ane/mcp-server"], "env": { "ANE_VAULT_ADDRESS": "0xYourVault" } } } }
The JSON form works for Claude Desktop (claude_desktop_config.json) and Cursor (Settings → MCP). At startup
the server checks that its key is the vault's active agent and refuses to run otherwise. The agent can then
discover services, quote them, check its budget and pay. Every payment stays within the budget the vault enforces.
The server is listed in the MCP registry as
io.github.bytesbrains/16ane. The package ships compiled JavaScript and depends only on @16ane/sdk. From a
checkout, run node --experimental-strip-types packages/mcp-server/src/main.ts (or the 16ane-mcp-server bin,
which runs the sources when they are present).
Tools
| Tool | Effect |
|---|---|
list_services | Lists directory services with prices and manifest signature checks. Read-only. |
get_quote | Fetches a 402 quote without paying; cross-checks the origin manifest. Read-only, never signs. |
wallet_balance | Vault tANE balance plus delegation accounting from chain state. Read-only. |
payment_status | On-chain payment record plus verifiable receipt lookup. Read-only. |
purchase_service | Pays for one service call within max_payment and vault policy. Spends funds. |
publish_service | Signs and registers this agent's own service manifest. Revenue is pinned to its vault. |
request_refund | Prepares a refund request from the on-chain record. Moves no funds; only the merchant can refund. |
Amounts are base-units integer strings ("16"). Every service description,
quote and purchase result is untrusted merchant content: it arrives fenced
as data (never instructions) in text output and flagged untrusted: true in
structured output.
Security model
- The process holds exactly one key: the delegated agentSigner
(
ANE_AGENT_PRIVATE_KEY). There is no owner-key option anywhere; fund, delegate and revoke outside this server (CLI, dashboard) first. - At startup the server verifies on-chain that the held key is the vault's delegated agentSigner and that the delegation is active, and refuses to serve otherwise.
- Spending is capped three deep: the call's required
max_payment, the optional server-sideANE_MCP_MAX_PAYMENTceiling, and the vault's on-chain policy (the real enforcement; prompt text never is). publish_serviceaccepts no payee/token/network override: revenue always points at this vault, in tANE, on the configured network.- The key is held in the SDK's
SecretKeywrapper and never appears in tool results, errors, logs or stdio output;test/security.test.tsproves it against prompt-injection fixtures. - Quote probes (
get_quote) cap merchant responses at 256 KiB and fail after 30 s, so a malicious or broken endpoint cannot exhaust memory or hang a call. - Streamable HTTP binds
127.0.0.1by default, validatesOrigin, enforces theMCP-Protocol-Version/Mcp-Method/Mcp-Nameheader/body mirrors, and supports anANE_MCP_AUTH_TOKENbearer token (set one whenever the endpoint leaves localhost).
Configure
Only ANE_VAULT_ADDRESS is required. With the network settings unset, the server uses the public sandbox
(https://sepolia.base.org, chain 84532, registry 0x01d5daB670DE5868305eB862721ebE62772C3Df3,
https://api.16ane.com). Set ANE_RPC_URL and ANE_CHAIN_ID together to use another chain. The agent key comes
from ANE_AGENT_PRIVATE_KEY, or else from the file init writes (ANE_AGENT_KEY_FILE, default
~/.config/16ane/agent.key, refused if other users can read it).
export ANE_VAULT_ADDRESS="0x..." # the vault whose owner delegated to this agent (required)
export ANE_RPC_URL="http://127.0.0.1:8545" # optional, with ANE_CHAIN_ID: another chain (e.g. Anvil)
export ANE_CHAIN_ID="31337" # optional, with ANE_RPC_URL: 84532 or 31337
export ANE_AGENT_PRIVATE_KEY="0x..." # optional: otherwise the init key file
export ANE_REGISTRY_ADDRESS="0x..." # optional on the sandbox; or the four ANE_*_ADDRESS values below
# export ANE_TOKEN_ADDRESS / ANE_VAULT_FACTORY_ADDRESS / ANE_FAUCET_ADDRESS / ANE_SERVICE_DIRECTORY_ADDRESS
export ANE_API_BASE_URL="https://api.16ane.com" # service listing, publishing, receipts
export ANE_MCP_MAX_PAYMENT="16" # optional per-call ceiling (base units)
Run with stdio (Claude Desktop, Cursor)
Command: node --experimental-strip-types /path/to/16ane/packages/mcp-server/src/main.ts
(or the 16ane-mcp-server bin after npm install; it re-execs with the flag).
Claude Desktop config (~/Library/Application Support/Claude/claude_desktop_config.json):
{
"mcpServers": {
"16ane": {
"command": "node",
"args": ["--experimental-strip-types", "/path/to/16ane/packages/mcp-server/src/main.ts"],
"env": {
"ANE_RPC_URL": "https://sepolia.base.org",
"ANE_CHAIN_ID": "84532",
"ANE_VAULT_ADDRESS": "0x...",
"ANE_AGENT_PRIVATE_KEY": "0x...",
"ANE_REGISTRY_ADDRESS": "0x...",
"ANE_API_BASE_URL": "https://api.16ane.com",
"ANE_MCP_MAX_PAYMENT": "16"
}
}
}
}
Cursor uses the same shape under Settings → MCP → Add server (stdio type).
Any MCP client that speaks protocol version 2026-07-28 works; clients that
only speak the legacy initialize handshake do not (this server is modern-era
only and answers initialize with JSON-RPC -32601).
Run with Streamable HTTP (remote)
export ANE_MCP_TRANSPORT="http" ANE_MCP_PORT="8786"
export ANE_MCP_AUTH_TOKEN="$(openssl rand -hex 32)"
export ANE_MCP_ALLOWED_ORIGINS="https://app.example.com"
node --experimental-strip-types packages/mcp-server/src/main.ts
# POST JSON-RPC to http://127.0.0.1:8786/mcp
Every POST needs MCP-Protocol-Version: 2026-07-28, Mcp-Method: <method>
(plus Mcp-Name: <tool> for tools/call) mirroring the body's method, and
Authorization: Bearer <token> when configured. Responses are single JSON
objects (the server never opens SSE streams); unknown methods answer 404,
protocol violations 400, notifications 202.
Develop
npm run test:mcp # or: make test-mcp (from the repo root)
npm run typecheck
Layout: src/protocol.ts (MCP 2026-07-28 JSON-RPC core), src/tools.ts
(the seven tools), src/backend.ts (SDK/REST wiring behind a mockable
interface), src/stdio.ts, src/http.ts, src/config.ts, src/main.ts.
Tests mirror the sources; test/security.test.ts is the prompt-injection
suite from the issue's acceptance criteria.
Comments
New to MCP?
From what the protocol is to installing your first server, these answers cover most first questions.
An open protocol that defines how AI applications connect to external tools and data in a uniform way. Clients talk to the model; MCP servers provide tools, resources and prompt templates. They exchange standard messages, so one server can be reused by many clients.