Mcp Postgres — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited Mcp Postgres (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Servidor Model Context Protocol que expone introspección y consulta read-only sobre PostgreSQL. Diseñado para alimentar de contexto a Claude (Claude Code, Claude Desktop) sin riesgo de escritura.
postgres://schema/{schema}, postgres://table/{schema}/{table})audit-table, find-tables, explain-foreign-keys, profile-slow-query)SET TRANSACTION READ ONLY, statement timeout, cap de filas, single-statement, validación de keywordsDB_SCHEMASpnpm run mcpb:pack)Requisitos: Node ≥ 18 y pnpm.
pnpm install
pnpm run build
cp .env.example .env # edita tus credenciales
npx tsx test-connection.ts # verifica conectividadLuego registra el servidor en Claude Code:
claude mcp add --transport stdio postgres \
-- node /ruta/absoluta/al/proyecto/dist/index.jsCopia .env.example a .env y edita los valores:
DB_HOST=localhost
DB_PORT=5432
DB_NAME=nombre_base_datos
DB_USER=usuario
DB_PASSWORD=contraseña
DB_SSL=false # true para AWS RDS / Supabase / Neon
DB_SSL_REJECT_UNAUTHORIZED=true # mantener true en producción
DB_SCHEMAS=public # esquemas permitidos, separados por coma. Vacío = todos los no-sistema
DEFAULT_LIMIT=5 # LIMIT por defecto en queries (máx 100)Hay varios archivos .env.<entorno> para alternar entre bases de datos sin reescribir credenciales:
cp .env.ecosistema-prd .env # producción
cp .env.ecosistema-tst .env # testing
cp .env.db-admision-tst .env # admisión testing
# ...etc.Recomendación: usa un rol de PostgreSQL de solo lectura (CREATE ROLE ... LOGIN; GRANT USAGE ON SCHEMA ... TO ...; GRANT SELECT ON ALL TABLES IN SCHEMA ... TO ...;). El servidor refuerza READ ONLY, pero la defensa en profundidad importa.claude mcp add (recomendado)Pasando credenciales como variables de entorno:
claude mcp add \
--transport stdio \
--env DB_HOST=localhost \
--env DB_PORT=5432 \
--env DB_NAME=mi_base \
--env DB_USER=mi_user \
--env DB_PASSWORD=mi_password \
--env DB_SCHEMAS=public \
postgres \
-- node /ruta/absoluta/al/proyecto/dist/index.jsTomando el .env del propio repo (omite los --env):
claude mcp add --transport stdio postgres \
-- node /ruta/absoluta/al/proyecto/dist/index.jsScope global (disponible en todos los proyectos):
claude mcp add --scope user --transport stdio postgres \
-- node /ruta/absoluta/al/proyecto/dist/index.js{
"mcpServers": {
"postgres": {
"command": "node",
"args": ["/ruta/absoluta/al/proyecto/dist/index.js"],
"env": {
"DB_HOST": "...",
"DB_NAME": "...",
"DB_USER": "...",
"DB_PASSWORD": "...",
"DB_SCHEMAS": "public"
}
}
}
}El proyecto incluye un manifest.json listo para empaquetar como MCPB (Claude Desktop Bundle).
pnpm run build
pnpm run mcpb:pack # genera mcp_postgres.mcpb en la raíz del repoEl .mcpb es un artefacto de build (está en .gitignore) — se regenera cuando lo necesites. No lo subas al repo.
mcp_postgres.mcpbUso personal (instalarlo en tu Claude Desktop):
mcp_postgres.mcpb a la ventana (o usa "Install extension")user_config del manifest.json — el campo db_password está marcado como sensitive.mcpb localDistribución privada (compartir con tu equipo):
gh release create v1.1.0 mcp_postgres.mcpb.mcpb y lo arrastran a Claude DesktopDistribución pública: publícalo en el MCP Bundle Directory cuando esté disponible. Mientras tanto, GitHub Releases es el canal estándar.
Si no lo vas a instalar ahora: simplemente bórralo (rm mcp_postgres.mcpb) y regenéralo con pnpm run mcpb:pack cuando lo necesites.
Todas las tools llevan readOnlyHint: true, destructiveHint: false y outputSchema Zod para structuredContent. Los errores recuperables se devuelven como { isError: true, content }, no como excepciones de protocolo.
| Tool | Descripción |
|---|---|
postgres_list_schemas | Lista esquemas accesibles. |
postgres_list_tables | Tablas de un esquema con conteo de columnas (paginado). |
postgres_describe_table | Columnas, constraints (PK/FK/UNIQUE) e índices. |
postgres_list_functions | Funciones/procedimientos con firma, retorno y lenguaje (paginado). |
postgres_list_triggers | Triggers con tabla, evento y timing (paginado). |
postgres_get_function_definition | Código fuente de una función (con soporte de sobrecarga). |
postgres_get_trigger_definition | Definición completa de un trigger. |
postgres_list_views | Vistas regulares y materializadas (paginado). |
postgres_search_columns | Busca columnas por nombre/patrón en todos los esquemas permitidos. |
| Tool | Descripción |
|---|---|
postgres_query_table | SELECT seguro sobre una sola tabla con filtros estructurados. |
postgres_execute_query | SELECT/WITH avanzado (JOINs, CTEs, agregaciones). Single-statement, READ ONLY. |
postgres_explain_query | EXPLAIN / EXPLAIN ANALYZE de un SELECT — perfila planes antes de ejecutar. |
postgres_get_table_stats | Tamaño total/tabla/índices/toast, vacuum/analyze, índices con idx_scan = 0. |
Las tools paginadas (postgres_list_*) aceptan limit/offset y devuelven has_more/next_offset para iterar.
URIs navegables que el host puede consumir como contexto:
| URI template | Contenido |
|---|---|
postgres://schema/{schema} | Resumen del esquema: tablas, vistas, funciones, triggers, conteos. |
postgres://table/{schema}/{table} | Estructura completa de una tabla (columnas + constraints + índices). |
Slash commands disponibles en Claude Code (/mcp__postgres__<prompt>):
| Prompt | Argumentos | Propósito |
|---|---|---|
audit-table | schema, table | Auditoría estructurada: schema, storage, sample, triggers, riesgos. |
find-tables | pattern | Encuentra columnas/tablas por patrón fuzzy en todos los esquemas. |
explain-foreign-keys | schema | Mapa textual del grafo de FKs (hubs, huérfanos). |
profile-slow-query | sql | EXPLAIN ANALYZE + recomendaciones priorizadas (índices faltantes, scans, sorts caros). |
Ejemplo (en Claude Code):
/mcp__postgres__audit-table schema=public table=users
/mcp__postgres__profile-slow-query sql="SELECT * FROM orders WHERE customer_id IN (SELECT id FROM customers WHERE country='PE')"DB_SCHEMAS restringe acceso a nivel de aplicación; además postgres_execute_query ajusta search_path local por consulta.postgres_query_table usa columnas/filtros estructurados con parámetros SQL — nunca concatena strings.postgres_execute_query y postgres_explain_query corren bajo SET TRANSACTION READ ONLY con statement_timeout = 30s.; interno y palabras clave de escritura (INSERT/UPDATE/DELETE/DROP/ALTER/CREATE/TRUNCATE/GRANT/REVOKE/EXECUTE/COPY) validadas por regex con \b.LIMIT automáticamente.DB_SSL=true, DB_SSL_REJECT_UNAUTHORIZED=true por defecto.DB_USER.src/
├── index.ts # Bootstrap — conecta transport y verifica DB
├── server.ts # createServer() — instancia McpServer, registra tools/resources/prompts
├── db/
│ └── pool.ts # Pool, allowedSchemas, defaultLimit, isSchemaAllowed
├── tools/
│ ├── introspection.ts # list_schemas / list_tables / describe_table / list_views / search_columns
│ ├── objects.ts # list_functions / list_triggers / get_*_definition
│ ├── query.ts # query_table / execute_query
│ └── analysis.ts # explain_query / get_table_stats
├── resources/
│ └── index.ts # postgres://schema/* y postgres://table/*
├── prompts/
│ └── index.ts # audit-table / find-tables / explain-foreign-keys / profile-slow-query
└── utils/
└── response.ts # formatResult(), assertSchemaAllowed(), CHARACTER_LIMITpnpm run build # Compila TypeScript → dist/
pnpm run dev # Watch mode
pnpm start # Ejecuta el servidor compilado
pnpm run mcpb:pack # Empaqueta como .mcpb para Claude DesktopTras editar cualquier archivo en src/, ejecuta pnpm run build antes de probar cambios. El binario que Claude Code/Desktop lanza es dist/index.js.
`Error: schema "X" is not allowed` — añade X a DB_SCHEMAS (o déjalo vacío para permitir todos los no-sistema).
`statement timeout` — la query supera 30 s. Usa postgres_explain_query con analyze=false primero, o filtra por una columna indexada.
`self-signed certificate` en RDS / Supabase — establece DB_SSL=true. Solo baja DB_SSL_REJECT_UNAUTHORIZED=false si el proveedor usa cert auto-firmado.
Claude Code no ve las tools — verifica con claude mcp list que postgres aparece como connected. Si no, claude mcp get postgres te muestra el comando registrado; comprueba que la ruta absoluta a dist/index.js es correcta y que el build está actualizado.
Query devuelve `has_more: true` — vuelve a llamar la tool pasando offset = next_offset. Las listas están paginadas para no inflar el contexto.
MIT
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.