Skip to main content
Glama
pavanjava

PostgreSQL Explorer MCP Server

by pavanjava

mcp-registry

A small, end-to-end walkthrough of the MLflow MCP Server Registry: build MCP servers with FastMCP, call them with a FastMCP client, then register them in MLflow so they are discoverable — with versions, access endpoints, and auto-discovered tools.

The repo has three moving parts:

Part

Path

What it does

MCP servers

src/

Two FastMCP servers — a toy greeting server and a real PostgreSQL explorer

MCP clients

clients/

Thin FastMCP clients that invoke tools over streamable HTTP

Registry utility

mlflow_mcp_registry_util.py

Registers servers with MLflow, refreshes their tools, lists access endpoints


Requirements

  • Python ≥ 3.13

  • An MLflow tracking server (v3.15+) running locally — the registry APIs are server-side

  • PostgreSQL, if you want to exercise the PostgreSQL server

  • uv (the repo ships a uv.lock)

Dependencies (pyproject.toml): fastmcp>=3.4.7, mlflow>=3.15.1, psycopg2 + psycopg2-binary, python-dotenv.

uv sync

Related MCP server: postgres-mcp-readonly

Configuration

The PostgreSQL server reads its connection settings from a .env file in the repo root (loaded via python-dotenv). .env is gitignored — create your own:

PGHOST=localhost
PGPORT=5432
PGUSER=root
PGPASSWORD=root
PGSSLMODE=prefer
PGADMINDB=postgres

Variable

Default

Purpose

PGHOST

localhost

Server host

PGPORT

5432

Server port

PGUSER

root

Login role

PGPASSWORD

root

Password

PGSSLMODE

prefer

libpq SSL mode

PGADMINDB

postgres

Database used for server-wide queries (ListDatabases)

src/simple_server.py needs no configuration.


1. Start an MLflow tracking server

mlflow_mcp_registry_util.py points at http://127.0.0.1:5000. The repo already contains a mlflow.db (gitignored) from a SQLite-backed run:

uv run mlflow server --backend-store-uri sqlite:///mlflow.db --host 127.0.0.1 --port 5000

If your server lives elsewhere, edit the mlflow.set_tracking_uri(...) call at the top of mlflow_mcp_registry_util.py.


2. Run an MCP server

Both servers bind port 8000 over streamable HTTP (http://localhost:8000/mcp), so run one at a time — or change the port in the mcp.run(...) call.

Simple greeting server — two tools, Greeting and Sendoff:

uv run python src/simple_server.py

PostgreSQL explorer — read-only introspection of a live PostgreSQL server:

uv run python src/postgresql_mcp.py

Or via the FastMCP CLI:

uv run fastmcp run src/postgresql_mcp.py --transport http --port 8000

PostgreSQL tools

Tool

Arguments

Returns

ListDatabases

Non-template databases with owner and pretty-printed size

ListSchemas

database

User-defined schemas (system schemas and temp schemas excluded)

ListTables

database, schema

Tables and views in the schema, with table_type

ListTableColumns

database, schema, table

Column name, type, nullability, default — in ordinal order

ListTableRelations

database, schema, table

Foreign keys split into outgoing (this table → others) and incoming (others → this table)

ListSchemaRelations

database, schema

Flat edge list from_table.from_column → to_table.to_column for the whole schema — an ERD in list form

Every tool goes through _query(), which opens a fresh connection to the named database, runs a single parameterised SELECT through a RealDictCursor, and closes the connection. Nothing writes.


3. Call a server from a client

With a server running on port 8000:

uv run python clients/postgres_server_client.py   # calls ListDatabases, prints each database name
uv run python clients/simple_server_client.py     # calls the greeting tool with "Ford"

clients/postgres_server_client.py unwraps the FastMCP result: each item in result.content carries a JSON text payload, which it parses and reads database from.

Note: clients/simple_server_client.py calls client.call_tool("greet", ...), but the tool in src/simple_server.py is registered under the name Greeting (greet is only the Python function name). Use "Greeting" for the call to resolve.


4. Register servers with MLflow

mlflow_mcp_registry_util.py holds four coroutines, each demonstrating one registry API:

register_postgresql_mcp_server()

Registers a remote server — one that is already running and reachable over HTTP:

mlflow.genai.register_mcp_server(
    server_json={
        "name": "io.github.pavanjava/postgresql-server",
        "version": "0.1.0",
        "description": "PostgreSQL FastMCP server exposing DB tools",
        "remotes": [{"url": "http://localhost:8000/mcp", "type": "streamable-http"}],
    },
    status="active",
    source="local dev server via fastmcp",
    create_access_endpoints_from_remotes=True,
)

create_access_endpoints_from_remotes=True turns each entry in remotes into an MLflow access endpoint, so consumers can resolve a connection URL from the registry instead of hardcoding it.

register_qdrant_mcp_server()

Registers a packaged server instead — no running process required. The entry describes how to launch it (uvx mcp-server-qdrant over stdio) and declares its environment variables, including which are required and which are secret (QDRANT_API_KEY).

discover_tools()

Calls refresh_mcp_server_version_tools(...). MLflow connects to the registered server version, enumerates its tools, and persists them on the version — after which server_version.tools lists the discovered tool names. This requires the server to actually be reachable.

list_endpoints()

Calls search_mcp_access_endpoints(server_name=...) and prints each endpoint's URL, transport type, and the server version it resolves to.

Running it

The __main__ block runs one coroutine at a time; the rest are commented out. Uncomment the one you want:

if __name__ == "__main__":
    # asyncio.run(register_postgresql_mcp_server())
    asyncio.run(register_qdrant_mcp_server())
    # asyncio.run(discover_tools())
    # asyncio.run(list_endpoints())
uv run python mlflow_mcp_registry_util.py

Registered servers then show up under the MCP Servers section of the MLflow UI at http://127.0.0.1:5000.


Suggested end-to-end path

  1. Start MLflow on port 5000.

  2. Start the PostgreSQL MCP server on port 8000.

  3. Verify it answers: uv run python clients/postgres_server_client.py.

  4. Register it: uncomment register_postgresql_mcp_server() and run the util.

  5. Discover its tools: switch to discover_tools() and run again — the six tools above should print.

  6. Inspect its access endpoint: switch to list_endpoints().

  7. Browse the result in the MLflow UI.


Repository layout

.
├── src/
│   ├── simple_server.py        # FastMCP "My MCP Server" — Greeting + Sendoff tools
│   └── postgresql_mcp.py       # FastMCP "PostgreSQL Explorer" — 6 read-only introspection tools
├── clients/
│   ├── simple_server_client.py     # calls a tool on the greeting server
│   └── postgres_server_client.py   # calls ListDatabases and prints database names
├── mlflow_mcp_registry_util.py # MLflow MCP registry: register / refresh tools / list endpoints
├── pyproject.toml
└── uv.lock

mlflow.db, .env, .venv, and .idea are gitignored.

F
license - not found
-
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    -
    quality
    D
    maintenance
    An open-source MCP server for PostgreSQL schema introspection and guarded read-only queries. It enables MCP clients to discover schemas, tables, columns, indexes, relationships, and safe queryable data from a configured PostgreSQL database.
    13
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    MCP server for PostgreSQL that enables safe read-only database queries, table schema inspection, and query execution planning.
    6
    34
    BSD 3-Clause

View all related MCP servers

Related MCP Connectors

  • MCP server for managing Prisma Postgres.

  • MCP server for interacting with the Supabase platform

  • A basic MCP server to operate on the Postman API.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/pavanjava/mcp_course'

If you have feedback or need assistance with the MCP directory API, please join our Discord server