MCP headersHelper runs without CLAUDE_PLUGIN_ROOT on claude-desktop 2.1.247 (regression from ≤2.1.221) — plugin HTTP servers fall into doomed OAuth/DCR
Environment
- claude-code 2.1.247 (claude-desktop, agent-sdk/0.3.247), macOS (darwin 25.5.0), desktop local-agent-mode (Cowork) session
- Plugin-provided HTTP MCP servers with
headersHelperin the plugin's.mcp.json
Bug
headersHelper for a plugin-provided HTTP MCP server executes with CLAUDE_PLUGIN_ROOT unset, even though the MCP docs list it as available to the helper when the server is plugin-provided. A helper command of the documented form
"headersHelper": "sh \"${CLAUDE_PLUGIN_ROOT}/scripts/mcp-headers.sh\" my-server"
degrades to sh "/scripts/mcp-headers.sh" → exit 127 → empty stdout. The MCP log then shows:
Executing headersHelper to get dynamic headers
Successfully retrieved 0 headers from headersHelper
...
No token data found
Saving discovery state (authServer: https://api.example.com/)
HTTP Connection failed after 1825ms: Dynamic Client Registration rejected (HTTP 404): ...
i.e. the connection goes out unauthenticated, the server answers 401, and the client falls into OAuth discovery + dynamic client registration against a server that doesn't do OAuth — every plugin HTTP server fails at session start.
Two secondary issues visible in the same log:
- The helper's non-zero exit / empty output is logged as "Successfully retrieved 0 headers" — a failed helper should at least log a warning (its stderr is not surfaced anywhere).
- On the 401, the client goes to OAuth discovery instead of treating the 401 per the documented headersHelper re-run behavior (similar to what the 2.1.233 changelog entry fixed for
Authorization-supplying helpers — but this server usesX-Api-Key, and with 0 headers there is nothing to re-run into).
Worked before
Identical plugin config returned "Successfully retrieved 1 headers" on claude-desktop 2.1.219 and 2.1.221 (logs from Aug 4–5). Suspect the 2.1.236 change ("MCP headersHelper … now runs without inherited credential env vars") scrubs/fails to re-inject CLAUDE_PLUGIN_ROOT in the desktop local-agent runtime.
Repro
- Install a plugin whose
.mcp.jsondeclares an HTTP server with the documented${CLAUDE_PLUGIN_ROOT}-based headersHelper (script prints{"X-Api-Key": "..."}). - Open a Claude desktop (Cowork/local Code) session on 2.1.247.
- MCP log for the server shows "retrieved 0 headers", then the OAuth/DCR failure. Running the same helper command manually with
CLAUDE_PLUGIN_ROOTset prints the header correctly.
Expected
CLAUDE_PLUGIN_ROOT set (or substituted) for plugin-provided headersHelper commands, per https://code.claude.com/docs/en/mcp — and a helper failure logged as a warning rather than "Successfully retrieved 0 headers".
🤖 Filed with Claude Code