Plugin --plugin-dir namespacing breaks skill allowed-tools resolution
Summary
When a plugin is loaded via --plugin-dir, Claude Code adds a plugin_<plugin-name>_ namespace prefix to MCP tool names that doesn't exist under normal installation. The plugin's allowed-tools declarations in skill frontmatter are not transformed to match, so they silently fail to grant any permissions.
Reproduction
- Create a plugin with an MCP server registered in
.mcp.jsonas"my-server" - In a skill's frontmatter, declare
allowed-tools: mcp__my-server__* - Load the plugin via
claude --plugin-dir /path/to/plugin - Invoke the skill and call the MCP tools
Expected: Tools are auto-approved per the skill's allowed-tools
Actual: Every MCP tool call prompts for manual approval
Root cause
The plugin loader namespaces MCP tools as mcp__plugin_<plugin-name>_<server-name>__<tool>, but the skill's allowed-tools wildcard mcp__<server-name>__* is evaluated literally without applying the same namespace transformation.
In the concrete case:
.mcp.jsonregisters server as"re-teams"- Skill declares
allowed-tools: mcp__re-teams__* - Runtime tool names are
mcp__plugin_re-teams_re-teams__team_list, etc. - The wildcard matches nothing
Expected behavior
Either:
- Preferred: When resolving a plugin's
allowed-tools, apply the same namespace prefix that was applied to the tool names — somcp__re-teams__*in the skill automatically matchesmcp__plugin_re-teams_re-teams__*at runtime. The skill author shouldn't need to know what prefix the loader adds. - Alternative:
--plugin-dirshould use the same tool naming scheme as normal plugin installation, so the names are consistent regardless of loading mechanism.
Environment
- Claude Code (CLI)
- macOS (Darwin 24.6.0)
- Plugin loaded via
--plugin-dir
This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗