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