claude code mcp spec compliance — list_changed, progress, sampling, messages, and async gaps

Resolved 💬 3 comments Opened Mar 7, 2026 by yigitkonur Closed Apr 4, 2026

hey team, consolidating a bunch of scattered issues (many closed in circular duplicate loops) into one place. hopefully this is useful as a single reference for mcp spec features that are missing or partially working.

list_changed notifications (server → claude code)

2.1.0 changelog says "added support for MCP list_changed notifications" — and it partially landed, but there are still gaps:

tools/list_changed:

  • works across prompt turns (tool added → next prompt sees it)
  • does NOT work within the same turn — if a tool is registered mid-turn, claude tries to call it and gets Error: No such tool available (#4118 comments confirm)
  • startup race condition: if tools register asynchronously after init (common with service discovery, plugin systems, agent registries), claude queries the tool list before they exist and the notification doesn't reliably trigger a re-fetch. mcp server authors have to add artificial delays (#24195)
  • someone decompiled cli.js and confirmed the zod schema existed but setNotificationHandler was never called (#13646) — unclear if 2.1.0 fully fixed this

prompts/list_changed:

  • three separate issues reported this (#2722, #3326, #4094) and they all got closed in a circular duplicate loop (2722 → dup of 4094, 4094 → dup of 2722, 3326 → dup of 2722). no open issue remained
  • new slash commands from mcp servers don't appear without restart

resources/list_changed:

  • dynamically added resources don't show up in @ autocomplete (#3326)

outgoing notifications (claude code → server)

roots/list_changed:

  • /add-dir mid-session updates claude code's internal state but never sends notifications/roots/list_changed to connected mcp servers (#26663)
  • servers that validate paths against workspace roots silently break
  • gemini cli handles this correctly, for reference

other mcp spec features not implemented

looked through the spec and existing issues — here's what else is missing:

| mcp spec feature | spec link | status in claude code | related issues |
|---|---|---|---|
| notifications/progress (progress tokens) | spec | ignored — no progress display for long-running tools | #4157 |
| notifications/message (server → client) | spec | received but never displayed to user or injected into context | #3174 |
| sampling (server requests llm inference) | spec | not implemented | #1785 |
| async/background tool execution | — | all mcp tool calls are sequential and blocking | #1759, #8712, #1478 |

context on why this matters

the agent sdk already has a sophisticated notification system for its own subagent lifecycle. looking at the published types in @anthropic-ai/claude-agent-sdk:

// task lifecycle events
SDKTaskStartedMessage    → { subtype: 'task_started', task_id, description }
SDKTaskProgressMessage   → { subtype: 'task_progress', task_id, usage: { total_tokens, tool_uses, duration_ms } }
SDKTaskNotificationMessage → { subtype: 'task_notification', task_id, status: 'completed'|'failed'|'stopped', summary }

// hook events
TeammateIdleHookInput    → { teammate_name, team_name }
TaskCompletedHookInput   → { task_id, task_subject, teammate_name?, team_name? }

this is great — start, progress, complete, with usage tracking and hook integration. the infrastructure for handling async notifications clearly exists and works well.

the mcp spec defines similar primitives (progress notifications, messages, list_changed, sampling) that would let third-party mcp servers participate in the same kind of workflows. implementing these would make the whole ecosystem stronger and let mcp servers do things like:

  • report progress on long-running operations without blocking
  • dynamically register tools based on runtime context (game state, service discovery, plugin loading)
  • hot-reload prompts and resources during development without restarting
  • request llm inference through the client's existing auth/subscription

prior issues (for reference)

| issue | topic | current state |
|---|---|---|
| #2722 | prompts/list_changed | closed (circular dup) |
| #3326 | resources/list_changed + autocomplete | closed (dup of #2722) |
| #4094 | prompts/list_changed | closed (circular dup of #2722) |
| #4118 | tools/list_changed | open, 14 comments, partially addressed |
| #13646 | tools/list_changed source analysis | closed (dup of #4118) |
| #15667 | tools/list_changed repro | closed (dup of #4118) |
| #24195 | tools/list_changed race condition | closed (dup of #4118) |
| #26663 | roots/list_changed (outgoing) | open |
| #1478 | notification-driven auto-resume | closed |
| #1759 | background tasks via mcp | closed |
| #1785 | sampling support | open |
| #2799 | elicitation support | open |
| #3174 | notifications/message display | closed |
| #4157 | progress notifications | closed |
| #8712 | background mcp tool execution | closed |

would love to see these gaps closed over time. happy to help test or provide repro cases for any of these. thanks for building claude code — it's genuinely great to work with, and getting mcp spec parity would make it even better.

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗