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 /mcpreturns405.
- 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-26and2024-11-05. A client that asks for another version is answered with2025-06-18.
- Name
Manifest- Type
- endpoint
- Description
https://api.arche.fi/mcp/manifestlists 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.
| Tool | What it returns | Plan |
|---|---|---|
companies_resolve | The CIK for a ticker. Call it first when you only have a ticker. | Free |
filings_list | A company's EDGAR filings, paginated. | Free |
statements_normalized | The latest normalized statement for a period, with optional version history. | Free |
provenance_as_of | Financials as they were known on a date, with provenance. | Free |
financials_get_as_of_snapshot | The same as provenance_as_of, under a name agents find more readily. | Free |
dq_anomalies | A normalized statement with its data-quality overlay. | Free |
system_health | Service health. | Free |
system_metadata | Service metadata and usage limits. | Free |
modeling_periods | Modeling period rows. | Growth |
modeling_ttm | Trailing-twelve-month rows. | Growth |
modeling_growth | Growth rows. | Growth |
modeling_ratios | Ratio rows. | Growth |
modeling_valuation_inputs | Valuation inputs for multi-year modeling. | Growth |
reconciliation_summary | Reconciliation results by category over a range of fiscal years. | Growth |
reconciliation_ledger | Individual reconciliation results for one statement. | Growth |
ai_narratives | Generated narratives for a company. | Growth |
ai_peers | Experimental. Peer companies by financial similarity. | Scale |
ai_anomalies_explanations | Explanations of data-quality anomalies. | Scale |
ai_embeddings_metadata | Experimental. 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.
datalists 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.