Signals. Infra
MCP server

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:

  • structuredContent is the machine-readable object described by outputSchema.
  • content[0].text is 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:

LayerSignalExamplesRetry?
HTTP auth/rate limitHTTP 401, 403, or 429Missing key, tier required, quotaOnly 429, after Retry-After
JSON-RPC requesterror.code-32700 parse, -32600 request, -32601 method, -32602 argumentsFix request; do not retry unchanged
Tool domain/runtimeresult.isError: trueUnknown symbol, unknown ID, backend tool failureFix 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-resource

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

On this page