Files
sure/docs/hosting/mcp.md
Claude ec38a89d0c Expose the Statement Vault to external agents over MCP
A user wants to manage patrimonial history — a document-backed record of a
family's wealth where every figure traces back to the statement it came from —
by pointing an external agent harness at Sure. That model belongs in the
harness, not in Sure: it needs numbered build deltas, golden tests and closed
periods that a mutable Postgres row cannot provide.

What Sure was missing was the seam. The Statement Vault already does most of
the work — original bytes retained, SHA-256 dedup, period detection, account
matching with a confidence score, reconciliation against ledger balances, and a
month-by-month coverage map — but it is reachable only from the web UI. An
agent could not archive a document, cite one, or check for gaps.

Adds five preview MCP tools over what already exists, plus a citation grammar
for values the agent writes:

- upload_account_statement, list_account_statements, get_account_statement,
  get_statement_coverage
- record_valuation, whose source citation is parsed rather than trusted:
  ["estimated: "] citation [" (grade: A|B|C)"]. An uncited or free-styled
  value is rejected at the write boundary instead of landing in the ledger
  looking authoritative.

link and reject are deliberately not exposed. Attaching a statement to an
account is the human's decision, and the vault UI is where it is made; the
agent reports the suggested match and stops there.

Assistant.function_classes now takes a user so preview tools stay out of the
default surface. They are hidden from tools/list and not callable by name
without the preference enabled, and the vault tools re-check the manager role
and per-account permissions, since MCP calls never pass through a controller.

Docs: the blueprint this implements, and a guide covering which side owns which
layer, the vocabulary map between the two, the monthly runbook, and the gaps
(non-user holders, non-statement documents, one value per date).

No migrations, no API endpoints, no UI.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JFDp9HhXDeswadu4cxFojn
2026-08-01 00:00:12 -07:00

11 KiB

MCP Server for External AI Assistants

Sure includes a Model Context Protocol (MCP) server endpoint that allows external AI assistants like Claude Desktop, GPT agents, or custom AI clients to query your financial data.

What is MCP?

Model Context Protocol is a JSON-RPC 2.0 protocol that enables AI assistants to access structured data and tools from external applications. Instead of copying and pasting financial data into a chat window, your AI assistant can directly query Sure's data through a secure API.

This is useful when:

  • You want to use an external AI assistant (Claude, GPT, custom agents) to analyze your Sure financial data
  • You prefer to keep your LLM provider separate from Sure
  • You're building custom AI agents that need access to financial tools

Prerequisites

To enable the MCP endpoint, you need to set two environment variables:

Variable Description Example
MCP_API_TOKEN Bearer token for authentication your-secret-token-here
MCP_USER_EMAIL Email of the Sure user whose data the assistant can access user@example.com

Both variables are required. The endpoint will not activate if either is missing.

Generating a secure token

Generate a random token for MCP_API_TOKEN:

# macOS/Linux
openssl rand -base64 32

# Or use any secure password generator

Choosing the user

The MCP_USER_EMAIL must match an existing Sure user's email address. The AI assistant will have access to all financial data for that user's family.

Caution

The AI assistant will have read access to all financial data for the specified user. Only set this for users you trust with your AI provider.

Configuration

Docker Compose

Add the environment variables to your compose.yml:

x-rails-env: &rails_env
  MCP_API_TOKEN: your-secret-token-here
  MCP_USER_EMAIL: user@example.com

Both web and worker services inherit this configuration.

Kubernetes (Helm)

Add the variables to your values.yaml or set them via Secrets:

env:
  MCP_API_TOKEN: your-secret-token-here
  MCP_USER_EMAIL: user@example.com

Or create a Secret and reference it:

envFrom:
  - secretRef:
      name: sure-mcp-credentials

Protocol Details

The MCP endpoint is available at:

POST /mcp

Authentication

All requests must include the MCP_API_TOKEN as a Bearer token:

Authorization: Bearer <MCP_API_TOKEN>

Supported Methods

Sure implements the following JSON-RPC 2.0 methods:

Method Description
initialize Protocol handshake, returns server info and capabilities
tools/list Lists available financial tools with schemas
tools/call Executes a tool with provided arguments

Available Tools

The MCP endpoint exposes these financial tools:

Tool Description
get_transactions Retrieve transaction history with filtering
get_accounts Get account information and balances
get_holdings Query investment holdings
get_balance_sheet Current financial position (assets, liabilities, net worth)
get_income_statement Income and expenses over a period
import_bank_statement Import bank statement data
search_family_files Search uploaded documents in the vault

These are the same tools used by Sure's builtin AI assistant.

Preview Tools

These additional tools appear only when the MCP user has opted into preview features (Settings → Preferences). Until then they are absent from tools/list, and calling one by name returns an "Unknown tool" error. The Statement Vault tools additionally require the user to be an admin or member, matching the permissions enforced in the web UI.

Tool Description
upload_account_statement Store a statement document (PDF/CSV/XLSX) in the Statement Vault; deduplicates by SHA-256
list_account_statements List vault documents with their SHA-256, period, linked account and review status
get_account_statement One statement's details, its reconciliation checks against the ledger, and a short-lived download URL
get_statement_coverage Month-by-month statement coverage for an account: covered, missing, mismatched, ambiguous
record_valuation Record an account's value on a date, with a required source citation

They exist for agents that maintain a document-backed record of a family's wealth over time. See Patrimonial history with an external agent harness.

Example Requests

Initialize

Handshake to verify protocol version and capabilities:

curl -X POST https://your-sure-instance/mcp \
  -H "Authorization: Bearer your-secret-token" \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "initialize"
  }'

Response:

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "protocolVersion": "2025-03-26",
    "capabilities": {
      "tools": {}
    },
    "serverInfo": {
      "name": "sure",
      "version": "1.0"
    }
  }
}

List Tools

Get available tools with their schemas:

curl -X POST https://your-sure-instance/mcp \
  -H "Authorization: Bearer your-secret-token" \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 2,
    "method": "tools/list"
  }'

Response includes tool names, descriptions, and JSON schemas for parameters.

Call a Tool

Execute a tool to get transactions:

curl -X POST https://your-sure-instance/mcp \
  -H "Authorization: Bearer your-secret-token" \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 3,
    "method": "tools/call",
    "params": {
      "name": "get_transactions",
      "arguments": {
        "start_date": "2024-01-01",
        "end_date": "2024-01-31"
      }
    }
  }'

Response:

{
  "jsonrpc": "2.0",
  "id": 3,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "[{\"id\":\"...\",\"amount\":-45.99,\"date\":\"2024-01-15\",\"name\":\"Coffee Shop\"}]"
      }
    ]
  }
}

Security Considerations

Transient Session Isolation

The MCP controller creates a transient session for each request. This prevents session state leaks that could expose other users' data if the Sure instance is using impersonation features.

Each MCP request:

  1. Authenticates the token
  2. Loads the user specified in MCP_USER_EMAIL
  3. Creates a temporary session scoped to that user
  4. Executes the tool call
  5. Discards the session

This ensures the AI assistant can only access data for the intended user.

Pipelock Security Scanning

For production deployments, we recommend using Pipelock to scan MCP traffic for security threats.

Pipelock provides:

  • DLP scanning: Detects secrets being exfiltrated through tool calls
  • Prompt injection detection: Identifies attempts to manipulate the AI
  • Tool poisoning detection: Prevents malicious tool call sequences
  • Policy enforcement: Block or warn on suspicious patterns
  • Signed receipts: Produces verifiable evidence for mediated MCP decisions when the flight recorder is configured with storage and a signing key

See the Pipelock documentation and the example configuration in compose.example.ai.yml for setup instructions.

Network Security

The /mcp endpoint is exposed on the same port as the web UI (default 3000). For hardened deployments:

Docker Compose:

  • The MCP endpoint is protected by the MCP_API_TOKEN but is reachable on port 3000
  • For additional security, use Pipelock's MCP reverse proxy (port 8889) which adds scanning
  • See compose.example.ai.yml for a Pipelock configuration

Kubernetes:

  • Use NetworkPolicies to restrict access to the MCP endpoint
  • Route external agents through Pipelock's MCP reverse proxy
  • See the Helm chart documentation for Pipelock ingress setup

Production Deployment

For a production-ready setup with security scanning:

  1. Download the example configuration:

    curl -o compose.ai.yml https://raw.githubusercontent.com/we-promise/sure/main/compose.example.ai.yml
    curl -o pipelock.example.yaml https://raw.githubusercontent.com/we-promise/sure/main/pipelock.example.yaml
    
  2. Set your MCP credentials in .env:

    MCP_API_TOKEN=your-secret-token
    MCP_USER_EMAIL=user@example.com
    
  3. Start the stack:

    docker compose -f compose.ai.yml up -d
    
  4. Connect your AI assistant to the Pipelock MCP proxy:

    http://your-server:8889
    

The Pipelock proxy (port 8889) scans all MCP traffic before forwarding to Sure's /mcp endpoint.

Connecting AI Assistants

Claude Desktop

Configure Claude Desktop to use Sure's MCP server:

  1. Open Claude Desktop settings
  2. Add a new MCP server
  3. Set the endpoint to http://your-server:8889 (if using Pipelock) or http://your-server:3000/mcp
  4. Add the authorization header: Authorization: Bearer your-secret-token

Custom Agents

Any AI agent that supports JSON-RPC 2.0 can connect to the MCP endpoint. The agent should:

  1. Send a POST request to /mcp
  2. Include the Authorization: Bearer <token> header
  3. Use the JSON-RPC 2.0 format for requests
  4. Handle the protocol methods: initialize, tools/list, tools/call

Troubleshooting

"MCP endpoint not configured" error

Symptom: Requests return HTTP 503 with "MCP endpoint not configured"

Fix: Ensure both MCP_API_TOKEN and MCP_USER_EMAIL are set as environment variables and restart Sure.

"unauthorized" error

Symptom: Requests return HTTP 401 with "unauthorized"

Fix: Verify the Authorization header contains the correct token: Bearer <MCP_API_TOKEN>

"MCP user not configured" error

Symptom: Requests return HTTP 503 with "MCP user not configured"

Fix: The MCP_USER_EMAIL does not match an existing user. Check that:

  • The email is correct
  • The user exists in the database
  • There are no typos or extra spaces

Pipelock connection refused

Symptom: AI assistant cannot connect to Pipelock's MCP proxy (port 8889)

Fix:

  1. Verify Pipelock is running: docker compose ps pipelock
  2. Check Pipelock health: docker compose exec pipelock /pipelock healthcheck --addr 127.0.0.1:8888
  3. Verify the port is exposed in your compose.yml

See Also