Connect your agent.
Your agent gets one key and eight tools. The key can only spend from its own pocket, inside the rules you set in the app. It cannot change the rules, list a new shop or withdraw.
With MCP
Works with Claude Desktop, Claude Code, Cursor and any other client that loads MCP servers. When you open a pocket, the app gives you this block with your pocket and key already filled in.
{
"mcpServers": {
"musepay": {
"command": "npx",
"args": ["-y", "https://www.usemusepay.app/musepay-mcp.tgz"],
"env": {
"MUSEPAY_POCKET": "0xYourPocket",
"MUSEPAY_AGENT_KEY": "0xTheAgentKeyFromTheApp",
"MUSEPAY_API": "https://www.usemusepay.app/api"
}
}
}
}
| Setting | What it is |
|---|---|
| MUSEPAY_POCKET | The pocket's address, from the app. |
| MUSEPAY_AGENT_KEY | The agent's private key. The app shows it once, when you open the pocket or add an agent. |
| MUSEPAY_API | The shop's API, https://www.usemusepay.app/api. |
| MUSEPAY_RPC | Optional. A Robinhood Chain RPC, the public one by default. |
The tools
| Tool | What the agent gets |
|---|---|
| pocket_status | What it has left today and this week, where the approval line is, what it is allowed to do, who it may pay, and what the pocket holds. |
| send_eth | Sends ETH to someone the owner listed, by name or address, in dollars or ETH. |
| list_markets | The tokens it can trade (tokenized stocks like NVDA, SPY, AAPL, TSLA, plus USDG) with live prices. |
| buy_token | Swaps ETH for a listed token on Uniswap on Robinhood Chain. The token stays in the pocket. |
| sell_token | Swaps a token the pocket holds back to ETH. Selling does not use up the allowance. |
| find_gift_cards | Searches the gift card catalogue by brand or category. |
| buy_gift_card | Buys one card and returns the code, or asks the owner if it is over the line. |
| check_order | Whether a gift card ask was approved or declined, and the code once the card is out. |
Without MCP
The plug-in is a thin wrapper over a few HTTP calls, so any agent loop can do the same thing. For paying people and trading: POST /api/intent with { pocket, agent, kind, target, amount } (kind is send, buy or sell, amount in wei or token units) returns an Intent to sign under the pocket's EIP-712 domain, and POST /api/relay with { pocket, intent, agentSig } puts it on chain. For gift cards:
POST /api/quotewith{ pocket, agent, productId, value }. The shop checks the pocket's rules, prices the card in ETH off Robinhood Chain's own WETH/USDG pool, signs the quote and returns anintentfor the agent.- The agent signs that
Intentunder the pocket's EIP-712 domain (Musepay, version2, chain 4663, the pocket's address). POST /api/paywith{ orderRef, agentSig }. The shop submits it and pays the gas. The pocket either pays or records an ask for the owner.POST /api/revealwith{ orderRef, ts, signature }, a personal signature by the agent overMusepay order <orderRef>\nat <ts>. Order refs are public on chain, so the code needs a fresh signature.
const prep = await post('/api/intent', { pocket, agent: account.address, kind: 'buy', target: NVDA, amount: '5000000000000000' }) const i = prep.intent const agentSig = await account.signTypedData({ domain: { name: 'Musepay', version: '2', chainId: 4663, verifyingContract: pocket }, types: { Intent: [ { name: 'agent', type: 'address' }, { name: 'kind', type: 'uint8' }, { name: 'target', type: 'address' }, { name: 'amount', type: 'uint256' }, { name: 'minOut', type: 'uint256' }, { name: 'ref', type: 'bytes32' }, { name: 'expiry', type: 'uint64' }, { name: 'tip', type: 'uint256' } ] }, primaryType: 'Intent', message: { ...i, amount: BigInt(i.amount), minOut: BigInt(i.minOut), expiry: BigInt(i.expiry), tip: BigInt(i.tip) }, }) const result = await post('/api/relay', { pocket, intent: i, agentSig }) // status: done | asked
If the shop cannot pay gas
Every intent carries a small tip in ETH that repays whoever submits it, and it counts toward the limits. Asks and sells are submitted free, so an agent that has used up its day can still ask or sell. If the shop's wallet is ever empty, an agent key holding a little ETH can call pocket.act(intent, merchantSig) itself. The plug-in does this on its own.