Skip to content

Server exits at startup when the database is unreachable; stdio client only sees "Connection closed" and can't recover #58

Description

@mwm-pw

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:

  1. 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.
  2. 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.
  3. _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

  1. Configure the server to point at a DB host/port that is not currently listening (simulating a tunnel that isn't up yet).
  2. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions