Describe the bug
targets: in apm.yml acts as a whitelist for skill file deployment, but MCP server installation ignores it entirely and configures all auto-detected runtimes. This inconsistency means users who explicitly restrict their target set still have MCP servers pushed to unintended runtimes.
To Reproduce
- Set
targets: [claude] in apm.yml
- Add a skill dependency that includes an MCP server (e.g.
yusukebe/hono-skill)
- Run
apm install
Expected behavior
targets: [claude] should restrict MCP server installation to Claude only, consistent with how it restricts skill deployment.
Environment:
- OS: macOS 15.4
- Python Version: [e.g. 3.12.x]
- APM Version: [e.g. 0.13.x]
- VSCode Version (if relevant): [e.g. 1.80.0]
Logs
Skills are correctly deployed to Claude only, but MCP server installation targets all detected runtimes regardless of targets::
[i] Targets: claude (source: apm.yml)
|-- Skill integrated -> .claude/skills/ ← respects targets:
...
+- Configuring for Copilot, Codex, Vscode, Claude... ← ignores targets:
Additional context
There are two independent defects causing this behavior:
1. Singular/plural key mismatch for project-scoped runtimes (codex, claude)
_gate_project_scoped_runtimes in src/apm_cli/integration/mcp_integrator.py:973 reads the raw config key directly:
config_target = explicit_target or (apm_config.get("target") if apm_config else None)
"target" (singular) returns None when targets: (plural — the canonical form per apm_cli.core.apm_yml) is used. As a result active_targets() falls back to directory auto-detection and the gating has no effect. parse_targets_field() in apm_cli.core.apm_yml already handles both keys correctly but is not called here.
2. Non-project-scoped runtimes are never gated
_PROJECT_SCOPED_RUNTIMES contains only codex and claude. Copilot and VSCode are outside this set, so _gate_project_scoped_runtimes never evaluates them — they are configured whenever their binary or directory is detected, regardless of targets:.
Both defects need to be addressed to make targets: a reliable whitelist for MCP installation.
Describe the bug
targets:inapm.ymlacts as a whitelist for skill file deployment, but MCP server installation ignores it entirely and configures all auto-detected runtimes. This inconsistency means users who explicitly restrict their target set still have MCP servers pushed to unintended runtimes.To Reproduce
targets: [claude]inapm.ymlyusukebe/hono-skill)apm installExpected behavior
targets: [claude]should restrict MCP server installation to Claude only, consistent with how it restricts skill deployment.Environment:
Logs
Skills are correctly deployed to Claude only, but MCP server installation targets all detected runtimes regardless of
targets::Additional context
There are two independent defects causing this behavior:
1. Singular/plural key mismatch for project-scoped runtimes (
codex,claude)_gate_project_scoped_runtimesinsrc/apm_cli/integration/mcp_integrator.py:973reads the raw config key directly:"target"(singular) returnsNonewhentargets:(plural — the canonical form perapm_cli.core.apm_yml) is used. As a resultactive_targets()falls back to directory auto-detection and the gating has no effect.parse_targets_field()inapm_cli.core.apm_ymlalready handles both keys correctly but is not called here.2. Non-project-scoped runtimes are never gated
_PROJECT_SCOPED_RUNTIMEScontains onlycodexandclaude.CopilotandVSCodeare outside this set, so_gate_project_scoped_runtimesnever evaluates them — they are configured whenever their binary or directory is detected, regardless oftargets:.Both defects need to be addressed to make
targets:a reliable whitelist for MCP installation.