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.
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.