feat(mcp): make sync opt-in and address review

Opt-in (mcpSyncEnabled, default OFF; routes 403 until on). Review fixes:
- codex TOML read/validated with smol-toml: CRLF, inline tables and
  command-less tables no longer yield a duplicate [mcp_servers.x]; the new
  text is re-parsed before writing
- null-prototype tables and own-key checks; unsafe names ignored at every level
- servers switched off in their own CLI (codex/opencode/antigravity) are not copied
- only CLIs that are installed or already have a config file take part
- files receiving env/headers are left 0600; symlinked configs are written through
- one apply at a time (409), unique tmp files cleaned on failure, failed status
- routes set real HTTP status codes; api-reference section; format type single-sourced

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Devvyn
2026-10-02 21:15:31 +08:00
co-authored by Claude Sonnet 5.5
parent 7616de13de
commit 4398dbfad0
15 changed files with 772 additions and 306 deletions
+10 -3
View File
@@ -2475,13 +2475,20 @@
</div>
</div>
<div class="set-group">
<div class="set-group" id="mcpSyncGroup">
<div class="set-group-head"><h4>MCP servers</h4><span class="set-scope">server</span></div>
<div class="set-group-body">
<div class="set-row" data-search="mcp server sync claude codex gemini opencode">
<div class="set-row" data-search="mcp server sync enable claude codex gemini opencode antigravity">
<div class="set-row-text">
<span class="set-row-label">Enable MCP server sync</span>
<span class="set-row-desc">Adds a control that copies MCP servers between your enabled CLIs by writing their own config files. Off by default: this changes other tools' configuration, not just Codeman's.</span>
</div>
<label class="switch switch-sm"><input type="checkbox" id="appSettingsMcpSync" onchange="app.applyMcpSyncVisibility()"><span class="slider"></span></label>
</div>
<div class="set-row" id="mcpSyncActionRow" style="display:none" data-search="mcp server sync preview">
<div class="set-row-text">
<span class="set-row-label">Sync MCP servers across CLIs</span>
<span class="set-row-desc">Copies each enabled CLI's MCP servers into the others' config files. Only adds missing servers; never edits or removes one. The previous file is kept as <code>.codeman-bak</code>.</span>
<span class="set-row-desc">Copies each installed, enabled CLI's MCP servers into the others. Only adds missing servers; never edits, removes or copies a server you switched off. Env values and headers are copied too, so a file that receives them is left readable by you only. The previous file is kept as <code>.codeman-bak</code> (overwritten by each sync).</span>
</div>
<span>
<button class="btn-toolbar btn-sm" id="mcpSyncPreviewBtn" onclick="app.mcpSync(false)">Preview</button>