Async MCP startup leaves Desktop tasks with an incomplete tool list despite tools/list_changed
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 125k
- Forks
- 19.4k
- PR merge metrics
- PR metrics pending
Description
Codex Desktop keeps an incomplete initial MCP tool list when an aggregator connects its backends asynchronously. Tools from later connections never become callable in the task.
This reproduces the notification issue in #37417, #35583 and #33266 during ordinary startup, without enabling any new integration at runtime.
Environment
- macOS 26.6.2
- Desktop app 26.901.51231, build 8109
- Bundled
codex-cli 0.153.4 - MCP transport: stdio
- MCP server: mcpfuse, aggregating multiple backends
Reproduction
- Start a Codex task with an MCP aggregator that connects backends concurrently.
- Return the currently available tools on the first
tools/list, while some backends are still connecting. - When another backend becomes ready, emit
notifications/tools/list_changed. Subsequenttools/listrequests return its tools. - Ask Codex to use one of the newly available tools, including in a later turn.
Expected: Codex refetches the list and makes the new tools callable.
Actual: no further tools/list request appears in the server log. The task keeps the initial catalog across turns. Restarting the affected backend through the aggregator does not refresh Codex's catalog either.
Observed startup
Times relative to the first tools/list request:
- +3.011 s: the aggregator starts collecting tools after its initial wait; one affected backend is not connected yet.
- +3.922 s: that backend connects successfully.
- +6.279 s: the initial response returns 57 tools, excluding that backend.
- Several minutes later: the aggregator's status tool reports all 12 backends connected and 96 tools available from the affected backend. Codex still cannot discover or call them.
The server log contains only the initial tools/list request for this session.
Independent protocol check
I tested the same installed aggregator binary with a separate JSON-RPC client. It advertises capabilities.tools.listChanged: true.
With the initial wait set to zero in an isolated diagnostic configuration:
- The first list lacks the target tool.
- The client receives
notifications/tools/list_changedafter backends connect. - A subsequent list returns 240 tools, including all 96 from the affected backend and the target tool.
No backend credentials, private URLs or raw session logs are included here.
Please handle tool-list notifications by invalidating and refetching the affected server's catalog, including when a notification arrives while the first discovery request is still in flight. Otherwise asynchronous MCP startup silently leaves the task with an incomplete toolset.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by tracing MCP tools/list discovery and notifications/tools/list_changed handling in the MCP client entry points; no file or test path is named in the issue. Reproduce with an asynchronous aggregator, then verify that a notification during the initial request refreshes the catalog so later turns can call newly available tools.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 56/100