Install
$ agentstack add mcp-aldruin-postgres-mcp-server ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo 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.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
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 →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.pycomo subprocesso e fala com ele porstdin/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
.envao lado deserver.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
list_schemas→ descobre os schemas do banco (se necessário).list_schema_objects(comname_patternopcional) → lista tabelas/views do schema escolhido.describe_tableoudescribe_view→ detalha colunas, tipos, tamanho.- 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
stdine escreve emstdout. - 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 umSELECTpróprio. - A única tool que monta SQL dinâmico é
sample_rows, e ela só compõeSELECT * FROM LIMIT %susandopsycopg.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) oupsycopg.sql.Identifier(quando precisam ir noFROM) — nunca via f-string ou concatenação.
Camada 4 — Caps e timeouts
sample_rowstem cap rígido de 50 linhas (constante no código, não configurável pelo cliente) estatement_timeout = 5saplicado 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_rowsmostra 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. .envem repo público. O.gitignorejá 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.
- Author: aldruin
- Source: aldruin/postgres-mcp-server
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.