.. _envoy_v3_api_file_envoy/extensions/clusters/mcp_multicluster/v3/cluster.proto: MCP multi cluster configuration (proto) ======================================= .. 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 :ref:`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. .. _envoy_v3_api_msg_extensions.clusters.mcp_multicluster.v3.ClusterConfig: extensions.clusters.mcp_multicluster.v3.ClusterConfig ----------------------------------------------------- :repo:`[extensions.clusters.mcp_multicluster.v3.ClusterConfig proto] ` Configuration for the MCP multi cluster. See the :ref:`architecture overview ` for more information. This cluster type allows aggregation of multiple clusters into one, providing metadata with the list of aggregated clusters. Use the ``attemptCount`` property of the request ``StreamInfo`` object to select host in a specific subcluster. If the ``attemptCount`` value is greater than the number of aggregated clusters, the host selection will fail. The primary purpose of this cluster extension is to provide the list of servers for the MCP router configured for tool and resource aggregation. For details of how tools and resource are aggregated see :ref:`MCP router documentation`. Example configuration: .. code-block:: yaml name: mcp_multicluster connect_timeout: 0.25s lb_policy: CLUSTER_PROVIDED cluster_type: name: envoy.clusters.mcp_multicluster typed_config: "@type": type.googleapis.com/envoy.extensions.clusters.mcp_multicluster.v3.ClusterConfig servers: - name: build_tools mcp_cluster: cluster: build_tools - name: review_tools mcp_cluster: cluster: review_tools host_rewrite_literal: "mcp.review_tools.acme.com" .. _extension_envoy.clusters.mcp_multicluster: This extension has the qualified name ``envoy.clusters.mcp_multicluster`` .. note:: This extension is functional but has not had substantial production burn time, use only with this caveat. This extension is not hardened 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: - :ref:`envoy.clusters ` This extension must be configured with one of the following type URLs: - :ref:`type.googleapis.com/envoy.extensions.clusters.mcp_multicluster.v3.ClusterConfig ` .. code-block:: json :force: { "servers": [] } .. _envoy_v3_api_field_extensions.clusters.mcp_multicluster.v3.ClusterConfig.servers: servers (**repeated** :ref:`extensions.clusters.mcp_multicluster.v3.ClusterConfig.McpBackend `, *REQUIRED*) A list of remote MCP servers. Based on the MCP multi cluster configuration the MCP router aggregates capabilities, tools and resources from remote MCP servers and presents itself as single MCP server to the client. All remote MCP servers are sent the same capabilities that the client presented to Envoy. MCP router prefixes tool names and resource path with the server name to resolve naming collisions. .. _envoy_v3_api_msg_extensions.clusters.mcp_multicluster.v3.ClusterConfig.McpCluster: extensions.clusters.mcp_multicluster.v3.ClusterConfig.McpCluster ---------------------------------------------------------------- :repo:`[extensions.clusters.mcp_multicluster.v3.ClusterConfig.McpCluster proto] ` Cluster-based backend configuration. .. code-block:: json :force: { "cluster": ..., "path": ..., "timeout": {...}, "host_rewrite_literal": ... } .. _envoy_v3_api_field_extensions.clusters.mcp_multicluster.v3.ClusterConfig.McpCluster.cluster: cluster (`string `_, *REQUIRED*) Cluster name to route requests to. .. _envoy_v3_api_field_extensions.clusters.mcp_multicluster.v3.ClusterConfig.McpCluster.path: path (`string `_) Path to use for MCP requests. Defaults to "/mcp". .. _envoy_v3_api_field_extensions.clusters.mcp_multicluster.v3.ClusterConfig.McpCluster.timeout: timeout (`Duration `_) Request timeout. If not set, uses cluster's timeout configuration. .. _envoy_v3_api_field_extensions.clusters.mcp_multicluster.v3.ClusterConfig.McpCluster.host_rewrite_literal: host_rewrite_literal (`string `_) Indicates that during forwarding, the host header will be swapped with this value. .. _envoy_v3_api_msg_extensions.clusters.mcp_multicluster.v3.ClusterConfig.HeaderForwarding: extensions.clusters.mcp_multicluster.v3.ClusterConfig.HeaderForwarding ---------------------------------------------------------------------- :repo:`[extensions.clusters.mcp_multicluster.v3.ClusterConfig.HeaderForwarding proto] ` Specifies which downstream request headers are allowed to be forwarded to an MCP backend. Modeled after :ref:`ext_proc's HeaderForwardingRules `, but MCP-local and secure-by-default: unlike ext_proc, an unset/empty policy forwards nothing rather than everything, because MCP requires audience-bound tokens and prohibits implicit token passthrough between a client and a backend it did not authenticate to. Evaluation order per header: 1. If the header matches ``disallowed_headers``, it is never forwarded — this takes precedence over everything below, including ``forward_all``. 2. Otherwise, if ``forward_all`` is true, the header is forwarded. 3. Otherwise, if the header matches ``allowed_headers``, it is forwarded. 4. Otherwise, the header is not forwarded. This does not cover header *mutation* or credential injection, which remain a separate concern from this policy. .. code-block:: json :force: { "forward_all": ..., "allowed_headers": {...}, "disallowed_headers": {...} } .. _envoy_v3_api_field_extensions.clusters.mcp_multicluster.v3.ClusterConfig.HeaderForwarding.forward_all: forward_all (`bool `_) If true, forward all downstream request headers to this backend (subject to ``disallowed_headers`` above), matching the legacy forward-everything behavior. Defaults to false. Users relying on the legacy behavior must set this explicitly. .. _envoy_v3_api_field_extensions.clusters.mcp_multicluster.v3.ClusterConfig.HeaderForwarding.allowed_headers: allowed_headers (:ref:`type.matcher.v3.ListStringMatcher `) If set, specifically allow any header in this list to be forwarded. Ignored for a header that also matches ``disallowed_headers``, and redundant (but harmless) for any header covered by ``forward_all``. .. _envoy_v3_api_field_extensions.clusters.mcp_multicluster.v3.ClusterConfig.HeaderForwarding.disallowed_headers: disallowed_headers (:ref:`type.matcher.v3.ListStringMatcher `) If set, specifically disallow any header in this list from being forwarded. This takes precedence over both ``forward_all`` and ``allowed_headers``. .. _envoy_v3_api_msg_extensions.clusters.mcp_multicluster.v3.ClusterConfig.McpBackend: extensions.clusters.mcp_multicluster.v3.ClusterConfig.McpBackend ---------------------------------------------------------------- :repo:`[extensions.clusters.mcp_multicluster.v3.ClusterConfig.McpBackend proto] ` Specification of the MCP server. .. code-block:: json :force: { "name": ..., "mcp_cluster": {...}, "header_forwarding": {...} } .. _envoy_v3_api_field_extensions.clusters.mcp_multicluster.v3.ClusterConfig.McpBackend.name: name (`string `_) Unique name for this backend. Used for: - Tool name prefixing (e.g., "time__get_current_time") - Session ID composition - Logging and error messages. Default will be the cluster name if not specified. .. _envoy_v3_api_field_extensions.clusters.mcp_multicluster.v3.ClusterConfig.McpBackend.mcp_cluster: mcp_cluster (:ref:`extensions.clusters.mcp_multicluster.v3.ClusterConfig.McpCluster `) Backend target specification. .. _envoy_v3_api_field_extensions.clusters.mcp_multicluster.v3.ClusterConfig.McpBackend.header_forwarding: header_forwarding (:ref:`extensions.clusters.mcp_multicluster.v3.ClusterConfig.HeaderForwarding `) Controls which downstream request headers are forwarded to this backend. If not set, no downstream-controlled headers are forwarded beyond those the router itself must synthesize (e.g. ``content-type``, ``accept``, the session header) — in particular, a client's ``authorization`` header is NOT forwarded by default. Router-owned, framing, session, and hop-by-hop headers are never affected by this policy; they are handled separately and can never be forwarded via this mechanism.