Skip to content

fix(converters): preserve user config when writing MCP servers#479

Merged
tmchow merged 5 commits into
mainfrom
feat/investigate-config-wipe
Apr 1, 2026
Merged

fix(converters): preserve user config when writing MCP servers#479
tmchow merged 5 commits into
mainfrom
feat/investigate-config-wipe

Conversation

@tmchow

@tmchow tmchow commented Apr 1, 2026

Copy link
Copy Markdown
Collaborator

Summary

Fixes #478 — the Codex, Copilot, and Qwen install/convert writers were overwriting user config files wholesale, wiping settings like model preferences and user-added MCP servers.

  • Codex: Introduced managed block markers (BEGIN/END) so plugin MCP config coexists with user TOML. Extracted shared mergeCodexConfig() used by both install and sync paths. Handles migration from previous-generation markers and legacy markers (# Generated by compound-plugin).
  • Copilot/Qwen: Track plugin-managed server names in a _compound_managed_mcp array. On re-install, only managed servers are replaced — user-added servers survive. Stale managed servers (renamed/removed) are cleaned up.
  • Legacy fallback guard: When no tracking key exists AND the plugin has zero MCP servers, skip pruning entirely. The legacy assumption ("all servers are plugin-managed") only applies when the plugin has servers to replace — otherwise it would wrongly delete user servers from a pre-existing untracked config.
  • Qwen top-level key tracking: Added _compound_managed_keys to track which top-level config keys the plugin wrote (e.g., settings). Stale keys are pruned on re-install; user-added keys are preserved.
  • All targets: Converge correctly when the plugin ships zero MCP servers (stale managed config is removed, tracking key retained as []). Malformed servers (neither command nor url) are skipped instead of emitting empty config sections.

Test plan

  • Codex: preserves user config alongside managed MCP block
  • Codex: idempotent — running twice doesn't duplicate managed block
  • Codex: migrates old marker format to new
  • Codex: migrates unmarked legacy format (# Generated by compound-plugin)
  • Codex: preserves user config before unmarked legacy format
  • Codex: strips stale block when bundle has no MCP servers
  • Codex sync: cleans up stale managed block on zero-server sync
  • Codex: skips malformed servers (no command/url)
  • Codex: skips malformed but keeps valid servers in same set
  • Copilot: removes stale plugin servers on re-install
  • Copilot: preserves user-added MCP servers
  • Copilot: prunes stale servers from legacy config without tracking key
  • Copilot: cleans up all plugin servers when bundle has none
  • Copilot: does not prune untracked user config when plugin has zero MCP servers
  • Copilot: preserves user servers across zero-MCP-then-MCP round trip
  • Qwen: removes stale plugin servers on re-install
  • Qwen: preserves user-added MCP servers
  • Qwen: preserves unknown top-level keys (verifies tracking key written)
  • Qwen: prunes stale servers from legacy config without tracking key
  • Qwen: does not prune untracked user config when plugin has zero MCP servers
  • Qwen: cleans up all plugin servers when bundle has none
  • Qwen: preserves user servers across zero-MCP-then-MCP round trip
  • Qwen: prunes stale top-level plugin keys when incoming config drops them
  • All 45 tests pass across 4 test files (165 assertions)

🤖 Generated with Claude Code

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6bd9e1d21e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/targets/codex.ts Outdated
tmchow added a commit that referenced this pull request Apr 1, 2026
- Strip unmarked legacy format (# Generated by compound-plugin) during
  merge to prevent duplicate TOML tables on first upgrade from old writer

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b26a02a98d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/targets/copilot.ts Outdated
Comment thread src/targets/qwen.ts Outdated
tmchow added a commit that referenced this pull request Apr 1, 2026
- Copilot/Qwen: treat all existing MCP servers as plugin-managed when
  _compound_managed_mcp tracking key is absent (legacy migration)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The install and convert paths for Codex, Copilot, and Qwen were
overwriting the entire config file with only plugin-managed MCP servers,
wiping user settings (model preferences, custom MCP servers, etc.).

Codex: Use managed block markers (BEGIN/END) so plugin MCP config
coexists with user TOML. Extract shared mergeCodexConfig() used by both
the install and sync paths. Migrate previous-generation markers and
the unmarked legacy format (# Generated by compound-plugin).

Copilot/Qwen: Track plugin-managed server names in a
_compound_managed_mcp array within the JSON config. On re-install,
only managed servers are replaced — user-added servers are preserved.
Stale managed servers (renamed/removed from plugin) are cleaned up.
Legacy configs without tracking key treat all existing servers as
plugin-managed for safe first migration.

All three targets now converge correctly when the plugin ships zero
MCP servers (stale managed config is removed).

Also skips malformed MCP servers (neither command nor url) instead of
emitting empty TOML sections.

Fixes #478

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@tmchow tmchow force-pushed the feat/investigate-config-wipe branch from e4235ca to 5ca4912 Compare April 1, 2026 17:29

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5ca4912af1

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/targets/qwen.ts Outdated
…servers

Always write _compound_managed_mcp (even as []) so the legacy fallback
doesn't treat user servers as plugin-managed on a future install.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8007603208

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/targets/copilot.ts Outdated
Comment thread src/targets/copilot.ts Outdated
…pilot and Qwen

When no tracking key exists AND incoming MCP is empty, skip the legacy
prune path that assumes all existing servers are plugin-managed. Also
always retain the tracking key (as []) to prevent the legacy fallback
from firing on future installs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 19a07ed26f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/targets/qwen.ts
tmchow and others added 2 commits April 1, 2026 11:24
…hanges

Track plugin-written top-level keys via _compound_managed_keys, same
pattern as _compound_managed_mcp for MCP servers. Keys removed from
the plugin config (e.g. settings) are pruned on re-install; user-added
keys are preserved.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ervation test

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@tmchow tmchow merged commit c65a698 into main Apr 1, 2026
2 checks passed
@github-actions github-actions Bot mentioned this pull request Apr 1, 2026
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.

bug: Codex Installation Wipes ~/.codex/config.toml (does save a backup)

1 participant