P2-T8: Gate broker tools/list on warmed tool catalog#165
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 62a7df7349
ℹ️ About Codex in GitHub
Your team has set up Codex to 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 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
Pull request overview
This PR fixes a broker cold-start race where strict MCP clients can cache an early, incomplete tools/list response before the broker finishes its internal warm-up, leading to partially discovered tools until users reconnect/restart.
Changes:
- Add a dedicated
tools_catalog_readyreadiness gate so externaltools/listwaits for a warmed, non-empty cached catalog (while other methods remain gated only on upstream initialization). - Add retry behavior for the broker-internal
tools/listwarm-up probe when results are empty/invalid, allowing recovery without reconnect/restart. - Update unit/integration tests and pytest configuration (
pythonpath = ["src"]) to validate the new contract and ensure local checkout imports.
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
src/mcpbridge_wrapper/broker/transport.py |
Gate client tools/list on tools_catalog_ready, preserving previous gating for other methods. |
src/mcpbridge_wrapper/broker/daemon.py |
Introduce tools_catalog_ready, cache validation (non-empty tools), and warm-up probe retry scheduling/cancellation. |
tests/unit/test_broker_transport.py |
Add coverage for tools/list gating/TTL behavior and adjust existing cache-hit/miss tests for the new gate. |
tests/unit/test_broker_daemon.py |
Add/extend coverage for catalog readiness, empty/invalid probe handling, retry behavior, and reconnect clearing. |
tests/integration/test_broker_multi_client.py |
Adjust concurrent-load test to use a forwarded method (tools/call) rather than the now-special-cased cached tools/list path. |
pyproject.toml |
Configure pytest to prefer checkout-local src on sys.path. |
SPECS/Workplan.md |
Record P2-T8 completion and acceptance criteria. |
SPECS/INPROGRESS/next.md |
Update “next task” status and archive note. |
SPECS/ARCHIVE/INDEX.md |
Add P2-T8 to the archive index and update “Last Updated”. |
SPECS/ARCHIVE/_Historical/REVIEW_p2_t8_tools_catalog_gate.md |
Add historical review report artifact. |
SPECS/ARCHIVE/P2-T8_Gate_broker_tools_list_on_warmed_tool_catalog/P2-T8_Validation_Report.md |
Add validation report artifact. |
SPECS/ARCHIVE/P2-T8_Gate_broker_tools_list_on_warmed_tool_catalog/P2-T8_Gate_broker_tools_list_on_warmed_tool_catalog.md |
Archive the task spec describing the race and fix. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Description
Fixes the broker startup race behind the repeated Cursor/Zed ON/OFF workaround.
Root cause: the broker exposed client
tools/listas soon as upstreaminitializecompleted, but strict MCP clients can cache that first successful response before the broker has finished its ownnotifications/initialized+tools/listwarm-up. On cold start that could leak an empty or invalid catalog and leave Xcode tools partially discovered.This PR:
tools_catalog_readygate so externaltools/listwaits for a warmed non-empty cache;tools/listwarm-up probe after empty/invalid results so the catalog can recover without reconnect/restart;tools/listbroker traffic gated only on upstream initialization;pytestprefer the checkout-localsrcpath so worktree validation does not accidentally import a sibling editable install.Validation artifacts:
SPECS/ARCHIVE/P2-T8_Gate_broker_tools_list_on_warmed_tool_catalog/P2-T8_Validation_Report.mdSPECS/ARCHIVE/_Historical/REVIEW_p2_t8_tools_catalog_gate.mdpytest,ruff check src/,mypy src/,pytest --covType of Change
Quality Gates
Before submitting, ensure all quality gates pass:
Or run individually:
make test- All tests pass with ≥90% coveragemake lint- No linting errorsmake format- Code is properly formattedmake typecheck- Type checking passesmake doccheck- Documentation is synced with DocC (if docs changed)Documentation Sync
If you modified files in
docs/, ensure corresponding DocC files are also updated:docs/installation.mdmcpbridge-wrapper.docc/Installation.mddocs/cursor-setup.mdmcpbridge-wrapper.docc/CursorSetup.mddocs/claude-setup.mdmcpbridge-wrapper.docc/ClaudeCodeSetup.mddocs/codex-setup.mdmcpbridge-wrapper.docc/CodexCLISetup.mddocs/troubleshooting.mdmcpbridge-wrapper.docc/Troubleshooting.mddocs/architecture.mdmcpbridge-wrapper.docc/Architecture.mddocs/environment-variables.mdmcpbridge-wrapper.docc/EnvironmentVariables.mdREADME.mdmcpbridge-wrapper.docc/mcpbridge-wrapper.mdTesting
Checklist