
Read-only PostgreSQL MCP server for AI assistants, with safe query tools and multi-environment
Read-only PostgreSQL MCP server for AI assistants, with safe query tools and multi-environment connection support
A Model Context Protocol (MCP) server for read-only PostgreSQL access over stdio.
SELECT/WITH queries, EXPLAIN plansINSERT/UPDATE/DELETE/MERGE/DROP/CREATE/ALTER/TRUNCATE and multi-statement payloads)READ ONLY + statement/lock/idle timeouts + hard row caps + streamed batched fetchespublic)uv for project managementuv sync| Variable | Purpose |
|---|---|
DATABASE_URL | Default connection string |
DATABASE_URL_<ENV> | Per-environment connection (e.g. DATABASE_URL_LOCAL, DATABASE_URL_STAGING, DATABASE_URL_PRODUCTION) |
DATABASE_TARGET_ENV | Selects active environment (aliases: DATABASE_ENV, DB_ENV; values like dev/prod/stage normalize to local/production/staging) |
Every MCP tool also accepts an environment argument to override per-call without restarting the server.
| Variable | Default | Purpose |
|---|---|---|
DB_STATEMENT_TIMEOUT_MS | 60000 | Per-query timeout |
DB_LOCK_TIMEOUT_MS | 15000 | Lock acquisition timeout |
DB_IDLE_IN_TRANSACTION_TIMEOUT_MS | 60000 | Kills idle-in-txn sessions |
DB_MAX_ROWS | 10000 | Hard row cap (truncation flagged in response) |
DB_FETCHMANY_SIZE | 1000 | Batch fetch size while streaming |
DB_POOL_SIZE | 5 | Connections per environment |
DB_MAX_OVERFLOW | 2 | Pool overflow |
DB_POOL_TIMEOUT | 30 | Pool wait timeout (s) |
DB_POOL_RECYCLE | 1800 | Recycle connections after (s) |
DB_ALLOWED_SCHEMAS | public | Comma-separated schemas exposed to tools |
| Tool | Purpose |
|---|---|
health_check | Database + server connectivity check |
database_query | Run a read-only SQL query (SELECT/WITH); supports max_rows, offset, statement_timeout_ms, environment |
explain_query | EXPLAIN [ANALYZE] for a query, JSON plan |
list_tables | Tables in the chosen schema |
get_table_schema | Columns + primary keys for one table |
get_all_schemas | Bulk dump: columns + primary keys (2 queries total) and optional sample_data |
database_query response shape:
{
"status": "success",
"results": [...],
"count": 42,
"truncated": false,
"offset": 0,
"max_rows": 10000,
"statement_timeout_ms": 60000,
"environment": "default"
}Cursor reads MCP config from .cursor/mcp.json (project) or ~/.cursor/mcp.json (global).
{
"mcpServers": {
"database-reader": {
"command": "uv",
"args": ["--directory", "${workspaceFolder}", "run", "database_read.py"],
"env": {
"DATABASE_TARGET_ENV": "local",
"DATABASE_URL_LOCAL": "${env:DATABASE_URL_LOCAL}",
"DATABASE_URL_STAGING": "${env:DATABASE_URL_STAGING}",
"DATABASE_URL_PRODUCTION": "${env:DATABASE_URL_PRODUCTION}"
}
}
}
}Config path: ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %AppData%\Claude\claude_desktop_config.json (Windows). Use absolute paths.
{
"mcpServers": {
"database-reader": {
"command": "uv",
"args": ["--directory", "/ABSOLUTE/PATH/TO/mcp-prototype", "run", "database_read.py"],
"env": {
"DATABASE_TARGET_ENV": "local",
"DATABASE_URL_LOCAL": "postgresql://user:password@localhost:5432/db_name"
}
}
}
}codex mcp add database-reader \
--env DATABASE_TARGET_ENV=local \
--env DATABASE_URL_LOCAL='postgresql://user:password@localhost:5432/db_name' \
-- uv --directory /ABSOLUTE/PATH/TO/mcp-prototype run database_read.pyOr ~/.codex/config.toml:
[mcp_servers.database-reader]
command = "uv"
args = ["--directory", "/ABSOLUTE/PATH/TO/mcp-prototype", "run", "database_read.py"]
[mcp_servers.database-reader.env]
DATABASE_TARGET_ENV = "local"
DATABASE_URL_LOCAL = "postgresql://user:password@localhost:5432/db_name"Any stdio MCP client accepts the same fields: command = "uv", args = ["--directory", "<repo>", "run", "database_read.py"], plus env entries for connection URLs.
{
"name": "database_query",
"arguments": {
"query": "SELECT * FROM users LIMIT 5",
"environment": "staging"
}
}The server keeps a separate connection pool per environment, so switching does not require a restart.
The MCP enforces read-only at the application layer (parse-time validator, SET TRANSACTION READ ONLY, dangerous-function blacklist). The strongest fourth layer is a Postgres role with SELECT-only grants — the database itself refuses writes even if every line of Python were replaced. See docs/database-role-setup.md for the minimal setup, triage query examples, and the optional view-based pattern for redacting sensitive columns without changing MCP code.
See CLAUDE.md for the regression suite (unit + integration).
postgresql:// (not postgres://).Pick your client and paste the snippet. Each one is the same server, written the way that client expects it.
claude mcp add database-reader -- uv --directory ${workspaceFolder} run database_read.py{
"mcpServers": {
"database-reader": {
"env": {
"DATABASE_URL_LOCAL": "",
"DATABASE_TARGET_ENV": "",
"DATABASE_URL_STAGING": "",
"DATABASE_URL_PRODUCTION": ""
},
"args": [
"--directory",
"${workspaceFolder}",
"run",
"database_read.py"
],
"command": "uv"
}
}
}code --add-mcp '{"name":"database-reader","env":{"DATABASE_URL_LOCAL":"","DATABASE_TARGET_ENV":"","DATABASE_URL_STAGING":"","DATABASE_URL_PRODUCTION":""},"args":["--directory","${workspaceFolder}","run","database_read.py"],"command":"uv"}'[mcp_servers.database-reader]
command = "uv"
args = ["--directory", "${workspaceFolder}", "run", "database_read.py"]Runs locally on your device. Your client starts the server itself, so nothing has to be hosted.
Paste this prompt into your agent. It reads this page and does the setup for you.
Read https://aiagentslisting.com/mcp/database-read-mcp-server to learn what the "Database Read MCP Server" MCP server does and how to install it. Add it to my coding agent's MCP configuration as documented on that page, then confirm the server connects and list the tools it exposes.Agents can also browse this directory over MCP at https://aiagentslisting.com/api/mcp
This server runs locally, so we can't read its tool list over the web yet.
Maintain this server? Claiming proves you own the listing and earns the last 4 points.
Claim this listingPaste this line near the top of your repository's README. The badge always renders the current score.
[](https://aiagentslisting.com/mcp/database-read-mcp-server)Nothing comparable is listed yet.
No tagged releases on record.
Connect to the AI Agents Listing MCP server at https://aiagentslisting.com/api/mcp using the HTTP transport and complete the sign-in when it asks. Then call the submit_review tool for the listing "database-read-mcp-server" with a rating from 1 to 5 and a short note on what worked and what did not.No reviews yet
Be the first to share your experience with this tool.
One email a week. New agents, MCP servers and skills, and what is actually getting traction.