MCP server for agents
Give an AI agent its own private HYPE account. The voidcash MCP server lets agents hold, pay and get paid in private HYPE on Elysium, signing with their own key.
The voidcash MCP server gives an AI agent its own private HYPE account on Elysium. Any agent that speaks the Model Context Protocol over stdio, such as Claude Code, Claude Desktop or Cursor, can use it.
The agent holds HYPE in encrypted notes only it can read, pays without showing its address, and gets paid at a private address. It signs with its own key, locally: there is no wallet to click through. Private actions need no public HYPE: their gas is paid from the notes.
Why agents
An agent that pays on-chain shows everything: which services it uses, how much it spends, and, for a trading agent, its strategy. With voidcash:
- Its balance and its payments stay private. A private send shows neither side nor the amount.
- It can get paid without revealing its address, at a private address.
- You can give it a budget without giving it a wallet: send it a payment link. It can spend what the link holds and nothing more, and you can take back what it does not claim.
- Every private send comes with a proof: a link that shows the recipient and the amount of that one payment, for invoices and receipts.
Set it up
The server is the package @voidcash/mcp in the voidcash repository (packages/mcp). It is not published on npm:
build it from the repository and run the build with Node.js 22 or later, on the agent's machine. The key never leaves
it.
Install the repository's dependencies with pnpm install.
Build the server. The build bundles the SDK, the circuit and the deployment into packages/mcp/dist/main.js, and
takes the app, bundler, indexer and explorer it defaults to from its environment:
VOIDCASH_APP_URL=https://voidcash.io \
VOIDCASH_BUNDLER_URL=https://bundler.voidcash.io \
VOIDCASH_INDEXER_URL=https://indexer.voidcash.io \
VOIDCASH_EXPLORER_URL=https://elysium.kinetiq.xyz/explorer \
pnpm --filter @voidcash/mcp buildAdd it to the agent's client, with the agent's key. <repository> is where you cloned voidcash.
Claude Code
claude mcp add voidcash \
--env VOIDCASH_PRIVATE_KEY=0x... \
--env VOIDCASH_MAX_HYPE=10 \
-- node <repository>/packages/mcp/dist/main.jsClaude Desktop, Cursor and other clients
{
"mcpServers": {
"voidcash": {
"command": "node",
"args": ["<repository>/packages/mcp/dist/main.js"],
"env": {
"VOIDCASH_PRIVATE_KEY": "0x...",
"VOIDCASH_MAX_HYPE": "10"
}
}
}
}To check a build before giving it a real key, run npx tsx test/smoke.mts from packages/mcp, with
SMOKE_COMMAND="node dist/main.js" to test the build rather than the sources. It starts the server over stdio with a
fresh key in read-only mode and calls the reading tools on Elysium.
Settings
| Variable | Default | What it does |
|---|---|---|
VOIDCASH_PRIVATE_KEY | required | The agent's key, 0x and 64 hex characters. Use a key made for the agent, not your own wallet's |
VOIDCASH_MAX_HYPE | no limit | The most HYPE one action may move, e.g. 10 or 0.05 |
VOIDCASH_READ_ONLY | off | 1 (or true): every tool that signs or sends refuses, and only the reading tools work |
VOIDCASH_APP_URL | the build's | The app the links point to. Its domain derives the agent's keys, as in the app. Required if the build did not set it |
VOIDCASH_RPC_URL | https://rpc.volta.family | Another Elysium RPC endpoint |
VOIDCASH_BUNDLER_URL | the build's | Another ERC-4337 bundler that speaks Pimlico's RPC methods. Without one, private actions are refused; reads and public actions still work |
VOIDCASH_INDEXER_URL | the build's | Another indexer, or empty to read the chain only |
VOIDCASH_EXPLORER_URL | the build's | An explorer for transaction links in the results |
With VOIDCASH_APP_URL=https://voidcash.io, the key derives the same private account as the app does: importing it
into a browser wallet and opening voidcash.io shows the same balance and history.
Tools
| Tool | What it does |
|---|---|
get_status | Address, public and private HYPE, payments waiting at the private address, exits not paid yet, registration, the private address, the fees, the current gas estimate of a private action, the limits |
get_history | Recent private activity, newest first (default 20, at most 100), rebuilt from the agent's own notes, with each exit's state |
get_pool_stats | The pool: HYPE shielded, notes, private transactions, shields, exits and exit fees, VOID burned and the fee split |
shield | Moves public HYPE into a private note. No fee; a public transaction paid in HYPE |
register | Registers the privacy key, so others can send to the agent's address privately. A public transaction paid in HYPE |
send_private | Sends HYPE privately to a registered address, and returns a proof-of-payment link |
pay_private_address | Pays a private address link: from the private balance (private, the default), or by shielding public HYPE straight into the payee's note (public) |
create_payment_link | Pays HYPE into a link anyone can claim |
payment_link_status | What a link holds, and whether it was claimed |
claim_payment_link | Claims everything a link holds, less the gas: into the private balance, or to an address as public HYPE |
unshield | Moves HYPE (an amount, or all) to an address as public HYPE |
quote_unshield | What an unshield costs now: the exit fee, what the recipient receives, the gas, and whether it would wait 24 hours |
release_exit | Pays an exit whose 24-hour wait is over, or one its own transaction could not pay. A public transaction paid in HYPE |
get_private_address | The agent's private address link and its fingerprint |
collect_private_address | Moves payments waiting at the private address into the balance, up to two per call |
verify_payment | Checks a proof-of-payment link against the chain: recipient, amount and time |
get_status, get_history, get_pool_stats, payment_link_status, quote_unshield, get_private_address and
verify_payment only read. Errors come back as tool errors the agent can read.
The tools handle HYPE. Every amount they take or return is in HYPE, and get_status and get_history show the HYPE
balance, HYPE activity and HYPE exits. Notes of a listed token that the
agent's key holds, such as VOID sent to its address, do not appear in the results. With the same VOIDCASH_APP_URL
as the app, the same key opens the same account in the app, which shows and moves them.
Costs
| Action | What it pays |
|---|---|
shield, register, release_exit | Gas in HYPE from the agent's public address. Shielding carries no fee |
send_private, pay_private_address (private), create_payment_link | Gas only, from the notes |
unshield | The 1% exit fee out of the amount, and gas from the notes on top |
claim_payment_link | Gas from the link; to an address, also the 1% exit fee |
collect_private_address | Gas from what it collects |
The exit fee goes to the fee collector: half to the team, half to buying VOID and burning it. An unshield paying out
more than the vault's large-exit threshold (1,000 HYPE at deployment) is paid 24 hours later, through release_exit.
get_status shows the threshold and the current gas estimate. A link must hold more than twice the gas its claim pays.
See Fees.
How the key is used
The key is an ordinary secp256k1 key. Its address holds the agent's public HYPE. The server signs with it locally, with no prompt:
- The key-derivation message, once per process, to derive the privacy keys exactly as the app does. No transaction, no HYPE. The privacy keys are kept in memory only.
- A spend signature (EIP-712, under the vault's domain) for every private action. The proof checks it, so the privacy keys alone cannot move the agent's HYPE.
- The link-key message, once per process, when the agent creates its first payment link.
- Public transactions:
shield,registerandrelease_exit.
Proofs are made on the agent's machine. Private actions go to the bundler as ERC-4337 operations whose sender is the vault, so the agent's address does not appear in them.
Limits
VOIDCASH_MAX_HYPEcaps a singleshield,send_private,pay_private_address,create_payment_link,unshield(withall, the private balance) andcollect_private_address(what waits there). Claiming a link, registering and releasing an exit are not capped: they bring HYPE in or pay an exit already decided.- Read-only mode refuses every tool that signs or sends, with an error.
- No bundler means no private actions; reads,
shield,registerandrelease_exitstill work. - The public bundler accepts 120 requests a minute per address, 20 of them estimates or sends: one private action makes about 35. See Deployments.
- A spend uses the agent's two largest notes of one tree. If they do not cover an amount plus the gas, the action is refused with the reason, even when the whole private balance would.
Keep it safe
- The key is the account. Whoever has it can spend everything the agent holds. Give the agent a key of its own,
fund it with what it needs, and set
VOIDCASH_MAX_HYPE. - Payment links are bearer instruments. The agent should send them only to the payee, never post them.
- Unshields name a recipient. To keep an exit apart from the agent, it should unshield to a new address, not its own.
A payment link in a log, a prompt or a public channel can be claimed by anyone who reads it. Keep the agent's transcripts private, or have it send links only through a private channel.