MCP Gateway
Call upstream MCP tools over JSON-RPC 2.0. The gateway proxies the tools of registered MCP servers that the key's agency and location can reach.
Overview
The MCP Gateway is a single JSON-RPC 2.0 endpoint. It authenticates the caller's mcp_ key, enforces scopes and agency/location access, then proxies the call to a registered upstream MCP server, injecting that client's credentials.
The gateway no longer serves the built-in insights/dashboards/canvases tools — those (and much more) live on the Settings Server, which accepts the same mcp_ keys. Calling a retired tool name here returns -32601 with the Settings Server URL.
Endpoint
POST https://mythic-analytics.gulp.workers.dev/mcp
The endpoint accepts a single JSON-RPC request object per HTTP call. CORS is open (*) for POST and OPTIONS.
Authentication
Send the mcp_ key as a bearer token or in X-Api-Key.
Authorization: Bearer mcp_...
See Authentication for scope rules.
JSON-RPC 2.0 format
Request
{
"jsonrpc": "2.0",
"id": "req-001",
"method": "tools/call",
"params": {
"name": "an_upstream_tool",
"arguments": { "limit": 10 }
}
}
Must be "2.0".
Request identifier, echoed back in the response.
One of server/discover, initialize, notifications/initialized, tools/list, tools/call.
Method-specific parameters. For tools/call, include name and arguments.
Success response
{
"jsonrpc": "2.0",
"id": "req-001",
"result": {
"content": [
{ "type": "text", "text": "[ ... insights ... ]" }
]
}
}
Error response
{
"jsonrpc": "2.0",
"id": "req-001",
"error": {
"code": -32601,
"message": "Method not found: tools/execute"
}
}
Protocol versions
The gateway supports 2024-11-05, 2025-03-26, 2025-06-18, and 2025-11-25. It answers initialize with the version you requested when it is one of those, and with 2025-11-25 otherwise.
If you send the MCP-Protocol-Version header on post-handshake requests (required of clients from 2025-06-18 onward), it must name one of the supported versions — anything else is rejected with 400 and error code -32600. Omitting the header is accepted.
The 2026-07-28 revision (stateless requests, _meta version negotiation, MRTR) is not yet served; clients that speak it should fall back to 2025-11-25, which server/discover advertises.
Methods
server/discover
Returns supported protocol versions, capabilities, and server identity in a single request. No handshake required — you may call it before anything else.
{ "jsonrpc": "2.0", "id": 1, "method": "server/discover", "params": {} }
Result:
{
"resultType": "complete",
"supportedVersions": ["2024-11-05", "2025-03-26", "2025-06-18", "2025-11-25"],
"capabilities": { "tools": {} },
"instructions": "Mythic Analytics gateway: per-client analytics and upstream MCP tools, scoped by the mcp_ API key.",
"ttlMs": 3600000,
"cacheScope": "private",
"_meta": {
"io.modelcontextprotocol/serverInfo": { "name": "mythic-analytics-gateway", "version": "1.0.0" }
}
}
initialize
Returns protocol and server info. No authentication side effects beyond the standard key check.
{ "jsonrpc": "2.0", "id": 1, "method": "initialize", "params": { "protocolVersion": "2025-11-25" } }
Result:
{
"protocolVersion": "2025-11-25",
"capabilities": { "tools": {} },
"serverInfo": { "name": "mythic-analytics-gateway", "version": "1.0.0" }
}
notifications/initialized
Client lifecycle notification. The gateway accepts it and returns an empty result.
tools/list
Returns every upstream tool the key can use, filtered by scope, agency access, and location access. Each entry has name, description, inputSchema, and annotations. Tools come back sorted by name, so the list is stable across calls and safe to cache. The result also carries ttlMs (300000) and cacheScope ("private") as caching hints.
{ "jsonrpc": "2.0", "id": 2, "method": "tools/list", "params": {} }
tools/call
Execute a tool by name.
{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "an_upstream_tool",
"arguments": { "query": "Q3 overview" }
}
}
The result is the tool's MCP content payload ({ "content": [...] }, optionally with "isError": true), proxied through from the upstream server unchanged.
Upstream calls receive that client's stored credentials automatically — you do not pass credentials in arguments.
Tools
Every tool comes from a registered upstream server and requires the <scope_prefix>:call scope (or upstream:call when the server has no scope prefix).
Retired built-in tools
The gateway previously implemented list_insights, get_insight, create_insight, update_insight, delete_insight, list_dashboards, get_dashboard, create_dashboard, update_dashboard, delete_dashboard, add_insight_to_dashboard, remove_insight_from_dashboard, list_canvases, and get_canvas itself. These names now return -32601 with a message pointing at the Settings Server, which serves them (and many more) with the same mcp_ key.
Error codes
Standard JSON-RPC codes are used throughout:
| Code | Meaning |
|---|---|
-32700 | Parse error — invalid JSON |
-32600 | Invalid request — bad envelope, auth failure, or access/scope denial |
-32601 | Method not found, or unknown tool |
-32602 | Invalid params — missing tool name |
-32603 | Internal error |
-32000 | Rate limit exceeded, or an upstream transport/HTTP error |
Authentication failures return HTTP 401 and rate-limit rejections return HTTP 429, each carrying a JSON-RPC error object. Scope and access denials are returned as -32600.
Rate limiting
The gateway enforces a per-key, per-minute request ceiling using a sliding window. The limit comes from the key's rate_limit_per_minute (default 60). Exceeding it returns HTTP 429:
{ "jsonrpc": "2.0", "id": null, "error": { "code": -32000, "message": "Rate limit exceeded" } }
Limits are per API key, not per location. Provision separate keys for separate services to isolate their limits.