Skip to content

fix: accept mcpServers as alias for mcp in config#621

Closed
VJ-yadav wants to merge 5 commits intoAltimateAI:mainfrom
VJ-yadav:fix/mcp-servers-config-alias
Closed

fix: accept mcpServers as alias for mcp in config#621
VJ-yadav wants to merge 5 commits intoAltimateAI:mainfrom
VJ-yadav:fix/mcp-servers-config-alias

Conversation

@VJ-yadav
Copy link
Copy Markdown
Contributor

@VJ-yadav VJ-yadav commented Apr 3, 2026

What does this PR do?

Fixes #619 — When AI tools (Claude Code, Copilot) auto-generate altimate-code.json, they write mcpServers instead of mcp, causing a startup error: Unrecognized key: "mcpServers".

Added normalization in config loading that renames mcpServersmcp before schema validation. Follows the existing pattern for legacy key migration (theme, keybinds, tui → deleted with warning). Only applies when mcp is not already set, so explicit mcp configs are not overwritten.

One file changed, 6 lines added.

Type of change

  • Bug fix
  • New feature
  • Test coverage
  • Documentation
  • Refactoring
  • Infrastructure

Issue for this PR

Closes #619

How did you verify your code works?

  • bun test test/config/config.test.ts — 66 pass
  • Follows existing normalization pattern in config.ts
  • Does not overwrite explicit mcp key if both present

Checklist

  • Follows existing normalization pattern in config.ts
  • No breaking changes
  • Does not overwrite explicit mcp key if both present
  • Tests pass locally

Summary by CodeRabbit

  • New Features
    • Configuration files now accept mcpServers as an alias for the mcp key. When mcpServers is present without mcp, the system automatically migrates the configuration and logs the change for transparency.

When AI tools (Claude Code, Copilot) generate altimate-code config,
they write `mcpServers` instead of `mcp`. This causes a startup error:
"Unrecognized key: mcpServers".

Add normalization during config loading that renames `mcpServers` to
`mcp` before schema validation, matching the existing pattern for
legacy key migration (theme, keybinds, tui).

Fixes AltimateAI#619

Co-Authored-By: Vijay Yadav <[email protected]>
Copy link
Copy Markdown

@claude claude bot left a comment

Choose a reason for hiding this comment

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

Claude Code Review

This pull request is from a fork — automated review is disabled. A repository maintainer can comment @claude review to run a one-time review.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 3, 2026

📝 Walkthrough

Walkthrough

Config normalization now supports mcpServers as an alias for the top-level mcp key. During config loading, if mcpServers exists and mcp does not, the configuration is normalized by copying mcpServers to mcp, deleting the original key, and logging an informational message with the source path.

Changes

Cohort / File(s) Summary
Config Alias Support
packages/opencode/src/config/config.ts
Added normalization logic to accept mcpServers as an alias for mcp during config loading, automatically converting legacy config format to the canonical format with logging.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~5 minutes

Poem

🐰 A config key once caused dismay,
mcpServers led users astray,
Now aliases smooth the way,
One name maps to another today,
Servers hop happily, hooray! 🎉

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description is largely complete with summary, test plan, and checklist sections, but is missing the required 'PINEAPPLE' identifier per the template for AI-generated contributions. Add 'PINEAPPLE' at the very top of the PR description as required by the template for AI-generated contributions.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and concisely describes the main change: adding support for mcpServers as an alias for the mcp configuration key.
Linked Issues check ✅ Passed The PR successfully addresses issue #619 by normalizing the mcpServers key to mcp before schema validation, preventing startup errors from unrecognized keys.
Out of Scope Changes check ✅ Passed All changes are scoped to the config normalization requirement; no extraneous modifications are present outside the linked issue requirements.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@dev-punia-altimate
Copy link
Copy Markdown

❌ Tests — Failures Detected

TypeScript — 15 failure(s)

  • connection_refused [3.08ms]
  • timeout [2.91ms]
  • permission_denied [3.04ms]
  • parse_error [2.63ms]
  • oom [2.90ms]
  • network_error [2.77ms]
  • auth_failure [2.96ms]
  • rate_limit [3.31ms]
  • internal_error [3.21ms]
  • empty_error [0.30ms]
  • connection_refused [0.16ms]
  • timeout [0.09ms]
  • permission_denied [0.09ms]
  • parse_error [0.08ms]
  • oom [0.08ms]

cc @VJ-yadav
Tested at c292be1b | Run log | Powered by QA Autopilot

@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 5, 2026

Thanks for updating your PR! It now meets our contributing guidelines. 👍

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/opencode/src/config/config.ts`:
- Around line 1436-1441: The duplicate top-level aliasing block that maps
copy.mcpServers → copy.mcp (checking "mcpServers" in copy && !("mcp" in copy")
and logging) should be removed so all MCP normalization is performed by
normalizeMcpConfig(); delete that if-block (the code referencing
copy.mcpServers, copy.mcp and the log.info call) and rely on
normalizeMcpConfig() to handle both top-level aliasing and per-server
normalization to avoid dead code and duplication.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 3c77c8e1-75d0-4a66-8ecb-c1475cd1272b

📥 Commits

Reviewing files that changed from the base of the PR and between ba9882f and 63e0986.

📒 Files selected for processing (1)
  • packages/opencode/src/config/config.ts

Comment on lines +1436 to +1441
// Alias mcpServers → mcp (Claude Code / Copilot format compatibility)
if ("mcpServers" in copy && !("mcp" in copy)) {
copy.mcp = copy.mcpServers
delete copy.mcpServers
log.info("aliased mcpServers to mcp in config", { path: source })
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Remove duplicate normalization logic.

This code duplicates the mcpServers → mcp aliasing already handled by normalizeMcpConfig() (lines 1375-1383), which is called immediately after at line 1450. Since this code executes first, the normalization logic inside normalizeMcpConfig becomes unreachable for the top-level key, creating dead code and maintenance confusion.

The normalizeMcpConfig function is more comprehensive—it handles both the top-level key aliasing and individual server entry normalization. Consolidating all MCP normalization in one place improves maintainability and follows the DRY principle.

♻️ Proposed fix: Remove duplicate normalization
  const normalized = (() => {
    if (!data || typeof data !== "object" || Array.isArray(data)) return data
    const copy = { ...(data as Record<string, unknown>) }
-   // Alias mcpServers → mcp (Claude Code / Copilot format compatibility)
-   if ("mcpServers" in copy && !("mcp" in copy)) {
-     copy.mcp = copy.mcpServers
-     delete copy.mcpServers
-     log.info("aliased mcpServers to mcp in config", { path: source })
-   }
    const hadLegacy = "theme" in copy || "keybinds" in copy || "tui" in copy
    if (hadLegacy) {
      delete copy.theme
      delete copy.keybinds
      delete copy.tui
      log.warn("tui keys in opencode config are deprecated; move them to tui.json", { path: source })
    }
    // altimate_change start — normalize mcpServers to mcp (common key used by other AI tools)
    return normalizeMcpConfig(copy, source)
    // altimate_change end
  })()
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/opencode/src/config/config.ts` around lines 1436 - 1441, The
duplicate top-level aliasing block that maps copy.mcpServers → copy.mcp
(checking "mcpServers" in copy && !("mcp" in copy") and logging) should be
removed so all MCP normalization is performed by normalizeMcpConfig(); delete
that if-block (the code referencing copy.mcpServers, copy.mcp and the log.info
call) and rely on normalizeMcpConfig() to handle both top-level aliasing and
per-server normalization to avoid dead code and duplication.

@anandgupta42
Copy link
Copy Markdown
Contributor

Multi-Model Code Review — Unanimous: CLOSE AS SUPERSEDED

Ran a 3-reviewer consensus pass (Claude + GPT 5.4 + Gemini 3.1 Pro). All three independently reached the same verdict: this PR should be closed without merging.

Root finding: dead code, superseded by #639

The 6 lines added here duplicate logic that already lives in normalizeMcpConfig() at packages/opencode/src/config/config.ts:1372-1421, which was added by #639 (merged April 4, 2026). Both run in the same normalized block — the PR's code runs first, then normalizeMcpConfig(copy, source) runs on the same object at line 1450.

Verified locally: reverted the PR's 6 lines and ran the full config test suite → 82/82 pass. The tests in this PR (test/config/config.test.ts:346-490) actually exercise normalizeMcpConfig, not the 6-line shim.

Additional issues (if this were the only fix)

  • Missing shape translation (Gemini, CRITICAL): Claude Code emits {command: \"npx\", args: [...], env: {...}} but altimate-code's `McpLocal` schema strictly requires {type: \"local\", command: string[], environment: {...}}. The PR just moves the object — it doesn't transform the shape, so Zod strict validation would still reject with unrecognized keys (`args`, `env`), missing `type`, and wrong `command` type. `normalizeMcpConfig()` handles this correctly.
  • Incomplete conflict handling (Gemini + GPT, MAJOR): When BOTH `mcp` and `mcpServers` exist, the `if ("mcpServers" in copy && !("mcp" in copy))` condition is false, the block skips, `mcpServers` remains in the object, and root schema strict-mode rejects with "Unrecognized key: mcpServers". `normalizeMcpConfig()` always deletes `mcpServers` regardless.
  • Log-level drift (GPT, MINOR): PR uses `log.info`; existing `normalizeMcpConfig()` uses `log.warn` (line 1378) for the same operation. Keeping this would produce duplicate messages at different severities.

Positive observations

Recommendation

Closing as superseded. Thanks @VJ-yadav for surfacing #619 — the compatibility gap you identified was legitimate and got fully fixed by #639. The comprehensive test suite you wrote here would be a valuable contribution if added to `test/config/config.test.ts` — want to open a separate PR with just the test cases not already covered by #639's tests?


Reviewed by 3 participants via consensus code review. Convergence: 0 rounds (unanimous).

@anandgupta42
Copy link
Copy Markdown
Contributor

Closing as superseded by #639. See review comment above for details.

@VJ-yadav
Copy link
Copy Markdown
Contributor Author

VJ-yadav commented Apr 5, 2026

Recommendation

Closing as superseded. Thanks @VJ-yadav for surfacing #619 — the compatibility gap you identified was legitimate and got fully fixed by #639. The comprehensive test suite you wrote here would be a valuable contribution if added to test/config/config.test.ts — want to open a separate PR with just the test cases not already covered by #639's tests?

Thanks @anandgupta42 for the detailed review and the multi-model consensus pass, really appreciate the thoroughness. Glad the compatibility gap I reported in #619 got a proper fix in #639, the shape translation and conflict handling there are much more robust than my simple alias approach.

To clarify, my PR only had the config alias in config.ts, no test file changes. The comprehensive test suite at config.test.ts:346-490 came with #639. So I don't have additional test cases from my end to port over, but I can review #639's coverage and open a test PR if I spot any gaps worth adding.

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 server config uses unrecognized 'mcpServers' key in altimate-code.json

3 participants