feat(mcp): support extended fields for Codex TOML conversion
## Problem
Previously, the Codex MCP configuration used a whitelist-only approach
for TOML conversion, which caused custom fields (like `timeout`,
`startup_timeout_ms`, etc.) to be silently dropped during JSON → TOML
conversion. Only Claude and Gemini (JSON format) could preserve
arbitrary fields.
## Solution
Implemented a three-tier field handling strategy:
1. **Core fields** (type, command, args, url, headers, env, cwd)
- Strong-typed manual processing (existing behavior preserved)
2. **Extended fields** (19 common optional fields)
- White-listed fields with automatic type conversion:
- General: timeout, timeout_ms, startup_timeout_ms/sec,
connection_timeout, read_timeout, debug, log_level, disabled
- stdio: shell, encoding, working_dir, restart_on_exit,
max_restart_count
- http/sse: retry_count, max_retry_attempts, retry_delay,
cache_tools_list, verify_ssl, insecure, proxy
3. **Custom fields** (generic converter)
- Automatic type inference for:
- String → TOML String
- Number (i64/f64) → TOML Integer/Float
- Boolean → TOML Boolean
- Simple arrays → TOML Array
- Shallow objects (string values only) → TOML Inline Table
- Unsupported types (null, mixed arrays, nested objects) are
gracefully skipped with debug logging
## Changes
### Core Implementation
- **json_value_to_toml_item()** (mcp.rs:843-947)
Generic JSON → TOML value converter with smart type inference
- **json_server_to_toml_table()** (mcp.rs:949-1072)
Refactored to use three-tier strategy, processes all fields beyond
core whitelist
- **build_servers_table()** (mcp.rs:616-633)
Now reuses the generic converter for consistency
- **import_from_codex()** (mcp.rs:432-605)
Extended with generic TOML → JSON converter for bidirectional
field preservation
### Logging
- DEBUG: Extended field conversions
- INFO: Custom field conversions
- WARN: Skipped unsupported types (with reason)
## Testing
- ✅ All 24 integration tests pass
- ✅ Compilation clean (zero errors)
- ✅ Backward compatible with existing configs
## Design Decision: No Auto Field Mapping
Explicitly NOT implementing automatic field mapping (e.g., Claude's
`timeout` → Codex's `startup_timeout_ms`) due to:
- Unit ambiguity (seconds vs milliseconds)
- Semantic ambiguity (same field name, different meanings)
- Risk of data corruption (30s → 30ms causes immediate timeout)
- Breaks user expectation of "what you see is what you get"
Recommendation: Use application-specific field names as documented.
## Example
User adds `timeout: 30` in MCP panel:
**Claude/Gemini** (~/.claude.json):
```json
{"mcpServers": {"srv": {"timeout": 30}}}
```
**Codex** (~/.codex/config.toml):
```toml
[mcp.servers.srv]
timeout = 30 # ✅ Now preserved!
```
Fixes the whitelist limitation reported in user feedback.