feat (mcp-conf): Project-level MCP configuration with merge/override strategy#2349
feat (mcp-conf): Project-level MCP configuration with merge/override strategy#2349asanisimov wants to merge 2 commits into
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: fe2ba8e679
ℹ️ About Codex in GitHub
Codex has been enabled to automatically 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 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| path=default_mcp_file, | ||
| ) | ||
| # Load MCP config files according to merge_strategy. | ||
| work_dir = session.dir |
There was a problem hiding this comment.
Use project root when loading web worker MCP configs
The web worker now calls collect_file_mcp_configs() with session.dir, which points to the session storage directory under ~/.kimi/sessions/..., not the user’s project workspace. As a result, project-level MCP config discovery (<work_dir>/.kimi/mcp.json) never finds the project file in web sessions, so web mode silently falls back to global/default MCP config and ignores project-specific servers. This breaks the new project-level MCP behavior for the web workflow.
Useful? React with 👍 / 👎.
| path=default_mcp_file, | ||
| ) | ||
| # Load MCP config files according to merge_strategy. | ||
| work_dir = session.dir |
There was a problem hiding this comment.
🔴 Web worker uses session storage directory instead of project working directory for MCP config discovery
In src/kimi_cli/web/runner/worker.py:34, work_dir = session.dir assigns the session's internal storage directory (e.g., ~/.kimi/sessions/<hash>/<session_id>/) to work_dir. This is then passed to collect_file_mcp_configs(strategy, work_dir=work_dir) which looks for .kimi/mcp.json inside work_dir. Since the session storage directory will never contain a .kimi/mcp.json project config, the project-level MCP config discovery will always fail silently in the web worker. The correct directory is the project working directory, accessible via session.work_dir (a KaosPath). Other call sites use session.work_dir.unsafe_to_local_path() or Path(str(session.work_dir)) for this purpose (see src/kimi_cli/web/api/sessions.py:480 and src/kimi_cli/web/api/sessions.py:959).
| work_dir = session.dir | |
| work_dir = session.work_dir.unsafe_to_local_path() | |
Was this helpful? React with 👍 or 👎 to provide feedback.
Related Issue
#1365
We've encountered similar limitations on our projects and, for now, have decided to maintain changes in our fork and rebase them ourselves. We'd appreciate the community's PR review and are open to improvements.
Description
This PR introduces project-level MCP configuration and a configurable merge strategy for combining MCP configs from multiple sources.
What changed
.kimi/mcp.jsoninside the working directory. If it exists, it is treated as the project-level MCP config.mcp.merge_strategyconfig field controls how configs from different sources are combined.collect_file_mcp_configs()helper so behavior is consistent across UIs.--mcp-config-filenow documents the automatic project-level fallback.Source priority (lowest → highest)
~/.kimi/mcp.json<work_dir>/.kimi/mcp.json--mcp-config-filepaths--mcp-configJSON stringsmerge_strategyoverride(default)mergeConfiguration examples
Project-level config (
my-project/.kimi/mcp.json):{ "mcpServers": { "project-docs": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/project/docs"] } } }Global config (
~/.kimi/mcp.json):{ "mcpServers": { "filesystem": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-filesystem"] } } }Config file (
~/.kimi/config.toml):Behavior examples
Scenario A — override (default): project isolates its own servers
You have a global filesystem server, but inside my-project you only want project-docs.
• ~/.kimi/mcp.json defines filesystem
• my-project/.kimi/mcp.json defines project-docs
• Running kimi --work-dir my-project loads only project-docs
Scenario B — merge: combine global and project servers
With the same files as above, both filesystem and project-docs are available. If a server name collides, the project config wins.
Scenario C — explicit --mcp-config-file wins
kimi --mcp-config-file ./explicit.jsonIn override mode, ./explicit.json is the only config loaded, even if a project .kimi/mcp.json exists.
Coverage
The feature is active in:
• CLI (interactive shell, --print, one-shot mode)
• ACP server (IDE integrations via the ACP protocol)
• Web worker (web UI sessions)
Tests
─────
Added tests/cli/test_project_mcp_config.py with 14 tests covering:
• get_project_mcp_config_file discovery
• collect_file_mcp_configs for both merge and override strategies
• Duplicate-name handling in merge mode
• Fallback chains (project → global, explicit → project, etc.)
• CLI integration via CliRunner
• ACP server integration (async)
Existing tests/core/test_plan_flag.py patches were updated to match the new import paths.
Checklist
make gen-changelogto update the changelog.make gen-docsto update the user documentation.