fix(brainstormer): isolate the SDK session from the operator's global MCP config#448
Merged
Merged
Conversation
… MCP config
The brainstormer never passed strict_mcp_config / mcp_servers /
load_timeout_ms to its SDK session, so the session enumerated every MCP
server in the operator's global Claude config — plus any servers the
TARGET repo's .claude config registers (which may need live backends) —
and died on "Control request timeout: initialize" before producing a
report. The worker path has defended against exactly this since the
early dogfood runs (see settings.WorkerSettings); the brainstormer was
left out.
The brainstormer needs ZERO MCP servers: the backlog scan happens
in-process before the session starts, and the session itself only reads
the repo and emits the JSON report. Default the Brainstormer dataclass
to strict isolation (strict_mcp_config=True, mcp_servers={},
load_timeout_ms=180000), pass the knobs through run() → sdk_fn, and
absorb them in the codex backend (no MCP handshake there).
Repro: `forge-loop brainstorm` on a repo whose .claude registers an
MCP server backed by a non-running service — times out at init 100%.
Note: tests/test_critic_sdk.py has 5 pre-existing failures on trunk
(verified on a clean origin/trunk worktree); untouched by this diff.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bug
forge-loop brainstormhung at SDK-session init ("Control request timeout: initialize") on any box where the operator's global Claude config registers MCP servers — or where the target repo's.claudeconfig registers servers needing live backends (hit 100% on getadaptiq, whoseadaptiq-tutorMCP needs the backend running).Root cause
Brainstormer.run()called the SDK shim with onlycwd/timeout_s/model. The MCP-isolation knobs the worker path has used since the early dogfood runs (strict_mcp_config,mcp_servers,load_timeout_ms— seesettings.WorkerSettings) were never plumbed through the brainstormer, so its session enumerated the full global MCP config at init.Fix
The brainstormer needs zero MCP servers — the backlog scan happens in-process before the session, and the session only reads the repo + emits the JSON report. So:
Brainstormerdataclass defaults:strict_mcp_config=True,mcp_servers={},load_timeout_ms=180000(mirrors worker defaults).run()passes the knobs tosdk_fn.codex exec).Tests
test_sdk_session_is_mcp_isolated_by_default(fails on trunk, passes here).tests/test_brainstormer.py: 44 passed.tests/test_cli_brainstorm.py+ SDK suites: green.tests/test_critic_sdk.pyhas 5 pre-existing failures on trunk — verified identical on a cleanorigin/trunkworktree; untouched by this diff.forge-loop brainstormon getadaptiq (previously 100% init-timeout) — verification run in progress on the operator box.🤖 Generated with Claude Code