a2db
Acesso a múltiplos bancos de dados (PostgreSQL, SQLite, MySQL, Oracle, SQL Server) com consultas em lote, conexões pré-configuradas e segurança somente leitura imposta pelo SQLGlot
Documentação
Translation
🗄️ a2db
Agent-to-Database
Dê aos agentes de IA acesso seguro e somente leitura aos seus bancos de dados. Uma chamada, várias consultas, resultados limpos.
5 bancos de dados · consultas em lote · conexões pré-configuradas · somente leitura com SQLGlot
Início Rápido · Ferramentas MCP · Segurança · Comparação · Configuração
Agent: "Show me active users and their recent orders"
↓
a2db execute → 2 queries, 1 call, structured results
↓
Agent: "Got it — 847 active users, avg order $42.50"
Por que a2db?
A maioria dos servidores MCP de banco de dados faz você executar uma consulta por vez, repetir os detalhes da conexão em cada chamada e retornar resultados duplamente codificados dentro de strings JSON. O a2db resolve tudo isso:
- Conexões pré-configuradas — defina bancos de dados em
.mcp.jsoncom--register, o agente consulta imediatamente - Consultas em lote — execute várias consultas nomeadas em uma única chamada de ferramenta
- Conexão padrão — defina a conexão uma vez, use-a em todas as consultas de um lote
- Saída limpa — envelope JSON estruturado com dados TSV compactos e tempo por consulta (veja por que TSV?)
- Somente leitura imposto — a análise AST do SQLGlot bloqueia todas as operações de escrita
- Todos os drivers incluídos —
pip install a2dbe pronto - Segredos ficam no ambiente —
${DB_PASSWORD}em DSNs, expandidos apenas no momento da conexão
Bancos de Dados Suportados
| Banco de Dados | Driver | Assíncrono |
|---|---|---|
| PostgreSQL | asyncpg | nativo |
| SQLite | aiosqlite | nativo |
| MySQL / MariaDB | mysql-connector-python | encapsulado |
| Oracle | oracledb | encapsulado |
| SQL Server | pymssql | encapsulado |
Início Rápido
pip install a2db
Como um Servidor MCP (recomendado)
Claude Code (com conexão pré-configurada):
claude mcp add -s user a2db -- a2db-mcp \
--register myapp/prod/main 'postgresql://user:${DB_PASSWORD}@host/mydb'
Claude Code (mínimo — o agente chama login sob demanda):
claude mcp add -s user a2db -- a2db-mcp
Claude Desktop / Cursor / qualquer cliente MCP (.mcp.json):
{
"mcpServers": {
"a2db": {
"command": "uvx",
"args": [
"a2db-mcp",
"--register", "myapp/prod/main", "postgresql://user:${DB_PASSWORD}@host/mydb"
],
"env": {
"DB_PASSWORD": "your-password-here"
}
}
}
}
Múltiplos bancos de dados:
{
"args": [
"a2db-mcp",
"--register", "myapp/prod/main", "postgresql://user:${DB_PASSWORD}@host/maindb",
"--register", "myapp/prod/analytics", "postgresql://user:${DB_PASSWORD}@host/analytics"
]
}
--register pré-registra conexões na inicialização do servidor — o agente pode consultar imediatamente. Senhas usam a sintaxe ${ENV_VAR} e são expandidas no momento da conexão, nunca armazenadas em texto simples.
Como CLI
# Save a connection (validates immediately)
a2db login -p myapp -e prod -d main 'postgresql://user:${DB_PASSWORD}@localhost/mydb'
# Query
a2db query -p myapp -e prod -d main "SELECT * FROM users LIMIT 10"
# JSON output
a2db query -p myapp -e prod -d main -f json "SELECT * FROM users LIMIT 10"
# Explore schema
a2db schema -p myapp -e prod -d main tables
a2db schema -p myapp -e prod -d main columns -t users
# List / remove connections
a2db connections
a2db logout -p myapp -e prod -d main
Ferramentas MCP
| Ferramenta | Descrição |
|---|---|
login | Salva uma conexão — valida conectando primeiro |
logout | Remove uma conexão salva |
list_connections | Lista conexões (sem expor segredos) |
execute | Executa consultas nomeadas em lote com paginação |
search_objects | Explora o esquema — tabelas, colunas, com níveis de detalhe |
execute — a ferramenta central
Dict nomeado com conexão padrão (preferido):
{
"connection": {"project": "myapp", "env": "prod", "db": "main"},
"queries": {
"active_users": {"sql": "SELECT id, name FROM users WHERE active = true"},
"recent_orders": {"sql": "SELECT id, total FROM orders ORDER BY created_at DESC LIMIT 5"}
}
}
Formato de lista (nomeados automaticamente q1, q2, ...):
{
"connection": {"project": "myapp", "env": "prod", "db": "main"},
"queries": [
{"sql": "SELECT COUNT(*) AS cnt FROM users"},
{"sql": "SELECT AVG(total) AS avg_order FROM orders"}
]
}
Resposta (formato TSV — padrão):
{
"active_users": {
"data": "id\tname\n1\tAlice\n2\tBob\n3\tCharlie",
"rows": 3,
"truncated": false,
"time_ms": 12
},
"recent_orders": {
"data": "id\ttotal\n501\t129.00\n500\t49.99",
"rows": 2,
"truncated": false,
"time_ms": 8
}
}
Sem conversões ::text — inteiros, floats, timestamps, arrays, NULLs funcionam nativamente.
Contexto de erro
Quando uma consulta falha com erro de coluna, o a2db enriquece a mensagem:
column "nme" does not exist
Did you mean: name?
Available columns: id (integer), name (text), email (text), active (integer)
Por que TSV?
Janelas de contexto de LLM são caras. Dados de linha em JSON são verbosos — cada linha repete o nome de cada coluna, adiciona chaves, vírgulas e aspas. TSV é uma grade plana: uma linha de cabeçalho, depois apenas valores separados por tabulações.
Para um conjunto de resultados de 100 linhas e 5 colunas, TSV normalmente usa 40-60% menos tokens que o formato JSON de linhas. O envelope JSON estruturado ainda fornece metadados (contagem de linhas, status de truncamento) — apenas o payload de linhas é TSV.
Defina format="json" se precisar de saída totalmente estruturada com nomes de colunas em cada linha.
Segurança
Imposição de Somente Leitura
Cada consulta é analisada por SQLGlot antes da execução:
- Bloqueados: INSERT, UPDATE, DELETE, DROP, TRUNCATE, ALTER, CREATE, GRANT, REVOKE
- À prova de bypass: ataques de múltiplas instruções e escritas envolvidas em comentários são detectados no nível da AST, não apenas por correspondência de palavras-chave
- Permitidos: SELECT, UNION, EXPLAIN, SHOW, DESCRIBE, PRAGMA
Isto é defesa em profundidade — você também deve usar um usuário de banco de dados somente leitura, mas o a2db não deixa escritas passarem mesmo que o usuário tenha permissões de escrita.
Suporte a escrita está implementado no núcleo, mas ainda não exposto via MCP. Planejado: permissões de escrita por conexão, habilitadas explicitamente pelo operador humano — não pelo agente. Veja TODO.md.
Armazenamento de Credenciais
Conexões são salvas em ~/.config/a2db/connections/ como arquivos TOML.
- Sintaxe
${DB_PASSWORD}— referências a variáveis de ambiente são armazenadas literalmente e expandidas apenas no momento da conexão. Segredos permanecem no seu ambiente, não no disco. - Sem segredos na saída de listagem —
list_connectionsmostra projeto/env/db e tipo de banco de dados, nunca DSNs ou senhas - Arquivos de conexão são locais à sua máquina e fora de qualquer repositório
Escopo de Implantação
O a2db atualmente roda como um servidor MCP stdio local. Ele herda variáveis de ambiente do processo que o inicia (seu shell, Claude Code, Docker). Este é o modelo padrão para servidores MCP locais — a mesma abordagem usada por DBHub, Google Toolbox e outros.
Planejado: transporte HTTP remoto com OAuth 2.1 conforme a especificação MCP. Por enquanto, se rodando em Docker, injete segredos via variáveis de ambiente no tempo de execução do contêiner.
Comparação
| Recurso | a2db | DBHub | Google Toolbox | PGMCP | Supabase MCP |
|---|---|---|---|---|---|
| Bancos de dados | 5 (PG, SQLite, MySQL, Oracle, MSSQL) | 5 (PG, MySQL, MSSQL, MariaDB, SQLite) | 40+ (nuvem + OSS) | somente PG | PG (Supabase) |
| Consultas em lote | Dict nomeado + lista | Separado por ponto e vírgula | Não | Não | Não |
| Conexão padrão | Defina uma vez, use para todas | Por consulta | N/A | Banco único | Projeto único |
| Somente leitura | SQLGlot AST (imposto) | Verificação de palavras-chave (config) | Dica/anotação | Transação somente leitura + regex | Flag de configuração |
| Suporte a escrita | Planejado (por conexão) | Flag de configuração | Via definição de ferramenta | Não | Flag de configuração |
| Saída | JSON + dados TSV | Texto estruturado | Protocolo MCP | Tabela / JSON / CSV | JSON |
| Descoberta de esquema | 3 níveis de detalhe | Ferramenta dedicada | Ferramentas prontas | Via NL-para-SQL | Ferramentas dedicadas |
| Pré-configurado | --register na configuração MCP | Arquivo de configuração | Config YAML | Variável de ambiente | Gerenciado na nuvem |
| Credenciais | ${ENV_VAR} em DSN | Strings DSN | Variáveis de ambiente + IAM GCP | Variável de ambiente | OAuth 2.1 |
| Drivers incluídos | Todos incluídos | Todos incluídos | Variados | Integrados | Gerenciados |
| CLI | Sim | Não | Sim | Sim | Não |
| Contexto de erro | Sugestões de coluna + tipos | Não | Não | Não | Não |
| Licença | Apache 2.0 | MIT | Apache 2.0 | Apache 2.0 | Apache 2.0 |
Quando usar o quê:
- a2db — consultas em lote multi-banco com saída limpa, design agent-first, configuração rápida
- DBHub — ferramentas personalizadas via configuração TOML, interface web de workbench
- Google Toolbox — ecossistema GCP, integração IAM, 40+ fontes
- PGMCP — linguagem natural para SQL no PostgreSQL (requer chave OpenAI)
- Supabase MCP — gerenciamento completo da plataforma Supabase (edge functions, branch, storage)
Configuração por Ambiente
Local (macOS / Linux)
pip install a2db
# CLI
a2db login -p myapp -e dev -d main 'postgresql://user:pass@localhost/mydb'
# Or add as MCP server (see Quick Start)
Docker
FROM python:3.12-slim
RUN pip install a2db
CMD ["a2db-mcp", "--register", "myapp/prod/main", "postgresql://user:${DB_PASSWORD}@host/mydb"]
docker run -e DB_PASSWORD=secret -i my-a2db-image
Segredos são injetados como variáveis de ambiente em tempo de execução — nunca gravados na imagem.
CI / Automação
pip install a2db
# Pre-configured — no login needed
a2db-mcp --register myapp/ci/main "postgresql://ci_user:${CI_DB_PASSWORD}@db-host/mydb"
# Or use CLI directly
a2db login -p myapp -e ci -d main "postgresql://ci_user:${CI_DB_PASSWORD}@db-host/mydb"
a2db query -p myapp -e ci -d main "SELECT COUNT(*) FROM migrations"
Desenvolvimento
make bootstrap # Install deps + hooks
make check # Lint + test + security (full gate)
make test # Tests with coverage (90% minimum)
make lint # Lint only (never modifies files)
make fix # Auto-fix + lint
Licença
Apache 2.0
🗄️ Acesso a banco de dados agent-first desde 2025.
Construído por Denis Tomilin