Repository navigation
Stop breaking 2025-11-25 clients with get_alerts' array output schema #272
Description
Problem
All five servers declare a top-level array outputSchema for get_alerts, on purpose: 2026-07-28 is the first revision that allows a non-object root. Up to and including 2025-11-25, the schema requires outputSchema to have type: "object" at the root (Schema Reference, Tool). But the servers also send the array schema to 2025-11-25 sessions, and that is the version clients negotiate today.
For each server I sent initialize with 2025-11-25, then tools/list. I checked all five at 99a4ea1 (2026-10-27) with mcpscore 1.29.1, then rechecked Python and Rust on main at 71164fd (2026-11-01):
| Server | SDK as locked on main |
tools/list on a 2025-11-25 session |
|---|---|---|
| TypeScript | @modelcontextprotocol/server 2.4.0 |
OK. The SDK wraps it as {"type":"object","properties":{"result":<array schema>}} |
| Python | mcp 2.3.0 |
-32603 "Handler returned an invalid result". The SDK's own ListToolsResult validation rejects tools.0.outputSchema.type = 'array', so the client gets no tools |
| Go | go-sdk v1.8.0 | Sends the array root |
| Ruby | mcp 1.8.1 |
Sends the array root |
| Rust | rmcp 3.7.0 | Sends the array root (also on 3.8.0) |
Clients handle the array root differently: strict clients reject the whole tool list, and Inspector 2.13.0 drops just get_alerts. Either way, a 2025-11-25 client can't use get_alerts.
The latest SDK releases (rmcp 3.8.0, Ruby mcp 1.8.2, TypeScript 2.4.0, Python mcp 2.3.0, go-sdk v1.8.0) behave the same way, so no SDK release fixes this yet.
#191 reports the Python failure on its own.
Decision needed
The array root is the feature these examples were written to show, so maintainers should pick one of these:
- Option A, interim fix in the quickstarts: all five servers return
{"alerts": [...]}until the SDKs convert the schema for older sessions. Every client works, but the examples stop showing an array root for now. - Option B, keep the array and fix the SDKs first: the Python, Go, Ruby and Rust SDKs wrap a non-object output schema and its
structuredContentfor sessions older than 2026-07-28. They do it the way the TypeScript SDK does, with the sameresultfield name. Then the quickstarts move to those releases.
Tasks
- Choose option A or option B.
- Explain in each server README what a 2025-11-25 client sees for
get_alerts. - Add a smoke test that sends one
tools/listper server on a 2025-11-25 session. It should assert that the call succeeds and that everyoutputSchemahas anobjectroot.
Acceptance criteria
tools/listsucceeds for all five servers on both a 2025-11-25 session and a 2026-07-28 session.
Activity