Pitch: Por que criei um MCP server para o PostgreSQL e o que ele tem a ver com o futuro do desenvolvimento orientado por agentes.
O ponto de virada
Há algum tempo atrás, percebi que minha dinâmica de trabalho com IA tinha mudado radicalmente. Eu não estava mais apenas pedindo ao agente para gerar código, eu estava deixando ele navegar pela minha base de dados, sugerir índices, explicar planos de execução e ajudar a construir queries complexas em tempo real.
O problema? O agente sabia muito pouco sobre o ambiente onde estava trabalhando. Ele adivinhava schemas. Ele inventava nomes de colunas. Ele escrevia queries que jamais teriam o desempenho que eu esperava, porque ele estava no escuro.
Pior ainda: para conectar o agente ao banco, eu precisava colocar credenciais direto no mcp.json. Um arquivo que vai para o repositório. Um arquivo que vários projetos compartilham. Isso me incomodou profundamente.
Foi aí que nasceu o postgres-mcp.
O problema de segurança que ninguém quer admitir
Quando você começa a usar MCPs com banco de dados, o caminho mais fácil é o mais perigoso: botar DB_PASSWORD=suasenha diretamente na configuração. Afinal, "é só pra dev". "Não tem risco". "Depois eu arrrumo".
Mas todo desenvolvedor sabe como termina esse papo.
O postgres-mcp foi construído com uma premissa de segurança não-negociável: nenhuma credencial deve residir no mcp.json. O arquivo de configuração armazena apenas mapeamentos - ele diz ao servidor quais variáveis do .env usar. As credenciais reais ficam no .env, que já é (ou deveria ser) ignorado pelo .gitignore.
"env": {
"MCP_KEY_HOST": "DB_HOST",
"MCP_KEY_USER": "DB_USER",
"MCP_KEY_PASS": "DB_PASS"
}
Isso parece um detalhe pequeno. Não é. É a diferença entre um repositório comprometido e um repositório seguro.
A segunda camada: read-only por padrão
Outro princípio que guiou o design: o menor privilégio possível deve ser o comportamento padrão.
Se você iniciar o servidor sem especificar nenhuma ferramenta, ele sobe em modo read-only, expondo apenas ferramentas de inspeção, análise e explicação. Nada que escreva. Nada que execute SQL arbitrário. Nada que possa derrubar uma tabela por acidente.
As ferramentas destrutivas pg_execute_query e pg_manage_query precisam ser habilitadas explicitamente. E quando você as habilita, elas aparecem visivelmente no mcp.json, auditáveis por qualquer pessoa que revisar o repositório.
Segurança não é uma feature. É um comportamento padrão.
Por que a observabilidade SQL importa no desenvolvimento com agentes
Agentes de IA são incrivelmente capazes - mas eles operam em um espaço de contexto limitado. Quando o agente não tem acesso ao schema real, às queries lentas, aos índices existentes e às políticas de segurança do banco, ele trabalha com suposições.
E suposições geram código frágil.
O postgres-mcp expõe um conjunto rico de ferramentas de observabilidade que transformam o agente de um gerador de código genérico em um assistente de banco de dados contextualizado:
| Ferramenta | O que ela entrega ao agente |
|---|---|
pg_manage_schema | Tabelas, colunas, tipos e enums - o mapa real do banco |
pg_manage_indexes | Índices existentes e análise de uso - evita duplicatas, sugere os que faltam |
pg_manage_query | EXPLAIN, queries lentas e estatísticas - o agente sabe se a query vai varrer a tabela inteira |
pg_manage_rls | Row-Level Security - o agente respeita as regras de acesso já definidas |
pg_monitor_database | Saúde do banco em tempo real - conexões, locks, bloats |
pg_manage_constraints | Constraints e chaves estrangeiras - integridade referencial visível ao agente |
pg_manage_functions | Funções e políticas RLS - lógica de negócio no banco exposta ao agente |
Com essas ferramentas ativas, o agente não adivinha mais. Ele pergunta. Ele verifica. Ele propõe com base em evidências reais.
Construindo código melhor, guiado por dados reais
Imagine o seguinte cenário: você pede ao agente que escreva uma query para listar os pedidos mais recentes de um usuário. Sem contexto, ele vai escrever algo genérico. Com o postgres-mcp ativo, o agente pode:
- Inspecionar o schema (
pg_manage_schema) para saber o nome exato das tabelas e colunas - Verificar os índices (
pg_manage_indexes) para garantir que a query vai usar o caminho de acesso mais rápido - Executar um
EXPLAIN(pg_manage_query) para validar o plano antes de você rodar em produção - Consultar as políticas de RLS (
pg_manage_rls) para garantir que o filtro de segurança por usuário já está coberto pelo banco - e não precisa ser reimplementado na aplicação
O resultado não é apenas uma query que funciona. É uma query que funciona bem, com segurança, e alinhada com a estrutura real do seu ambiente.
Isso é o que diferencia código gerado de código orientado por agente.
Como começar
{
"servers": {
"Postgres Tools": {
"type": "stdio",
"command": "npx",
"args": [
"-y",
"@edelciomolina/postgres-mcp"
],
"env": {
"MCP_KEY_HOST": "DB_HOST",
"MCP_KEY_PORT": "DB_PORT",
"MCP_KEY_NAME": "DB_NAME",
"MCP_KEY_SSLMODE": "DB_SSLMODE",
"MCP_KEY_USER": "DB_USER",
"MCP_KEY_PASS": "DB_PASS"
}
}
}
}
Adicione isso ao seu mcp.json, aponte para as variáveis do seu .env, e seu agente passa a ter acesso completo à observabilidade do seu banco - com segurança, de forma auditável, e sem nenhuma credencial exposta.
📦 npm: @edelciomolina/postgres-mcp
🐙 GitHub: edelciomolina/postgres-mcp
Considerações finais
Passamos anos aprendendo que boas práticas de engenharia como testes, revisões de código e segurança existem por um motivo. Agora que estamos delegando partes cada vez maiores do trabalho para agentes de IA, essas práticas se tornam ainda mais críticas, não menos.
Dar ao agente acesso ao banco sem contexto, sem limites e sem segurança não é produtividade. É imprudência com boa intenção.
Chega de vibing code. É hora do agentic coding - onde o agente não apenas gera código, mas o constrói com inteligência, contexto e responsabilidade.
E não esqueça de dar aquela forcinha com uma ⭐️ lá no meu repo. Valeu!