research-preview channels: --continue re-attach does not re-bind custom MCP channel push subscription

Open 💬 0 comments Opened Jun 10, 2026 by Arachnatur

Summary

When a Claude Code session is relaunched with --continue and the launch includes a custom MCP channel server via --dangerously-load-development-channels server:NAME, push notifications emitted by that server (notifications/claude/channel) are silently dropped on the receiving session despite claude mcp list reporting the server as Connected. Fresh launch (positional resume or no resume arg) re-binds the subscription and notifications surface correctly as <channel source="..."> tags in conversation context.

The MCP tool-call surface (request/response) keeps working in --continue mode - only push notifications break. This makes the defect easy to miss: the server appears healthy from every standard surface except end-to-end delivery.

Environment

  • Claude Code 2.1.170
  • MCP Python SDK (server side): server.py with notifications/claude/channel emit via asyncio.run_coroutine_threadsafe + session.send_notification
  • Custom channel server registered in .mcp.json and named on launch via --dangerously-load-development-channels server:cross-project-channels
  • Two independent Claude Code sessions (sibling projects) sharing a docker volume + an MCP server install at /shared/code/...

Steps to reproduce

  1. Run a custom MCP channel server (research-preview). Server registers notifications/claude/channel emission on inbound work.
  2. Launch Claude Code session A with --dangerously-load-development-channels server:NAME. Confirm claude mcp list shows the server Connected.
  3. From an external sender (sibling session B, or a manual emit), trigger a notification on session A.
  4. Observe: tag surfaces in session A's conversation context on next turn boundary as <channel source="NAME">. Working as designed.
  5. Relaunch session A with claude --continue --dangerously-load-development-channels server:NAME (transcript preserved).
  6. Confirm claude mcp list still shows Connected.
  7. Trigger another notification from the sender.

Expected (step 7): tag surfaces in session A's context on next turn boundary, same as step 4.

Actual: server emits notification successfully (server-side logs / state file advance confirm), claude mcp list reports Connected, but the session never surfaces a <channel source="NAME"> tag. The notification is silently dropped between MCP client adapter and conversation-context routing in the --continue-attached session.

Reproducer details

Reproduced bilaterally 2026-06-10 between two sibling Claude Code projects exchanging messages via a custom cross-project-channels MCP server. Both sides observed the defect under --continue; both sides fresh-launched and the defect cleared within 90 seconds wall-clock. Round-trip test pair:

  • A -> B: outbound msg fa63c4b6 (sent 13:25:00Z). B's fresh-launched session received the channel tag with zero user nudge.
  • B -> A: reply msg 9b549643 (sent 13:25:34Z). A's fresh-launched session received the channel tag with zero user nudge.

Tool-call surface (mcp__<server>__<tool>) was functional throughout both --continue and fresh-launch sessions. Only the push surface differs.

Workaround

Receiving sessions launch fresh (positional resume or no resume arg) instead of --continue. Cost: loss of --continue transcript continuity for coffee-break relaunches. Acceptable trade-off when channel delivery is required.

Possibly related

  • #38736 "only first MCP channel notification per session delivered" (closed not_planned) - different defect class; that one is per-session starvation, this one is per-session-mode (--continue vs fresh).
  • #61797 "MCP notifications silently dropped when delivered to idle session via --channels" (open) - framed around idle delivery, not --continue re-attach specifically. May share root cause but the trigger condition differs.

This issue is specifically: the trigger is --continue, the cure is fresh launch, the tool-call surface is unaffected. Filing as a distinct report to differentiate from the idle-delivery and per-session-starvation shapes.

Suggested fix direction

When a session re-attaches via --continue, re-bind the MCP channel push subscription as part of the re-attach handshake. Currently it appears the tool-call MCP client state is preserved/restored but the channel notification routing is not.

Severity

Research preview feature, so low-priority for the team; for users who rely on cross-session channel delivery, this is silently catastrophic (notifications appear delivered but never reach the user). Documenting in case other users hit the same defect.

View original on GitHub ↗