MCP Server for External AI Assistants

September 8, 2026 · View on GitHub

Sure includes a Model Context Protocol (MCP) server endpoint that allows external AI assistants like Claude.ai, Claude Desktop, GPT agents, or custom AI clients to query and act on 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

Authentication Modes

Sure supports two ways to authenticate MCP clients:

This is the best option for Claude.ai and other MCP clients that support OAuth. Sure exposes:

  • /.well-known/oauth-protected-resource
  • /.well-known/oauth-authorization-server
  • POST /register for dynamic client registration

These endpoints let compatible MCP clients register a public OAuth client, redirect you back to Sure for sign-in, and receive a bearer token with the read_write scope.

2. Static bearer token via environment variables

This is the simpler fallback for custom agents, scripts, and deployments where you want to pin the MCP server to a specific Sure user.

Set these environment variables:

VariableDescriptionExample
MCP_API_TOKENBearer token for authenticationyour-secret-token-here
MCP_USER_EMAILEmail of the Sure user whose data the assistant can accessuser@example.com

Both variables are required for the legacy token flow. OAuth clients using the MCP discovery and dynamic registration endpoints do not need these variables.

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 for static-token auth

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 can call the MCP tools available to the specified user. This includes reading financial data and write-capable tools such as statement import, goal/category/tag changes, transaction updates, and budget updates. 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

MCP supports OAuth authorization-code flow for clients such as Claude Code. Clients should discover the protected-resource metadata, register dynamically, request the advertised read_write scope, and send the resulting access token as a Bearer token. Dynamically registered clients are assigned this scope so their tokens can authenticate to MCP.

For self-hosted deployments or clients without OAuth support, requests may use the legacy MCP_API_TOKEN as a Bearer token:

Authorization: Bearer <token>

That token can come from either:

  • an OAuth authorization flow handled by the MCP client, or
  • the static MCP_API_TOKEN environment variable described above.

Supported Methods

Sure implements the following JSON-RPC 2.0 methods:

MethodDescription
initializeProtocol handshake, returns server info and capabilities
tools/listLists available financial tools with schemas
tools/callExecutes a tool with provided arguments

Available Tools

The MCP endpoint exposes the same tool registry used by Sure's built-in assistant. Clients should treat tools/list as the source of truth.

At the time of writing, tools/list includes:

ToolDescription
get_transactionsSearch transactions with filters (exact names or ids), sorting by date or absolute amount, and pagination
get_recurring_transactionsDetected and manual recurring transactions (subscriptions, bills, salaries) with expected dates and per-currency totals
get_accountsAccounts with ids and current balances; pass include_balance_series: true for a period-bounded history series
get_holdingsQuery investment holdings
get_balance_sheetNet worth, assets and liabilities with a configurable history period and interval
get_income_statementIncome and expenses for a period, with optional monthly series, prior-period comparison and account filtering
get_budgetBudget summary for a month, with optional prior months
get_merchantsMerchants with the ids update_transaction accepts and the exact names get_transactions filters on
get_tagsTags with pagination
get_categoriesCategories with hierarchy and pagination
create_goalCreate a savings goal linked to depository accounts
create_tag / update_tagManage tags
create_category / update_categoryManage categories
update_transactionEdit a transaction's metadata (name, notes, category, merchant, tags)
update_budgetUpdate budget allocations for a month
import_bank_statementImport bank statement data
search_family_filesSearch documents uploaded through the import flow. Note this is the vector-store document index, not the Statement Vault — statements archived via upload_account_statement are not searchable through it

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.

ToolDescription
upload_account_statementStore a statement document (PDF/CSV/XLSX) in the Statement Vault; deduplicates by SHA-256
list_account_statementsList vault documents with their SHA-256, period, linked account and review status
get_account_statementOne statement's details and its reconciliation checks against the ledger — present only once someone has entered the statement's opening/closing balances in the web UI, since nothing extracts them from the document. Does not return the file: stored documents are served only to a signed-in browser session
get_statement_coverageMonth-by-month statement coverage for an account: covered, missing, mismatched, ambiguous, duplicate, not_expected, each with a reconciliation status
record_valuationRecord an account's value on a date, with a required source citation
get_valuationsList recorded valuations newest first, including the citation stored in each entry's notes; the read pair for record_valuation
get_insightsRead the proactive insights feed (spending anomalies, cash-flow warnings, subscription audits and more) without marking anything read
get_billsList bills, subscriptions and other recurring obligations with each one's current payment state
get_bill_detailsOne bill's full configuration, open occurrences, payment history, price-change history and cost analytics
get_paycheck_planIncome plan sliced into pay periods: what is due before the next payday, what stays reserved for later bills, what is safe to spend
get_bill_auditDeterministic bills review: possible duplicates, price changes, trials about to convert, upcoming renewals, long-overdue bills and undeclared recurring patterns
create_billCreate a bill, subscription, installment plan or income schedule
update_billUpdate one bill's configuration; amount changes apply from today forward
record_bill_paymentRecord a partial payment against a bill's open occurrence, or settle it in full

Because tool calls never pass through the Bills pages' controllers, the bills tools re-check the family's recurring-transactions feature gate (Settings → Recurring transactions) and the MCP user's per-account access on every call. With the feature disabled they return an error result instead of data, bills tied to accounts the user cannot see are never returned, and the write tools refuse series on accounts shared with the user read-only.

They exist for agents that maintain a document-backed record of a family's wealth over time. See Wealth 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.

OAuth discovery

MCP clients that support OAuth can discover Sure's metadata automatically:

curl https://your-sure-instance/.well-known/oauth-protected-resource
curl https://your-sure-instance/.well-known/oauth-authorization-server

The authorization-server metadata includes:

  • authorization_endpoint: https://your-sure-instance/oauth/authorize
  • token_endpoint: https://your-sure-instance/oauth/token
  • registration_endpoint: https://your-sure-instance/register
  • scopes_supported: ["read_write"]

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 authorized Sure user
  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.ai

Sure's Settings UI is already geared toward Claude.ai OAuth integrations:

  1. Open Settings -> Integrations in Claude.ai
  2. Click Add integration
  3. Paste your Sure MCP URL
  4. Claude redirects you to Sure to sign in and authorize access

If you are using Pipelock, use the reverse-proxy URL on port 8889. Otherwise use the app URL ending in /mcp.

Claude Desktop

If your Claude Desktop build expects a raw MCP endpoint instead of an OAuth integration flow, point it at:

  • http://your-server:8889 when using Pipelock, or
  • http://your-server:3000/mcp for direct access

Use either the client's OAuth support or a bearer token, depending on what that build supports.

Cursor and other native MCP clients

Desktop MCP clients such as Cursor and VS Code authenticate with OAuth Dynamic Client Registration (POST /register) and then open a browser for consent. Native clients register a private-use redirect URI rather than an https:// callback, for example:

  • Cursor desktop: cursor://anysphere.cursor-mcp/oauth/callback
  • Newer Cursor IDE/CLI builds: http://localhost:8787/callback
  • Cursor web: https://www.cursor.com/agents/mcp/oauth/callback
  • VS Code extensions: vscode://...

Sure accepts those native-app URI schemes, loopback http:// callbacks, and https:// callbacks. After you authorize in the browser, the client exchanges the authorization code (PKCE) for a bearer token and calls /mcp.

If OAuth is inconvenient (CI, scripts, or a client that cannot complete the browser flow), use the static MCP_API_TOKEN bearer token instead.

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

"unauthorized" error

Symptom: Requests return HTTP 401 with "unauthorized"

Fix: Verify one of these is true:

  • The OAuth flow completed successfully and the client is sending the issued bearer token
  • The static token matches MCP_API_TOKEN
  • If you are using the static-token flow, MCP_USER_EMAIL matches an existing Sure user

Static token works, but the user still gets rejected

Symptom: Requests return HTTP 401 even though the bearer token matches MCP_API_TOKEN

Fix: The MCP_USER_EMAIL probably 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