Plugin MCP servers: \${PLUGIN_ROOT} placeholder not expanded (Agent Plugins spec non-conformance)

Status Open
Reported on v2.1.260
Maintainer reply None cached
Activity 0 comments · opened Sep 10, 2026

Summary

Claude Code does not expand the spec-standard ${PLUGIN_ROOT} placeholder in plugin mcp.json files. It only recognizes its own ${CLAUDE_PLUGIN_ROOT} variant. This breaks cross-host plugin compatibility with any host that follows the Agent Plugins specification.

Spec reference

The Agent Plugins spec v1.1.0 defines:

  • §9.1 — Hosts MUST provide PLUGIN_ROOT and PLUGIN_DATA as environment variables to plugin subprocesses.
  • §9.2 — Hosts MUST expand ${PLUGIN_ROOT} and ${PLUGIN_DATA} in args, env, and cwd fields of MCP server configurations.

Current behavior (Claude Code 2.1.260)

Claude Code only expands ${CLAUDE_PLUGIN_ROOT} (its own prefixed variant). A plugin using the spec-standard ${PLUGIN_ROOT} in its mcp.json:

{
  "mcpServers": {
    "my-server": {
      "command": "node",
      "args": ["${PLUGIN_ROOT}/dist/index.js"],
      "cwd": "${PLUGIN_ROOT}"
    }
  }
}

...results in the literal string ${PLUGIN_ROOT}/dist/index.js being passed to node, causing MODULE_NOT_FOUND and a CONNECTION_CLOSED error at session startup. The error message gives no hint that the real cause is unexpanded placeholders.

Evidence from the binary (2.1.260): the allowlist regex for placeholder expansion is:

^\$\{CLAUDE_(?:PROJECT_DIR|PLUGIN_ROOT|PLUGIN_DATA)\}$

Only the CLAUDE_-prefixed variants are matched.

Expected behavior

Claude Code should expand the spec-standard ${PLUGIN_ROOT} and ${PLUGIN_DATA} in addition to (or as aliases of) its own ${CLAUDE_PLUGIN_ROOT} and ${CLAUDE_PLUGIN_DATA}.

Workaround

Using a relative path from the plugin root with no explicit cwd avoids the placeholder entirely, since both the spec and Claude Code default cwd to the plugin root when omitted:

{
  "mcpServers": {
    "my-server": {
      "command": "node",
      "args": ["./dist/index.js"]
    }
  }
}

Impact

Any plugin using the spec-standard ${PLUGIN_ROOT} in its MCP server configuration will fail silently on Claude Code with a CONNECTION_CLOSED error. The error message does not indicate that placeholder expansion failed, making this very difficult to diagnose.

View original on GitHub ↗