{ "openapi": "3.1.0", "info": { "title": "Secure MCP Tunnel client control-plane API", "description": "Language-independent HTTP and JSON contract implemented by Secure MCP Tunnel clients. This document intentionally contains only the client-facing metadata, managed Cloudflare runtime fetch, long-poll, and response endpoints.", "version": "0.0.1" }, "servers": [ { "url": "https://api.openai.com" } ], "security": [ { "BearerAuth": [] } ], "paths": { "/v1/tunnels/{tunnel_id}": { "get": { "summary": "Fetch a tunnel metadata record by id", "description": "Fetch the minimal tunnel metadata used for startup diagnostics. Clients only depend on id, name, and description and must ignore additional fields.", "operationId": "getTunnelMetadata", "parameters": [ { "name": "tunnel_id", "in": "path", "required": true, "schema": { "type": "string", "description": "Opaque tunnel identifier.", "title": "Tunnel Id" }, "description": "Opaque tunnel identifier.", "example": "tunnel_1234abcd" }, { "name": "X-Tunnel-MCP-Server-Info", "in": "header", "required": false, "description": "Optional compact JSON declaration of MCP channel capabilities. Version 1 is unchanged and allows only `version`, `channels`, channel `name`, and optional `proc_affinity`. Version 2 adds optional `stateless`; `stateless` and `proc_affinity` are independent booleans, omitted values mean false, and false values are not serialized. Clients emit v1 when no stateless capability is advertised and v2 when stateless is present. Names are canonical and unique, with at most 32 channels and 4096 UTF-8 bytes. The value must not include URLs, commands, transport details, headers, payloads, secrets, targets, or customer IDs. This is additive metadata; older tunnel-service versions ignore it.", "schema": { "type": "string", "maxLength": 4096 }, "examples": { "legacy-stdio-and-harpoon": { "summary": "Legacy v1 process-affine stdio main plus built-in Harpoon", "value": "{\"version\":1,\"channels\":[{\"name\":\"main\",\"proc_affinity\":true},{\"name\":\"harpoon\",\"proc_affinity\":true}]}" }, "modern-harpoon": { "summary": "Self-contained Harpoon requests with replica-local registration", "value": "{\"version\":2,\"channels\":[{\"name\":\"harpoon\",\"stateless\":true,\"proc_affinity\":true}]}" } } }, { "name": "X-Tunnel-Client-Wire-Protocol-Version", "in": "header", "required": false, "description": "Optional dated tunnel-client/control-plane wire-contract version. A missing header means legacy/backfill semantics; unknown future values must not be treated as the current version. This header is independent of per-channel MCP capabilities in X-Tunnel-MCP-Server-Info.", "schema": { "type": "string" }, "example": "2026-08-25" }, { "name": "X-Tunnel-Client-Name", "in": "header", "required": false, "description": "Stable client implementation name for diagnostics.", "schema": { "type": "string" } }, { "name": "X-Tunnel-Client-Version", "in": "header", "required": false, "description": "Client implementation version for diagnostics.", "schema": { "type": "string" } } ], "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TunnelClientMetadata" }, "example": { "id": "tunnel_123", "name": "Production MCP", "description": "Tunnel for the production MCP server" } } } }, "403": { "description": "Tunnel-service error response (403). Stable codes: `tunnel_active_organization_required`, `tunnel_use_forbidden`. Code details and mitigations are documented in the APIErrorBody.code schema.", "x-tunnel-error-codes": [ "tunnel_active_organization_required", "tunnel_use_forbidden" ], "content": { "application/json": { "schema": { "$ref": "#/components/schemas/APIErrorResponse" } } } }, "429": { "description": "Tunnel-service error response (429). Stable codes: `rate_limit_exceeded`. Code details and mitigations are documented in the APIErrorBody.code schema.", "x-tunnel-error-codes": [ "rate_limit_exceeded" ], "content": { "application/json": { "schema": { "$ref": "#/components/schemas/APIErrorResponse" } } } } }, "security": [ { "BearerAuth": [] } ] } }, "/v1/tunnels/{tunnel_id}/cloudflare/runtime": { "get": { "summary": "Fetch managed Cloudflare runtime material for a tunnel client", "description": "Fetch managed Cloudflare provider metadata and the runtime token for an explicitly enabled bundled cloudflared companion. This endpoint requires a non-admin secret runtime API key with api.organization.tunnel.use, and the same currently attached organization or workspace principal must pass a fresh per-tunnel use check. Treat the entire response as secret-bearing and never persist, cache, or log it.", "operationId": "getCloudflareRuntime", "parameters": [ { "name": "tunnel_id", "in": "path", "required": true, "schema": { "type": "string", "description": "Opaque tunnel identifier.", "title": "Tunnel Id" }, "description": "Opaque tunnel identifier." }, { "name": "X-Tunnel-MCP-Server-Info", "in": "header", "required": false, "description": "Optional compact JSON declaration of MCP channel capabilities. Version 1 is unchanged and allows only `version`, `channels`, channel `name`, and optional `proc_affinity`. Version 2 adds optional `stateless`; `stateless` and `proc_affinity` are independent booleans, omitted values mean false, and false values are not serialized. Clients emit v1 when no stateless capability is advertised and v2 when stateless is present. Names are canonical and unique, with at most 32 channels and 4096 UTF-8 bytes. The value must not include URLs, commands, transport details, headers, payloads, secrets, targets, or customer IDs. This is additive metadata; older tunnel-service versions ignore it.", "schema": { "type": "string", "maxLength": 4096 }, "examples": { "legacy-stdio-and-harpoon": { "summary": "Legacy v1 process-affine stdio main plus built-in Harpoon", "value": "{\"version\":1,\"channels\":[{\"name\":\"main\",\"proc_affinity\":true},{\"name\":\"harpoon\",\"proc_affinity\":true}]}" }, "modern-harpoon": { "summary": "Self-contained Harpoon requests with replica-local registration", "value": "{\"version\":2,\"channels\":[{\"name\":\"harpoon\",\"stateless\":true,\"proc_affinity\":true}]}" } } }, { "name": "X-Tunnel-Client-Wire-Protocol-Version", "in": "header", "required": false, "description": "Optional dated tunnel-client/control-plane wire-contract version. A missing header means legacy/backfill semantics; unknown future values must not be treated as the current version. This header is independent of per-channel MCP capabilities in X-Tunnel-MCP-Server-Info.", "schema": { "type": "string" }, "example": "2026-08-25" }, { "name": "X-Tunnel-Client-Name", "in": "header", "required": false, "description": "Stable client implementation name for diagnostics.", "schema": { "type": "string" } }, { "name": "X-Tunnel-Client-Version", "in": "header", "required": false, "description": "Client implementation version for diagnostics.", "schema": { "type": "string" } } ], "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ManagedCloudflareRuntimeResponse" } } }, "headers": { "Cache-Control": { "description": "Prevents storage of this secret-bearing response.", "schema": { "type": "string" } }, "Pragma": { "description": "Legacy no-cache hint for this secret-bearing response.", "schema": { "type": "string" } } } }, "400": { "description": "Tunnel-service error response (400). Stable codes: `invalid_tunnel_id_format`. Code details and mitigations are documented in the APIErrorBody.code schema.", "x-tunnel-error-codes": [ "invalid_tunnel_id_format" ], "content": { "application/json": { "schema": { "$ref": "#/components/schemas/APIErrorResponse" } } } }, "401": { "description": "Tunnel-service error response (401). Stable codes: `tunnel_active_organization_required`, `tunnel_missing_principals`, `tunnel_use_forbidden`. Code details and mitigations are documented in the APIErrorBody.code schema.", "x-tunnel-error-codes": [ "tunnel_active_organization_required", "tunnel_missing_principals", "tunnel_use_forbidden" ], "content": { "application/json": { "schema": { "$ref": "#/components/schemas/APIErrorResponse" } } } }, "404": { "description": "The logical tunnel has no managed Cloudflare runtime material.", "headers": { "Cache-Control": { "description": "Prevents storage of this secret-bearing response.", "schema": { "type": "string" } }, "Pragma": { "description": "Legacy no-cache hint for this secret-bearing response.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/APIErrorResponse" } } } }, "429": { "description": "Tunnel-service error response (429). Stable codes: `rate_limit_exceeded`. Code details and mitigations are documented in the APIErrorBody.code schema.", "x-tunnel-error-codes": [ "rate_limit_exceeded" ], "content": { "application/json": { "schema": { "$ref": "#/components/schemas/APIErrorResponse" } } } }, "500": { "description": "Managed Cloudflare runtime material could not be loaded or decrypted.", "headers": { "Cache-Control": { "description": "Prevents storage of this secret-bearing response.", "schema": { "type": "string" } }, "Pragma": { "description": "Legacy no-cache hint for this secret-bearing response.", "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/APIErrorResponse" } } } }, "503": { "description": "Tunnel runtime surface is temporarily unavailable; optional Retry-After.", "headers": { "Retry-After": { "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/APIErrorResponse" } } } } }, "security": [ { "BearerAuth": [] } ] } }, "/v1/tunnels/{tunnel_id}/poll": { "get": { "summary": "Long-poll for pending MCP requests destined for a tunnel client", "operationId": "pollTunnelCommands", "parameters": [ { "name": "tunnel_id", "in": "path", "required": true, "schema": { "type": "string", "description": "Opaque tunnel identifier.", "title": "Tunnel Id" }, "description": "Opaque tunnel identifier." }, { "name": "limit", "in": "query", "required": false, "schema": { "anyOf": [ { "type": "integer", "maximum": 25, "minimum": 1 }, { "type": "null" } ], "description": "Optional maximum number of requests to return", "title": "Limit" }, "description": "Optional maximum number of requests to return" }, { "name": "timeout_ms", "in": "query", "required": false, "schema": { "anyOf": [ { "type": "integer", "minimum": 1 }, { "type": "null" } ], "description": "Optional client-requested poll wait timeout in milliseconds", "title": "Timeout Ms" }, "description": "Optional client-requested poll wait timeout in milliseconds" }, { "name": "X-Tunnel-MCP-Server-Info", "in": "header", "required": false, "description": "Optional compact JSON declaration of MCP channel capabilities. Version 1 is unchanged and allows only `version`, `channels`, channel `name`, and optional `proc_affinity`. Version 2 adds optional `stateless`; `stateless` and `proc_affinity` are independent booleans, omitted values mean false, and false values are not serialized. Clients emit v1 when no stateless capability is advertised and v2 when stateless is present. Names are canonical and unique, with at most 32 channels and 4096 UTF-8 bytes. The value must not include URLs, commands, transport details, headers, payloads, secrets, targets, or customer IDs. This is additive metadata; older tunnel-service versions ignore it.", "schema": { "type": "string", "maxLength": 4096 }, "examples": { "legacy-stdio-and-harpoon": { "summary": "Legacy v1 process-affine stdio main plus built-in Harpoon", "value": "{\"version\":1,\"channels\":[{\"name\":\"main\",\"proc_affinity\":true},{\"name\":\"harpoon\",\"proc_affinity\":true}]}" }, "modern-harpoon": { "summary": "Self-contained Harpoon requests with replica-local registration", "value": "{\"version\":2,\"channels\":[{\"name\":\"harpoon\",\"stateless\":true,\"proc_affinity\":true}]}" } } }, { "name": "X-Tunnel-Client-Wire-Protocol-Version", "in": "header", "required": false, "description": "Optional dated tunnel-client/control-plane wire-contract version. A missing header means legacy/backfill semantics; unknown future values must not be treated as the current version. This header is independent of per-channel MCP capabilities in X-Tunnel-MCP-Server-Info.", "schema": { "type": "string" }, "example": "2026-08-25" }, { "name": "X-Tunnel-Client-Name", "in": "header", "required": false, "description": "Stable client implementation name for diagnostics.", "schema": { "type": "string" } }, { "name": "X-Tunnel-Client-Version", "in": "header", "required": false, "description": "Client implementation version for diagnostics.", "schema": { "type": "string" } } ], "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PolledCommandList" }, "example": { "commands": [ { "request_id": "req_123", "shard_token": "opaque-shard-token", "command_type": "jsonrpc", "channel": "main", "created_at": "2026-01-01T00:00:00Z", "response_timeout": "30s", "headers": { "Mcp-Session-Id": [ "session_123" ] }, "jsonrpc": { "jsonrpc": "2.0", "id": "rpc_123", "method": "tools/list", "params": {} } }, { "request_id": "req_124", "shard_token": "opaque-shard-token", "command_type": "session_termination", "channel": "main", "created_at": "2026-01-01T00:00:01Z", "response_timeout": "30s", "headers": { "Mcp-Session-Id": [ "session_123" ] } } ] } } } }, "204": { "description": "No Content" }, "400": { "description": "Tunnel-service error response (400). Stable codes: `invalid_tunnel_id_format`. Code details and mitigations are documented in the APIErrorBody.code schema.", "x-tunnel-error-codes": [ "invalid_tunnel_id_format" ], "content": { "application/json": { "schema": { "$ref": "#/components/schemas/APIErrorResponse" } } } }, "401": { "description": "Tunnel-service error response (401). Stable codes: `tunnel_active_organization_required`, `tunnel_missing_principals`, `tunnel_use_forbidden`. Code details and mitigations are documented in the APIErrorBody.code schema.", "x-tunnel-error-codes": [ "tunnel_active_organization_required", "tunnel_missing_principals", "tunnel_use_forbidden" ], "content": { "application/json": { "schema": { "$ref": "#/components/schemas/APIErrorResponse" } } } }, "429": { "description": "Tunnel-service error response (429). Stable codes: `rate_limit_exceeded`. Code details and mitigations are documented in the APIErrorBody.code schema.", "x-tunnel-error-codes": [ "rate_limit_exceeded" ], "headers": { "Retry-After": { "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/APIErrorResponse" } } } }, "503": { "description": "Retryable service unavailability; optional Retry-After.", "headers": { "Retry-After": { "schema": { "type": "string" } } }, "x-tunnel-error-codes": [ "tunnel_transport_unavailable" ], "content": { "application/json": { "schema": { "$ref": "#/components/schemas/APIErrorResponse" } } } } }, "security": [ { "BearerAuth": [] } ], "description": "Long-poll for pending commands. A 204 response means the poll completed without commands; issue another poll. A 200 response contains every command the client must process. When present, response_timeout is a relative duration for the complete command lifecycle, anchored when the poll response is received." } }, "/v1/tunnels/{tunnel_id}/response": { "post": { "summary": "Deliver the final JSON-RPC response for an in-flight tunnel request", "operationId": "postTunnelResponse", "parameters": [ { "name": "tunnel_id", "in": "path", "required": true, "schema": { "type": "string", "description": "Opaque tunnel identifier.", "title": "Tunnel Id" }, "description": "Opaque tunnel identifier." }, { "name": "X-Tunnel-MCP-Server-Info", "in": "header", "required": false, "description": "Optional compact JSON declaration of MCP channel capabilities. Version 1 is unchanged and allows only `version`, `channels`, channel `name`, and optional `proc_affinity`. Version 2 adds optional `stateless`; `stateless` and `proc_affinity` are independent booleans, omitted values mean false, and false values are not serialized. Clients emit v1 when no stateless capability is advertised and v2 when stateless is present. Names are canonical and unique, with at most 32 channels and 4096 UTF-8 bytes. The value must not include URLs, commands, transport details, headers, payloads, secrets, targets, or customer IDs. This is additive metadata; older tunnel-service versions ignore it.", "schema": { "type": "string", "maxLength": 4096 }, "examples": { "legacy-stdio-and-harpoon": { "summary": "Legacy v1 process-affine stdio main plus built-in Harpoon", "value": "{\"version\":1,\"channels\":[{\"name\":\"main\",\"proc_affinity\":true},{\"name\":\"harpoon\",\"proc_affinity\":true}]}" }, "modern-harpoon": { "summary": "Self-contained Harpoon requests with replica-local registration", "value": "{\"version\":2,\"channels\":[{\"name\":\"harpoon\",\"stateless\":true,\"proc_affinity\":true}]}" } } }, { "name": "X-Tunnel-Client-Wire-Protocol-Version", "in": "header", "required": false, "description": "Optional dated tunnel-client/control-plane wire-contract version. A missing header means legacy/backfill semantics; unknown future values must not be treated as the current version. This header is independent of per-channel MCP capabilities in X-Tunnel-MCP-Server-Info.", "schema": { "type": "string" }, "example": "2026-08-25" }, { "name": "X-Tunnel-Client-Name", "in": "header", "required": false, "description": "Stable client implementation name for diagnostics.", "schema": { "type": "string" } }, { "name": "X-Tunnel-Client-Version", "in": "header", "required": false, "description": "Client implementation version for diagnostics.", "schema": { "type": "string" } }, { "name": "X-Tunnel-Shard-Token", "in": "header", "required": true, "description": "Opaque shard token from the polled command. Echo it exactly; do not place it in the JSON body.", "schema": { "type": "string" } }, { "name": "X-Client-Request-Id", "in": "header", "required": false, "description": "Optional control-plane request identifier for diagnostics.", "schema": { "type": "string" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TunnelResponsePayload" }, "example": { "request_id": "req_123", "channel": "main", "resp_json": { "jsonrpc": "2.0", "id": "rpc_123", "result": { "tools": [] } }, "resp_headers": { "Content-Type": [ "application/json" ] }, "resp_code": 200, "resp_type": "jsonrpc_response" } } } }, "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TunnelResponseAck" } } } }, "400": { "description": "Tunnel-service error response (400). Stable codes: `invalid_channel_format`, `invalid_tunnel_id_format`. Code details and mitigations are documented in the APIErrorBody.code schema.", "x-tunnel-error-codes": [ "invalid_channel_format", "invalid_tunnel_id_format" ], "content": { "application/json": { "schema": { "$ref": "#/components/schemas/APIErrorResponse" } } } }, "401": { "description": "Tunnel-service error response (401). Stable codes: `tunnel_active_organization_required`, `tunnel_missing_principals`, `tunnel_request_mismatch`, `tunnel_use_forbidden`. Code details and mitigations are documented in the APIErrorBody.code schema.", "x-tunnel-error-codes": [ "tunnel_active_organization_required", "tunnel_missing_principals", "tunnel_request_mismatch", "tunnel_use_forbidden" ], "content": { "application/json": { "schema": { "$ref": "#/components/schemas/APIErrorResponse" } } } }, "404": { "description": "Tunnel-service error response (404). Stable codes: `pending_request_not_found`. Code details and mitigations are documented in the APIErrorBody.code schema.", "x-tunnel-error-codes": [ "pending_request_not_found" ], "content": { "application/json": { "schema": { "$ref": "#/components/schemas/APIErrorResponse" } } } }, "413": { "description": "Tunnel-service error response (413). Stable codes: `request_body_too_large`. Code details and mitigations are documented in the APIErrorBody.code schema.", "x-tunnel-error-codes": [ "request_body_too_large" ], "content": { "application/json": { "schema": { "$ref": "#/components/schemas/APIErrorResponse" } } } }, "429": { "description": "Tunnel-service error response (429). Stable codes: `rate_limit_exceeded`. Code details and mitigations are documented in the APIErrorBody.code schema.", "x-tunnel-error-codes": [ "rate_limit_exceeded" ], "headers": { "Retry-After": { "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/APIErrorResponse" } } } }, "503": { "description": "Retryable service unavailability; optional Retry-After.", "headers": { "Retry-After": { "schema": { "type": "string" } } }, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/APIErrorResponse" } } } } }, "security": [ { "BearerAuth": [] } ], "description": "Post the result for one polled command. Echo the command request_id in the JSON body and its shard_token in the X-Tunnel-Shard-Token header. Preserve recognized target JSON-RPC errors, including -32003 and -32004, exactly in resp_json. Only non-protocol failures may synthesize -32603 with optional error.data.tunnel_failure provenance." } } }, "components": { "securitySchemes": { "BearerAuth": { "type": "http", "scheme": "bearer", "bearerFormat": "API key", "description": "Send the tunnel API key as Authorization: Bearer ." } }, "schemas": { "APIErrorResponse": { "properties": { "error": { "$ref": "#/components/schemas/APIErrorBody" } }, "type": "object", "required": [ "error" ], "title": "APIErrorResponse" }, "ManagedCloudflareRuntimeResponse": { "properties": { "cloudflare_tunnel": { "$ref": "#/components/schemas/CloudflareTunnelResponse", "description": "Non-secret metadata for the managed Cloudflare tunnel." }, "runtime_token": { "type": "string", "format": "password", "title": "Runtime Token", "description": "Managed Cloudflare runtime token for cloudflared." } }, "type": "object", "required": [ "cloudflare_tunnel", "runtime_token" ], "title": "ManagedCloudflareRuntimeResponse" }, "PolledCommandList": { "properties": { "commands": { "items": { "oneOf": [ { "$ref": "#/components/schemas/JsonRpcPolledCommand" }, { "$ref": "#/components/schemas/SessionTerminationPolledCommand" } ], "discriminator": { "propertyName": "command_type", "mapping": { "jsonrpc": "#/components/schemas/JsonRpcPolledCommand", "session_termination": "#/components/schemas/SessionTerminationPolledCommand" } } }, "type": "array", "title": "Commands", "description": "Pending commands the tunnel client must process from this poll response." } }, "type": "object", "required": [ "commands" ], "title": "PolledCommandList" }, "TunnelClientMetadata": { "type": "object", "description": "Minimal tunnel metadata used by a tunnel client during startup. The service may return additional management fields; clients must ignore fields they do not recognize.", "properties": { "id": { "type": "string", "description": "Opaque tunnel identifier." }, "name": { "type": "string", "description": "Human-readable tunnel name." }, "description": { "type": "string", "description": "Human-readable tunnel description." } }, "required": [ "id", "name", "description" ], "additionalProperties": true }, "TunnelResponseAck": { "properties": { "status": { "type": "string", "const": "ok", "title": "Status", "description": "Acknowledgement indicator", "default": "ok" } }, "type": "object", "title": "TunnelResponseAck" }, "TunnelResponsePayload": { "properties": { "request_id": { "type": "string", "title": "Request Id", "description": "Request identifier received from long-poll" }, "channel": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "title": "Channel", "description": "Logical channel for routing MCP traffic (defaults to main)." }, "resp_json": { "anyOf": [ { "additionalProperties": true, "type": "object" }, { "type": "null" } ], "title": "Resp Json", "description": "Final JSON payload (omitted when acknowledging notifications). Preserve recognized target JSON-RPC errors exactly. A synthesized -32603 failure may carry optional provenance at error.data.tunnel_failure; the nested schema is published in x-tunnel-failure-schema while this payload remains runtime-opaque.", "x-tunnel-failure-schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "additionalProperties": true, "allOf": [ { "if": { "properties": { "source": { "const": "target_http" } }, "required": [ "source" ] }, "then": { "properties": { "upstream_response_received": { "const": true }, "upstream_status": { "maximum": 599, "minimum": 400, "type": "integer" } }, "required": [ "upstream_status" ] } }, { "if": { "properties": { "upstream_status": { "type": "integer" } }, "required": [ "upstream_status" ] }, "then": { "properties": { "source": { "const": "target_http" }, "upstream_response_received": { "const": true } } } }, { "if": { "properties": { "source": { "const": "transport_closed" } }, "required": [ "source" ] }, "then": { "properties": { "upstream_response_received": { "const": false }, "upstream_status": { "type": "null" } } } } ], "description": "Bounded provenance for a synthesized non-protocol MCP failure.\n\nThe response payload remains opaque at the tunnel-service wire boundary. This\nmodel owns the published nested contract and gives readers an opt-in validator\nwithout making provenance mandatory for existing clients.", "properties": { "version": { "description": "Positive schema version; readers must tolerate future versions.", "minimum": 1, "title": "Version", "type": "integer", "x-current-version": 1 }, "source": { "description": "Bounded failure source. Readers use known values only and treat unknown values as an unclassified tunnel failure.", "maxLength": 64, "minLength": 1, "title": "Source", "type": "string", "x-known-values": [ "target_http", "dns", "tls", "connect", "transport_closed", "timeout", "protocol", "client_internal" ] }, "upstream_response_received": { "description": "Whether the target returned an HTTP response before the failure.", "title": "Upstream Response Received", "type": "boolean" }, "upstream_status": { "anyOf": [ { "maximum": 599, "minimum": 400, "type": "integer" }, { "type": "null" } ], "description": "Target HTTP error status. Present only for source=target_http when an actual target response was received; omit it for synthesized gateway status.", "title": "Upstream Status" }, "transport_error_kind": { "description": "Optional bounded diagnostic kind emitted by newer tunnel-clients for a synthesized transport failure. Readers must tolerate omission and unknown future values.", "maxLength": 64, "minLength": 1, "title": "Transport Error Kind", "type": "string", "x-known-values": [ "closed_pipe", "connection_aborted", "connection_closed", "connection_refused", "connection_reset", "dial", "dns", "eof", "host_unreachable", "http_status", "invalid_mcp_error", "invalid_protocol_response", "malformed_json", "network_unreachable", "non_protocol_response", "response_body_missing", "response_body_too_large", "response_body_unreadable", "timeout", "tls", "unexpected_eof", "unknown" ] } }, "required": [ "version", "source", "upstream_response_received" ], "title": "TunnelFailureProvenance", "type": "object" } }, "resp_headers": { "additionalProperties": { "items": { "type": "string" }, "type": "array" }, "type": "object", "title": "Resp Headers", "description": "Auxiliary metadata for the response" }, "resp_code": { "type": "integer", "title": "Resp Code", "description": "HTTP-style status code describing the upstream MCP response" }, "resp_type": { "$ref": "#/components/schemas/ResponsePayloadType", "description": "Indicates whether the payload contains a JSON response body (JSON-RPC response, JSON-RPC notification), or an ack-only notification/session termination response", "default": "jsonrpc_response" } }, "additionalProperties": false, "type": "object", "required": [ "request_id", "resp_code" ], "title": "TunnelResponsePayload" }, "APIErrorBody": { "properties": { "message": { "type": "string", "title": "Message", "description": "Human-readable error message." }, "type": { "type": "string", "title": "Type", "description": "OpenAI API error category, for example invalid_request_error or server_error." }, "param": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "title": "Param", "description": "Request parameter related to the error when one is available." }, "code": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "title": "Code", "description": "Stable tunnel-service error code when one is available. Generic platform or validation errors can return null or a non-tunnel code.\n\nKnown tunnel-service codes:\n- `invalid_channel_format`: The MCP channel name contains unsupported characters. Mitigation: Use lowercase letters, digits, hyphens, or underscores in channel names.\n- `invalid_json_payload`: The MCP request body could not be decoded as a JSON object. Mitigation: Fix the MCP caller/server to send a valid JSON object payload.\n- `invalid_tunnel_id_format`: The tunnel ID path segment is not a tunnel_<32 lowercase alphanumeric> value. Mitigation: Use the exact tunnel ID from Platform tunnel settings in control_plane.tunnel_id, CONTROL_PLANE_TUNNEL_ID, or --control-plane.tunnel-id.\n- `missing_mcp_session_id`: An MCP session termination request did not include Mcp-Session-Id. Mitigation: Send DELETE session termination requests with the Mcp-Session-Id header from the active MCP session.\n- `oauth_shim_audience_unavailable`: The connected tunnel-client does not advertise OAuth token audience lookup. Mitigation: Upgrade tunnel-client before using the opt-in private_key_jwt audience lookup.\n- `oauth_shim_harpoon_call_failed`: The OAuth shim Harpoon call failed or returned an invalid upstream response. Mitigation: Check the Harpoon target URL, upstream MCP server health, and tunnel-client logs.\n- `oauth_shim_invalid_target_uri`: An OAuth shim metadata URI was malformed or used an invalid harpoon target label. Mitigation: Use an absolute http(s) URI or harpoon://