AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
MCP verified MIT Self-run

Postgres Mcp Server

mcp-aldruin-postgres-mcp-server · by aldruin

MCP server from aldruin/postgres-mcp-server.

No reviews yet
0 installs
15 views
0.0% view→install

Install

$ agentstack add mcp-aldruin-postgres-mcp-server

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets Used
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/mcp-aldruin-postgres-mcp-server)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
4mo ago

Declared compatibility

Claude CodeClaude DesktopCursorWindsurf

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Postgres Mcp Server? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

postgres-mcp-server

Servidor MCP (Model Context Protocol) que expõe metadados (e amostras pequenas) de um banco PostgreSQL como tools para agentes de IA — Claude Code, Claude Desktop, Cursor, e qualquer cliente MCP que fale stdio.

A intenção é dar ao agente uma visão segura e somente-leitura do catálogo do banco: ele pode descobrir schemas, descrever tabelas/views, inspecionar FKs e indexes, e amostrar até 50 linhas — mas nunca executar SQL arbitrário.


Sumário

  • [Como funciona](#como-funciona)
  • [Tools expostas](#tools-expostas)
  • [Instalação](#instalação)
  • [1. Clonar e configurar](#1-clonar-e-configurar)
  • [2. Instalar dependências](#2-instalar-dependências)
  • [3. Registrar em um cliente MCP](#3-registrar-em-um-cliente-mcp)
  • [Claude Code](#claude-code)
  • [Claude Desktop](#claude-desktop)
  • [Cursor](#cursor)
  • [Outros clientes MCP](#outros-clientes-mcp)
  • [Fluxo típico de uso](#fluxo-típico-de-uso)
  • [Modelo de segurança](#modelo-de-segurança)
  • [Variáveis de ambiente](#variáveis-de-ambiente)
  • [Troubleshooting](#troubleshooting)
  • [Roadmap](#roadmap)

Como funciona

┌───────────────────┐    stdio (JSON-RPC)    ┌──────────────────┐    libpq/TCP    ┌────────────┐
│  Cliente MCP      │ ─────────────────────► │ postgres-mcp-    │ ──────────────► │ PostgreSQL │
│  (Claude Code,    │ ◄───────────────────── │ server (Python)  │ ◄────────────── │            │
│   Cursor, etc.)   │                        │                  │                 │            │
└───────────────────┘                        └──────────────────┘                 └────────────┘
  • Transport: stdio. O cliente MCP inicia o processo server.py como subprocesso e fala com ele por stdin/stdout. Não há servidor HTTP, nem porta aberta, nem rede. Outro processo (ou outra máquina) não tem como falar com este servidor.
  • Autenticação: nenhuma — por design. Como o transport é stdio local, o "autenticador" é o próprio sistema operacional: só processos do seu usuário conseguem iniciar o servidor. Quem tem acesso ao seu shell já tem acesso ao seu banco; o MCP server não adiciona nem remove superfície.
  • Credenciais do banco: lidas de um .env ao lado de server.py. Use um usuário read-only (ver [Modelo de segurança](#modelo-de-segurança)).
  • Linguagem: Python ≥3.10. Dependências principais: mcp, psycopg, python-dotenv, pydantic.

Tools expostas

Descoberta

| Tool | O que faz | |---|---| | list_schemas | Lista os schemas do banco com contagem de tabelas, views e sequences. Ponto de partida quando não souber em qual schema os objetos estão. | | list_schema_objects | Lista tabelas e views de um schema, com filtro opcional por padrão LIKE (ex.: view_%, %log%). |

Detalhamento

| Tool | O que faz | |---|---| | describe_table | Colunas + estimativa de linhas + tamanho em disco de uma tabela base. | | describe_view | Colunas + (para MV) tamanho de uma view ou materialized view. | | get_view_definition | Retorna o SELECT (SQL) que define uma view/MV. Suporta max_lines para truncar saídas grandes. | | list_foreign_keys | Lista FKs de uma tabela com referência destino (schema.tabela.coluna) e regras ON UPDATE/DELETE. | | list_indexes | Lista indexes de uma tabela com tipo (btree/hash/gin/...) e definição. |

Dados (limitado)

| Tool | O que faz | |---|---| | sample_rows | Retorna até 50 linhas (cap rígido) de uma tabela/view, sem WHERE, com statement_timeout de 5s. Útil para inferir conteúdo. |

Todas as tools retornam dict (serializado em JSON pelo transport MCP automaticamente).


Instalação

1. Clonar e configurar

git clone  postgres_mcp_server
cd postgres_mcp_server
cp .env.example .env

Edite .env com host, porta, db, usuário e senha. Defina PG_DEFAULT_SCHEMA com o schema mais usado (ex.: public). Recomenda-se um usuário com GRANT SELECT apenas — veja [Modelo de segurança](#modelo-de-segurança).

2. Instalar dependências

Com uv (recomendado — resolve em segundos e cria .venv automaticamente):

uv sync

Ou com pip:

python -m venv .venv
# Windows:
.venv\Scripts\activate
# Linux/macOS:
source .venv/bin/activate
pip install -e .

Teste standalone:

uv run server.py
# ou: python server.py

O processo fica em foreground escutando MCP via stdio. Encerre com Ctrl+C. (Em uso normal você não roda assim — o cliente MCP cuida disso.)

3. Registrar em um cliente MCP

Substitua C:/caminho/para/postgres_mcp_server pelo caminho absoluto onde você clonou o repo.

Claude Code

Via CLI (recomendado — scope user deixa disponível em todos os seus projetos):

claude mcp add --scope user postgres -- uv --directory "C:/caminho/para/postgres_mcp_server" run server.py

Ou edite manualmente ~/.claude.json:

{
  "mcpServers": {
    "postgres": {
      "command": "uv",
      "args": [
        "--directory",
        "C:/caminho/para/postgres_mcp_server",
        "run",
        "server.py"
      ]
    }
  }
}

Reinicie a sessão e confirme com /mcp.

Claude Desktop

Edite claude_desktop_config.json:

  • Windows: %APPDATA%\Claude\claude_desktop_config.json
  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
{
  "mcpServers": {
    "postgres": {
      "command": "uv",
      "args": [
        "--directory",
        "C:/caminho/para/postgres_mcp_server",
        "run",
        "server.py"
      ]
    }
  }
}

Reinicie o Claude Desktop. O ícone do MCP aparece no rodapé da janela de chat.

Cursor

Edite ~/.cursor/mcp.json (ou via Settings → MCP):

{
  "mcpServers": {
    "postgres": {
      "command": "uv",
      "args": [
        "--directory",
        "C:/caminho/para/postgres_mcp_server",
        "run",
        "server.py"
      ]
    }
  }
}

Reinicie o Cursor. As tools aparecem no painel de Tools do chat.

Outros clientes MCP

Qualquer cliente que suporte MCP via stdio (Continue, Zed, Cline, etc.) funciona com a mesma assinatura — o que muda é onde fica o arquivo de config. O contrato é sempre:

{
  "command": "uv",
  "args": ["--directory", "", "run", "server.py"]
}

> Sem uv? Use "command": "python" e "args": ["C:/caminho/para/postgres_mcp_server/server.py"]. Garanta que o python do PATH é o do venv com as deps instaladas.


Fluxo típico de uso

  1. list_schemas → descobre os schemas do banco (se necessário).
  2. list_schema_objects (com name_pattern opcional) → lista tabelas/views do schema escolhido.
  3. describe_table ou describe_view → detalha colunas, tipos, tamanho.
  4. Conforme necessidade, aprofunde:
  • get_view_definition → entender semântica de uma view (joins, filtros).
  • list_foreign_keys / list_indexes → entender relações e performance de uma tabela.
  • sample_rows → ver linhas reais quando nome/descrição não bastam.

Modelo de segurança

A segurança aqui é em camadas. Cada uma é independente — mesmo que uma falhe, as outras seguram.

Camada 1 — Transport (stdio local)

  • O servidor não abre porta, não escuta TCP, não tem endpoint HTTP. Só lê de stdin e escreve em stdout.
  • O cliente MCP é quem inicia o processo. Quem não tem acesso à sua máquina não consegue invocar tool nenhuma.
  • Consequência: não há (nem precisa haver) autenticação no servidor MCP. O modelo de ameaça é o mesmo de qualquer script que você roda no seu shell.

Camada 2 — Sem SQL arbitrário

  • Todas as queries são constantes literais no código (ver bloco _SQL_* em [server.py](server.py)). O agente nunca consegue submeter um SELECT próprio.
  • A única tool que monta SQL dinâmico é sample_rows, e ela só compõe SELECT * FROM LIMIT %s usando psycopg.sql.Identifier (blindagem nativa do driver contra injeção em identificadores).

Camada 3 — Validação de identificadores

  • Nomes de schema/objeto passam por regex ^[A-Za-z_][A-Za-z0-9_$]*$ antes de qualquer uso. Qualquer coisa com aspas, ponto-e-vírgula, espaço ou byte estranho é rejeitada antes de tocar o banco.
  • Identificadores vão para o PostgreSQL via %(param)s (quando são literais no WHERE) ou psycopg.sql.Identifier (quando precisam ir no FROM) — nunca via f-string ou concatenação.

Camada 4 — Caps e timeouts

  • sample_rows tem cap rígido de 50 linhas (constante no código, não configurável pelo cliente) e statement_timeout = 5s aplicado por conexão.
  • Demais tools só fazem queries no pg_catalog — baratas por natureza.

Camada 5 — Defesa em profundidade (configurar no banco)

Recomendado configurar do lado do PostgreSQL:

CREATE ROLE mcp_readonly LOGIN PASSWORD '...';
GRANT CONNECT ON DATABASE seu_db TO mcp_readonly;
GRANT USAGE ON SCHEMA public TO mcp_readonly;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO mcp_readonly;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO mcp_readonly;

ALTER ROLE mcp_readonly SET statement_timeout = '30s';
ALTER ROLE mcp_readonly CONNECTION LIMIT 5;

Confirme que o role só lê:

SELECT n.nspname AS schema, c.relname AS objeto,
       CASE WHEN has_table_privilege('mcp_readonly', c.oid, 'INSERT') THEN 'INSERT' END AS ins,
       CASE WHEN has_table_privilege('mcp_readonly', c.oid, 'UPDATE') THEN 'UPDATE' END AS upd,
       CASE WHEN has_table_privilege('mcp_readonly', c.oid, 'DELETE') THEN 'DELETE' END AS del
FROM pg_class c JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE c.relkind IN ('r','p','v','m')
  AND n.nspname NOT IN ('pg_catalog','information_schema')
  AND (has_table_privilege('mcp_readonly', c.oid, 'INSERT')
    OR has_table_privilege('mcp_readonly', c.oid, 'UPDATE')
    OR has_table_privilege('mcp_readonly', c.oid, 'DELETE'));

0 rows = só lê. Qualquer linha aqui significa que o role tem permissão de escrita — revogue.

O que não é coberto

  • Vazamento de dados via amostra. sample_rows mostra até 50 linhas reais. Se a tabela contém PII/segredos, o agente vê. Restrinja o usuário read-only às tabelas que você está disposto a expor.
  • .env em repo público. O .gitignore já cobre .env, mas confirme antes de cada push.
  • Logs do cliente MCP. Claude Desktop/Code/Cursor logam tool calls e respostas. Trate esses logs com o mesmo cuidado que dados do banco.

Variáveis de ambiente

| Variável | Descrição | |---|---| | PG_HOST | Endereço do servidor PostgreSQL. | | PG_PORT | Porta (default: 5432). | | PG_DB | Nome do banco. | | PG_USER | Usuário (preferencialmente read-only). | | PG_PASSWORD | Senha. | | PG_DEFAULT_SCHEMA | Schema usado quando a tool não recebe schema_name explícito (default: public). |


Troubleshooting

/mcp mostra o servidor como failed no Claude Code. Rode uv run server.py direto no terminal e veja o erro. Causas comuns: .env ausente, uv fora do PATH, caminho do --directory errado (use barra normal / mesmo no Windows).

PG_HOST, PG_DB e PG_USER precisam estar definidos no .env. O .env precisa estar ao lado de server.py — não é lido do CWD do cliente. Confirme com ls postgres_mcp_server/.env.

Tool retorna {"erro": "..."} em vez do dado esperado. O servidor captura exceções e devolve como erro estruturado. O campo detalhe traz a mensagem do PostgreSQL/psycopg — geralmente identifica a causa (permissão, nome errado, schema inexistente).

sample_rows estoura timeout. A tabela é grande ou tem trigger pesada no SELECT. Use describe_table para ver row_estimate antes; se for muito grande, prefira inspecionar a definição da view ou pedir ao DBA uma sample materializada.


Roadmap

  • Tools para listar funções, sequences e triggers.
  • explain_query(sql) — análise de plano de execução (read-only por natureza).
  • Suporte a múltiplas conexões nomeadas (atender mais de um banco no mesmo MCP).
  • Pacote distribuível via uvx / PyPI.

Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.