Skip to content

Server rejects MCP clients sending capabilities.sampling.tools field (2025-11-25 spec) #184

Description

@SelfParody

Description

The Jenkins MCP Server plugin (v0.168.v13951585050d, latest as of 2026-04-09) rejects connections from MCP clients that include capabilities.sampling.tools in their initialize request. This breaks compatibility with the official Python MCP SDK (mcp 1.27.0) and any client built on top of it that exposes sampling tool support.

This is the same class of bug as #120 (resolved for elicitation.form in v0.149). The fix there was to bump the MCP Java SDK to a version that recognized the newer 2025-11-25 spec. The same fix is needed again — the Java SDK version currently bundled does not recognize the sampling.tools capability, even though the spec it advertises support for (2025-11-25) does include it.

Error Message

When the Python MCP SDK initializes, the server returns:

{
  "jsonrpc": "2.0",
  "jsonRpcError": {
    "code": -32600,
    "message": "Invalid message format: Unrecognized field \"tools\" (class io.modelcontextprotocol.spec.McpSchema$ClientCapabilities$Sampling), not marked as ignorable"
  }
}

(HTTP 400 on POST /mcp-server/mcp.)

Client Initialize Request

This is what the official Python MCP SDK (mcp 1.27.0) sends — captured from a working Streamable-HTTP MCP client connecting to other MCP servers in the same agent process:

{
  "jsonrpc": "2.0",
  "id": 0,
  "method": "initialize",
  "params": {
    "protocolVersion": "2025-11-25",
    "capabilities": {
      "sampling": {
        "tools": {}
      },
      "roots": {
        "listChanged": true
      }
    },
    "clientInfo": {
      "name": "hermes-agent",
      "version": "..."
    }
  }
}

The sampling.tools field is defined in the 2025-11-25 spec (SamplingCapability) and indicates that the client supports the tools and toolChoice parameters in sampling requests. The Python SDK includes it whenever sampling is supported — there is no public hook to omit it.

Expected Behavior

Either:

  1. (Preferred) Bump io.modelcontextprotocol.sdk:mcp-bom to a version that recognizes the full 2025-11-25 spec including SamplingCapability.tools (and any other sub-fields the latest spec adds).
  2. (Defensive) Add @JsonIgnoreProperties(ignoreUnknown = true) to McpSchema$ClientCapabilities$Sampling (and to all other capability sub-types) so unknown fields from newer specs are silently dropped instead of failing the entire frame. This would prevent the next instance of this same bug class.

Approach (2) is cheap and would future-proof against the next spec addition; (1) is the long-term right answer.

Reproduction

  1. Install Python MCP SDK 1.27.0: pip install mcp==1.27.0
  2. Connect to https://<jenkins>/mcp-server/mcp using the SDK's streamablehttp_client with HTTP Basic auth
  3. Server returns 400 with the error above on the very first initialize frame

Workaround

We currently work around this with a stdio↔HTTP bridge that translates the outgoing initialize payload before forwarding to Jenkins:

  • Downgrades protocolVersion "2025-11-25""2024-11-05"
  • Replaces sampling: {"tools": {}} with sampling: {}

This is the same pattern used by other MCP clients to talk to v0.119 before #143 landed — but it should not be necessary against the latest plugin version.

Environment

  • Jenkins MCP Server Plugin: 0.168.v13951585050d (latest, 2026-04-09)
  • Jenkins: LTS 2.516.x
  • MCP client: Python mcp 1.27.0 (sends protocolVersion: 2025-11-25)

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions