Skip to content

agentforge-ru/mcp-postgres-server

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

mcp-postgres-server

CI Python License: MIT MCP

A production-safe MCP server for PostgreSQL — lets Claude introspect your schema, run parameterized read queries, and (opt-in) perform writes, with safety guards against destructive operations.

Built on psycopg[binary] 3.x. Use it on a read-replica or a sanitized dev database first; never point it at unfiltered production without auditing the audit log.


🇷🇺 На русском

Кому это подойдёт:

  • У тебя PostgreSQL в production / staging и ты хочешь чтобы Claude/Cursor мог делать аналитику без переноса данных в чат
  • Ты dev-консультант и тебе нужен structured Postgres access для пары клиентов
  • Ты аналитик/dev на проекте — хочешь чтобы AI читал твою схему и предлагал SQL без guessing типов

Что внутри: Python-сервер на psycopg 3, авторизация через connection string (env var), безопасность (запрет DROP/TRUNCATE/ALTER по умолчанию + read-only режим default), готовый docker-compose с PostgreSQL 16 для теста, sample schema.

Заказать кастомную версию (под твою специфическую схему, дополнительные tools, RLS-aware queries, multi-tenant access): Kwork → agentforge_ru — от 4 500 ₽, сроки 2-4 дня.


What it does

Tool Purpose Default behavior
list_tables(schema) Lists tables in a schema (default: public) Always available
get_schema(table, schema) Returns columns, types, constraints, indexes for a table Always available
query(sql, params) Runs a SELECT/WITH query with parameter binding Always available
execute_write(sql, params) Runs INSERT/UPDATE/DELETE with parameter binding Off by default; enable with --allow-writes
database_stats(schema) Per-table row counts (estimate from pg_class.reltuples) Always available
explain_query(sql) Returns EXPLAIN ANALYZE for a SELECT Always available

Destructive operations (DROP, TRUNCATE, ALTER, GRANT, REVOKE) are blocked unless the server is started with --unsafe.

Installation

pip install git+https://github.com/agentforge-ru/mcp-postgres-server

Configuration

Set DATABASE_URL in your environment or via Claude Desktop's env block:

DATABASE_URL=postgresql://user:pass@localhost:5432/mydb

For read-only access (recommended), use a dedicated Postgres role:

CREATE USER claude_reader WITH PASSWORD 'strong-password';
GRANT CONNECT ON DATABASE mydb TO claude_reader;
GRANT USAGE ON SCHEMA public TO claude_reader;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO claude_reader;
ALTER DEFAULT PRIVILEGES IN SCHEMA public
    GRANT SELECT ON TABLES TO claude_reader;

Wiring into Claude Desktop

Add to claude_desktop_config.json:

{
  "mcpServers": {
    "postgres-readonly": {
      "command": "python",
      "args": ["-m", "mcp_postgres_server"],
      "env": {
        "DATABASE_URL": "postgresql://claude_reader:strong-password@localhost:5432/mydb"
      }
    }
  }
}

For read-write access (use a separate user with INSERT/UPDATE/DELETE grants):

{
  "mcpServers": {
    "postgres-readwrite": {
      "command": "python",
      "args": ["-m", "mcp_postgres_server", "--allow-writes"],
      "env": {
        "DATABASE_URL": "postgresql://claude_writer:strong-password@localhost:5432/mydb"
      }
    }
  }
}

Restart Claude Desktop. Tools appear in the model's context.

Usage examples (in Claude Desktop)

You: What's in the public schema?
Claude: [calls list_tables(schema="public")]
You have 12 tables: users, accounts, transactions, ...

You: Show me the schema of the transactions table.
Claude: [calls get_schema(table="transactions")]
- id BIGSERIAL PRIMARY KEY
- account_id BIGINT REFERENCES accounts(id) ON DELETE CASCADE
- amount NUMERIC(12,2) NOT NULL CHECK (amount > 0)
- created_at TIMESTAMPTZ DEFAULT now()
- INDEX idx_transactions_account_id ON (account_id)
- INDEX idx_transactions_created_at ON (created_at)

You: Top 10 accounts by total transaction volume last month?
Claude: [calls query with appropriate SQL]

Safety model

Blocked unless --unsafe:

  • DROP TABLE, DROP DATABASE, DROP SCHEMA, DROP INDEX, DROP VIEW, DROP TRIGGER, DROP FUNCTION
  • TRUNCATE TABLE
  • ALTER TABLE ... DROP
  • GRANT / REVOKE
  • CREATE EXTENSION (privilege escalation risk)

Recommended layering:

  1. Use a read-only Postgres role for the connection (defense at the database layer)
  2. Run with default flags (the destructive guard layer)
  3. Audit stderr output between sessions (the audit log layer)

Three layers; any one alone is not sufficient.

Architecture

[ Claude Desktop / Cursor / Claude Code ]
              ↓ MCP protocol (stdio)
        [ mcp-postgres-server ]
              ↓ psycopg 3 (binary build)
        [ PostgreSQL 12+ ]

Single connection per session. The server reuses one psycopg connection across all tool calls in the session. When the MCP client closes, the connection closes.

Limitations

  • Single-connection model. Long-running queries block other tool calls within the session. For production analytics where you need concurrency, fork and add pooling.
  • No transaction support exposed. Each execute_write is auto-committed. For multi-statement transactions, wrap them as a single SQL string (BEGIN; ...; COMMIT;).
  • No COPY / bulk-load tools. If you need to ingest CSVs, do it from your application code.
  • No notify/listen. Postgres LISTEN/NOTIFY would need a different transport.
  • Free-tier Postgres compatible but I haven't tested it against managed services (RDS, Supabase, Neon) — should work, but YMMV.

License

MIT — see LICENSE.

Author

Built by agentforge_ru — custom Claude Code subagents, MCP servers, and Telegram bots with AI logic.

Need a custom MCP server for your specific stack (MySQL? ClickHouse? MongoDB? Your internal API?) — open an issue or reach via Kwork.

About

MCP server for PostgreSQL — read/write tools with safety guards against destructive operations. psycopg 3, three-layer safety model.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages