BREAKING CHANGE: The [mcp.servers] format was completely incorrect and not
any official Codex format. The only correct format is [mcp_servers] at the
top level of config.toml.
Changes:
- Remove incorrect [mcp.servers] nested table support
- Always use [mcp_servers] top-level table (official Codex format)
- Auto-migrate and cleanup erroneous [mcp.servers] entries on write
- Preserve error-tolerant import for migrating old incorrect configs
- Simplify sync logic by removing format selection branches (~60 lines)
- Update all documentation and tests to reflect correct format
- Add warning logs when detecting and cleaning incorrect format
Backend (Rust):
- mcp.rs: Simplify sync_enabled_to_codex by removing Target enum
- mcp.rs: sync_single_server_to_codex now always uses [mcp_servers]
- mcp.rs: remove_server_from_codex cleans both locations
- mcp.rs: Update import_from_codex comments to clarify format status
- tests: Rename test to sync_enabled_to_codex_migrates_erroneous_*
- tests: Update assertions to verify migration behavior
Frontend (TypeScript):
- tomlUtils.ts: Prioritize [mcp_servers] format in parsing
- tomlUtils.ts: Update error messages to guide correct format
Documentation:
- README.md: Correct MCP format reference to [mcp_servers]
- CLAUDE.md: Add comprehensive format specification with examples
All 79 tests pass. This ensures backward compatibility while enforcing
the correct Codex official standard going forward.
Refs: https://github.com/openai/codex/issues/3441
- Extract internal functions in commands/mcp.rs and commands/provider.rs
to enable unit testing without Tauri context
- Add test hooks: set_mcp_enabled_test_hook, import_mcp_from_claude_test_hook,
import_mcp_from_codex_test_hook, import_default_config_test_hook
- Migrate error types from String to AppError for precise error matching in tests
- Extend ProviderService with delete() method to unify Codex/Claude cleanup logic
- Add comprehensive test coverage:
- tests/mcp_commands.rs: command-level tests for MCP operations
- tests/provider_service.rs: service-level tests for switch/delete operations
- Run cargo fmt to fix formatting issues (EOF newlines)
- Update BACKEND_REFACTOR_PLAN.md to mark phase 3 complete
When users set a custom Claude configuration directory, the MCP config
file (.claude.json) is now placed alongside the overridden directory
instead of the default ~/.claude.json location.
Changes:
- Add path derivation logic to generate MCP path from override directory
(e.g., /custom/.claude → /custom/.claude.json)
- Implement automatic migration from legacy path on first access
- Add comprehensive unit tests covering 4 edge cases
- Update UI descriptions to clarify MCP file placement
- Fix documentation: correct MCP config path from ~/.claude/mcp.json
to ~/.claude.json
Technical details:
- New function: derive_mcp_path_from_override() extracts directory name
and creates sibling .json file
- Migration copies ~/.claude.json to new location if override is set
- All MCP operations (read/write/sync) now use the derived path via
user_config_path() unified entry point
Breaking changes: None (backward compatible with default behavior)
- Add normalize_server_keys() to ensure MCP server map keys match internal id fields
- Auto-normalize on all read/write operations (get, upsert, delete, import, sync)
- Handle edge cases: empty/whitespace ids, key renaming, conflict resolution
- Auto-save config when normalization detects changes
- Apply cargo fmt for code formatting consistency
This enhancement improves data integrity by automatically fixing inconsistencies
between server entry keys and their id fields, especially after manual config edits.
- Separate MCP server metadata from connection spec for cleaner architecture
- Add comprehensive server entry fields: name, description, tags, homepage, docs
- Remove legacy format compatibility logic from extract_server_spec
- Implement data validation and filtering in get_servers_snapshot_for
- Add strict id consistency check in upsert_in_config_for
- Enhance import logic with defensive programming for corrupted data
- Simplify frontend by removing normalization logic (moved to backend)
- Improve error messages with contextual information
- Add comprehensive i18n support for new metadata fields
- Backend: reject "sse" in validators; accept missing type as stdio; require url only for http (mcp.rs, claude_mcp.rs)
- Frontend: McpServer.type narrowed to "stdio" | "http" (optional) (src/types.ts)
- UI: avoid undefined in list item details (McpListItem)
- Claude-only sync after delete to update ~/.claude.json (commands.rs)
Notes:
- Ran typecheck and cargo check: both pass
- Clippy shows advisory warnings unrelated to this change
- Prettier check warns on a few files; limited scope changes kept minimal
- Add McpConfig to MultiAppConfig and persist MCP servers in ~/.cc-switch/config.json
- Add Tauri commands: get_mcp_config, upsert_mcp_server_in_config, delete_mcp_server_in_config, set_mcp_enabled, sync_enabled_mcp_to_claude, import_mcp_from_claude
- Only write enabled MCPs to ~/.claude.json (mcpServers) and strip UI-only fields (enabled/source)
- Frontend: update API wrappers and MCP panel to read/write via config.json; seed presets on first open; import from ~/.claude.json
- Fix warnings (remove unused mut, dead code)
- Verified with cargo check and pnpm typecheck
- Replace deprecated 'sse' type with 'http' (as per Claude Code official docs)
- Add HTTP-specific fields: url (required) and headers (optional)
- Implement dynamic UI: show different fields based on selected type
- Improve args input: support multi-line input (one argument per line)
- Add headers parsing supporting both 'KEY: VALUE' and 'KEY=VALUE' formats
- Update backend validation to enforce type-specific required fields
- Update i18n translations (zh/en) with new HTTP-related labels
- Read/write ~/.claude.json (preserve unknown fields) for mcpServers
- Remove settings.local.json and mcp.json handling
- Drop enableAllProjectMcpServers command and UI toggle
- Update types, Tauri APIs, and MCP panel to reflect new status fields
- Keep atomic write and command validation behaviors