Summary
The MCP server cannot start unless the database is reachable at launch. If the DB is temporarily unreachable — e.g. it sits behind an SSH tunnel / port-forward that is opened on demand — the server process exits before the stdio transport comes up. The MCP client only sees Connection closed, with no way to recover other than a manual reconnect/restart once the DB becomes reachable.
This is a chicken-and-egg problem for tunnel-based setups: the server needs the DB to start, but the operator typically opens the tunnel after the client (and thus the server) is already running.
Root cause
In src/server.py:
run_async_server() calls await self.initialize_pool() before self.mcp.run_async(...). When the DB is unreachable the connect raises, the exception propagates, and the process exits before the transport is ever started.
register_tools() raises RuntimeError("Database pool must be initialized before registering tools.") if self.pool is None, so tools cannot be registered without a live pool either.
_execute_query() raises RuntimeError("Database connection pool not available.") if self.pool is None, with no attempt to (re)establish it.
Net effect: a DB that is reachable a few seconds after startup never gets used — the server is already gone.
Steps to reproduce
- Configure the server to point at a DB host/port that is not currently listening (simulating a tunnel that isn't up yet).
- Start the server over stdio and drive the MCP
initialize handshake.
Expected: the server starts, registers its tools, and reports a clear error on a query if the DB is still unreachable — then works as soon as the DB becomes reachable.
Actual: the process exits during startup; the client reports Connection closed.
Expected behavior
- Server startup should not depend on a live database connection.
- Tools should register regardless of DB state.
- The connection pool should be established lazily on first use (and rebuilt after a connection-level failure), with a clear, actionable error when the DB is still unreachable.
A fix is proposed in #57.
Summary
The MCP server cannot start unless the database is reachable at launch. If the DB is temporarily unreachable — e.g. it sits behind an SSH tunnel / port-forward that is opened on demand — the server process exits before the stdio transport comes up. The MCP client only sees
Connection closed, with no way to recover other than a manual reconnect/restart once the DB becomes reachable.This is a chicken-and-egg problem for tunnel-based setups: the server needs the DB to start, but the operator typically opens the tunnel after the client (and thus the server) is already running.
Root cause
In
src/server.py:run_async_server()callsawait self.initialize_pool()beforeself.mcp.run_async(...). When the DB is unreachable the connect raises, the exception propagates, and the process exits before the transport is ever started.register_tools()raisesRuntimeError("Database pool must be initialized before registering tools.")ifself.pool is None, so tools cannot be registered without a live pool either._execute_query()raisesRuntimeError("Database connection pool not available.")ifself.pool is None, with no attempt to (re)establish it.Net effect: a DB that is reachable a few seconds after startup never gets used — the server is already gone.
Steps to reproduce
initializehandshake.Expected: the server starts, registers its tools, and reports a clear error on a query if the DB is still unreachable — then works as soon as the DB becomes reachable.
Actual: the process exits during startup; the client reports
Connection closed.Expected behavior
A fix is proposed in #57.