[FEATURE] Pass CLAUDE_CODE_SESSION_ID to plugin MCP server subprocess env (stdio)
Plugin-bundled stdio MCP servers (declared via mcpServers in .claude-plugin/plugin.json) currently receive these env vars at spawn time:
CLAUDE_PLUGIN_ROOTCLAUDE_PLUGIN_DATACLAUDE_PROJECT_DIR
They do not receive CLAUDE_CODE_SESSION_ID, even though that variable already exists in the codebase and is propagated to Bash-tool subprocesses per #25642 (resolved in v2.1.132).
Why this matters
A plugin MCP server that wants to route messages per-session — for example, push events into a specific running session via a localhost sidecar — cannot reliably identify which session spawned it. The plugin sees its own pid, its plugin-data dir, the project dir, but has no way to correlate any of that with the host session whose lifecycle it shares.
Existing related discussion:
- #41836 — same gap for HTTP-transport MCP servers (Mcp-Session-Id header not echoed,
clientInfois anonymous). - #25642 — resolved by adding
CLAUDE_CODE_SESSION_IDto Bash-tool subprocess env only. - #44607 — closed as duplicate of #25642, no MCP angle.
- #56879 — documented
CLAUDE_CODE_SESSION_IDas Bash-tool-only scope. - modelcontextprotocol/modelcontextprotocol#231 — confirms MCP spec doesn't prescribe how a host conveys session identity to a stdio server; this is a host-implementation choice.
Why workarounds don't compose
Tried writing a sibling SessionStart hook that drops the current session_id into ${CLAUDE_PLUGIN_DATA}/active-session.json for the plugin server to read at startup. Fails for concurrent sessions — a Worker spawn races with a Conductor's startup; both hooks write to the same file; the second-spawning plugin server reads the first-spawning session's sid. Result: cross-session message routing failure.
PID-keying (writing active-session-by-pid/<parent-pid>.json) is the next-cleanest fallback but still depends on hook-vs-server-startup ordering and breaks on session-resume.
Proposed fix
Add CLAUDE_CODE_SESSION_ID: <current-session-id> to the env literal already built for plugin stdio MCP server spawn, next to the existing three plugin vars. Single-line addition.
Concrete dispatch-routing breakage this would fix
In a plugin I'm building (orchestrates Conductor/Worker Claude Code sessions via per-session MCP channels), the missing env var means:
- The Conductor's channel server can't reliably write a sidecar keyed on its own sid (races with Worker startup overwriting the shared hint file).
- A GUI trying to push
/handback <worker-sid>to the Conductor ends up POSTing to the Worker's channel server because the sidecar was written with the wrong sid. - The Worker reasonably refuses the misrouted message, and the dispatch loop stalls.
Happy to send a PR if helpful.
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗