Skip to content

Event Schema

mcpr emits events through its event bus. Events are routed to registered sinks — stderr, SQLite, cloud, or custom implementations. Each event has a variant and an associated payload.

The ProxyEvent enum has four variants:

VariantWhenKey data
RequestA request transaction completesrequest and response projections, latency, span breakdown
SessionAn MCP initialize handshake captures session infosession ID, AI client name, version, platform
SchemaA discovery response is capturedmethod, items, change diff
HeartbeatEvery 30 secondsproxy state snapshot

The primary observability event. One event per request transaction, emitted after the response stage completes (or once on the error path when the response stage never ran).

{
"request_id": "req_abc123",
"ts": 1712050530142,
"request": {
"kind": "mcp",
"method": "POST",
"path": "/mcp",
"mcp_method": "tools/call",
"tool": "search_products"
},
"response": {
"kind": "mcp",
"status": 200,
"result": "ok"
},
"latency_us": 142000,
"upstream_us": 138000,
"spans": [
["Parse", 800],
["RequestLogStage", 1200],
["Router", 124000]
],
"openai": null
}
FieldTypeDescription
request_idstringCorrelation key. For MCP requests, the JSON-RPC id (stringified). For HTTP, a fresh UUID v4 minted at pipeline entry.
tstimestampCaptured at emit time so cloud-sink batching delay does not skew analytics
requestLoggedRequestLogging projection of the inbound request — see below
responseLoggedResponse | nullLogging projection of the outbound response. null for orphan transactions (parse-pass-but-pipeline-fail, client disconnects, request-stage errors).
latency_usnumberTotal round-trip time in microseconds
upstream_usnumberTime spent waiting for the upstream response in microseconds. 0 when the router never ran.
spans[string, number][]Per-stage timer breakdown — [span_name, duration_us] pairs
openaiobject | nullOpenAI client context (ChatGPT Apps SDK / Connectors) when _meta.openai/* keys are present; null otherwise

MCP variants carry the full JSON-RPC envelope and inbound HTTP Parts; the HTTP variant keeps only routing-level metadata.

VariantFields
McpHTTP Parts, JSON-RPC request
McpBatchHTTP Parts, list of JSON-RPC requests (legacy, removed from spec in 2025-06-18)
Httpmethod, uri, body_size

Mirrors LoggedRequest. MCP keeps the full JSON-RPC result and upstream Parts; HTTP carries only the status and body size.

VariantFields
McpHTTP Parts, JSON-RPC result
McpBatchHTTP Parts, list of JSON-RPC results
Httpstatus, body_size

For resources/list, resources/templates/list, and resources/read, the logging projection slims items down to the naming/path fields. Widget HTML, blob bodies, descriptions, and other large fields are stripped before the event reaches sinks. The response sent to the client is untouched.

Captured when an MCP initialize handshake completes.

{
"session_id": "sess_abc123",
"client_name": "ChatGPT",
"client_version": "2024.04.01",
"client_platform": "web",
"upstream": "http://localhost:9000"
}
FieldTypeDescription
session_idstringMCP session ID
client_namestring | nullAI client name from clientInfo
client_versionstring | nullClient version
client_platformstring | nullClient platform (when available)
upstreamstringUpstream MCP server URL

Emitted when a discovery response (tools/list, resources/list, resources/templates/list, prompts/list) is captured. Includes the diff against the previous snapshot so additions, modifications, and removals are tracked over time.

FieldTypeDescription
mcp_methodstringThe discovery method that triggered capture
upstreamstringUpstream MCP server URL
itemsarrayCaptured entries (tools, resources, prompts)
change_typestringinitial, added, modified, removed

Periodic snapshot of a proxy’s runtime status, emitted every 30 seconds by the CLI host (not by the request pipeline). Cloud uses these to answer “is this server up and where does it live?” without a dedicated control-plane connection.

{
"ts": 1712050540000,
"mcp_status": "running",
"tunnel_status": "connected",
"tunnel_address": "https://abc123.tunnel.mcpr.app",
"upstream": "http://localhost:9000",
"export_port": 3004
}
FieldTypeDescription
tstimestampHeartbeat tick time
mcp_statusstringUpstream MCP status (running)
tunnel_statusstringdisabled, disconnected, connected, or evicted
tunnel_addressstring | nullPublic URL when the tunnel is connected
upstreamstringUpstream MCP server URL
export_portnumberLocal port the proxy is listening on