|
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. |
|---|
|
|
| navi/mcp/client.py |
|---|
| tests/unit/test_mcp.py |
|---|