a2db

Acceso a múltiples bases de datos (PostgreSQL, SQLite, MySQL, Oracle, SQL Server) con consultas por lotes, conexiones preconfiguradas y seguridad de solo lectura impuesta por SQLGlot

Documentación

🗄️ a2db

Agente a Base de Datos

Dale a los agentes de IA acceso seguro y de solo lectura a tus bases de datos. Una llamada, múltiples consultas, resultados limpios.

5 bases de datos · consultas por lotes · conexiones preconfiguradas · SQLGlot de solo lectura

PyPI Python versions License CI MCP Registry

Inicio Rápido · Herramientas MCP · Seguridad · Comparación · Configuración


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 qué a2db?

La mayoría de los servidores MCP de bases de datos te obligan a ejecutar una consulta a la vez, repetir los detalles de conexión en cada llamada y devolver resultados doblemente codificados dentro de cadenas JSON. a2db soluciona todo eso:

  • Conexiones preconfiguradas — define bases de datos en .mcp.json con --register, el agente consulta inmediatamente
  • Consultas por lotes — ejecuta múltiples consultas nombradas en una sola llamada de herramienta
  • Conexión predeterminada — configura la conexión una vez, úsala en todas las consultas de un lote
  • Salida limpia — envoltorio JSON estructurado con datos TSV compactos y tiempos por consulta (ver ¿por qué TSV?)
  • Solo lectura garantizada — el análisis AST de SQLGlot bloquea todas las operaciones de escritura
  • Todos los controladores incluidospip install a2db y listo
  • Los secretos permanecen en el entorno${DB_PASSWORD} en los DSN, expandidos solo al momento de la conexión

Bases de Datos Soportadas

Base de datosControladorAsync
PostgreSQLasyncpgnativo
SQLiteaiosqlitenativo
MySQL / MariaDBmysql-connector-pythonenvuelto
Oracleoracledbenvuelto
SQL Serverpymssqlenvuelto

Inicio Rápido

pip install a2db

Como Servidor MCP (recomendado)

Claude Code (con conexión preconfigurada):

claude mcp add -s user a2db -- a2db-mcp \
  --register myapp/prod/main 'postgresql://user:${DB_PASSWORD}@host/mydb'

Claude Code (mínimo — el agente llama a login bajo demanda):

claude mcp add -s user a2db -- a2db-mcp

Claude Desktop / Cursor / cualquier 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últiples bases de datos:

{
  "args": [
    "a2db-mcp",
    "--register", "myapp/prod/main", "postgresql://user:${DB_PASSWORD}@host/maindb",
    "--register", "myapp/prod/analytics", "postgresql://user:${DB_PASSWORD}@host/analytics"
  ]
}

--register pre-registra conexiones al iniciar el servidor — el agente puede consultar de inmediato. Las contraseñas usan la sintaxis ${ENV_VAR} y se expanden al momento de la conexión, nunca se almacenan en texto plano.

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

Herramientas MCP

HerramientaDescripción
loginGuarda una conexión — valida conectándose primero
logoutElimina una conexión guardada
list_connectionsLista conexiones (sin exponer secretos)
executeEjecuta consultas por lotes nombradas con paginación
search_objectsExplora el esquema — tablas, columnas, con niveles de detalle

execute — la herramienta principal

Diccionario nombrado con conexión predeterminada (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 (auto-nombrado 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"}
  ]
}

Respuesta (formato TSV — predeterminado):

{
  "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
  }
}

No se necesitan conversiones ::text — enteros, flotantes, marcas de tiempo, arreglos, NULL funcionan de forma nativa.

Contexto de errores

Cuando una consulta falla con un error de columna, a2db enriquece el mensaje:

column "nme" does not exist
Did you mean: name?
Available columns: id (integer), name (text), email (text), active (integer)

¿Por qué TSV?

Las ventanas de contexto de los LLM son costosas. Los datos de filas en JSON son verbosos — cada fila repite cada nombre de columna, agrega llaves, comas y comillas. TSV es una cuadrícula plana: una fila de encabezado, luego solo valores separados por tabulaciones.

Para un conjunto de resultados de 100 filas y 5 columnas, TSV típicamente usa 40-60% menos tokens que el formato JSON de filas. El envoltorio JSON estructurado aún te da metadatos (conteo de filas, estado de truncamiento) — solo la carga útil de filas es TSV.

Configura format="json" si necesitas salida estructurada completa con nombres de columna en cada fila.

Seguridad

Cumplimiento de Solo Lectura

Cada consulta es analizada por SQLGlot antes de la ejecución:

  • Bloqueado: INSERT, UPDATE, DELETE, DROP, TRUNCATE, ALTER, CREATE, GRANT, REVOKE
  • Resistente a evasión: ataques de múltiples declaraciones y escrituras envueltas en comentarios se detectan a nivel de AST, no solo por coincidencia de palabras clave
  • Permitido: SELECT, UNION, EXPLAIN, SHOW, DESCRIBE, PRAGMA

Esto es defensa en profundidad — también deberías usar un usuario de base de datos de solo lectura, pero a2db no permitirá escrituras incluso si el usuario tiene permisos de escritura.

Soporte de escritura está implementado en el núcleo pero aún no expuesto vía MCP. Planificado: permisos de escritura por conexión, habilitados explícitamente por el operador humano — no por el agente. Ver TODO.md.

Almacenamiento de Credenciales

Las conexiones se guardan en ~/.config/a2db/connections/ como archivos TOML.

  • Sintaxis ${DB_PASSWORD} — las referencias a variables de entorno se almacenan literalmente y se expanden solo al momento de la conexión. Los secretos permanecen en tu entorno, no en el disco.
  • Sin secretos en la salida de listalist_connections muestra proyecto/entorno/BD y tipo de base de datos, nunca DSN o contraseñas
  • Los archivos de conexión son locales a tu máquina y fuera de cualquier repositorio

Alcance de Implementación

a2db actualmente se ejecuta como un servidor MCP stdio local. Hereda variables de entorno del proceso que lo lanza (tu shell, Claude Code, Docker). Este es el modelo estándar para servidores MCP locales — el mismo enfoque usado por DBHub, Google Toolbox y otros.

Planificado: transporte HTTP remoto con OAuth 2.1 según la especificación MCP. Por ahora, si se ejecuta en Docker, inyecta secretos vía variables de entorno en el tiempo de ejecución del contenedor.

Comparación

Característicaa2dbDBHubGoogle ToolboxPGMCPSupabase MCP
Bases de datos5 (PG, SQLite, MySQL, Oracle, MSSQL)5 (PG, MySQL, MSSQL, MariaDB, SQLite)40+ (nube + OSS)Solo PGPG (Supabase)
Consultas por lotesDiccionario nombrado + listaSeparadas por punto y comaNoNoNo
Conexión predeterminadaConfigura una vez, usa para todasPor consultaN/ABD únicaProyecto único
Solo lecturaSQLGlot AST (garantizado)Verificación de palabras clave (config)Sugerencia/anotaciónTransacción de solo lectura + regexBandera de configuración
Soporte de escrituraPlanificado (por conexión)Bandera de configuraciónVía definición de herramientaNoBandera de configuración
SalidaJSON + datos TSVTexto estructuradoProtocolo MCPTabla / JSON / CSVJSON
Descubrimiento de esquema3 niveles de detalleHerramienta dedicadaHerramientas preconstruidasVía NL-a-SQLHerramientas dedicadas
Preconfigurado--register en configuración MCPArchivo de configuraciónConfiguración YAMLVariable de entornoGestionado en la nube
Credenciales${ENV_VAR} en DSNCadenas DSNVariables de entorno + IAM de GCPVariable de entornoOAuth 2.1
Controladores incluidosTodos incluidosTodos incluidosVaríaIntegradosGestionados
CLINoNo
Contexto de erroresSugerencias de columna + tiposNoNoNoNo
LicenciaApache 2.0MITApache 2.0Apache 2.0Apache 2.0

Cuándo usar qué:

  • a2db — consultas por lotes multi-BD con salida limpia, diseño primero para agentes, configuración rápida
  • DBHub — herramientas personalizadas vía configuración TOML, interfaz web de trabajo
  • Google Toolbox — ecosistema GCP, integración IAM, 40+ fuentes
  • PGMCP — lenguaje natural a SQL para PostgreSQL (requiere clave de OpenAI)
  • Supabase MCP — gestión completa de la plataforma Supabase (funciones edge, ramificaciones, almacenamiento)

Configuración por Entorno

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

Los secretos se inyectan como variables de entorno en tiempo de ejecución — nunca se hornean en la imagen.

CI / Automatización

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"

Desarrollo

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

Licencia

Apache 2.0


🗄️ Acceso a bases de datos primero para agentes desde 2025.

Construido por Denis Tomilin