Developers
DEVELOPERS · MCP

MCP server

api.signalraven.ai/mcp — an OAuth-gated Model Context Protocol server exposing your signals as tools an AI assistant can call.

Looking to just connect Claude or ChatGPT? See Connect to Claude / ChatGPT. This page is the technical reference.

Endpoint & transport

  • URLhttps://api.signalraven.ai/mcp
  • Transport — Streamable HTTP, JSON-RPC 2.0
  • Auth — OAuth 2.1 (the client discovers the authorization server automatically)

Discovery

Connectors find the authorization server via standard metadata:

  • api.signalraven.ai/.well-known/oauth-protected-resource (RFC 9728)
  • auth.signalraven.ai/.well-known/openid-configuration

A 401 from /mcp carries a WWW-Authenticate: Bearer resource_metadata="…" header so clients can auto-discover the flow.

OAuth for connectors

Any MCP client that follows the discovery above can connect with no configuration on our side.

  • Registration — dynamic client registration (RFC 7591) at api.signalraven.ai/oauth/register, advertised in the metadata. Client ID metadata documents also work.
  • Scopesread:signals read:sources read:watchlist read:icp read:intelligence read:usage read:destinations write:intelligence write:destinations. The two write scopes gate the tools that spend credits or change delivery. Registered clients may also request offline_access or its alias offline for a refresh token.
  • Where scopes are advertised — the 401 challenge’s scope parameter, scopes_supported in the RFC 8414 metadata, and scopes_supported in the OpenID document. Clients differ in which one they read; all three agree.
  • Consent — the user signs in at signalraven.ai and approves the listed scopes; a member with several workspaces picks one. The token is bound to that workspace.
  • Sample data — an account without an active workspace completes the same flow and every tool returns clearly labeled sample data, so a connector can be exercised end to end before a workspace exists.
  • Tool metadata — every tool carries a title, readOnlyHint, destructiveHint, openWorldHint and an outputSchema for its result envelope (mode, data, and total for lists).

Tools

ToolScopeDescription
list_signalsread:signalsList signals (limit, offset, type, minStrength)
get_signalread:signalsFetch one signal by id
list_sourcesread:sourcesList sources + metrics (period)
get_watchlistread:watchlistList watchlist posts
get_icpread:icpGet the workspace ICP profile
list_intelligenceread:intelligenceList Account + Person Intelligence reports (limit, offset, type, q)
get_account_intelligenceread:intelligenceFetch one Account Intelligence report by id
get_person_intelligenceread:intelligenceFetch one Person Intelligence snapshot by id
get_usageread:usageWorkspace activity counts
list_destinationsread:destinationsWhere signals are delivered, with health
run_account_intelligencewrite:intelligenceStart an Account Intelligence run (spends credits)
run_person_intelligencewrite:intelligenceStart a Person Intelligence run (spends credits)
create_destinationwrite:destinationsCreate a delivery destination
update_destinationwrite:destinationsRename, pause or re-route a destination

Results carry structuredContent.mode = "live" or "sample", mirroring the REST _meta.mode.

Approved vs. sample data

There are two permission layers — worth understanding the difference:

  1. You authorizing a client — “I let this app read my workspace” (OAuth consent, or creating an API key).
  2. SignalRaven approving a client to operate — a platform-level gate for third-party connectors.
Client stateResult
Your own API keyLive data immediately — auto-approved for your workspace
Approved third-party connectorLive data for workspaces users consent to
Pending / unknown connectorSample data + a prompt to get approved
Denied connector403 — no access

So an unknown agent that discovers the server can complete the handshake, see the tool list, and get a realistic taste — but never a real customer’s data — until a human at SignalRaven approves it.

// Example: list_signals tool call (JSON-RPC)
{ "jsonrpc": "2.0", "id": 1, "method": "tools/call",
  "params": { "name": "list_signals", "arguments": { "limit": 5 } } }