MCP JSON REST Bridge (proto)

This extension has the qualified name envoy.filters.http.mcp_json_rest_bridge

Note

This extension is functional but has not had substantial production burn time, use only with this caveat.

This extension has an unknown security posture and should only be used in deployments where both the downstream and upstream are trusted.

Tip

This extension extends and can be used with the following extension category:

This extension must be configured with one of the following type URLs:

Warning

This API feature is currently work-in-progress. API features marked as work-in-progress are not considered stable, are not covered by the threat model, are not supported by the security team, and are subject to breaking changes. Do not use this feature without understanding each of the previous points.

extensions.filters.http.mcp_json_rest_bridge.v3.McpJsonRestBridge

[extensions.filters.http.mcp_json_rest_bridge.v3.McpJsonRestBridge proto]

Configuration for the MCP MCP JSON REST Bridge.

This extension translates Model Context Protocol (MCP) JSON-RPC requests into standard JSON-REST HTTP requests. This enables existing REST backends to function as MCP servers without native MCP support.

Main functionalities:

  1. Transcoding: Converts JSON-RPC request payload to HTTP REST request, and maps JSON response back to JSON-RPC.

  2. Session negotiation: Handles MCP connection prerequisites.

The core logic transforms “tools/call” request into HTTP request following the HttpRule specification.

Example 1: GET request with path and query parameters

tools: {
  name: "getResource"
  http_rule: {
    get: "/v1/projects/{project_id}/resources/{resource_id}"
    // body is omitted for GET
  }
}
If tools/call params are:
{ "name": "getResource", "arguments": {"project_id": "foo", "resource_id": "res-789", "view": "FULL"} }
Translation:
- Method: GET
- URL: /v1/projects/foo/resources/res-789?view=FULL
  (Arguments not matching path templates become query parameters.)

Example 2: POST request with wildcard body

tools: {
  name: "createResource"
  http_rule: {
    post: "/v1/projects/{project_id}/resources"
    body: "*"
  }
}
If tools/call params are:
{ "name": "createResource", "arguments": {"project_id": "foo", "resource_id": "res-456", "payload": { "data": "some value" }} }
Translation:
- Method: POST
- URL: /v1/projects/foo/resources
- Body: {"resource_id": "res-456", "payload": { "data": "some value" }}
  (Arguments not used in the path form the body, as per body: "*".)

Example 3: PUT request with a specific field as body

tools: {
  name: "updateResource"
  http_rule: {
    put: "/v1/projects/{project_id}"
    body: "payload"
  }
}
If tools/call params are:
{ "name": "updateResource", "arguments": {"project_id": "foo", "resource_id": "res-456", "payload": { "data": "updated value" }} }
Translation:
- Method: PUT
- URL: /v1/projects/foo?resource_id=res-456
- Body: {"data": "updated value"}
  (Only the "payload" field from arguments is used as the body. Other arguments not in the
  path, like 'resource_id', become query parameters.)
{
  "server_info": {...},
  "tool_config": {...},
  "max_request_body_size": {...},
  "max_response_body_size": {...},
  "request_storage_mode": ...,
  "trace_context_extraction": {...},
  "disable_clear_route_cache": ...
}
server_info

(extensions.filters.http.mcp_json_rest_bridge.v3.ServerInfo) General server information.

tool_config

(extensions.filters.http.mcp_json_rest_bridge.v3.ServerToolConfig) Configuration for the MCP tools.

max_request_body_size

(UInt32Value) Maximum size of the request body to buffer for transcoding and validation. If the request body exceeds this size, the request is rejected with 413 Payload Too Large. This limit applies to prevent unbounded buffering.

It defaults to 64KB (65536 bytes) as the MCP calls (tools, resources, or prompts) only pass small arguments or identifiers.

Setting it to 0 would disable the limit. It is not recommended to do so in production.

max_response_body_size

(UInt32Value) Maximum size of the response body to buffer for transcoding. If the response body exceeds this size, the response is rejected with an appropriate error. This limit applies to prevent unbounded buffering.

It defaults to 1MB (1048576 bytes) to prevent transcoding failures on large payloads like file reads, while aligning with Envoy’s standard default connection buffer limit.

Setting it to 0 would disable the limit. It is not recommended to do so in production.

request_storage_mode

(extensions.filters.http.mcp_json_rest_bridge.v3.McpJsonRestBridge.RequestStorageMode) Where to store parsed MCP request attributes. Default is not storing anything. When set to DYNAMIC_METADATA, attributes are stored in dynamic metadata using the filter’s config name (i.e. the name field of this filter’s entry in the http_filters list) as the metadata namespace.

trace_context_extraction

(extensions.filters.http.mcp_json_rest_bridge.v3.TraceContextExtractionOptions) If set, extract OpenTelemetry (OTel) trace context from MCP requests and propagate it to request headers. The keys traceparent, tracestate, and baggage will be extracted from _meta. Ref: Request Meta SEP

disable_clear_route_cache

(bool) When set to true, the filter will not clear the route cache after transcoding. This allows the route to be re-selected based on the updated request path or method.

Enum extensions.filters.http.mcp_json_rest_bridge.v3.McpJsonRestBridge.RequestStorageMode

[extensions.filters.http.mcp_json_rest_bridge.v3.McpJsonRestBridge.RequestStorageMode proto]

Where to store parsed MCP request attributes.

MODE_UNSPECIFIED

(DEFAULT) ⁣Unspecified. Uses default behavior (nothing is stored).

DYNAMIC_METADATA

⁣Store request attributes in dynamic metadata. The metadata namespace is the filter’s config name as specified by the name field in the http_filters list (e.g. envoy.filters.http.mcp_json_rest_bridge if using the canonical filter name).

extensions.filters.http.mcp_json_rest_bridge.v3.TraceContextExtractionOptions

[extensions.filters.http.mcp_json_rest_bridge.v3.TraceContextExtractionOptions proto]

Options for trace context extraction.

extensions.filters.http.mcp_json_rest_bridge.v3.ServerInfo

[extensions.filters.http.mcp_json_rest_bridge.v3.ServerInfo proto]

Configuration for the server metadata.

{
  "fallback_protocol_version": {...}
}
fallback_protocol_version

(StringValue) The fallback protocol version to use if the client does not provide the mcp-protocol-version header.

extensions.filters.http.mcp_json_rest_bridge.v3.ToolsListLocal

[extensions.filters.http.mcp_json_rest_bridge.v3.ToolsListLocal proto]

Configuration for sending locally-generated responses to tools/list requests.

extensions.filters.http.mcp_json_rest_bridge.v3.ServerToolConfig

[extensions.filters.http.mcp_json_rest_bridge.v3.ServerToolConfig proto]

Configuration for the MCP tool capability of the server.

{
  "tools": [],
  "tool_list_http_rule": {...},
  "tool_list_local": {...}
}
tools

(repeated extensions.filters.http.mcp_json_rest_bridge.v3.ToolConfig) List of MCP tools configurations.

tool_list_http_rule

(extensions.filters.http.mcp_json_rest_bridge.v3.HttpRule) Configuration to transcode the tools/list requests to a standard HTTP request. If provided: The extension transcodes the request and forwards it down the filter chain. The response (whether from an upstream backend, a configured direct_response, or another extension) MUST be a JSON body strictly matching the MCP ListToolsResult schema. Ref: https://modelcontextprotocol.io/specification/2025-11-25/schema#listtoolsresult

Optional configuration for tools/list requests. If not set: The tools/list request is passed through. This allows subsequent extension or the backend itself to handle the tools/list request if they support it.

Only one of tool_list_http_rule, tool_list_local may be set.

tool_list_local

(extensions.filters.http.mcp_json_rest_bridge.v3.ToolsListLocal) If provided: The extension sends a local response, according to each tool’s ToolsListSpecificConfig.

Optional configuration for tools/list requests. If not set: The tools/list request is passed through. This allows subsequent extension or the backend itself to handle the tools/list request if they support it.

Only one of tool_list_http_rule, tool_list_local may be set.

extensions.filters.http.mcp_json_rest_bridge.v3.ToolsListSpecificConfig

[extensions.filters.http.mcp_json_rest_bridge.v3.ToolsListSpecificConfig proto]

Configuration for a tool’s entry in tools/list responses.

{
  "title": ...,
  "description": ...,
  "input_schema": ...
}
title

(string) Optional, human-readable name of the tool for display purposes.

description

(string, REQUIRED) Human-readable description of functionality.

input_schema

(string) A JSON Schema describing expected parameters, as a serialized JSON string, in the JSON Schema 2020-12 dialect. This should be raw JSON, including the “properties” and “required” keys, but not “type”. Tools with no parameters may omit this to signify a tool with no constraints on the parameters object, or set to ‘“additionalProperties”: false’ to require empty parameters.

extensions.filters.http.mcp_json_rest_bridge.v3.McpServerInfo

[extensions.filters.http.mcp_json_rest_bridge.v3.McpServerInfo proto]

{
  "path": ...,
  "host": ...
}
path

(string) The path to the endpoint hosting this tool.

host

(string) The host hosting this tool.

extensions.filters.http.mcp_json_rest_bridge.v3.ToolConfig

[extensions.filters.http.mcp_json_rest_bridge.v3.ToolConfig proto]

{
  "name": ...,
  "http_rule": {...},
  "tool_list_config": {...},
  "text_content_streaming_enabled": ...
}
name

(string, REQUIRED) Unique identifier of the tool. Used both for tools/list and tools/call transcoding.

http_rule

(extensions.filters.http.mcp_json_rest_bridge.v3.HttpRule) The HTTP configuration rules that apply to the normal backend.

tool_list_config

(extensions.filters.http.mcp_json_rest_bridge.v3.ToolsListSpecificConfig) Config for this tool’s entry in a local tools/list response. Used when tool_list_local is set in the ServerToolConfig.

text_content_streaming_enabled

(bool) Enables streaming transcoding for unstructured text responses (content field of a result).

When enabled, the response body is streamed directly to the client without buffering. Each chunk is JSON escaped as it arrives and wrapped with a pre-built JSON-RPC prefix and suffix.

Streaming flow:

input:  [chunk1] → [chunk2] → [chunk3]
output: [prefix+escaped_chunk1] → [escaped_chunk2] → [escaped_chunk3+suffix]

Disabled by default.

extensions.filters.http.mcp_json_rest_bridge.v3.HttpRule

[extensions.filters.http.mcp_json_rest_bridge.v3.HttpRule proto]

Defines the schema of the JSON-RPC to REST mapping. It specifies how the “arguments” in a tools/call request are mapped to the URL path, query parameters, and HTTP request body.

Mapping Rules:

  1. Path: Fields defined in the path template (e.g., /v1/resources/{id}) are extracted from arguments and placed in the URL.

  2. Body: Determined by the body field. - If “*”: All arguments not used in the path become the HTTP JSON body. - If specify a field: Only that specific argument becomes the HTTP JSON body. - If empty: No body is sent.

  3. Query: Any leaf arguments not mapped to Path or Body are added as URL query parameters.

{
  "get": ...,
  "put": ...,
  "post": ...,
  "delete": ...,
  "patch": ...,
  "body": ...
}
get

(string) Determines the HTTP method and the URL path template.

Path templating uses curly braces {} to mark a section of the URL path as replaceable. Each template variable MUST correspond to a field in the JSON-RPC “arguments”. Use dot-notation to access fields within nested objects (e.g., “user.id” maps the value of the “id” field inside “user”).

To support backward compatibility with future methods, these are defined as individual fields rather than a “oneof”. If multiple fields are present, the one with the highest field number highest priority) is the effective method.

Maps to HTTP GET.

put

(string) Maps to HTTP PUT.

post

(string) Maps to HTTP POST.

delete

(string) Maps to HTTP DELETE.

patch

(string) Maps to HTTP PATCH.

body

(string) The name of the request field whose value is mapped to the HTTP request body.

  • If “*”: All fields not bound by the path template are mapped to the request body.

  • If specify a field: This specific field is mapped to the body. Uses dot-notation for nested fields (e.g., “user.data” maps the value of the “data” field inside “user”).

  • If omitted: There is no HTTP request body; fields not in the path become query parameters.

extensions.filters.http.mcp_json_rest_bridge.v3.McpJsonRestBridgePerRoute

[extensions.filters.http.mcp_json_rest_bridge.v3.McpJsonRestBridgePerRoute proto]

Per-route override configuration for the MCP JSON REST Bridge filter.

{
  "tool_config": []
}
tool_config

(repeated extensions.filters.http.mcp_json_rest_bridge.v3.ServerToolConfig)