MCP PostgreSQL

Servidor Model Context Protocol que expõe introspecção e consulta somente leitura sobre PostgreSQL

Documentação

MCP PostgreSQL

Servidor Model Context Protocol que expõe introspecção e consulta somente leitura sobre PostgreSQL. Projetado para fornecer contexto ao Claude (Claude Code, Claude Desktop) sem risco de escrita.

  • 13 tools de introspecção, consulta, EXPLAIN e estatísticas de armazenamento
  • 2 resources navegáveis (postgres://schema/{schema}, postgres://table/{schema}/{table})
  • 4 prompts prontos para uso (audit-table, find-tables, explain-foreign-keys, profile-slow-query)
  • Somente leitura reforçado: SET TRANSACTION READ ONLY, statement timeout, limite de linhas, single-statement, validação de keywords
  • Schema allow-list via DB_SCHEMAS
  • Empacotável como MCPB para Claude Desktop (pnpm run mcpb:pack)

Sumário


Quickstart

Pré-requisitos: Node ≥ 18 e pnpm.

pnpm install
pnpm run build
cp .env.example .env       # edita tus credenciales
npx tsx test-connection.ts # verifica conectividad

Em seguida, registre o servidor no Claude Code:

claude mcp add --transport stdio postgres \
  -- node /ruta/absoluta/al/proyecto/dist/index.js

Configuração

Copie .env.example para .env e edite os valores:

DB_HOST=localhost
DB_PORT=5432
DB_NAME=nombre_base_datos
DB_USER=usuario
DB_PASSWORD=contraseña
DB_SSL=false                       # true para AWS RDS / Supabase / Neon
DB_SSL_REJECT_UNAUTHORIZED=true    # mantener true en producción
DB_SCHEMAS=public                  # esquemas permitidos, separados por coma. Vacío = todos los no-sistema
DEFAULT_LIMIT=5                    # LIMIT por defecto en queries (máx 100)

Ambientes pré-configurados

Existem vários arquivos .env.<entorno> para alternar entre bancos de dados sem reescrever credenciais:

cp .env.ecosistema-prd .env       # producción
cp .env.ecosistema-tst .env       # testing
cp .env.db-admision-tst .env      # admisión testing
# ...etc.

Recomendação: use um papel de PostgreSQL somente leitura (CREATE ROLE ... LOGIN; GRANT USAGE ON SCHEMA ... TO ...; GRANT SELECT ON ALL TABLES IN SCHEMA ... TO ...;). O servidor reforça READ ONLY, mas a defesa em profundidade importa.

Integração com Claude Code

Opção A — claude mcp add (recomendado)

Passando credenciais como variáveis de ambiente:

claude mcp add \
  --transport stdio \
  --env DB_HOST=localhost \
  --env DB_PORT=5432 \
  --env DB_NAME=mi_base \
  --env DB_USER=mi_user \
  --env DB_PASSWORD=mi_password \
  --env DB_SCHEMAS=public \
  postgres \
  -- node /ruta/absoluta/al/proyecto/dist/index.js

Usando o .env do próprio repositório (omite os --env):

claude mcp add --transport stdio postgres \
  -- node /ruta/absoluta/al/proyecto/dist/index.js

Escopo global (disponível em todos os projetos):

claude mcp add --scope user --transport stdio postgres \
  -- node /ruta/absoluta/al/proyecto/dist/index.js

Opção B — JSON manual

{
  "mcpServers": {
    "postgres": {
      "command": "node",
      "args": ["/ruta/absoluta/al/proyecto/dist/index.js"],
      "env": {
        "DB_HOST": "...",
        "DB_NAME": "...",
        "DB_USER": "...",
        "DB_PASSWORD": "...",
        "DB_SCHEMAS": "public"
      }
    }
  }
}

Integração com Claude Desktop (MCPB)

O projeto inclui um manifest.json pronto para empacotar como MCPB (Claude Desktop Bundle).

pnpm run build
pnpm run mcpb:pack    # genera mcp_postgres.mcpb en la raíz del repo

O .mcpb é um artefato de build (está em .gitignore) — é regenerado quando necessário. Não o envie para o repositório.

O que fazer com mcp_postgres.mcpb

Uso pessoal (instalar no seu Claude Desktop):

  1. Abra o Claude Desktop → SettingsExtensions
  2. Arraste mcp_postgres.mcpb para a janela (ou use "Install extension")
  3. O Claude Desktop solicitará os dados de conexão (host, user, password, etc.) por meio do formulário definido em user_config do manifest.json — o campo db_password está marcado como sensitive
  4. Após a instalação, você pode excluir o arquivo .mcpb local

Distribuição privada (compartilhar com sua equipe):

  • Envie como release asset no GitHub: gh release create v1.1.0 mcp_postgres.mcpb
  • Ou distribua por um storage interno (S3, Drive, etc.) e compartilhe o link
  • Seus colegas baixam o .mcpb e o arrastam para o Claude Desktop

Distribuição pública: publique no MCP Bundle Directory quando estiver disponível. Enquanto isso, GitHub Releases é o canal padrão.

Se não for instalar agora: simplesmente exclua (rm mcp_postgres.mcpb) e regenere com pnpm run mcpb:pack quando precisar.

Tools

Todas as tools possuem readOnlyHint: true, destructiveHint: false e outputSchema Zod para structuredContent. Erros recuperáveis são retornados como { isError: true, content }, não como exceções de protocolo.

Introspecção

ToolDescrição
postgres_list_schemasLista esquemas acessíveis.
postgres_list_tablesTabelas de um esquema com contagem de colunas (paginado).
postgres_describe_tableColunas, constraints (PK/FK/UNIQUE) e índices.
postgres_list_functionsFunções/procedimentos com assinatura, retorno e linguagem (paginado).
postgres_list_triggersTriggers com tabela, evento e timing (paginado).
postgres_get_function_definitionCódigo-fonte de uma função (com suporte a sobrecarga).
postgres_get_trigger_definitionDefinição completa de um trigger.
postgres_list_viewsViews regulares e materializadas (paginado).
postgres_search_columnsBusca colunas por nome/pattern em todos os esquemas permitidos.

Consulta e análise

ToolDescrição
postgres_query_tableSELECT seguro sobre uma única tabela com filtros estruturados.
postgres_execute_querySELECT/WITH avançado (JOINs, CTEs, agregações). Single-statement, READ ONLY.
postgres_explain_queryEXPLAIN / EXPLAIN ANALYZE de um SELECT — perfila planos antes de executar.
postgres_get_table_statsTamanho total/tabela/índices/toast, vacuum/analyze, índices com idx_scan = 0.

As tools paginadas (postgres_list_*) aceitam limit/offset e retornam has_more/next_offset para iterar.

Resources

URIs navegáveis que o host pode consumir como contexto:

URI templateConteúdo
postgres://schema/{schema}Resumo do esquema: tabelas, views, funções, triggers, contagens.
postgres://table/{schema}/{table}Estrutura completa de uma tabela (colunas + constraints + índices).

Prompts

Slash commands disponíveis no Claude Code (/mcp__postgres__<prompt>):

PromptArgumentosPropósito
audit-tableschema, tableAuditoria estruturada: schema, storage, sample, triggers, riscos.
find-tablespatternEncontra colunas/tabelas por pattern fuzzy em todos os esquemas.
explain-foreign-keysschemaMapa textual do grafo de FKs (hubs, órfãos).
profile-slow-querysqlEXPLAIN ANALYZE + recomendações priorizadas (índices ausentes, scans, sorts caros).

Exemplo (no Claude Code):

/mcp__postgres__audit-table schema=public table=users
/mcp__postgres__profile-slow-query sql="SELECT * FROM orders WHERE customer_id IN (SELECT id FROM customers WHERE country='PE')"

Segurança

  • Filtragem de esquemas: DB_SCHEMAS restringe acesso a nível de aplicação; além disso, postgres_execute_query ajusta search_path local por consulta.
  • Query table seguro: postgres_query_table usa colunas/filtros estruturados com parâmetros SQL — nunca concatena strings.
  • Somente leitura reforçado: postgres_execute_query e postgres_explain_query rodam sob SET TRANSACTION READ ONLY com statement_timeout = 30s.
  • Single-statement: rejeita queries com ; interno e palavras-chave de escrita (INSERT/UPDATE/DELETE/DROP/ALTER/CREATE/TRUNCATE/GRANT/REVOKE/EXECUTE/COPY) validadas por regex com \b.
  • Limite de linhas: máximo de 100 linhas por consulta; o LIMIT é injetado ou limitado automaticamente.
  • TLS seguro por padrão: quando DB_SSL=true, DB_SSL_REJECT_UNAUTHORIZED=true por padrão.
  • Timeouts: 10 s para estabelecer conexão, 30 s para statement.
  • Defesa em profundidade: mesmo assim, use um papel de PostgreSQL somente leitura no DB_USER.

Estrutura do projeto

src/
├── index.ts              # Bootstrap — conecta transport y verifica DB
├── server.ts             # createServer() — instancia McpServer, registra tools/resources/prompts
├── db/
│   └── pool.ts           # Pool, allowedSchemas, defaultLimit, isSchemaAllowed
├── tools/
│   ├── introspection.ts  # list_schemas / list_tables / describe_table / list_views / search_columns
│   ├── objects.ts        # list_functions / list_triggers / get_*_definition
│   ├── query.ts          # query_table / execute_query
│   └── analysis.ts       # explain_query / get_table_stats
├── resources/
│   └── index.ts          # postgres://schema/* y postgres://table/*
├── prompts/
│   └── index.ts          # audit-table / find-tables / explain-foreign-keys / profile-slow-query
└── utils/
    └── response.ts       # formatResult(), assertSchemaAllowed(), CHARACTER_LIMIT

Desenvolvimento

pnpm run build      # Compila TypeScript → dist/
pnpm run dev        # Watch mode
pnpm start          # Ejecuta el servidor compilado
pnpm run mcpb:pack  # Empaqueta como .mcpb para Claude Desktop

Após editar qualquer arquivo em src/, execute pnpm run build antes de testar alterações. O binário que Claude Code/Desktop executa é dist/index.js.

Troubleshooting

Error: schema "X" is not allowed — adicione X a DB_SCHEMAS (ou deixe vazio para permitir todos os não-sistema).

statement timeout — a query excede 30 s. Use postgres_explain_query com analyze=false primeiro, ou filtre por uma coluna indexada.

self-signed certificate em RDS / Supabase — defina DB_SSL=true. Apenas baixe DB_SSL_REJECT_UNAUTHORIZED=false se o provedor usar cert auto-assinado.

Claude Code não vê as tools — verifique com claude mcp list que postgres aparece como connected. Se não, claude mcp get postgres mostra o comando registrado; confira se o caminho absoluto para dist/index.js está correto e se o build está atualizado.

Query retorna has_more: true — chame a tool novamente passando offset = next_offset. As listas são paginadas para não inflar o contexto.

Licença

MIT