Skip to main content
Glama
david-mogbeyi

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:

  1. 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.

  2. 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).

  3. LIMIT forzado: cada consulta se envuelve en SELECT * FROM (...) LIMIT N, con un tope de MAX_LIMIT independientemente de lo que se solicite.

  4. statement_timeout: las consultas se cancelan después de STATEMENT_TIMEOUT_MS.

  5. 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 install

2. 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 .env

Edita .env y establece DATABASE_URL con la cadena de conexión del rol de solo lectura:

DATABASE_URL=postgresql://myapp_readonly:<password>@localhost:5432/myapp

Consulta Configuración más abajo para las otras variables.

4. Compilar

npm run build

Esto 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

DATABASE_URL

Cadena de conexión de Postgres para el rol de solo lectura.

DEFAULT_LIMIT

No

100

Límite de filas aplicado cuando una consulta no especifica uno.

MAX_LIMIT

No

1000

Tope máximo de filas devueltas, independientemente de lo solicitado.

STATEMENT_TIMEOUT_MS

No

5000

statement_timeout de Postgres para cada consulta, en milisegundos.

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-file

Estructura 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/validation

Solución de problemas

  • "DATABASE_URL environment variable is required" — falta .env o no se está cargando; confirma que existe (desde cp .env.example .env) y que tu cliente MCP lo está recogiendo en su bloque env o en npm 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/WITH o 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 .env si 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

MIT

A
license - permissive license
Not graded
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

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

  • F
    license
    A
    quality
    D
    maintenance
    Enables AI assistants to interact with PostgreSQL databases using natural language queries, providing secure read-only access to database schemas and SQL translation capabilities.
    6
    7
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables 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.
    90
    Apache 2.0
  • A
    license
    Not graded
    quality
    Not graded
    maintenance
    Provides AI assistants with safe, controlled access to PostgreSQL databases with read-only defaults, granular permissions, query safety features, and schema introspection capabilities.
    1
  • F
    license
    A
    quality
    C
    maintenance
    Enables read-only exploration of a Postgres database using natural language, with multiple safety layers to prevent any modifications.
    5

View all related MCP servers

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.

View all MCP Connectors

Latest Blog Posts

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