Skip to content

ClientLifecycleMode::Auto does not fall back for deployed legacy-server responses #1040

Description

@tsarlandie-oai

Summary

ClientLifecycleMode::Auto only retries legacy initialize when
server/discover fails with JSON-RPC METHOD_NOT_FOUND (-32601). Existing
production MCP servers communicate unsupported modern discovery through other
recognizable responses, so enabling modern negotiation breaks servers that
previously worked.

Observed against deployed servers

Testing protocol 2026-07-28 against public legacy MCP services reproduced the
problem with:

  • OpenAI documentation, which exposes five tools through legacy initialization.
  • Microsoft Learn, which exposes three tools.
  • DeepWiki, which exposes three tools.

All three worked before modern discovery was enabled. With the modern lifecycle
enabled, startup failed with:

Unsupported protocol version: 2026-07-28

Codex’s existing rmcp 1.8 implementation connected to the same servers by retrying initialize with protocol 2025-06-18.

Current behavior

match discover_startup(...).await {
    Ok(()) => {}
    Err(ClientInitializeError::JsonRpcError(error))
        if error.code == ErrorCode::METHOD_NOT_FOUND =>
    {
        legacy_startup(...).await?;
    }
    Err(error) => return Err(error),
}

Production-shaped HTTP prevalidation responses observed during interoperability
testing include:

{
  "jsonrpc": "2.0",
  "id": null,
  "error": {
    "code": -32000,
    "message": "Bad Request: Unsupported protocol version: 2026-07-28 (supported versions: 2025-11-25, 2025-06-18, 2025-03-26, 2024-11-05, 2024-10-07)"
  }
}
{
  "jsonrpc": "2.0",
  "id": null,
  "error": {
    "code": -32000,
    "message": "Bad Request: No valid session ID provided"
  }
}

Both occur as initial HTTP 400 responses before a session exists. Other useful
legacy-only signals include correlated unsupported-version errors, discovery
results advertising exclusively historical protocol versions, and initial HTTP
404/405 responses.

Observed versus expected lifecycle

Actual:

→ server/discover, protocol 2026-07-28
← recognizable legacy-only rejection
✗ startup terminates without attempting initialize

Expected:

→ server/discover, protocol 2026-07-28
← recognizable legacy-only rejection
→ initialize, protocol 2025-06-18
← successful initialization
→ notifications/initialized
→ tools/list

Integration tests now reproduce these production-shaped responses and verify
the successful sequence
["server/discover", "initialize", "notifications/initialized"].

Downgrade safety

Fallback must remain conservative. Unrelated response IDs, arbitrary null-ID
errors, unknown or future protocol versions, HTTP 401/403 responses, existing-
session 404 responses, and ordinary modern-server rejections must not trigger
downgrade.

The observed public-server failures and successful reference-client comparison
demonstrate an existing interoperability regression rather than a hypothetical
extension to automatic lifecycle negotiation.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1High: significant functionality gap or spec violationbugSomething is not working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions