MCP

Arche runs a Model Context Protocol (MCP) server, so an AI agent can look up companies, read normalized statements and point-in-time financials, and check data quality without custom integration code. Each tool calls the same HTTP route your code would, under your API key, so an agent gets the same figures, the same provenance and the same plan coverage.

MCP is available on every plan, including Free. A Free key reaches the same 25 companies it can query over HTTP. Modeling, reconciliation and AI tools need a paid plan; the tool table lists the plan each one needs.

Connect a client

  • Name
    URL
    Type
    endpoint
    Description

    https://api.arche.fi/mcp

  • Name
    Transport
    Type
    protocol
    Description

    Streamable HTTP. Every response is a single JSON body; the server opens no event stream, so GET /mcp returns 405.

  • Name
    Authentication
    Type
    header
    Description

    X-Api-Key: ak_…. Use this header rather than a bearer token: tools pass it on to the routes they call, so your plan and coverage apply to every tool call.

  • Name
    Protocol versions
    Type
    string
    Description

    2025-06-18, 2025-03-26 and 2024-11-05. A client that asks for another version is answered with 2025-06-18.

  • Name
    Manifest
    Type
    endpoint
    Description

    https://api.arche.fi/mcp/manifest lists every tool with its input schema and the plan it needs, and the MCP rate limit for each plan. It needs no API key, so an agent can read it before it connects.

Any client that can connect to a remote MCP server over HTTP with a custom header can use Arche. With Claude Code, for example:

claude mcp add --transport http arche https://api.arche.fi/mcp \
  --header "X-Api-Key: YOUR_API_KEY"

Clients configured from JSON generally take the same three values:

{
  "mcpServers": {
    "arche": {
      "type": "http",
      "url": "https://api.arche.fi/mcp",
      "headers": { "X-Api-Key": "YOUR_API_KEY" }
    }
  }
}

Keep the key out of shared configuration files. Most clients can read it from an environment variable instead.

Call it directly

The server speaks JSON-RPC 2.0 and supports initialize, ping, tools/list and tools/call. Notifications such as notifications/initialized are acknowledged with 202 and no body.

List the tools:

curl -X POST "https://api.arche.fi/mcp" \
  -H "X-Api-Key: $ARCHE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc": "2.0", "id": 1, "method": "tools/list"}'

Each tool carries a name, a description and an inputSchema. Call one with its arguments:

curl -X POST "https://api.arche.fi/mcp" \
  -H "X-Api-Key: $ARCHE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc": "2.0", "id": 2, "method": "tools/call", "params": {"name": "companies_resolve", "arguments": {"ticker": "AAPL"}}}'

The result is the tool's output as JSON text:

{
  "jsonrpc": "2.0",
  "id": 2,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "{\"as_of\": \"2026-09-26\", \"cik\": \"0000320193\", \"exchange\": null, \"request_id\": \"58c0f33bcff243b9a4cd83ebc36b89df\", \"ticker\": \"AAPL\"}"
      }
    ],
    "isError": false
  }
}

Tools

Tool names are the method names with _ in place of .. Every tool is available on every plan unless the table says otherwise; a tool above your plan returns a FEATURE_NOT_AVAILABLE result naming the plan it needs. The same list, with each tool's input schema, is served at GET /mcp/manifest.

ToolWhat it returnsPlan
companies_resolveThe CIK for a ticker. Call it first when you only have a ticker.Free
filings_listA company's EDGAR filings, paginated.Free
statements_normalizedThe latest normalized statement for a period, with optional version history.Free
provenance_as_ofFinancials as they were known on a date, with provenance.Free
financials_get_as_of_snapshotThe same as provenance_as_of, under a name agents find more readily.Free
dq_anomaliesA normalized statement with its data-quality overlay.Free
system_healthService health.Free
system_metadataService metadata and usage limits.Free
modeling_periodsModeling period rows.Growth
modeling_ttmTrailing-twelve-month rows.Growth
modeling_growthGrowth rows.Growth
modeling_ratiosRatio rows.Growth
modeling_valuation_inputsValuation inputs for multi-year modeling.Growth
reconciliation_summaryReconciliation results by category over a range of fiscal years.Growth
reconciliation_ledgerIndividual reconciliation results for one statement.Growth
ai_narrativesGenerated narratives for a company.Growth
ai_peersExperimental. Peer companies by financial similarity.Scale
ai_anomalies_explanationsExplanations of data-quality anomalies.Scale
ai_embeddings_metadataExperimental. Embedding metadata.Scale

The modeling_* and ai_* tools take company_id, a UUID, rather than a CIK. Get one from /v1/identity/resolve. The modeling tools also need a snapshot for their as_of date; see Modeling.

Errors

Two kinds of failure come back differently.

A malformed request is a JSON-RPC error, returned with HTTP 200:

  • Name
    -32700
    Type
    JSON-RPC error
    Description

    The body is not valid JSON.

  • Name
    -32600
    Type
    JSON-RPC error
    Description

    The body is not a JSON-RPC 2.0 request, or is an empty batch.

  • Name
    -32601
    Type
    JSON-RPC error
    Description

    The JSON-RPC method is not supported.

  • Name
    -32602
    Type
    JSON-RPC error
    Description

    The tool does not exist, or its arguments failed validation. data lists the failures.

A tool that runs and fails, because of your plan, a rate limit or the route it calls, returns a result with isError: true. Its text is a JSON error:

{
  "type": "FEATURE_NOT_AVAILABLE",
  "message": "This feature requires the growth plan or higher.",
  "retryable": false,
  "http_status": 403,
  "http_code": "FEATURE_NOT_AVAILABLE",
  "trace_id": null,
  "retry_after_s": null
}

Retry only when retryable is true, and wait retry_after_s seconds when it is set. Quote trace_id when you escalate.

Limits

MCP requests are metered in their own class; see Rate limits for your plan's budget, which the manifest also reports under rate_limits. A request body larger than 1 MiB is refused with 413.

Was this page helpful?