Repository navigation
[Bug] MCP servers from .agents/mcp.json are not loaded when the project is selected via the project picker (CLI started from an ancestor directory) #957
Description
Activity
Hi, I'd like to fix this one, and I already have the fix on my fork.
Root cause confirmed in the code: the CLI loads MCP servers exactly once at startup in initializeAgentRegistry() via loadMCPConfigSync(), which reads {cwd}/.agents/mcp.json. When you launch from an ancestor directory and then pick a project, handleProjectChange in cli/src/index.tsx does process.chdir(newProjectPath) and resets the codebuff client, but never re-runs the agent registry. So mcpServersCache stays empty and loadAgentDefinitions() merges nothing into the base agents.
The fix adds a reloadLocalAgentRegistry() helper in cli/src/utils/local-agent-registry.ts that clears the derived caches (agent listings and the resolved .agents dir) and re-runs initializeAgentRegistry(). handleProjectChange now calls it right after chdir and setProjectRoot, so the selected project's .agents/mcp.json is picked up.
Verification:
- New regression test reproduces the exact scenario from the report (registry initialized in a directory without mcp.json, then chdir + setProjectRoot to a project that has one, then reload): it fails on the original code (the export does not exist) and passes with the fix.
- Local Agent Integration suite: 37/37 pass.
- tsc on cli: no errors in the changed files (10 total, same as baseline modulo one pre-existing react-dom/server declaration issue that my change actually resolves).
Branch: fix/mcp-config-project-picker-957 (1 commit). PR is up next. Let me know if you'd like any changes.
PR is up: #973
- addedarea:cliThe Codebuff/Freebuff terminal clientThe Codebuff/Freebuff terminal clientbot:triagedClassified by the community triage botClassified by the community triage bottype:bugA defect in the code with a reproducible failureA defect in the code with a reproducible failure
on Aug 19, 2026 - addedstaleNo activity after a maintainer request; queued for closingNo activity after a maintainer request; queued for closing
on Sep 9, 2026 Marking this stale - there has been no activity here for 29 days. It will close in 7 days unless someone comments.
This is backlog upkeep, not a verdict on the issue. A single comment keeps it open, and anything closed this way can be reopened.
Closing this as stale - no activity since it was flagged 7 days ago. Reopen it any time if it is still relevant; that is not a hassle and we would rather have it open than lost.
Closed automatically by the community triage bot. If this is wrong, reopen the issue or reply and a maintainer will take another look.
- addedbot:auto-closedClosed by the community triage bot; reopen if wrongClosed by the community triage bot; reopen if wrong
on Sep 17, 2026
Summary
When the Freebuff CLI is started from a directory outside the project and the project is then selected via the project picker, the MCP servers defined in the project's
.agents/mcp.jsonare silently not exposed to the main agent. ThemcpServersare only loaded if the CLI is started directly inside the project directory (e.g.cd ~/projects/foo && freebuff).Environment
freebuffnpm package0.0.142(native binary at~/.config/manicode/freebuff)Steps to reproduce
Create a project with an
.agents/mcp.jsoncontaining one or more MCP servers, e.g.:{ "mcpServers": { "context7": { "type": "http", "url": "https://mcp.context7.com/mcp", "headers": { "Authorization": "Bearer $CONTEXT7_API_KEY" } }, "chrome-devtools": { "command": "npx", "args": ["-y", "chrome-devtools-mcp@latest", "--headless", "--isolated"] } } }Start the CLI from a directory above the project (e.g.
cd ~ && freebuff).In the project picker, select the project.
Ask the main agent which tools it has available.
Result: the MCP tools (
context7__*,chrome-devtools__*) are not present.cd ~/projects/<project> && freebuff(no project picker).Result: the MCP tools are present.
Expected behavior
MCP servers from the selected project's
.agents/mcp.jsonshould be available to the main agent regardless of which directory the CLI was launched from.Actual behavior
MCP servers are only available when the CLI is launched inside the project directory. Selecting the project afterwards via the picker never exposes them.
Root cause analysis
The MCP config is loaded once, at boot time, using the then-current
process.cwd():cli/src/index.tsx(~line 260):await initializeAgentRegistry()runs during startup. This callsloadMCPConfigSync({ verbose: false })(sdk/src/agents/load-mcp-config.ts), which resolves{cwd}/.agents/mcp.jsonagainstprocess.cwd()and populates a module-levelmcpServersCache.cli/src/index.tsx(~line 347): only later, when the user picks a project, does the CLI callprocess.chdir(newProjectPath)followed byresetCodebuffClient().resetCodebuffClient()recreates the client but never reloadsmcp.json— themcpServersCachemodule variable was already populated (with an empty/absent config) at boot.The merge itself is correct and does run afterwards:
cli/src/utils/local-agent-registry.tsmergesmcpServersCacheinto every agent definition whoseid.startsWith('base')(the Freebuff root agentbase2-free-deepseek-flashqualifies):(Confirmed in the installed binary's minified JS:
if(Object.keys(VW).length>0){for(let D of A)if(D.id.startsWith("base")){if(!D.mcpServers)D.mcpServers={};D.mcpServers={...D.mcpServers,...VW}}}.)Because the cache was populated at boot from the wrong cwd, the merge operates on an empty cache → the main agent template ends up with
mcpServersmissing/null.Evidence
Session state (
run-state.json) for the same chat, comparing both launch modes:mcpServersfreebufffrom~, project picked via pickernullcd ~/projects/mathema && freebuff{ "context7": …, "chrome-devtools": … }The agent's registered
toolNames(from the session log) match:context7__resolve-library-id,context7__query-docs, and 29chrome-devtools__*tools appear only in the second mode.Suggested fixes
process.chdir(newProjectPath)in the project-picker path, re-run the MCP config load (or invalidate/re-populatemcpServersCacheand re-runloadAgentDefinitions()/initializeAgentRegistry()).mcp.jsonfrom an explicit project root — instead ofprocess.cwd(), pass the resolved project path toloadMCPConfigSyncso it is independent of launch directory andchdirtiming.Workaround
Always launch the CLI from inside the project directory:
Affected files (approx., from
main)cli/src/index.tsx— boot order:initializeAgentRegistry()beforeprocess.chdir()/resetCodebuffClient()in the project picker pathcli/src/utils/local-agent-registry.ts— the merge ofmcpServersCacheintobase*agent definitionssdk/src/agents/load-mcp-config.ts—loadMCPConfigSyncresolves config fromprocess.cwd()