Skip to content

Dual-era servers serve modern Tool schemas unchanged to legacy clients #1188

Description

@SamMorrowDrums

Summary

The Go SDK supports both legacy MCP (2025-11-25 and earlier) and modern MCP (2026-07-28), but a server registers one static Tool.InputSchema and appears to return that same schema from tools/list regardless of the negotiated/requested protocol version.

That can make a dual-era server emit a schema that is valid under 2026-07-28 but outside the 2025-11-25 Tool.inputSchema envelope.

Specification boundary

In 2025-11-25, Tool.inputSchema permits only:

{
  $schema?: string;
  type: "object";
  properties?: { [key: string]: object };
  required?: string[];
}

SEP-2106, shipped in 2026-07-28, changes this to:

{ $schema?: string; type: "object"; [key: string]: unknown }

This explicitly permits root composition keywords such as anyOf, oneOf, and allOf for modern clients.

Reproduction shape

  1. Create a Go SDK server using the normal dual-era/default protocol support.
  2. Register a tool whose root input schema contains type: "object" plus anyOf.
  3. Connect a client using protocol version 2025-11-25.
  4. Call tools/list.
  5. Observe that the modern schema is returned unchanged even though root anyOf was not representable by the legacy Tool.inputSchema definition.

A concrete downstream incident is documented in github/github-mcp-server#3126. That incident also involved a model-provider restriction, but this issue is specifically about MCP protocol-era conformance.

Expected SDK behavior / API

The SDK should provide a deliberate way for dual-era servers to remain schema-conformant. Possible approaches:

  1. Validate tool schemas against every enabled protocol version at registration/startup and reject modern-only schemas unless the server supplies a legacy representation.
  2. Provide a version-aware tool/schema callback or tools/list projection hook so applications can supply a legacy-compatible representation.
  3. Document that dual-era servers must keep canonical tool schemas within the legacy intersection unless they opt into version-specific representations.

I do not think the SDK should silently strip modern keywords, because removing constraints can change tool semantics.

Immutability and concurrency

Any version-specific representation should:

  • deep-clone or use copy-on-write per inventory/list response;
  • never mutate shared Tool, InputSchema, Properties, or nested schema maps in place;
  • remain safe when legacy and modern requests are served concurrently;
  • preserve the canonical modern schema for modern clients and caches.

Provider compatibility is separate

This issue should not attempt to solve Anthropic/OpenAI tool-schema subsets. A client using modern MCP may still need a provider-specific schema adapter before forwarding tools to an LLM API. That is independent of the MCP protocol version selected between client and server.

Existing issues checked

I did not find an issue covering version-specific tools/list schema representations for a dual-era server.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Moderate issues, valuable feature requests

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions