Description
After the parallel refactor of `connect_oauth_deferred` in `crates/zeph-mcp/src/manager.rs`, the function no longer calls `self.log_tool_collisions` at the end of the drain-commit phase, while `connect_all` does (line ~753).
This means tools registered through the OAuth flow are never checked for `sanitized_id` collisions with tools registered in the earlier `connect_all` pass. A collision is silently accepted; dispatch goes to whichever tool was registered first.
Reproduction Steps
- Configure 2+ MCP servers where one is OAuth and one is non-OAuth
- Both servers expose a tool with the same sanitized ID
- Observe: no collision warning in logs, behavior is non-deterministic
Expected Behavior
`log_tool_collisions` is called after the OAuth tools are committed, matching the behavior of `connect_all`.
Actual Behavior
`log_tool_collisions` is never called from the OAuth path. Collision is silent.
Fix
Collect a flat tools vec in the `connect_oauth_deferred` drain loop (mirroring lines 718–730 of `connect_all`) and call `self.log_tool_collisions` before returning.
Environment
Description
After the parallel refactor of `connect_oauth_deferred` in `crates/zeph-mcp/src/manager.rs`, the function no longer calls `self.log_tool_collisions` at the end of the drain-commit phase, while `connect_all` does (line ~753).
This means tools registered through the OAuth flow are never checked for `sanitized_id` collisions with tools registered in the earlier `connect_all` pass. A collision is silently accepted; dispatch goes to whichever tool was registered first.
Reproduction Steps
Expected Behavior
`log_tool_collisions` is called after the OAuth tools are committed, matching the behavior of `connect_all`.
Actual Behavior
`log_tool_collisions` is never called from the OAuth path. Collision is silent.
Fix
Collect a flat tools vec in the `connect_oauth_deferred` drain loop (mirroring lines 718–730 of `connect_all`) and call `self.log_tool_collisions` before returning.
Environment