Skip to content

Plugin MCP Server installation support#217

Merged
danielmeppiel merged 8 commits intomainfrom
copilot/add-mcp-server-installation-support
Mar 9, 2026
Merged

Plugin MCP Server installation support#217
danielmeppiel merged 8 commits intomainfrom
copilot/add-mcp-server-installation-support

Conversation

Copy link
Contributor

Copilot AI commented Mar 9, 2026

Description

Plugins shipping MCP servers (via mcpServers in plugin.json or .mcp.json) now have those servers extracted, converted to MCPDependency format, and emitted into the synthesized apm.yml for deployment through the existing MCP pipeline.

Trust model: direct dependencies (depth=1) auto-trust self-defined MCPs; transitive deps still require --trust-transitive-mcp.

Extraction (plugin_parser.py)

  • _extract_mcp_servers() — resolves mcpServers as dict (inline), str (file ref), or list (multi-file, last-wins). Falls back to .mcp.json.github/.mcp.json auto-discovery. Skips symlinks, validates path containment, substitutes ${CLAUDE_PLUGIN_ROOT}.
  • _mcp_servers_to_apm_deps() — infers stdio from command, http/sse/streamable-http from url+type. All entries get registry: false.
  • synthesize_apm_yml_from_plugin() and _generate_apm_yml() wired to emit dependencies.mcp when plugin MCPs are present.

Trust model (mcp_integrator.py)

  • collect_transitive() builds direct_paths set from lockfile depth=1 entries. Self-defined MCPs from direct deps are auto-trusted; transitive deps (depth>1) still gated behind trust_private.
# Synthesized apm.yml for a plugin with .mcp.json
dependencies:
  mcp:
    - name: my-server
      registry: false
      transport: stdio
      command: npx
      args: ["-y", "my-mcp-server"]

Type of change

  • Bug fix
  • New feature
  • Documentation
  • Maintenance / refactor

Testing

  • Tested locally
  • All existing tests pass
  • Added tests for new functionality (if applicable)

27 new tests for extraction/conversion (TestExtractMCPServers, TestMCPServersToDeps, TestGenerateApmYmlMCPDeps, TestSynthesizeMCPIntegration), 4 new trust model tests, 1 updated e2e test. Full suite: 1383 passing.


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI linked an issue Mar 9, 2026 that may be closed by this pull request
Copilot AI and others added 4 commits March 9, 2026 22:35
- Add _extract_mcp_servers() to extract MCP configs from plugin manifests
  (supports string/array/dict mcpServers, .mcp.json and .github/.mcp.json fallback)
- Add _mcp_servers_to_apm_deps() to convert MCP configs to MCPDependency format
- Wire extraction into synthesize_apm_yml_from_plugin() and _generate_apm_yml()
- Modify collect_transitive() to auto-trust self-defined MCPs from direct deps (depth=1)
- Add comprehensive tests for extraction, conversion, and trust model
- Update e2e trust gating tests to reflect new direct-dep trust behavior

Co-authored-by: danielmeppiel <[email protected]>
- Remove unused `re` import from plugin_parser.py
- Update docs/plugins.md with MCP server definitions section
- Update docs/dependencies.md with direct-dep trust model

Co-authored-by: danielmeppiel <[email protected]>
Copilot AI changed the title [WIP] Add support for MCP server installation through APM pipeline Plugin MCP Server installation support Mar 9, 2026
@danielmeppiel danielmeppiel marked this pull request as ready for review March 9, 2026 22:49
@danielmeppiel danielmeppiel self-requested a review as a code owner March 9, 2026 22:49
Copilot AI review requested due to automatic review settings March 9, 2026 22:49
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds MCP server installation support for plugins. It enables plugins to ship MCP server definitions (via mcpServers in plugin.json or .mcp.json files), which are extracted, converted to MCPDependency format, and emitted into the synthesized apm.yml for deployment through the existing MCP pipeline. It also refines the trust model so self-defined MCP servers from direct dependencies (depth=1) are auto-trusted without needing --trust-transitive-mcp.

Changes:

  • plugin_parser.py: Adds _extract_mcp_servers(), _read_mcp_file(), _read_mcp_json(), _substitute_plugin_root(), and _mcp_servers_to_apm_deps() to extract and convert plugin MCP server definitions, and wires them into synthesize_apm_yml_from_plugin() and _generate_apm_yml().
  • mcp_integrator.py: Updates collect_transitive() to build a direct_paths set from lockfile depth=1 entries, auto-trusting self-defined MCPs from direct dependencies while keeping transitive deps gated behind trust_private=True.
  • Docs & tests: Updates docs/plugins.md and docs/dependencies.md with trust model documentation, and adds 32 new unit/e2e tests.

Reviewed changes

Copilot reviewed 7 out of 8 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/apm_cli/deps/plugin_parser.py Core extraction logic for MCP servers from plugin manifests and .mcp.json files
src/apm_cli/integration/mcp_integrator.py Trust model: auto-trust self-defined MCPs from direct deps (depth=1)
docs/plugins.md New documentation section for MCP server definitions in plugins
docs/dependencies.md Updated transitive trust rule to reflect direct dep auto-trust
tests/unit/test_plugin_parser.py 27 new tests for extraction, conversion, and integration
tests/unit/test_transitive_mcp.py 4 new tests for trust model changes
tests/unit/test_mcp_lifecycle_e2e.py Updated and new e2e tests for self-defined MCP trust gating
uv.lock Version bump from 0.7.4 to 0.7.5

danielmeppiel and others added 3 commits March 10, 2026 00:46
Self-defined MCP servers (declared inline in plugin.json) had their
args mangled by runtime-specific formatting logic. The npm code path
prepended the server name as a fake package, and copilot's argument
parser couldn't handle the {is_required, value_hint} format.

Add _raw_stdio field to synthetic server info in _build_self_defined_info()
and handle it with an early return in all three adapters (vscode, copilot,
codex) to bypass registry-specific formatting.
On repeated 'apm install', sub-skills from the same package triggered
spurious overwrite warnings because their previous deployment still
existed at the target path.

Use the lockfile's deployed_files to build a skill_name → owner map.
Only warn when a different package would overwrite an existing skill.
@danielmeppiel danielmeppiel merged commit 73461f5 into main Mar 9, 2026
6 checks passed
@danielmeppiel danielmeppiel deleted the copilot/add-mcp-server-installation-support branch March 9, 2026 23:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Plugin MCP Server installation support

3 participants