fix(mcp): drop cleaned-up servers from active_servers when keeping failed servers - #4610
fix(mcp): drop cleaned-up servers from active_servers when keeping failed servers#4610AAliKKhan wants to merge 2 commits into
Conversation
…iled servers cleanup_all() advertised cleaned-up servers as active whenever drop_failed_servers=False, because _refresh_active_servers() returned all servers unconditionally. Derive the post-cleanup active list from the connected set instead: that flag governs connect-phase failures only, and this completes the contract stated in openai#4586.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ccf5738718
ℹ️ 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".
| # server may remain advertised as active regardless of `drop_failed_servers`: | ||
| # that flag only governs whether connect-phase failures stay listed. |
There was a problem hiding this comment.
Update the public flag contract to match cleanup behavior
When drop_failed_servers=False, this new cleanup branch makes active_servers empty, but the public MCPServerManager docstring still promises that active_servers “will still include all servers” when the flag is false. That documentation is now misleading for callers inspecting the class contract after cleanup_all(); qualify the flag description as connect-phase behavior and document the post-cleanup result.
Useful? React with 👍 / 👎.
|
Thanks for the follow-up. I confirmed the state difference after cleanup, but this is not an uncovered part of #4586. That PR was scoped to the default Changing only the cleanup path would make the flag phase-dependent and duplicate active-list derivation outside I am going to close this PR. If there is a concrete use case that requires failed servers to remain visible after connection attempts but cleaned servers to disappear after cleanup, we can revisit that contract explicitly. |
Summary
MCPServerManager.cleanup_all()(and thereforeasync withexit) leaves cleaned-up servers listed inactive_serverswheneverdrop_failed_servers=False. This completes the post-cleanup contract established by #4586 for the non-default flag path.Problem
Repro on current
main:Callers following the documented pattern (
agent.mcp_servers = manager.active_servers, including after cleanup within a lifespan) observe stale state: every server remains "active" even though the manager no longer owns any live connection.Root cause
_cleanup_all()refreshesactive_serversvia_refresh_active_servers()in its guaranteedfinally. Withdrop_failed_servers=Truethat derives the list from the connected set (emptying it), but theelsebranch returns all servers unconditionally - so the disconnect performed by_cleanup_server()(which always discards from_connected_servers) is never reflected.Solution
Derive the post-cleanup active list from
_connected_serversdirectly in_cleanup_all()'sfinally. Behavior is unchanged fordrop_failed_servers=True; forFalse, that flag continues to govern only connect-phase failures (the_connect_all()failure path is untouched), while servers whose lifecycle the manager has torn down are no longer advertised as active.This matches #4586's stated intent ("consistently derives the active list from the canonical connected-server set") and the class docstring's guarantee that
active_serversreflects successfully connected servers after connection attempts and cleanup.Test plan
drop_failed_servers=False,cleanup_all()emptiesactive_serversand_connected_serversdrop_failed_servers=Falsecoverageruff format/check,mypy src/agents, andpyrightall clean