Documentation

Set up Keyhole

Keyhole gives any MCP-capable AI agent its own Solana wallet. It runs as a small server on the same machine as the agent, keeps keys in an encrypted vault, and enforces spending limits that only you can change.

You need Node.js 20 or newer. Everything runs locally. There is no account to create.

Install

Install the package globally. It adds two commands: keyhole for you and keyhole-mcp for your agent.

npm install -g keyhole-money

Create the vault

The vault is one encrypted file that holds every wallet key and its limits. Pick a passphrase of at least 12 characters. If you lose it, the keys inside can't be recovered, so export anything valuable first (see Export a wallet).

keyhole init

The vault is written to ~/.keyhole/vault.json with permissions set so only your user can read it.

Connect your agent

For Claude Code, one command does it:

claude mcp add keyhole \ -e KEYHOLE_PASSPHRASE='your passphrase' \ -- keyhole-mcp

Config for Claude Desktop, Cursor, Codex and other clients is on the MCP page. The server starts on devnet. Add KEYHOLE_RPC pointing at a mainnet RPC when you want real funds.

First wallet

Ask your agent something like:

you Open a wallet called scout and give me the address. agent calling wallet_create { label: "scout" } agent Done. Send SOL to 7Kq3bXw9RfLm2VtP8cYh4NnAe6JdGsUo1ZiQ5HrkTWpE

Send a small amount of SOL to that address from any wallet. The agent can now check its balance and pay within its limits. You can also open wallets yourself with keyhole create scout.

Owner CLI

Everything that changes what an agent is allowed to do sits here, not in MCP. Each command asks for your passphrase, or reads it from KEYHOLE_PASSPHRASE.

CommandWhat it does
keyhole initCreate the vault
keyhole create [label]Open a wallet yourself
keyhole listEvery wallet with its SOL balance
keyhole limits <wallet>Caps and spend in the last 24 hours
keyhole policy <wallet> …Change limits, tokens, allowlist, freeze
keyhole settings …Vault-wide switches
keyhole export <wallet>Print the secret key for import elsewhere

Changes are read by the running server on the next tool call. No restart needed.

Limits

Every new wallet starts with these defaults:

RuleDefaultChange with
Largest single SOL send0.1 SOL--max-tx 0.5
SOL used in any 24 hours, Keyhole fee, network fees and token-account rent included0.5 SOL--daily 2
Only pay approved addressesoff--allow <addr,addr> --allowlist-only on
Sign plain-text log-in messagesoff--sign on
Freeze all sends and signingoff--freeze / --unfreeze
Tokensnone allowedsee Tokens
keyhole policy scout --max-tx 0.25 --daily 1 keyhole policy scout --allow 9xF2pLqTzR4mWv8NcY3hKs6BdJa1GeUo7XiQ5HrnvQ7c --allowlist-only on keyhole policy scout --freeze

The 24-hour window rolls, so a send made at 09:00 stops counting at 09:00 the next day. Each send reserves its amount before it is broadcast, so an agent firing many payments at once still stops at the cap. A send that times out keeps counting, because it may still land. Vault-wide, you can stop agents opening wallets and cap how many exist:

keyhole settings --agent-create off --max-wallets 5

Tokens

No token can be sent until you give its mint a limit. This stops an agent moving something you didn't expect it to hold. Amounts are in whole tokens.

# allow USDC: up to 50 per send, 200 per day keyhole policy scout --token EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v --token-max 50 --token-daily 200 # take it away again keyhole policy scout --token-remove EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v

Classic SPL and Token-2022 mints both work. If the recipient has no token account yet, the wallet creates one and pays its rent (about 0.002 SOL), which counts against the SOL daily limit.

Fees

On mainnet, every send pays a 1% Keyhole fee on top of the amount, in the same transaction. The recipient always gets exactly what the agent sent.

Export a wallet

Prints the address and the base58 secret key, which Phantom, Solflare and the Solana CLI can import. Only run this in a terminal nobody else can see.

keyhole export scout

MCP tools

The agent sees eight tools: wallet_create, wallet_list, wallet_balance, wallet_limits, wallet_send_sol, wallet_send_token, wallet_sign_message and wallet_history. Inputs, outputs and errors for each are on the MCP page.

Environment

VariableDefaultPurpose
KEYHOLE_PASSPHRASEnoneUnlocks the vault. Required by the server.
KEYHOLE_RPCdevnetSolana RPC endpoint for reads and sends.
KEYHOLE_HOME~/.keyholeVault folder. Use one per agent to keep them apart.

Security model

What it protects against

What it doesn't

Rule of thumb: an agent wallet is a spending account, not savings. Top it up with what the agent needs for the week. Limits enforced on chain, which hold even if the machine is compromised, are on the roadmap.

Privacy tips

Troubleshooting

MessageFix
no vault at …Run keyhole init, or check KEYHOLE_HOME.
wrong passphraseThe passphrase in your MCP config doesn't match the one used at init.
over the per-transaction limitWorking as intended. Raise it with --max-tx if you want.
has no limit setAllow that token's mint with --token.
Send fails with insufficient fundsThe wallet needs a little SOL for fees, even when sending tokens.
changed outside keyholeThe vault or spend ledger was edited by hand. Restore vault.json.bak from the same folder, or create a new vault and move funds.
message signing is offTurn it on for that wallet with keyhole policy <wallet> --sign on.
Tools don't appearRestart your client after adding the server, and check that keyhole-mcp is on your PATH.