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.
Event types
Section titled “Event types”The ProxyEvent enum has four variants:
| Variant | When | Key data |
|---|---|---|
Request | A request transaction completes | request and response projections, latency, span breakdown |
Session | An MCP initialize handshake captures session info | session ID, AI client name, version, platform |
Schema | A discovery response is captured | method, items, change diff |
Heartbeat | Every 30 seconds | proxy state snapshot |
Request
Section titled “Request”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}| Field | Type | Description |
|---|---|---|
request_id | string | Correlation key. For MCP requests, the JSON-RPC id (stringified). For HTTP, a fresh UUID v4 minted at pipeline entry. |
ts | timestamp | Captured at emit time so cloud-sink batching delay does not skew analytics |
request | LoggedRequest | Logging projection of the inbound request — see below |
response | LoggedResponse | null | Logging projection of the outbound response. null for orphan transactions (parse-pass-but-pipeline-fail, client disconnects, request-stage errors). |
latency_us | number | Total round-trip time in microseconds |
upstream_us | number | Time 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 |
openai | object | null | OpenAI client context (ChatGPT Apps SDK / Connectors) when _meta.openai/* keys are present; null otherwise |
LoggedRequest
Section titled “LoggedRequest”MCP variants carry the full JSON-RPC envelope and inbound HTTP Parts; the HTTP variant keeps only routing-level metadata.
| Variant | Fields |
|---|---|
Mcp | HTTP Parts, JSON-RPC request |
McpBatch | HTTP Parts, list of JSON-RPC requests (legacy, removed from spec in 2025-06-18) |
Http | method, uri, body_size |
LoggedResponse
Section titled “LoggedResponse”Mirrors LoggedRequest. MCP keeps the full JSON-RPC result and upstream Parts; HTTP carries only the status and body size.
| Variant | Fields |
|---|---|
Mcp | HTTP Parts, JSON-RPC result |
McpBatch | HTTP Parts, list of JSON-RPC results |
Http | status, 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.
Session
Section titled “Session”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"}| Field | Type | Description |
|---|---|---|
session_id | string | MCP session ID |
client_name | string | null | AI client name from clientInfo |
client_version | string | null | Client version |
client_platform | string | null | Client platform (when available) |
upstream | string | Upstream MCP server URL |
Schema
Section titled “Schema”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.
| Field | Type | Description |
|---|---|---|
mcp_method | string | The discovery method that triggered capture |
upstream | string | Upstream MCP server URL |
items | array | Captured entries (tools, resources, prompts) |
change_type | string | initial, added, modified, removed |
Heartbeat
Section titled “Heartbeat”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}| Field | Type | Description |
|---|---|---|
ts | timestamp | Heartbeat tick time |
mcp_status | string | Upstream MCP status (running) |
tunnel_status | string | disabled, disconnected, connected, or evicted |
tunnel_address | string | null | Public URL when the tunnel is connected |
upstream | string | Upstream MCP server URL |
export_port | number | Local port the proxy is listening on |
