Summary
A failed streamable HTTP MCP connection can terminate the entire Raven gateway when the MCP SDK/anyio surfaces a bare asyncio.CancelledError.
connect_mcp_servers() currently catches (Exception, BaseExceptionGroup), but asyncio.CancelledError directly inherits from BaseException. It is therefore not caught by this handler and can escape the per-server connection boundary, terminating the gateway instead of logging a failed MCP connection and continuing startup.
In my case, the failure was triggered by an MCP server receiving no valid runtime authentication. After ensuring the Authorization header was available to the gateway process, the same server connected successfully and registered 25 tools. This fixes the local trigger, but does not address the uncaught-cancellation behavior.
Steps to reproduce
- Configure a streamable HTTP MCP server in Raven.
- Start Raven with invalid, missing, or otherwise rejected authentication for that MCP endpoint.
- Let the server/SDK cancel the streamable HTTP request during MCP initialization.
- Observe that a bare
asyncio.exceptions.CancelledError can escape connect_mcp_servers() and terminate the entire gateway.
Relevant connection code currently uses:
except (Exception, BaseExceptionGroup) as e:
logger.error("MCP server '{}': failed to connect: {}", name, e)
A bare asyncio.CancelledError is neither an Exception nor a BaseExceptionGroup.
Expected behavior
A single MCP server failing to connect should not terminate the Raven gateway.
Raven should:
- log the failed MCP server name;
- preserve useful context about the underlying transport/HTTP failure where possible;
- skip that MCP server and continue starting the gateway.
External cancellation of the gateway/task should still propagate normally.
Actual behavior
The gateway terminated with a bare cancellation error similar to:
asyncio.exceptions.CancelledError: Cancelled via cancel scope ...
The original HTTP failure/status was not logged, so the underlying authentication rejection was not visible in the gateway log.
After valid runtime authentication was supplied, the MCP connection succeeded:
MCP server 'tanka': connected, 25 tools registered
Environment
- OS: macOS arm64
- Python: 3.12.13
- Raven CLI: v0.1.3
- MCP SDK: 1.28.1
- httpx: 0.28.1
- anyio: 4.14.2
- MCP transport: streamable HTTP
Logs or screenshots
Please redact all credentials.
Failure:
asyncio.exceptions.CancelledError: Cancelled via cancel scope ...
Successful connection after valid runtime authentication:
MCP server 'tanka': connected, 25 tools registered
Summary
A failed streamable HTTP MCP connection can terminate the entire Raven gateway when the MCP SDK/anyio surfaces a bare
asyncio.CancelledError.connect_mcp_servers()currently catches(Exception, BaseExceptionGroup), butasyncio.CancelledErrordirectly inherits fromBaseException. It is therefore not caught by this handler and can escape the per-server connection boundary, terminating the gateway instead of logging a failed MCP connection and continuing startup.In my case, the failure was triggered by an MCP server receiving no valid runtime authentication. After ensuring the Authorization header was available to the gateway process, the same server connected successfully and registered 25 tools. This fixes the local trigger, but does not address the uncaught-cancellation behavior.
Steps to reproduce
asyncio.exceptions.CancelledErrorcan escapeconnect_mcp_servers()and terminate the entire gateway.Relevant connection code currently uses:
A bare
asyncio.CancelledErroris neither anExceptionnor aBaseExceptionGroup.Expected behavior
A single MCP server failing to connect should not terminate the Raven gateway.
Raven should:
External cancellation of the gateway/task should still propagate normally.
Actual behavior
The gateway terminated with a bare cancellation error similar to:
The original HTTP failure/status was not logged, so the underlying authentication rejection was not visible in the gateway log.
After valid runtime authentication was supplied, the MCP connection succeeded:
Environment
Logs or screenshots
Please redact all credentials.
Failure:
Successful connection after valid runtime authentication: