> For the complete documentation index, see [llms.txt](https://docs.robotmoney.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.robotmoney.com/mcp-server/overview.md).

# Overview

RobotMoney exposes a **Model Context Protocol (MCP) server** so agents can read financial state, retrieve memory, and propose actions within tenant-signed policy. RobotMoney runs the underlying ingest, normalization, policy, and execution; the agent works against a single scoped surface.

Agents propose actions. Policies decide what runs. Humans stay in control where the policy says they should.

| Property      | Value                                                                           |
| ------------- | ------------------------------------------------------------------------------- |
| **Endpoint**  | `https://mcp.robotmoney.com` (canonical; maps to `POST /v1/agents/mcp`)         |
| **Transport** | JSON-RPC 2.0 over single-shot HTTP                                              |
| **Backed by** | The same Ledger, Wiki, Authorization, and PaymentIntent surface as the HTTP API |

{% hint style="info" %}
The MCP surface uses single-shot HTTP. One request, one response, one audit event. Streaming transports may follow once we see a use case that needs them.
{% endhint %}

### Surface Map

The MCP surface is intentionally small. **21 tools, 1 concrete resource plus 6 resource templates, 5 canned prompts.**

<table data-view="cards"><thead><tr><th></th><th></th><th data-type="content-ref"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>21 Tools</strong></td><td>Five Ledger reads, two Wiki reads, two Raw tools, three PaymentIntent tools, four Authorization tools, three proposal tools, one evidence resolve, one agent action propose.</td><td><a href="/mcp-server/tools.md">Tools</a></td><td></td></tr><tr><td><strong>7 Resources</strong></td><td>One concrete resource (<code>brain://payments/action_types</code>) readable via <code>resources/read</code>, plus six templated <code>brain://</code> URIs (ledger accounts/transactions/obligations/payment-intents, wiki pages, per-action proofs) returned only from <code>resources/templates/list</code>, not <code>resources/list</code>.</td><td><a href="/mcp-server/resources.md">Resources</a></td><td></td></tr><tr><td><strong>5 Prompts</strong></td><td>Canned prompts for the most common agent loops: cash flow, bills, spending, invoices, subscriptions.</td><td><a href="/mcp-server/prompts.md">Prompts</a></td><td></td></tr><tr><td><strong>Authentication</strong></td><td>JWT plus on-chain scope hash verification against <code>BrainMCPAgentRegistry</code>. Per-tenant rate limit on the route so one misbehaving agent cannot crowd out other tenants.</td><td><a href="/mcp-server/mcp-authentication.md">MCP Authentication</a></td><td></td></tr></tbody></table>

### What an External Agent Can Do

| Capability               | Tools                                                                                                                             | On-chain Scope           |
| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------- | ------------------------ |
| **Read Ledger**          | `ledger.account.get`, `ledger.accounts.list`, `ledger.transactions.list`, `ledger.obligations.list`, `ledger.counterparties.list` | `ledger:read`            |
| **Read Wiki**            | `wiki.question`, `wiki.page.get`                                                                                                  | `wiki:read`              |
| **Contribute to Raw**    | `raw.contribute`                                                                                                                  | `raw:write`              |
| **Propose payment**      | `payment_intent.propose`                                                                                                          | `payment_intent:propose` |
| **Request a decision**   | `authorizations.create`, `authorizations.get`                                                                                     | `payment_intent:propose` |
| **Read proposals**       | `proposals.list`, `proposals.get`, `evidence.resolve`                                                                             | `execution:read`         |
| **Review a proposal**    | `proposals.decide`, `authorizations.approve`, `authorizations.reject`                                                             | member authority         |
| **Propose agent action** | `agent.action.propose`                                                                                                            | `execution:propose`      |

{% hint style="info" %}
`proposals.decide` declares no tool scope of its own. It accepts either `payment_intent:approve` or `execution:read` at the call boundary, then enforces member approval authority downstream (user-principal actor resolution, active-member and approval-role checks, and the money-path approval gates).
{% endhint %}

{% hint style="warning" %}
There is no `payment_intent.execute` on the MCP surface. External agents may **propose** but never **execute**. Execution always goes through RobotMoney's deterministic pre-execution gate (13 numbered checks + 4 hardening additions), behind human approval where policy demands it.
{% endhint %}

[**→ The pre-execution gate**](/how-it-works/the-pre-execution-gate.md)

### What Makes the MCP Surface Different

The MCP tools call the same Ledger, Wiki, Authorization, and PaymentIntent code paths that back the HTTP API. That has three concrete consequences:

| Property                     | Effect                                                                                                                   |
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| **Identical Policy gating**  | A `payment_intent.propose` over MCP runs through the same Policy evaluator as one created via HTTP                       |
| **Identical audit emission** | Tools that mutate state emit the same inner audit events the HTTP API emits, plus an outer `agent.mcp.tool_called` event |
| **No bypass path**           | There is no shortcut. MCP cannot skip Policy or write to the Ledger directly.                                            |

### Architecture

```
        ┌─────────────────────────────────┐
        │  External agent              │
        └────────────┬────────────────────┘
                     │  JSON-RPC 2.0 over HTTPS
                     │  Authorization: Bearer <jwt>
                     ▼
        ┌─────────────────────────────────┐
        │  RobotMoney edge                │
        │  Validates JWT, resolves        │
        │  principal (tenant + scopes)    │
        └────────────┬────────────────────┘
                     │
                     ▼
        ┌─────────────────────────────────┐
        │  MCP dispatcher                 │
        │  - Method routing               │
        │  - 3 pre-call checks:           │
        │    a) agent active              │
        │    b) JWT scope_hash matches    │
        │       on-chain hash             │
        │    c) JWT tenant == agent       │
        │       tenant                    │
        │  - Per-tool scope enforcement   │
        └────────────┬────────────────────┘
                     │
                     ▼
        ┌─────────────────────────────────┐
        │  Shared RobotMoney services:    │
        │  Ledger reads & writes          │
        │  Wiki Q&A and pages             │
        │  PaymentIntent proposal flow    │
        └─────────────────────────────────┘
                     │
                     ▼
            Audit events emitted at every step
```

### A First Call

```http
POST / HTTP/1.1
Host: mcp.robotmoney.com
Authorization: Bearer <jwt>
Content-Type: application/json

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "wiki.question",
    "arguments": {
      "question": "What's our top expense category this month?"
    }
  }
}
```

Response:

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "**Q:** What's our top expense category this month?\n**A:** AWS at $61,404 across 3 environments.\n\nCited evidence:\n  - `tx_4127` (ledger_transaction): AWS Inc $61,404.00"
      }
    ],
    "structuredContent": {
      "answer": "AWS at $61,404 across 3 environments.",
      "evidence": [
        {
          "entityId": "tx_4127",
          "entityType": "ledger_transaction",
          "excerpt": "AWS Inc $61,404.00"
        }
      ],
      "model": "...",
      "usage": { "inputTokens": 812, "outputTokens": 46 }
    }
  }
}
```

### What's Next

<table data-view="cards"><thead><tr><th></th><th></th><th data-type="content-ref"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Tools</strong></td><td>The 21 tools in detail.</td><td><a href="/mcp-server/tools.md">Tools</a></td><td></td></tr><tr><td><strong>Authentication</strong></td><td>How JWT and on-chain scope verification work together.</td><td><a href="/mcp-server/mcp-authentication.md">MCP Authentication</a></td><td></td></tr></tbody></table>
