PostgreSQL Explorer MCP Server
A FastMCP server for read-only introspection of PostgreSQL databases, providing tools to list databases, schemas, tables, columns, and relations.
README
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 auv.lock)
Dependencies (pyproject.toml): fastmcp>=3.4.7, mlflow>=3.15.1, psycopg2 + psycopg2-binary,
python-dotenv.
uv sync
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.pycallsclient.call_tool("greet", ...), but the tool insrc/simple_server.pyis registered under the nameGreeting(greetis 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
- Start MLflow on port 5000.
- Start the PostgreSQL MCP server on port 8000.
- Verify it answers:
uv run python clients/postgres_server_client.py. - Register it: uncomment
register_postgresql_mcp_server()and run the util. - Discover its tools: switch to
discover_tools()and run again — the six tools above should print. - Inspect its access endpoint: switch to
list_endpoints(). - 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.
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.