Skip to content

Add extra passthrough for harness-specific MCP keys (#1670)#1765

Open
sergio-sisternes-epam wants to merge 2 commits into
mainfrom
sergio-sisternes-epam/fix-mcp-extra-passthrough-1670
Open

Add extra passthrough for harness-specific MCP keys (#1670)#1765
sergio-sisternes-epam wants to merge 2 commits into
mainfrom
sergio-sisternes-epam/fix-mcp-extra-passthrough-1670

Conversation

@sergio-sisternes-epam

Copy link
Copy Markdown
Collaborator

TL;DR

MCPDependency now captures unknown keys from apm.yml into a generic extra dict and round-trips them into generated target manifests, enabling harness-specific configuration (e.g. Claude Code's oauth block) to survive the install pipeline.

Problem

When a user declares harness-specific keys (like oauth for Claude Code remote-MCP OAuth) in an apm.yml MCP dependency entry, those keys are silently dropped during parsing because MCPDependency.from_dict() only recognises a fixed set of known fields. The warning was already landed, but the keys were still discarded -- they never appeared in the generated .mcp.json.

Approach

A generic extra: dict[str, Any] | None field on MCPDependency captures all unknown keys and passes them through the full data flow:

apm.yml  ->  from_dict() [captures into extra]
         ->  to_dict()   [merges extra at top level]
         ->  _build_self_defined_info() [passes as _extra]
         ->  adapter._format_server_config() [merges via _merge_extra()]
         ->  target manifest (.mcp.json)

Shadow prevention: extra keys never override known fields or adapter-set keys. In both to_dict() and _merge_extra(), known keys take precedence.

Changes

File Change
src/apm_cli/models/dependency/mcp.py Added extra field, updated from_dict(), to_dict(), __repr__
src/apm_cli/integration/mcp_integrator.py Added _extra passthrough in _build_self_defined_info()
src/apm_cli/adapters/client/base.py Added _merge_extra() static method
src/apm_cli/adapters/client/{copilot,codex,cursor,gemini,kiro,vscode}.py Added _merge_extra() calls at all return points
tests/unit/test_mcp_from_dict_unknown_keys.py Updated existing tests, added 4 new test classes (25 tests total)
docs/src/content/docs/reference/manifest-schema.md Documented extra passthrough behaviour and example
docs/src/content/docs/consumer/install-mcp-servers.md Added example with oauth extra key
packages/apm-guide/.apm/skills/apm-usage/dependencies.md Added example with oauth extra key

Validation

  • All 17150 unit tests pass
  • Full lint chain passes (ruff check, ruff format, pylint R0801, auth-signals)
  • Warning message updated from "dropped" to "preserved in extra"

Out of scope

  • apm pack credential stripping for extra keys (follow-up)
  • Per-harness override blocks (claude:, vscode:) -- generic extra is simpler and sufficient

Closes #1670

MCPDependency now captures unknown keys from apm.yml into an 'extra'
dict instead of silently dropping them. The extra fields round-trip
through to_dict() and flow through _build_self_defined_info() into
every client adapter's _format_server_config(), where _merge_extra()
writes them into the generated target manifest without shadowing
known keys.

This enables harness-specific configuration such as Claude Code's
oauth block for remote-MCP OAuth client config to be declared once
in apm.yml and appear in the generated .mcp.json.

Closes #1670

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 13, 2026 13:57

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 a forward-compatible “extra passthrough” mechanism for MCP dependencies: unknown keys found in apm.yml MCP dependency objects are preserved on the model and then merged into the generated target manifests so harness-specific config (e.g., an oauth block) is not lost.

Changes:

  • Extend MCPDependency to capture unknown keys into extra and round-trip them via to_dict().
  • Plumb _extra through MCP integration and merge it into per-harness adapter configs.
  • Add/adjust unit tests and update docs to describe the passthrough behavior with examples.

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/apm_cli/models/dependency/mcp.py Adds extra field and merges unknown keys into extra, then into to_dict() output.
src/apm_cli/integration/mcp_integrator.py Adds _extra passthrough for adapter consumption (currently only in self-defined path; see comments).
src/apm_cli/adapters/client/base.py Introduces _merge_extra() helper used by adapters to merge passthrough keys.
src/apm_cli/adapters/client/copilot.py Calls _merge_extra() before returning formatted config.
src/apm_cli/adapters/client/codex.py Calls _merge_extra() on some return paths (remote-only path still misses it; see comments).
src/apm_cli/adapters/client/cursor.py Calls _merge_extra() before returning formatted config.
src/apm_cli/adapters/client/gemini.py Calls _merge_extra() before returning formatted config.
src/apm_cli/adapters/client/kiro.py Calls _merge_extra() before returning formatted config.
src/apm_cli/adapters/client/vscode.py Calls _merge_extra() before returning formatted config.
tests/unit/test_mcp_from_dict_unknown_keys.py Updates/adds tests for unknown-key preservation, round-tripping, and merge behavior.
docs/src/content/docs/reference/manifest-schema.md Documents extra passthrough semantics and adds an example.
docs/src/content/docs/consumer/install-mcp-servers.md Adds an example using a harness-specific extra key (oauth).
packages/apm-guide/.apm/skills/apm-usage/dependencies.md Updates dependency docs with an extra-key example for MCP.

Comment thread src/apm_cli/models/dependency/mcp.py
Comment thread src/apm_cli/integration/mcp_integrator.py
Comment thread src/apm_cli/adapters/client/codex.py
…remote path

- Add 'extra' to _KNOWN_DICT_KEYS so an explicit 'extra:' YAML block
  merges into dep.extra without nesting
- Propagate dep.extra via _apply_overlay for registry-resolved deps
- Add _merge_extra call in codex remote-only return path
- Add 7 new tests covering all three fixes

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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.

MCP model silently drops harness-specific keys (e.g. Claude Code oauth) — no passthrough for remote-MCP OAuth client config

2 participants