db-readonly-mcp
db-readonly-mcp
Un servidor MCP que le da a un asistente de IA (Claude Code, Claude Desktop o cualquier otro cliente MCP) acceso protegido y de solo lectura a una base de datos Postgres. Pide algo como "dame todos los comercios creados ayer" y el asistente escribe el SQL y lo ejecuta a través de este servidor, que garantiza que la consulta solo pueda leer datos.
Solo Postgres: no se admiten otras bases de datos.
Por qué existe esto
Dejar que un asistente consulte tu base de datos directamente es realmente útil para depurar, explorar datos y responder preguntas de "cuántos X" sin escribir un script cada vez. El riesgo es obvio: un LLM puede alucinar o ser inducido a escribir una consulta destructiva. Este servidor existe para reducir ese riesgo a casi cero, con varias capas independientes de protección en lugar de depender de una sola.
Related MCP server: Postgres Scout MCP
Modelo de seguridad
En capas, en orden de cuánto se confía realmente en ellas:
Rol de base de datos: la conexión usa un rol de Postgres dedicado con permisos de solo
SELECT. Este es el límite real: incluso si se omitieran todas las demás capas, el rol no puede escribir.Validación de consultas: rechaza cualquier cosa que no sea una sola sentencia
SELECT/WITH ... SELECT(sin sentencias apiladas con punto y coma, sin palabras clave DDL/DML).LIMITforzado: cada consulta se envuelve enSELECT * FROM (...) LIMIT N, con un tope deMAX_LIMITindependientemente de lo que se solicite.statement_timeout: las consultas se cancelan después deSTATEMENT_TIMEOUT_MS.Registro de inicio: registra la base de datos/usuario conectados en stderr al arrancar, para que sea obvio a qué base de datos apuntas antes de que se ejecute cualquier consulta.
Solo apunta este servidor a una base de datos de desarrollo/pruebas/staging, nunca a producción. Las capas 2-5 son defensa en profundidad; la capa 1 (el rol de base de datos) es la única capa en la que deberías confiar realmente, y ni siquiera esa debería usarse con datos de producción.
Requisitos
Node.js >= 20
Una base de datos Postgres en la que puedas crear un rol
Un cliente MCP (por ejemplo, Claude Code, Claude Desktop o cualquier otro cliente que admita servidores MCP sobre stdio)
Configuración
1. Clonar e instalar
git clone https://github.com/david-mogbeyi/db-readonly-mcp.git
cd db-readonly-mcp
npm install2. Crear el rol de solo lectura
Ejecuta esto contra tu base de datos Postgres de destino: reemplaza el nombre del rol, la contraseña,
el nombre de la base de datos y el esquema/propietario si tu aplicación usa algo distinto de public:
CREATE ROLE myapp_readonly WITH LOGIN PASSWORD '<choose-a-password>';
GRANT CONNECT ON DATABASE myapp TO myapp_readonly;
GRANT USAGE ON SCHEMA public TO myapp_readonly;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO myapp_readonly;
-- Keeps future tables (new migrations) readable automatically, without
-- re-running this grant every time the schema changes.
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO myapp_readonly;Si tu esquema no es public, o tienes varios esquemas, repite las líneas GRANT USAGE/GRANT SELECT/ALTER DEFAULT PRIVILEGES para cada uno. Este servidor
actualmente solo consulta el esquema public para list_tables/describe_table, pero
query_readonly puede referenciar cualquier esquema al que se le haya concedido acceso al rol.
3. Configurar
cp .env.example .envEdita .env y establece DATABASE_URL con la cadena de conexión del rol de solo lectura:
DATABASE_URL=postgresql://myapp_readonly:<password>@localhost:5432/myappConsulta Configuración más abajo para las otras variables.
4. Compilar
npm run buildEsto compila src/ a dist/ mediante tsc. Vuelve a ejecutarlo después de hacer cambios o editar
el código fuente.
Registrar con un cliente MCP
Claude Code
En el proyecto desde el que quieras consultar, añade un .mcp.json (o edita el que ya
tengas):
{
"mcpServers": {
"db-readonly": {
"command": "node",
"args": ["/absolute/path/to/db-readonly-mcp/dist/index.js"],
"env": {
"DATABASE_URL": "postgresql://myapp_readonly:<password>@localhost:5432/myapp"
}
}
}
}Reemplaza /absolute/path/to/db-readonly-mcp con la ubicación donde clonaste este repositorio.
Reinicia Claude Code (o reconecta los servidores MCP) para que lo detecte.
También puedes registrarlo globalmente en lugar de por proyecto: consulta la documentación de MCP de Claude
Code para las opciones de claude mcp add y
de alcance.
Claude Desktop / otros clientes MCP
Cualquier cliente que admita servidores MCP sobre stdio puede usarlo de la misma manera: apúntalo
a node /absolute/path/to/db-readonly-mcp/dist/index.js con DATABASE_URL (y
opcionalmente las demás variables de entorno de abajo) establecidas en su entorno. Consulta la documentación de tu cliente
para saber dónde está su configuración de servidor MCP: para Claude Desktop es
claude_desktop_config.json, usando la misma forma de command/args/env que arriba.
Configuración
Toda la configuración se hace mediante variables de entorno (establecidas en .env para ejecuciones locales, o en
el bloque env de la configuración de tu cliente MCP).
Variable | Requerida | Por defecto | Descripción |
| Sí | — | Cadena de conexión de Postgres para el rol de solo lectura. |
| No | 100 | Límite de filas aplicado cuando una consulta no especifica uno. |
| No | 1000 | Tope máximo de filas devueltas, independientemente de lo solicitado. |
| No | 5000 |
|
Herramientas
El servidor expone tres herramientas al asistente:
list_tables
Lista las tablas del esquema public. Sin argumentos.
→ [
{ "table_name": "merchants" },
{ "table_name": "orders" },
...
]describe_table(table)
Columnas, tipos, nulabilidad y valores por defecto de una tabla del esquema public.
{ "table": "merchants" }
→ [
{ "column_name": "id", "data_type": "uuid", "is_nullable": "NO", "column_default": "gen_random_uuid()" },
{ "column_name": "created_at", "data_type": "timestamp with time zone", "is_nullable": "NO", "column_default": "now()" },
...
]query_readonly(sql, limit?)
Ejecuta una sola sentencia SELECT (o WITH ... SELECT) protegida. limit es opcional
y se limita a MAX_LIMIT incluso si se pasa un valor mayor.
{ "sql": "SELECT id, name, created_at FROM merchants WHERE created_at > now() - interval '1 day'" }
→ { "rowCount": 3, "rows": [ { "id": "...", "name": "...", "created_at": "..." }, ... ] }Cualquier cosa que no sea una sola sentencia SELECT/WITH (múltiples sentencias, DDL,
DML, SET, etc.) se rechaza antes de llegar a la base de datos, con una explicación de
por qué.
Desarrollo local
npm run dev # runs src/index.ts directly via tsx, loads .env via Node's --env-fileEstructura del proyecto
src/
index.ts # MCP server setup and tool definitions
sqlGuard.ts # query validation (layer 2 of the safety model)
db.ts # Postgres pool setup (statement_timeout, pool size)
config.ts # env var loading/validationSolución de problemas
"DATABASE_URL environment variable is required" — falta
.envo no se está cargando; confirma que existe (desdecp .env.example .env) y que tu cliente MCP lo está recogiendo en su bloqueenvo ennpm run dev/npm start.El servidor registra la base de datos/usuario incorrectos al inicio — revisa
DATABASE_URL; el registro de inicio (connected as "..." to database "...") se imprime precisamente para que sea fácil detectarlo antes de que se ejecute cualquier consulta."Query rejected: ..." — la consulta no era una sola sentencia
SELECT/WITHo contenía una palabra clave no permitida. Esto es la capa 2 del modelo de seguridad funcionando como se espera, no un error.La consulta se cuelga y luego da error — probablemente está alcanzando
STATEMENT_TIMEOUT_MS; súbelo en.envsi tu carga de trabajo legítimamente necesita más tiempo, u optimiza la consulta.
Contribuciones
Las incidencias y las solicitudes de extracción son bienvenidas. Esta es intencionalmente una herramienta pequeña y auditable: el objetivo es mantener el modelo de seguridad lo bastante simple como para leerlo completo, no convertirlo en un constructor de consultas general.
Licencia
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- FlicenseAqualityDmaintenanceEnables AI assistants to interact with PostgreSQL databases using natural language queries, providing secure read-only access to database schemas and SQL translation capabilities.67
- AlicenseNot gradedqualityDmaintenanceEnables AI assistants to safely explore, analyze, and maintain PostgreSQL databases with read-only mode by default, SQL injection prevention, query performance analysis, and optional write operations.90Apache 2.0
- AlicenseNot gradedqualityNot gradedmaintenanceProvides AI assistants with safe, controlled access to PostgreSQL databases with read-only defaults, granular permissions, query safety features, and schema introspection capabilities.1
- FlicenseAqualityCmaintenanceEnables read-only exploration of a Postgres database using natural language, with multiple safety layers to prevent any modifications.5
Related MCP Connectors
Query PostgreSQL databases in plain English — LLM-generated, safety-validated SQL.
Read-only bank access for your AI agent. Connects Claude, ChatGPT, Cursor, Gemini, Codex.
Deterministic validation for AI-generated artifacts: JSON Schema, OpenAPI response, SQL syntax.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/david-mogbeyi/db-readonly-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server