Protocol and errors
MCP methods, response envelopes, validation errors, limits, and retry semantics.
Signals Data MCP uses JSON-RPC 2.0 over an authenticated Streamable HTTP POST
endpoint. Send Content-Type: application/json and a Bearer API key.
Initialize
{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2025-06-18",
"capabilities": {},
"clientInfo": { "name": "my-agent", "version": "1.0.0" }
}
}The response advertises only the tools capability and includes server
instructions. Agents should treat those instructions as part of the tool
contract: resolve symbols, inspect coverage, discover IDs before fetches, and
preserve source URLs and quotes.
Tool descriptors
tools/list returns six fields per tool:
{
"name": "get_kpi_series",
"title": "Get KPI series",
"description": "Use this when you have a metric_key from list_company_kpis and need one company-native KPI time series...",
"inputSchema": {
"type": "object",
"required": ["symbol", "metric_key"],
"properties": {
"symbol": { "type": "string", "minLength": 1 },
"metric_key": { "type": "string", "minLength": 1 },
"limit": { "type": "integer", "minimum": 1, "maximum": 50, "default": 12 }
},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"required": ["symbol", "metric", "points"]
},
"annotations": {
"readOnlyHint": true,
"destructiveHint": false,
"idempotentHint": true,
"openWorldHint": false
}
}Clients should refresh tools/list when server version changes and validate
arguments locally. Unknown fields are rejected rather than silently ignored.
Successful tool call
Every successful call returns the same data twice:
structuredContentis the machine-readable object described byoutputSchema.content[0].textis its serialized JSON fallback for clients that do not yet consume structured output.
{
"jsonrpc": "2.0",
"id": 8,
"result": {
"content": [{ "type": "text", "text": "{\"symbol\":\"AAPL:US\",...}" }],
"structuredContent": { "symbol": "AAPL:US", "exists": true, "datasets": {} },
"isError": false
}
}Prefer structuredContent; do not parse the text copy unless your MCP host
requires it.
Error layers
Transport, JSON-RPC, and tool-domain failures are different:
| Layer | Signal | Examples | Retry? |
|---|---|---|---|
| HTTP auth/rate limit | HTTP 401, 403, or 429 | Missing key, tier required, quota | Only 429, after Retry-After |
| JSON-RPC request | error.code | -32700 parse, -32600 request, -32601 method, -32602 arguments | Fix request; do not retry unchanged |
| Tool domain/runtime | result.isError: true | Unknown symbol, unknown ID, backend tool failure | Fix identifier; retry transient runtime failures with a cap |
Example invalid arguments:
{
"jsonrpc": "2.0",
"id": 9,
"error": {
"code": -32602,
"message": "missing required argument: metric_key"
}
}Example domain error:
{
"jsonrpc": "2.0",
"id": 10,
"result": {
"content": [{ "type": "text", "text": "{\"error\":\"unknown-symbol\",\"symbol\":\"NOPE:US\"}" }],
"structuredContent": { "error": "unknown-symbol", "symbol": "NOPE:US" },
"isError": true
}
}Limits and retries
Collection limits are bounded in each tool's schema. Most allow 1–50 rows;
search_corpus allows 1–20. Tool calls count against the same account limits as
REST requests. On HTTP 429, wait for Retry-After, add jitter, and cap retries.
Do not parallelize enough calls to exceed the account's concurrency limit.
OAuth discovery
The resource publishes RFC 9728 metadata at:
https://api.signals.ai/.well-known/oauth-protected-resourceThis is resource-server plumbing for future hosted integrations. It does not mean Signals is currently listed in the ChatGPT or Claude directories. The supported public production path is a developer API key.