Using an LLM to inspect a database

Following on the heels of @rubys’s post about a filesystem MCP server, I wanted to have a go at running a Postgres MCP server. This would enable me to ask questions of an LLM about a Postgres database.

Credit for this idea goes fully to @jphenow!

For this, I’m going to be using the sample database that Neon makes available. But you can hook this up to any database. The Postgres MCP server we’re using provides read-only access to the database, so it won’t be able to seriously ruin anything, although obviously if you’ve got triggers setup to track reads or anything like that, then the queries made by the LLM will have some discernible impact.

Creating the database and MCP server app

I’m not going to belabour the details of the database itself, so I’ll just say that I have a Postgres connection URI for a database preloaded with the data from the Neon dump.

Locally, I created a db-inspection directory, and then added the following contents to a Dockerfile within:

FROM node:slim
COPY --from=flyio/flyctl flyctl /usr/bin
EXPOSE 8080
# Not using array syntax here so that the env var is expanded.
CMD /usr/bin/flyctl mcp wrap --mcp=npx -- -f @modelcontextprotocol/server-postgres "$DATABASE_URL"

In order to run this, we need to set a DATABASE_URL secret, but we can’t do that until we’ve created an app, so fly launch --no-deploy to do that, and create a fly.toml in the process.

I’ll run fly secrets set -c fly.toml 'DATABASE_URL=postgres://...', with my aforementioned Postgres URI.

Now I can fly deploy to start the MCP server.

MCP Configuration

All that’s left to do is add the following to our Claude Desktop config:

{
  "mcpServers": {
    "postgres": {
      // Replace with path to `flyctl` on your computer
      "command": "/opt/homebrew/bin/fly",
      "args": [
        "mcp",
        "proxy",
        // Replace with your own app's URL
        "--url=https://db-inspection.fly.dev"
      ]
    }
  }
}

Then we can restart Claude Desktop and it should establish communication with the MCP server.

Here’s a screenshot of the two questions I asked it, which definitely weren’t trivial! It didn’t seem to quite understand my second question, but it landed on an interpretation of my phrasing that was still pretty interesting.

Here’s a link to the shared convo: https://claude.ai/share/292c9400-a4fe-40b1-9c75-9a544c076b47.

5 Likes