mcp: a dead MCP endpoint no longer kills server startup
A failed transport connect inside the MCP SDK's anyio cancel scopes
surfaces as CancelledError without any task.cancel(). The runner mistook
that for a real teardown, cancelled the in-flight caller's future, and
McpManager.load_all (which only catches Exception) let it blow up the
whole lifespan startup — one unreachable server in mcp_servers.d/ meant
a dead Navi.

The runner now distinguishes real task cancellation
(asyncio.current_task().cancelling()) from the anyio artifact: the
latter is surfaced to the caller as a normal connect failure, the
server pool marks it disconnected and the health-check loop retries.
Also, when the runner dies for any reason, pending queue commands are
failed instead of leaving _send callers hanging forever.
1 parent 33bc418 commit 5b594f7dbcf9ca6f0105cb7880c32e3b62cb39c9
@Eugene Sukhodolskiy Eugene Sukhodolskiy authored 19 hours ago
Showing 2 changed files
View
navi/mcp/client.py
View
tests/unit/test_mcp.py