@carlos.e.alves3/mcp-postgres-server
v1.4.0
Published
MCP server for read-only PostgreSQL database access
Downloads
561
Maintainers
Readme
PostgreSQL MCP Server
Servidor MCP (Model Context Protocol) para acesso somente-leitura a bancos de dados PostgreSQL. Permite que assistentes de IA como Claude consultem bancos PostgreSQL de forma segura.
Funcionalidades
- Acesso Somente-Leitura: Apenas queries SELECT são permitidas (modo seguro padrão)
- Modo Inseguro (Opcional): Permite operações de escrita (INSERT, UPDATE, DELETE) para desenvolvimento
- Paginação: Suporte a limit e offset para consultas grandes
- Validação de Segurança: Prevenção de SQL injection, limites de tamanho e timeout
- Múltiplos Formatos: Saída em TEXT, JSON, YAML ou TOON (otimizado para LLMs)
- Suporte SSH Tunnel: Conexão segura via bastion/jump host
- Ferramentas MCP:
query- Executar queries SQL (SELECT ou CRUD se insecure=true)list_tables- Listar tabelas de um schemadescribe_table- Detalhar estrutura de tabela (colunas, índices, foreign keys)
Requisitos
- Bun v1.0+
- PostgreSQL 12+
Instalação
bun installConfiguração
Variáveis de Ambiente
Crie um arquivo .env baseado no exemplo:
cp .env.example .envConexão Direta:
POSTGRES_HOST=localhost
POSTGRES_PORT=5432
POSTGRES_DATABASE=mydb
POSTGRES_USER=postgres
POSTGRES_PASSWORD=sua_senha
POSTGRES_MAX_CONNECTIONS=10
# Modo inseguro - permite operações de escrita (default: false)
# ⚠️ ATENÇÃO: Use apenas em ambientes de desenvolvimento/teste
POSTGRES_INSECURE=falseConexão via SSH Tunnel:
POSTGRES_HOST=db-interno.example.com
POSTGRES_PORT=5432
POSTGRES_DATABASE=mydb
POSTGRES_USER=postgres
POSTGRES_PASSWORD=sua_senha
SSH_TUNNEL_ENABLED=true
SSH_HOST=bastion.example.com
SSH_PORT=22
SSH_USERNAME=seu_usuario
SSH_PASSWORD=sua_senha_ssh
# ou
SSH_PRIVATE_KEY_PATH=/home/user/.ssh/id_rsaConfiguração MCP Client
Adicione ao seu cliente MCP (ex: Claude Desktop, Claude Code):
Opção 1: Usando pacote npm publicado (Recomendado)
{
"mcpServers": {
"postgres": {
"command": "bunx",
"args": ["@carlos.e.alves3/mcp-postgres-server"],
"env": {
"POSTGRES_HOST": "localhost",
"POSTGRES_PORT": "5432",
"POSTGRES_DATABASE": "mydb",
"POSTGRES_USER": "postgres",
"POSTGRES_PASSWORD": "sua_senha",
"POSTGRES_INSECURE": "false"
}
}
}
}Opção 2: Usando repositório local (Desenvolvimento)
{
"mcpServers": {
"postgres": {
"command": "bun",
"args": ["run", "/caminho/absoluto/para/mcp-database-client/index.ts"],
"env": {
"POSTGRES_HOST": "localhost",
"POSTGRES_PORT": "5432",
"POSTGRES_DATABASE": "mydb",
"POSTGRES_USER": "postgres",
"POSTGRES_PASSWORD": "sua_senha",
"POSTGRES_INSECURE": "false"
}
}
}
}Uso
Executar Servidor
# Produção
bun start
# Desenvolvimento (hot reload)
bun dev
# Build executável standalone
bun run build
./mcp-database-clientFerramentas Disponíveis
query - Executar SQL com paginação:
{
"sql": "SELECT * FROM users WHERE age > 18",
"limit": 50,
"offset": 100,
"format": "JSON"
}Resposta inclui metadados de paginação:
{
"data": [...],
"rowCount": 50,
"pagination": {
"limit": 50,
"offset": 100,
"hasMore": true
}
}list_tables - Listar tabelas:
{
"schema": "public",
"format": "TEXT"
}describe_table - Descrever tabela:
{
"table": "users",
"schema": "public",
"format": "YAML"
}Formatos de Saída
- TEXT - Formato tabular legível
- JSON - JSON formatado com indentação
- YAML - YAML estruturado
- TOON - Token-Oriented Object Notation (otimizado para LLMs, padrão)
Segurança
Validações Implementadas
- Query Read-Only (padrão): Apenas SELECT e WITH (CTEs) permitidos
- Keywords Bloqueadas: INSERT, UPDATE, DELETE, DROP, ALTER, CREATE, TRUNCATE, GRANT, REVOKE, EXEC, EXECUTE, CALL, COPY, IMPORT
- Padrões Bloqueados: INTO OUTFILE, LOAD DATA
- Normalização: Remove comentários SQL para evitar bypass
- Limites:
- Tamanho máximo: 10.000 caracteres
- Máximo de linhas retornadas: 1.000 (ajustável via paginação)
- Timeout: 30 segundos
- Queries Parametrizadas: Para list_tables e describe_table
Modo Inseguro (Desenvolvimento)
⚠️ ATENÇÃO: Use apenas em ambientes de desenvolvimento/teste!
Quando POSTGRES_INSECURE=true, todas as operações SQL são permitidas:
POSTGRES_INSECURE=trueIsso habilita:
- INSERT, UPDATE, DELETE
- CREATE, ALTER, DROP
- TRUNCATE, GRANT, REVOKE
- Todas as operações DDL e DML
Avisos de segurança:
⚠️ WARNING: INSECURE MODE ENABLED - Write operations are allowed
[WARN] INSECURE MODE: Query validation bypassed - write operations allowedLogging de Segurança
Todas as queries bloqueadas são logadas com detalhes:
[SECURITY] Query blocked: contains blocked keyword {"keyword":"INSERT"}
[SECURITY] Query blocked: exceeds maximum length {"queryLength":10500}Testes
O projeto inclui 174 testes unitários cobrindo segurança, formatação e validação.
# Executar todos os testes
bun test
# Com relatório de cobertura
bun test --coverage
# Teste específico
bun test src/security.test.tsCobertura de Testes
| Módulo | Funções | Linhas | |---------------------|----------|--------| | security.ts | 100% | 100% | | config.ts | 100% | 100% | | query-tool.ts | 100% | 100% | | formatter.ts | 88.89% | 93.65% | | list-tables-tool.ts | 66.67% | 92.31% |
Estrutura do Projeto
mcp-database-client/
├── index.ts # Entry point MCP server
├── src/
│ ├── config.ts # Configuração do banco
│ ├── database.ts # Pool de conexões
│ ├── security.ts # Validação de queries
│ ├── formatter.ts # Formatação de saída
│ ├── logger.ts # Sistema de logging
│ ├── ssh-tunnel.ts # Suporte SSH tunnel
│ ├── *.test.ts # Testes unitários
│ └── tools/
│ ├── query-tool.ts # Ferramenta query
│ ├── list-tables-tool.ts # Ferramenta list_tables
│ ├── describe-table-tool.ts # Ferramenta describe_table
│ └── *.test.ts # Testes das ferramentas
├── package.json
├── tsconfig.json
└── CLAUDE.md # Instruções para Claude CodeLogging
Níveis de Log
Configure via LOG_LEVEL:
LOG_LEVEL=info # debug | info | warn | errorFormato
LOG_FORMAT=json # ou text (padrão)Exemplos
[2025-01-15T10:30:45.123Z] INFO: [QUERY] Executing SQL query {"queryLength":45}
[2025-01-15T10:30:45.234Z] INFO: [QUERY] Query executed successfully {"rowCount":150,"duration":111}
[2025-01-15T10:30:50.456Z] WARN: [SECURITY] Query blocked: contains blocked keyword {"keyword":"INSERT"}Troubleshooting
Erros de Conexão
Verifique se PostgreSQL está rodando:
pg_isready -h localhost -p 5432Confira credenciais no
.envVerifique firewall e
pg_hba.conf
Query Bloqueada
- Query deve iniciar com SELECT ou WITH
- Não pode conter keywords de escrita (INSERT, UPDATE, DELETE, etc.)
- Tamanho máximo: 10.000 caracteres
Timeout
- Otimize queries com índices
- Divida queries grandes
- Verifique performance do banco
Stack Técnica
- Runtime: Bun
- Database: PostgreSQL via
postgreslibrary - Protocol: Model Context Protocol (MCP)
- Transport: stdio
Licença
MIT
