Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions _topic_maps/_topic_map.yml
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ Topics:
File: mcp-gateway-revoke-tool-access
- Name: Use credentials to access external APIs
File: mcp-gateway-vault
- Name: Multi-protocol support for the MCP gateway
File: mcp-gateway-multi-protocol-support
---
Name: Develop APIs with the web console
Dir: develop
Expand Down
28 changes: 28 additions & 0 deletions mcp_gateway_config/mcp-gateway-multi-protocol-support.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
:_mod-docs-content-type: ASSEMBLY
include::_attributes/attributes.adoc[]
[id="mcp-gateway-multi-protocol-support"]
= Multi-protocol support for the {mcpg}
:context: mcp-gateway-multi-protocol-support

toc::[]

[role="_abstract"]
You can use the {mcpg} to serve both stateful and stateless MCP protocol versions from a single instance. Clients negotiate their preferred version automatically.

include::modules/con-mcp-gateway-multi-protocol-support.adoc[leveloffset=+1]

include::modules/proc-mcp-gateway-verify-protocol-support.adoc[leveloffset=+1]

include::modules/ref-mcp-gateway-protocol-behavior-differences.adoc[leveloffset=+1]

include::modules/proc-mcp-gateway-set-protocol-routes.adoc[leveloffset=+1]

include::modules/ref-mcp-gateway-protocol-specific-routes.adoc[leveloffset=+1]

[id="additional-resources_mcp-gateway-multi-protocol-support"]
[role="_additional-resources"]
== Additional resources

* xref:../mcp_gateway_config/mcp-gateway-register-ext-mcp-servers.adoc#mcp-gateway-register-ext-mcp-servers[Register external MCP servers with the {mcpg}]
* xref:../mcp_gateway_config/mcp-gateway-authentication.adoc#mcp-gateway-authentication[Use authentication with {mcpg}]
* xref:../mcp_gateway_discover/mcp-gateway-introduction.adoc#mcp-gateway-introduction[Introduction to the {mcpg}]
62 changes: 62 additions & 0 deletions modules/con-mcp-gateway-multi-protocol-support.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Module included in the following assemblies:
//
// *mcp_gateway_config/mcp-gateway-multi-protocol-support.adoc

:_mod-docs-content-type: CONCEPT
[id="con-mcp-gateway-multi-protocol-support_{context}"]
= Understand multi-protocol support

[role="_abstract"]
The {mcpg} can serve both the `2025-11-25`, stateful, and `2026-07-28`, stateless, Model Context Protocol (MCP) protocol versions from a single instance.

The new stateless protocol has the following cloud-native pattern:

* Round-robin load balancing: Because any container instance can handle any incoming request, you can horizontally scale your stateful MCP servers behind a plain round-robin load balancer.
* Serverless deployment: You can now run MCP servers as serverless functions on cloud platforms because there is no need for a persistent connection.
* Transparent failover: If a container crashes, the load balancer routes the next request to a healthy peer with zero session disruption.
* No Redis sessions: Because persistency and sticky sessions are no longer needed, you can remove Redis session storage. Database writes and reads on every single call are not required.

Clients negotiate their preferred version automatically

[id="con-mcp-gateway-multi-protocol-version-detection_{context}"]
== How version detection works

When an MCP client SDK connects, the {mcpg} detects the MCP protocol version by using the following sequence:
//Q: is this really just an MCP client?
. The SDK client sends a `server/discover` request with a `MCP-Protocol-Version: 2026-07-28` header.
. The {mcpg} responds with `supportedVersions`, which is the union of all upstream MCP server protocol versions.
. If the client and the {mcpg} share a common version, the SDK negotiates the highest one.
. If the client does not send a `server/discover` request, the {mcpg} falls back to the `initialize` handshake with `2025-11-25`. This is typically the case for older SDKs.

The following table shows how the {mcpg} negotiates the protocol version depending on the available backend MCP servers:

.Protocol version negotiation
[cols="1,1,1",options="header"]
|===
|Backend MCP server versions
|Supported protocol versions
|SDK negotiates

|2025
|2025-11-25
|2025-11-25

|2026
|2026-07-28
|2026-07-28

|Both
|2025-11-25, 2026-07-28
|2026-07-28
|===

[id="con-mcp-gateway-multi-protocol-tool-visibility_{context}"]
== Tool visibility by protocol version

The `tools/list` response returns only tools from the following protocol-compatible backends:

* 2025-11-25 clients: Use tools from servers that negotiated `2025-11-25`, plus the `discover_tools` and `select_tools` meta-tools.

* 2026-07-28 clients: Use tools from servers that negotiated `2026-07-28`, without `meta-tools`.

`UserSpecificList` servers follow the same filtering. Per-user tools are only displayed from backends that match the client protocol version.
29 changes: 29 additions & 0 deletions modules/proc-mcp-gateway-set-protocol-routes.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Module included in the following assemblies:
//
// *mcp_gateway_config/mcp-gateway-multi-protocol-support.adoc

:_mod-docs-content-type: PROCEDURE
[id="proc-mcp-gateway-set-protocol-specific-routes_{context}"]
= Set MCP protocol-specific routes

[role="_abstract"]
The {mcpg} exposes two endpoints on every Model Context Protocol (MCP) listener. You can use the default endpoint for automatic version negotiation, or the stateful endpoint to force the `2025-11-25` protocol version.

* Use the `/mcp` default endpoint for most clients. The {mcpg} negotiates the correct version automatically.
* Use the `/mcp/stateful` endpoint when a `2026-07-28`-capable agent also needs access to `2025-11-25`-only tools.

.Procedure

* Configure an agent with two MCP server entries that point at the same gateway host by using the following example:
+
[source,yaml]
----
mcpServers:
gateway-default:
url: https://_<gateway_hostname>_/mcp
gateway-legacy:
url: https://_<gateway_hostname>_/mcp/stateful
----
+
* Replace with your MCP gateway `Gateway` object hostname.
* The default entry negotiates `2026-07-28` and shows stateless tools. The `/mcp/stateful` entry forces `2025-11-25` and shows stateful tools plus the `discover_tools` and `select_tools` meta-tools.
42 changes: 42 additions & 0 deletions modules/proc-mcp-gateway-verify-protocol-support.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Module included in the following assemblies:
//
// *mcp_gateway_config/mcp-gateway-multi-protocol-support.adoc

:_mod-docs-content-type: PROCEDURE
[id="proc-mcp-gateway-verify-protocol-support_{context}"]
= Verify protocol support for the {mcpg}

[role="_abstract"]
You can check which Model Context Protocol (MCP) protocol versions your {mcpg} instance advertises by sending a `server/discover` request.

.Prerequisites

* You have access to the {mcpg} endpoint.
* You installed the `jq` CLI tool.

.Procedure

. Check which protocol versions the {mcpg} advertises by running the following command:
+
[source,terminal,subs="+quotes"]
----
$ curl -sS -X POST https://_<gateway_hostname>_/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "Mcp-Protocol-Version: 2026-07-28" \
-d '{"jsonrpc":"2.0","id":1,"method":"server/discover","params":{"_meta":{"io.modelcontextprotocol/protocolVersion":"2026-07-28"}}}' \
| jq '.result.supportedVersions'
----
+
Replace `_<gateway_hostname>_` with the hostname of your {mcpg} instance.

. Confirm that the output lists the expected protocol versions. For example:
+
[source,text]
----
[
"2025-11-25",
"2026-07-28"
]
----
//Q: what if it accepts only the older version?
42 changes: 42 additions & 0 deletions modules/ref-mcp-gateway-protocol-behavior-differences.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Module included in the following assemblies:
//
// *mcp_gateway_config/mcp-gateway-multi-protocol-support.adoc

:_mod-docs-content-type: REFERENCE
[id="ref-mcp-gateway-protocol-behavior-differences_{context}"]
= Protocol behavior differences

[role="_abstract"]
The stateful and stateless Model Context Protocol (MCP) protocol versions differ in how the {mcpg} handles routing, sessions, backend initialization, and response handling.

.Behavior differences between protocol versions
[cols="1,1,1",options="header"]
|===
|Behavior
|2025-11-25, stateful
|2026-07-28, stateless

|Routing
|Body-parsed: JSON-RPC method and parameters
|Header-based: `Mcp-Method`, `Mcp-Name`

|Sessions
|JWT-based `mcp-session-id`
|None

|Backend initialization
|Hairpin initialization through the {mcpg}
|`server/discover`

|Response handling
|Session ID rewriting, elicitation ID rewriting
|Pass-through

|Header-body validation
|Not applicable
|Rejects mismatches between the `Mcp-Name` header and the body `params.name`

|Meta-tools
|`discover_tools`, `select_tools` available
|Not available
|===
26 changes: 26 additions & 0 deletions modules/ref-mcp-gateway-protocol-specific-routes.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Module included in the following assemblies:
//
// *mcp_gateway_config/mcp-gateway-multi-protocol-support.adoc

:_mod-docs-content-type: REFERENCE
[id="ref-mcp-gateway-protocol-specific-routes_{context}"]
= Protocol-specific routes

[role="_abstract"]
The {mcpg} exposes two endpoints on every Model Context Protocol (MCP) listener. The broker `MCPHandler` serves these endpoints. You do not need to make any configurations or additional `HTTPRoute` objects.

.MCP listener endpoints
[cols="1,1,2",options="header"]
|===
|Endpoint
|Protocol
|Behavior

|`/mcp`
|Auto-negotiated
|The `server/discover` method determines the version. Falls back to `initialize` for older SDKs. A `2026-07-28` SDK client that connects to `/mcp` negotiates `2026-07-28` by default.

|`/mcp/stateful`
|Forces 2025-11-25
|Session-based routing. The `discover_tools` and `select_tools` meta-tools are available. The `/mcp/stateful` route is available for agents that also need tools from `2025-11-25`-only backends. It forces `2025-11-25` negotiation regardless of the client capabilities.
|===