[FEATURE] Pass CLAUDE_CODE_SESSION_ID to plugin MCP server subprocess env (stdio)

Resolved 💬 2 comments Opened May 23, 2026 by i2pacg Closed May 27, 2026

Plugin-bundled stdio MCP servers (declared via mcpServers in .claude-plugin/plugin.json) currently receive these env vars at spawn time:

  • CLAUDE_PLUGIN_ROOT
  • CLAUDE_PLUGIN_DATA
  • CLAUDE_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, clientInfo is anonymous).
  • #25642 — resolved by adding CLAUDE_CODE_SESSION_ID to Bash-tool subprocess env only.
  • #44607 — closed as duplicate of #25642, no MCP angle.
  • #56879 — documented CLAUDE_CODE_SESSION_ID as 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.

View original on GitHub ↗

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