Connect an AI agent (MCP)
If an AI agent decides what your robot does, mova-mcp lets that agent use the robot’s wallet. It is an MCP server: it gives the agent a small set of tools to check the wallet and pay.
Why this is safe to hand to an agent
Section titled “Why this is safe to hand to an agent”An agent can be wrong, and it can be tricked. Two things limit the damage:
- The daily limit is enforced on-chain. The robot’s spending account refuses any payment that would pass the owner’s limit. The agent can’t raise the limit, and neither can the key it uses.
- It won’t pay from a wallet with no limit. If the robot only has a plain wallet, the
paytool refuses.
The owner can also pause spending or replace the key at any time from the app.
What the agent can do
Section titled “What the agent can do”| Tool | What it does |
|---|---|
wallet_status |
Balance, the daily limit, what’s been spent today, and what can be spent now |
pay |
Pay USDG to an address, with a note saying what it’s for |
income |
Recent payments the robot received, from about the last 11 days |
pay_link |
The link someone can use to pay the robot |
The agent can’t change the limit, withdraw, or pause. Those belong to the owner.
Set up
Section titled “Set up”mova-mcp runs on the robot, next to the agent. The robot’s key never leaves the machine. You need Node 20 or newer.
- Download it and install its dependencies:
mkdir mova-mcp && cd mova-mcpcurl -O https://docs.mova.build/mova-mcp/mova-mcp.mjscurl -O https://docs.mova.build/mova-mcp/package.jsonnpm install- Add it to the agent’s MCP settings, with the robot’s key and ID:
{ "mcpServers": { "mova": { "command": "node", "args": ["/home/robot/mova-mcp/mova-mcp.mjs"], "env": { "MOVA_ROBOT_KEY": "0x...", "MOVA_ROBOT_ID": "7609796266404622865478520861685648070859553970607516824731969204689381529297" } } }}With Claude Code, the same thing from the command line:
claude mcp add mova \ --env MOVA_ROBOT_KEY=0x... \ --env MOVA_ROBOT_ID=7609796266404622865478520861685648070859553970607516824731969204689381529297 \ -- node /home/robot/mova-mcp/mova-mcp.mjs- Make sure the robot has a spending account, with some USDG in it and a little ETH at the robot key’s address for fees.
What it looks like
Section titled “What it looks like”Ask the agent to check its wallet:
{ "spending_account": true, "wallet": "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512", "currency": "USDG", "balance": "104.2", "daily_limit": "25", "spent_today": "0", "can_spend_now": "25", "paused_by_owner": false, "limit_resets": "00:00 UTC", "robot_key": "0x70997970C51812dc3A010C7d01b50e0d17dc79C8", "gas_eth": "0.002"}A payment:
{ "paid": "1.1 USDG", "to": "0xChargerAddress", "memo": "Charging pad 14", "transaction": "0x1f63…", "explorer": "https://robinhoodchain.blockscout.com/tx/0x1f63…", "left_today": "23.9 USDG"}When a payment is refused
Section titled “When a payment is refused”The tool checks the rules before sending, so a refusal costs no fee. The agent gets a plain reason it can act on:
| The agent is told | Meaning |
|---|---|
Over today's limit: 23.9 USDG left of 25 USDG. The limit resets at 00:00 UTC. |
The payment would pass the daily limit. |
Not enough money: the account holds … |
The balance is too low. |
The owner has paused spending. |
The owner paused the account. |
The configured key isn't this account's robot key. |
Wrong key, or the owner replaced it. |
The robot key has no ETH for gas. |
The key’s address needs ETH on Robinhood Chain. |
This robot's wallet is a plain address with no spending limit… |
No spending account yet. |
Settings
Section titled “Settings”| Variable | Required | Purpose |
|---|---|---|
MOVA_ROBOT_ID |
Yes, unless MOVA_WALLET is set |
Finds the robot’s wallet; needed for pay_link and for notes in income |
MOVA_ROBOT_KEY |
For pay |
The robot’s private key. Without it, the read-only tools still work. |
MOVA_WALLET |
No | The spending account’s address, to skip the lookup |
MOVA_RPC |
No | A different Robinhood Chain node |
Good practice
Section titled “Good practice”- Set the limit to what a day of work should cost. It is the most the agent can lose in a day.
- Tell the agent what it’s allowed to pay for in its instructions. The limit caps the amount, not the purpose.
- Watch the Spending panel. Every payment the agent makes shows there with its note.