# Overview

External AI agents connect to Brain via the **Model Context Protocol (MCP)**. Brain ships an MCP server that exposes the same primitives as the HTTP API, gated by the same Policy and emitting the same Audit events.

| Property                         | Value                                                  |
| -------------------------------- | ------------------------------------------------------ |
| **Endpoint**                     | `POST /v1/agents/mcp`                                  |
| **Transport**                    | JSON-RPC 2.0 over single-shot HTTP                     |
| **Workspace**                    | `@brain/mcp` (`services/mcp/`)                         |
| **Service shared with HTTP API** | `LedgerService`, `WikiService`, `PaymentIntentService` |

{% hint style="info" %}
SSE and streamable transports are post-MVP behind a feature flag. Single-shot HTTP keeps the surface small and the audit story clean: one request, one response, one audit event.
{% endhint %}

### Surface map

The MCP surface is intentionally small. **10 tools, 5 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>🛠️ 10 Tools</strong></td><td>Five Ledger reads, two Wiki reads, one Raw contribute, one PaymentIntent propose, one agent action propose.</td><td><a href="/pages/LEWpOYJSpmIuTr20aNe8">/pages/LEWpOYJSpmIuTr20aNe8</a></td><td></td></tr><tr><td><strong>📦 5 Resources</strong></td><td>Resource templates addressable by <code>brain://</code> URIs: accounts, transactions, payment-intents, wiki pages, raw evidence.</td><td><a href="/pages/L2DEzPLxdznDACZBKJEr">/pages/L2DEzPLxdznDACZBKJEr</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="/pages/IGFOhlkkHijzYzj8v8lp">/pages/IGFOhlkkHijzYzj8v8lp</a></td><td></td></tr><tr><td><strong>🪪 Authentication</strong></td><td>JWT plus on-chain scope hash verification against <code>BrainMCPAgentRegistry</code>.</td><td><a href="/pages/ZNnH2CuEVwz0dbBj8bG0">/pages/ZNnH2CuEVwz0dbBj8bG0</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` |
| **Propose agent action** | `agent.action.propose`                                                                                                            | `agent:propose`          |

{% hint style="warning" %}
There is no `payment_intent.execute` on the MCP surface. External agents may **propose** but never **execute**. Execution always goes through Brain's deterministic §6 13-step pre-execution gate, behind human approval where policy demands it.
{% endhint %}

[**→ The Pre-Execution Gate**](/protocol/the-pre-execution-gate.md)

### What makes the MCP surface different

The same `LedgerService`, `WikiService`, and `PaymentIntentService` methods that back the HTTP API back the MCP tools. 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 AI Agent              │
        └────────────┬────────────────────┘
                     │  JSON-RPC 2.0 over HTTPS
                     │  Authorization: Bearer <jwt>
                     ▼
        ┌─────────────────────────────────┐
        │  Fastify authPlugin             │
        │  Validates JWT, resolves        │
        │  principal (tenant + scopes)    │
        └────────────┬────────────────────┘
                     │
                     ▼
        ┌─────────────────────────────────┐
        │  @brain/mcp  (services/mcp/)    │
        │  - Method dispatcher            │
        │  - 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 service methods:        │
        │  LedgerService                  │
        │  WikiService                    │
        │  PaymentIntentService           │
        └─────────────────────────────────┘
                     │
                     ▼
            Audit events emitted at every step
```

### Boot wiring

The MCP server is mounted onto the existing Fastify app via the `registerMcp` callback on `buildExecutionApp`. This keeps `services/execution` unaware of `@brain/mcp` so there is no workspace cycle.

```typescript
// services/api boot
import { buildExecutionApp } from "@brain/execution";
import { registerMcp } from "@brain/mcp";

const app = await buildExecutionApp({
  registerMcp,  // optional, pass to enable the MCP surface
});
```

### A first call

```http
POST /v1/agents/mcp HTTP/1.1
Host: api.brain.fi
Authorization: Bearer <jwt>
Content-Type: application/json

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

Response:

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "content": [
      { "type": "text", "text": "AWS at $61,404 across 3 environments." }
    ],
    "metadata": {
      "ledger_evidence": [
        { "type": "ledger_transactions", "id": "tx_4127" },
        { "type": "ledger_transactions", "id": "tx_4128" }
      ],
      "audit_event_id": "evt_a1b2c3..."
    }
  }
}
```

### 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 10 tools in detail.</td><td><a href="/pages/LEWpOYJSpmIuTr20aNe8">/pages/LEWpOYJSpmIuTr20aNe8</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="/pages/ZNnH2CuEVwz0dbBj8bG0">/pages/ZNnH2CuEVwz0dbBj8bG0</a></td><td></td></tr></tbody></table>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.brain.fi/mcp-server/overview.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
