Skip to content

[Feature]: Expose MCP protocol version configuration in McpClientBuilder #1173

@BeastDamon

Description

@BeastDamon

Title: [Feature]: Expose MCP protocol version configuration in McpClientBuilder

Body:

Is your feature request related to a problem? Please describe.

When connecting to third-party MCP servers via stdio transport, the client fails with "Unsupported protocol version" if the server responds with a protocol version other than "2024-11-05".

For example, [CodeGraphContext](https://github.com/CodeGraphContext/CodeGraphContext) returns "protocolVersion": "2025-03-26" in its initialize response ([server.py#L149](https://github.com/CodeGraphContext/CodeGraphContext/blob/main/src/codegraphcontext/server.py)). The underlying MCP Java SDK's StdioClientTransport defaults protocolVersions() to List.of("2024-11-05") only, and LifecycleInitializer.doInitialize() performs a strict protocolVersions.contains(result.protocolVersion()) check, throwing an error immediately.

The MCP Java SDK already defines multiple protocol version constants in [ProtocolVersions.java](https://github.com/modelcontextprotocol/java-sdk/blob/main/mcp-core/src/main/java/io/modelcontextprotocol/spec/ProtocolVersions.java):

String MCP_2024_11_05 = "2024-11-05";
String MCP_2025_03_26 = "2025-03-26";
String MCP_2025_06_18 = "2025-06-18";
String MCP_2025_11_25 = "2025-11-25";

And McpAsyncClient has a package-private setProtocolVersions() method, but it is explicitly marked as "test only". Neither McpClient builder nor AgentScope's McpClientBuilder exposes this configuration to users.

Root Cause Trace:

  1. [McpTransport.protocolVersions()](https://github.com/modelcontextprotocol/java-sdk/blob/main/mcp-core/src/main/java/io/modelcontextprotocol/spec/McpTransport.java) → defaults to List.of(ProtocolVersions.MCP_2024_11_05)
  2. StdioClientTransport does not override protocolVersions()
  3. McpAsyncClient constructor passes transport.protocolVersions() to LifecycleInitializer
  4. [LifecycleInitializer.doInitialize()](https://github.com/modelcontextprotocol/java-sdk/blob/main/mcp-core/src/main/java/io/modelcontextprotocol/client/LifecycleInitializer.java) does strict check:
    if (!this.protocolVersions.contains(initializeResult.protocolVersion())) {
        return Mono.error(McpError.builder(-32602)
            .message("Unsupported protocol version")
            .data("Unsupported protocol version from the server: " + initializeResult.protocolVersion())
            .build());
    }
  5. AgentScope's McpClientBuilder wraps the SDK but has no way to pass custom protocol versions through

Describe the solution you'd like

Option A (Preferred): Add a protocolVersions(String...) method to McpClientBuilder:

McpClientWrapper client = McpClientBuilder.create("server")
        .stdioTransport("python", "server.py")
        .protocolVersions("2024-11-05", "2025-03-26")
        .buildAsync()
        .block();

Option B: Default StdioClientTransport.protocolVersions() to include all versions defined in ProtocolVersions.java, since stdio is a local transport and version mismatch is common with diverse third-party MCP server implementations.

Describe alternatives you've considered

  1. Proxy script workaround (my current approach): A Python proxy that intercepts the stdio stream and patches "2025-03-26""2024-11-05" in the server's initialize response. Works but adds complexity and fragility:

    def patch_response(line: str) -> str:
        line = line.replace('"2025-03-26"', '"2024-11-05"')
        line = line.replace('"listTools"', '"listChanged"')
        return line
  2. Subclass StdioClientTransport and override protocolVersions(). However, AgentScope's McpClientBuilder instantiates the transport internally, making this difficult without forking.

  3. Wait for upstream MCP Java SDK update. But AgentScope wraps the SDK and could provide this independently.

Environment:

  • AgentScope-Java Version: 1.0.10
  • MCP Java SDK Version: 0.17.0 (transitive dependency via agentscope)
  • Java Version: 17
  • OS: Linux (production), Windows (development)
  • MCP Server: CodeGraphContext 0.4.0 (Python, stdio transport, returns protocolVersion "2025-03-26")

To Reproduce:

  1. McpClientBuilder.create("CGCServer").stdioTransport("python", "cgc-server.py").buildAsync().block()
  2. CGC server responds with "protocolVersion": "2025-03-26"
  3. Client throws: Unsupported protocol version from the server: 2025-03-26

Additional context

  • The MCP specification describes protocol version negotiation as a client-server handshake where the server MAY respond with a different version, and the client SHOULD then decide whether it supports that version. The current implementation does not allow the client to express support for multiple versions.
  • The MCP protocol is actively evolving (4 versions already), making hardcoded single-version lists increasingly problematic for third-party server integration.
  • This issue also affects the upstream MCP Java SDK ([modelcontextprotocol/java-sdk](https://github.com/modelcontextprotocol/java-sdk)), where McpClient.SyncSpec / AsyncSpec builders similarly lack a protocolVersions setter. A coordinated fix at both levels would be ideal.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Projects

Status

In progress

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions