Skip to content

Broker silently drops upstreams that negotiate an older 2025 revision or run stateless (no Mcp-Session-Id) #1451

Description

@rwlove

Summary

The broker silently serves no tools/prompts for an upstream that (a) negotiates a 2025 protocol revision other than 2025-11-25 (e.g. 2025-03-26) and/or (b) runs the streamable-HTTP transport in stateless mode (no Mcp-Session-Id). Such an upstream connects successfully but is dropped from every served set with no error, and — because the broker treats any non-2026 upstream as stateful — its session ping is rejected, de-federating it.

Why it happens

  • rebuildProtocolCaches partitions an upstream's tools into the stateful/stateless served set on an exact Version2025 (2025-11-25) / Version2026 (2026-07-28) match. An upstream advertising 2025-03-26 matches neither → served to no client.
  • The broker requests 2025-11-25 at initialize; an upstream on an older MCP SDK down-negotiates to the newest revision it knows (e.g. 2025-03-26), so this is the common case for any not-freshly-updated server.
  • Statelessness is inferred from protocol version >= 2026-07-28, not from the transport. A session-less 2025 server therefore gets a session ping (rejected by strict stateless servers) and a session-keyed GET SSE watcher (nothing to watch).

Reproduction

Stock baruchiro/paperless-mcp (stateless streamable-HTTP, @modelcontextprotocol/sdk 1.11 → negotiates 2025-03-26): registers behind the broker, connects, and lists zero tools downstream. mcp-searxng 2.0.0 exhibits the same class of interop failure (cf. #1419).

Proposed fix

Decouple "served" from "stateless":

  • serve any 2025- family upstream on the stateful route (consistently in rebuildProtocolCaches, buildRoutingTable, and FetchUserSpecificTools so tools list, route, and fetch);
  • detect statelessness by transport (session.ID() == ""), skipping the session ping and GET SSE watcher and recycling the connection each health tick (as 2026 upstreams already do) so liveness/recovery is preserved.

A complete, unit-tested implementation (9 files, go vet/gofmt clean, broker + upstream suites green) is ready on a branch and can be opened as a PR once this is triaged:
https://github.com/rwlove/mcp-gateway/tree/feat/serve-stateless-2025-upstreams

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugpriority/highShould be worked on first, prior to any normal or low priority itemstriage/acceptedHas been assessed, and accepted for work

Type

No type

Projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions