mcp-database-server

Servidor de Protocolo de Contexto de Modelo (MCP) de grado de producción para acceso unificado a bases de datos SQL. Conecta múltiples bases de datos a través de un solo servidor MCP con descubrimiento de esquemas, mapeo de relaciones, almacenamiento en caché y controles de seguridad.

Documentación

@adevguide/mcp-database-server

npm version npm downloads

Servidor MCP (Model Context Protocol) de nivel de producción para acceso unificado a bases de datos SQL. Conecta múltiples bases de datos a través de un único servidor MCP con descubrimiento de esquemas, mapeo de relaciones, caché y controles de seguridad.

Contenido

Características

  • Soporte multi-base de datos: PostgreSQL, MySQL/MariaDB, SQLite, SQL Server, Oracle
  • Descubrimiento automático de esquemas: tablas, columnas, índices, claves foráneas, relaciones
  • Caché persistente de esquemas: TTL + versionado, actualización manual, estadísticas de caché
  • Inferencia de relaciones: claves foráneas + heurísticas
  • Inteligencia de consultas: seguimiento, estadísticas, tiempos de espera
  • Asistencia de joins: rutas de join sugeridas basadas en grafos de relaciones
  • Controles de seguridad: modo solo lectura, permitir/denegar operaciones de escritura, redacción de secretos
  • Optimización de consultas: recomendaciones de índices, perfilado de rendimiento, detección de consultas lentas
  • Monitoreo de rendimiento: análisis de ejecución detallado, identificación de cuellos de botella
  • Reescritura de consultas: sugerencias de optimización automatizadas con estimaciones de impacto en el rendimiento

Por qué existe esto

Este proyecto fue originalmente creado con vibe-coding para resolver problemas reales que enfrentaba al conectar herramientas LLM a múltiples bases de datos SQL (conectividad consistente, descubrimiento de esquemas y ejecución segura de consultas). Desde entonces se ha endurecido hasta convertirse en un servidor MCP reutilizable con caché y valores de seguridad predeterminados.

Arquitectura

┌─────────────────────────────────────────────────────────┐
│                    MCP Client                            │
│            (Claude Desktop, IDEs, etc.)                  │
└────────────────┬────────────────────────────────────────┘
                 │ JSON-RPC over stdio
┌────────────────▼────────────────────────────────────────┐
│                MCP Database Server                       │
│  ┌──────────────────────────────────────────────────┐   │
│  │           Schema Cache (TTL + Versioning)        │   │
│  └──────────────────────────────────────────────────┘   │
│  ┌──────────────────────────────────────────────────┐   │
│  │  Query Tracker (History + Statistics)            │   │
│  └──────────────────────────────────────────────────┘   │
│  ┌──────────────────────────────────────────────────┐   │
│  │  Security Layer (Read-only, Operation Controls)  │   │
│  └──────────────────────────────────────────────────┘   │
└────┬─────────┬─────────┬──────────┬──────────┬─────────┘
     │         │         │          │          │
┌────▼───┐ ┌──▼────┐ ┌──▼─────┐ ┌──▼──────┐ ┌▼────────┐
│Postgres│ │ MySQL │ │ SQLite │ │ MSSQL   │ │ Oracle  │
└────────┘ └───────┘ └────────┘ └─────────┘ └─────────┘

Bases de datos compatibles

Base de datosDriverEstadoNotas
PostgreSQLpg✅ Soporte completoIncluye compatibilidad con CockroachDB
MySQL/MariaDBmysql2✅ Soporte completoIncluye compatibilidad con Amazon Aurora MySQL
SQLitesql.js✅ Soporte completoSQLite respaldado por WASM con persistencia de archivos
SQL Servertedious✅ Soporte completoMicrosoft SQL Server / Azure SQL
Oracleoracledb⚠️ StubRequiere Oracle Instant Client

Instalación

Instalación global (recomendada)

npm install -g @adevguide/mcp-database-server

Ejecuta:

mcp-database-server --config /absolute/path/to/.mcp-database-server.config

Ejecutar vía npx (sin instalación global)

npx -y @adevguide/mcp-database-server --config /absolute/path/to/.mcp-database-server.config

Instalar desde el código fuente

git clone https://github.com/iPraBhu/mcp-database-server.git
cd mcp-database-server
npm install
npm run build
node dist/index.js --config ./.mcp-database-server.config

Configuración

Crea un archivo .mcp-database-server.config en la raíz de tu proyecto:

Nota: El archivo de configuración se descubre automáticamente dentro del árbol del proyecto actual. Si no especificas --config, la herramienta busca hacia arriba desde el directorio actual hasta que alcanza la raíz del proyecto detectada (por ejemplo, un directorio que contenga package.json o .git). No continúa más allá de la raíz del proyecto. Si usas credentialCommand, pasa --config explícitamente.

{
  "databases": [
    {
      "id": "postgres-main",
      "type": "postgres",
      "secretRef": "DB_URL_POSTGRES",
      "readOnly": true,
      "pool": {
        "min": 2,
        "max": 10,
        "idleTimeoutMillis": 30000
      },
      "introspection": {
        "includeViews": true,
        "excludeSchemas": ["pg_catalog"]
      }
    },
    {
      "id": "mariadb-reporting",
      "type": "mysql",
      "secretRef": "DB_URL_MARIADB",
      "readOnly": true,
      "pool": {
        "min": 1,
        "max": 5
      }
    },
    {
      "id": "sqlite-local",
      "type": "sqlite",
      "path": "./data/app.db"
    }
  ],
  "cache": {
    "directory": ".sql-mcp-cache",
    "ttlMinutes": 10
  },
  "security": {
    "allowWrite": false,
    "allowedWriteOperations": ["INSERT", "UPDATE"],
    "disableDangerousOperations": true,
    "redactSecrets": true
  },
  "logging": {
    "level": "info",
    "pretty": false
  }
}

Referencia de configuración

Configuración de base de datos

Cada base de datos en el arreglo databases representa una conexión a una base de datos SQL.

Propiedades principales
PropiedadTipoObligatorioPredeterminadoDescripción
idstring✅ Sí-Identificador único para esta conexión de base de datos. Se usa en todas las llamadas de herramientas MCP. Debe ser único entre todas las bases de datos.
typeenum✅ Sí-Tipo de sistema de base de datos. Valores válidos: postgres, mysql, sqlite, mssql, oracle
urlstringCondicional*-Cadena de conexión explícita a la base de datos. Soporta interpolación de variables de entorno con ${DB_URL}, pero no es la ruta recomendada para el manejo de secretos.
secretRefstringCondicional*-Nombre de una variable de entorno que contiene la cadena de conexión completa. Se resuelve desde el entorno del proceso o desde un archivo .env junto al archivo de configuración.
credentialCommandstringCondicional*-Comando de shell que imprime la cadena de conexión completa en stdout al iniciar. Útil para 1Password, Vault, utilidades de AWS o herramientas de secretos personalizadas. Requiere iniciar el servidor con una ruta --config explícita.
pathstringCondicional**-Ruta del sistema de archivos al archivo de base de datos SQLite. Requerido solo para type: sqlite. Puede ser relativa o absoluta.
readOnlybooleanNotrueCuando es true, bloquea todas las operaciones de escritura (INSERT, UPDATE, DELETE, etc.). Recomendado para seguridad en producción.
eagerConnectbooleanNofalseCuando es true, se conecta a la base de datos inmediatamente al iniciar (fail-fast). Cuando es false, se conecta en la primera consulta (carga diferida).

* Requerido para postgres, mysql, mssql, oracle
** Requerido solo para sqlite

Formatos de cadena de conexión:

PostgreSQL:  postgresql://username:password@host:5432/database
MySQL:       mysql://username:password@host:3306/database  
SQL Server:  Server=host,1433;Database=dbname;User Id=user;Password=pass
SQLite:      (use path property instead)
Oracle:      username/password@host:1521/servicename
Configuración del pool de conexiones

El objeto pool controla el comportamiento del pool de conexiones. Mejora el rendimiento al reutilizar las conexiones de base de datos.

PropiedadTipoObligatorioPredeterminadoDescripción
minnumberNo2Número mínimo de conexiones a mantener en el pool. Se mantienen activas incluso cuando están inactivas.
maxnumberNo10Número máximo de conexiones concurrentes. No excedas el límite de conexiones de tu base de datos.
idleTimeoutMillisnumberNo30000Tiempo (ms) para mantener conexiones inactivas antes de cerrarlas. Ejemplo: 60000 = 1 minuto.
connectionTimeoutMillisnumberNo10000Tiempo (ms) de espera al establecer una conexión antes de agotar el tiempo. Fail-fast si la base de datos es inalcanzable.

Recomendaciones:

  • Desarrollo: min: 1, max: 5
  • Producción (tráfico bajo): min: 2, max: 10
  • Producción (tráfico alto): min: 5, max: 20
Configuración de introspección

El objeto introspection controla el comportamiento del descubrimiento de esquemas. Determina qué objetos de base de datos se analizan.

PropiedadTipoObligatorioPredeterminadoDescripción
includeViewsbooleanNotrueIncluir vistas de base de datos en el descubrimiento de esquemas. Establece a false si las vistas causan problemas de rendimiento.
includeRoutinesbooleanNofalseIncluir procedimientos almacenados y funciones. (No implementado por completo: funcionalidad planificada)
maxTablesnumberNoilimitadoLimitar la introspección a las primeras N tablas. Útil para bases de datos con más de 1000 tablas. Puede resultar en un descubrimiento de relaciones incompleto.
includeSchemasstring[]NotodosLista blanca de esquemas a inspeccionar. Solo aplicable a PostgreSQL y SQL Server. Ejemplo: ["public", "app"]
excludeSchemasstring[]NoningunoLista negra de esquemas a omitir. Valores comunes: ["pg_catalog", "information_schema", "sys"]

Esquema vs. base de datos:

  • PostgreSQL/SQL Server: Admite múltiples esquemas por base de datos. Usa includeSchemas/excludeSchemas.
  • MySQL/MariaDB: Esquema = base de datos. Usa el nombre de la base de datos en la cadena de conexión.
  • SQLite: Base de datos de archivo único, sin concepto de esquema.

Configuración de caché

Controla el almacenamiento en caché de metadatos de esquema para mejorar el rendimiento de inicio y reducir la carga de la base de datos.

PropiedadTipoObligatorioPredeterminadoDescripción
directorystringNo.sql-mcp-cacheRuta del directorio donde se almacenan los archivos de esquema en caché. Un archivo JSON por base de datos.
ttlMinutesnumberNo10Tiempo de vida (TTL) en minutos. Cuánto tiempo se considera válido el esquema en caché antes de una actualización automática.

Comportamiento de la caché:

  • Al iniciar: Carga el esquema desde la caché si está disponible y no ha expirado
  • Después de la expiración del TTL: La siguiente consulta activa una nueva introspección automática
  • Actualización manual: Usa la herramienta clear_cache o introspect_schema con forceRefresh: true
  • Archivos de caché: Se almacenan como {database-id}.json (p. ej., postgres-main.json)

Valores TTL recomendados:

  • Desarrollo: 5 minutos (el esquema cambia con frecuencia)
  • Staging: 30-60 minutos
  • Producción (estática): 1440 minutos (24 horas)
  • Producción (activa): 60-240 minutos (1-4 horas)

Configuración de seguridad

Controles de seguridad integrales para proteger tus bases de datos de operaciones no autorizadas o peligrosas.

PropiedadTipoObligatorioPredeterminadoDescripción
allowWritebooleanNofalseInterruptor maestro para operaciones de escritura. Cuando es false, todas las escrituras se bloquean en todas las bases de datos.
allowedWriteOperationsstring[]NotodasLista blanca de operaciones SQL permitidas cuando allowWrite: true. Valores válidos: INSERT, UPDATE, DELETE, CREATE, ALTER, DROP, TRUNCATE, REPLACE, MERGE
disableDangerousOperationsbooleanNotrueCapa de seguridad adicional. Cuando es true, bloquea las operaciones DELETE, TRUNCATE y DROP incluso si las escrituras están permitidas. Evita la pérdida accidental de datos.
redactSecretsbooleanNotrueRedacta cadenas de conexión, contraseñas y credenciales similares en registros y mensajes de error devueltos.

Capas de seguridad (evaluadas en orden):

  1. readOnly a nivel de base de datos → Bloquea todas las escrituras para una base de datos específica
  2. allowWrite global → Interruptor maestro para todas las bases de datos
  3. disableDangerousOperations → Bloquea específicamente DELETE/TRUNCATE/DROP
  4. allowedWriteOperations → Lista blanca de operaciones permitidas

Ejemplos de configuración:

// Read-only access (default - safest)
{
  "allowWrite": false
}

// Allow INSERT and UPDATE only (no deletes)
{
  "allowWrite": true,
  "allowedWriteOperations": ["INSERT", "UPDATE"],
  "disableDangerousOperations": true
}

// Full write access (development only - dangerous!)
{
  "allowWrite": true,
  "disableDangerousOperations": false
}

Configuración de registro (logging)

Controla la verbosidad y el formato de salida de los registros.

PropiedadTipoObligatorioPredeterminadoDescripción
levelenumNoinfoNivel de registro. Valores válidos: trace, debug, info, warn, error. Los niveles inferiores incluyen los niveles superiores.
prettybooleanNofalseCuando es true, formatea los registros como texto legible. Cuando es false, genera JSON estructurado (mejor para la agregación de registros en producción).

Niveles de registro:

  • trace: Todo (extremadamente verboso: úsalo solo para depuración)
  • debug: Información de diagnóstico detallada
  • info: Mensajes informativos generales (recomendado para producción)
  • warn: Mensajes de advertencia que no impiden la operación
  • error: Solo mensajes de error

Recomendaciones:

  • Desarrollo: level: "debug", pretty: true
  • Producción: level: "info", pretty: false
  • Solución de problemas: level: "trace", pretty: true

Ejemplo de configuración completa

{
  "databases": [
    {
      "id": "postgres-production",
      "type": "postgres",
      "url": "${DATABASE_URL}",
      "readOnly": true,
      "pool": {
        "min": 5,
        "max": 20,
        "idleTimeoutMillis": 60000,
        "connectionTimeoutMillis": 5000
      },
      "introspection": {
        "includeViews": true,
        "includeRoutines": false,
        "excludeSchemas": ["pg_catalog", "information_schema"]
      },
      "eagerConnect": true
    },
    {
      "id": "mysql-analytics",
      "type": "mysql",
      "url": "${MYSQL_URL}",
      "readOnly": true,
      "pool": {
        "min": 2,
        "max": 10
      },
      "introspection": {
        "includeViews": true,
        "maxTables": 100
      }
    },
    {
      "id": "sqlite-local",
      "type": "sqlite",
      "path": "./data/app.db",
      "readOnly": true
    }
  ],
  "cache": {
    "directory": ".sql-mcp-cache",
    "ttlMinutes": 60
  },
  "security": {
    "allowWrite": false,
    "allowedWriteOperations": ["INSERT", "UPDATE"],
    "disableDangerousOperations": true,
    "redactSecrets": true
  },
  "logging": {
    "level": "info",
    "pretty": false
  }
}

Resolución de secretos

Enfoque recomendado: secretRef

Mantén los secretos fuera de la configuración del cliente MCP y fuera de los valores de configuración del servidor.

Ejemplo de configuración:

{
  "databases": [
    {
      "id": "production-db",
      "type": "postgres",
      "secretRef": "DATABASE_URL"
    }
  ]
}

El servidor resuelve secretRef desde el entorno del proceso primero, y luego desde un archivo .env junto a .mcp-database-server.config.

Archivo de entorno (.env):

DATABASE_URL=postgresql://user:password@localhost:5432/dbname
DB_URL_MYSQL=mysql://user:password@localhost:3306/dbname
DB_URL_MARIADB=mysql://report_user:password@mariadb.local:3306/reporting
DB_URL_MSSQL=Server=host,1433;Database=db;User Id=sa;Password=pass

Alternativa: credentialCommand

{
  "databases": [
    {
      "id": "analytics-db",
      "type": "mysql",
      "credentialCommand": "op read op://analytics/mysql/url"
    }
  ]
}

El comando debe imprimir solo la cadena de conexión en stdout. Por seguridad, credentialCommand solo se permite cuando el servidor se inicia con una ruta --config explícita. Las configuraciones auto-descubiertas no pueden ejecutar comandos de credenciales.

Aún compatible: interpolación directa de entorno

Todavía puedes escribir "url": "${DATABASE_URL}", pero secretRef es la opción más limpia porque hace explícita la fuente del secreto.

Mejores prácticas:

  • ✅ Almacena el archivo .env fuera del control de versiones (agrégalo a .gitignore)
  • ✅ Usa archivos .env diferentes para cada entorno (dev, staging, prod)
  • ✅ Nunca subas credenciales a repositorios de git
  • ✅ Usa servicios de gestión de secretos (AWS Secrets Manager, HashiCorp Vault) en producción

Referencia de cadenas de conexión

Base de datosFormatoEjemplo
PostgreSQLpostgresql://user:pass@host:port/dbpostgresql://admin:secret@localhost:5432/myapp
MySQLmysql://user:pass@host:port/dbmysql://root:password@localhost:3306/myapp
MariaDBmysql://user:pass@host:port/dbmysql://report_user:password@mariadb.local:3306/reporting
SQL ServerServer=host,port;Database=db;User Id=user;Password=passServer=localhost,1433;Database=myapp;User Id=sa;Password=secret
SQLiteUsa la propiedad path"path": "./data/app.db" o "path": "/var/db/app.sqlite"

Parámetros adicionales:

PostgreSQL:

postgresql://user:pass@host:5432/db?sslmode=require&connect_timeout=10

MySQL:

mysql://user:pass@host:3306/db?charset=utf8mb4&timezone=Z

MariaDB:

mysql://user:pass@host:3306/db?charset=utf8mb4

SQL Server:

Server=host;Database=db;User Id=user;Password=pass;Encrypt=true;TrustServerCertificate=false

Integración con clientes MCP

Ubicaciones de archivos de configuración

Cliente MCPRuta del archivo de configuración
Claude Desktop (macOS)~/Library/Application Support/Claude/claude_desktop_config.json
Claude Desktop (Windows)%APPDATA%\Claude\claude_desktop_config.json
Cline (VS Code)Configuración de VS Code → Servidores MCP
Otros clientesConsulta la documentación específica del cliente

Métodos de configuración

Método 1: Instalación global con npm

Configuración:

{
  "mcpServers": {
    "database": {
      "command": "mcp-database-server",
      "args": ["--config", "/absolute/path/to/.mcp-database-server.config"]
    }
  }
}

Método 2: Instalación desde el código fuente

Configuración:

{
  "mcpServers": {
    "database": {
      "command": "node",
      "args": [
        "/absolute/path/to/mcp-database-server/dist/index.js",
        "--config",
        "/absolute/path/to/.mcp-database-server.config"
      ]
    }
  }
}

Propiedades de configuración

PropiedadDescripciónEjemplo
commandEjecutable a utilizar. Usa mcp-database-server para instalación con npm, node para instalación desde el código fuente."mcp-database-server"
argsMatriz de argumentos de línea de comandos. El primer argumento suele ser --config seguido de la ruta del archivo de configuración.["--config", "/path/to/config"]
envVariables de entorno opcionales que se pasan al servidor. Prefiere secretRef con un archivo .env local o herramientas externas de secretos para las credenciales de la base de datos.{"APP_ENV": "production"}

Cómo encontrar rutas absolutas:

# macOS/Linux
cd /path/to/mcp-database-server
pwd  # prints: /Users/username/projects/mcp-database-server

# Windows (PowerShell)
cd C:\path\to\mcp-database-server
$PWD.Path  # prints: C:\Users\username\projects\mcp-database-server

Herramientas MCP disponibles

Este servidor proporciona 15 herramientas para la interacción y optimización integral de bases de datos.

Referencia de herramientas

HerramientaPropósitoAcceso de escrituraDatos en caché
list_databasesLista todas las bases de datos configuradas con su estadoNoUsa caché
introspect_schemaDescubre y almacena en caché el esquema de la base de datosNoEscribe en caché
get_schemaRecupera metadatos de esquema almacenados en cachéNoLee de caché
run_queryEjecuta consultas SQL con controles de seguridadCondicional*Actualiza estadísticas
export_queryExporta resultados de consultas grandes de solo lectura a un archivo localNoSin caché
explain_queryAnaliza planes de ejecución de consultasNoSin caché
suggest_joinsObtiene recomendaciones inteligentes de rutas de uniónNoUsa caché
clear_cacheLimpia la caché de esquema y las estadísticasNoLimpia caché
cache_statusMuestra el estado y las estadísticas de la cachéNoLee de caché
health_checkPrueba la conectividad de la base de datosNoSin caché
analyze_performanceObtiene análisis detallados de rendimientoNoUsa estadísticas
suggest_indexesAnaliza consultas y recomienda índicesNoUsa estadísticas
detect_slow_queriesIdentifica y alerta sobre consultas lentasNoUsa estadísticas
rewrite_querySugiere versiones optimizadas de consultasNoUsa caché
profile_queryPerfila el rendimiento de consultas con cuellos de botellaNoSin caché

* Requiere allowWrite: true y respeta la configuración de seguridad


1. list_databases

Lista todas las bases de datos configuradas con su estado de conexión e información de caché.

Parámetros de entrada:

No se requiere ninguno.

Respuesta:

[
  {
    "id": "postgres-main",
    "type": "postgres",
    "connected": true,
    "cached": true,
    "cacheAge": 45000,
    "version": "abc123"
  }
]

Campos de la respuesta:

CampoTipoDescripción
idstringIdentificador de la base de datos según la configuración
typestringTipo de base de datos (postgres, mysql, sqlite, mssql, oracle)
connectedbooleanIndica si la conexión a la base de datos está activa
cachedbooleanIndica si el esquema está actualmente en caché
cacheAgenumberAntigüedad del esquema en caché en milisegundos (si está en caché)
versionstringHash de versión de la caché (si está en caché)

2. introspect_schema

Descubre y almacena en caché el esquema completo de la base de datos, incluyendo tablas, columnas, índices, claves foráneas y relaciones.

Parámetros de entrada:

ParámetroTipoObligatorioDescripción
dbIdstringIdentificador de la base de datos a inspeccionar
forceRefreshbooleanNoFuerza una nueva inspección incluso si la caché es válida (predeterminado: false)
schemaFilterobjectNoFiltra qué objetos inspeccionar
schemaFilter.includeSchemasstring[]NoInspeccionar solo estos esquemas (PostgreSQL/SQL Server)
schemaFilter.excludeSchemasstring[]NoOmitir estos esquemas durante la inspección
schemaFilter.includeViewsbooleanNoIncluir vistas de la base de datos (predeterminado: true)
schemaFilter.maxTablesnumberNoLimitar a las primeras N tablas

Ejemplo de solicitud:

{
  "dbId": "postgres-main",
  "forceRefresh": false,
  "schemaFilter": {
    "includeSchemas": ["public"],
    "excludeSchemas": ["temp"],
    "includeViews": true,
    "maxTables": 100
  }
}

Respuesta:

{
  "dbId": "postgres-main",
  "version": "a1b2c3d4",
  "introspectedAt": "2026-01-26T10:00:00.000Z",
  "schemas": [
    {
      "name": "public",
      "tableCount": 15,
      "viewCount": 3
    }
  ],
  "totalTables": 15,
  "totalRelationships": 12
}

3. get_schema

Recupera metadatos detallados del esquema desde la caché sin consultar la base de datos.

Parámetros de entrada:

ParámetroTipoObligatorioDescripción
dbIdstringIdentificador de la base de datos
schemastringNoFiltrar por un nombre de esquema específico
tablestringNoFiltrar por un nombre de tabla específico

Ejemplo de solicitud:

{
  "dbId": "postgres-main",
  "schema": "public",
  "table": "users"
}

Respuesta: Metadatos completos del esquema, incluyendo tablas, columnas, tipos de datos, índices, claves foráneas y relaciones inferidas.


4. run_query

Ejecuta consultas SQL con almacenamiento automático en caché del esquema, anotación de relaciones y controles de seguridad integrales.

Parámetros de entrada:

ParámetroTipoObligatorioDescripción
dbIdstringIdentificador de la base de datos a consultar
sqlstringConsulta SQL a ejecutar
paramsarrayNoValores de consulta parametrizados (previene la inyección SQL)
limitnumberNoNúmero máximo de filas a devolver
offsetnumberNoDesplazamiento de filas para lecturas paginadas. Requiere limit.
maxBytesnumberNoMáximo aproximado de bytes serializados para las filas devueltas.
includeMetadatabooleanNoIncluir metadatos de relaciones y estadísticas de consulta en la respuesta. Predeterminado: true.
trackQuerybooleanNoRegistrar esta consulta en el historial y los análisis de rendimiento. Predeterminado: true.
timeoutMsnumberNoTiempo de espera de la consulta en milisegundos

Ejemplo de solicitud:

{
  "dbId": "postgres-main",
  "sql": "SELECT * FROM users WHERE active = $1 ORDER BY id",
  "params": [true],
  "limit": 10,
  "offset": 0,
  "maxBytes": 32768,
  "includeMetadata": false,
  "trackQuery": false,
  "timeoutMs": 5000
}

Respuesta:

{
  "rows": [
    {"id": 1, "name": "Alice", "email": "alice@example.com", "active": true},
    {"id": 2, "name": "Bob", "email": "bob@example.com", "active": true}
  ],
  "columns": ["id", "name", "email", "active"],
  "rowCount": 2,
  "executionTimeMs": 15,
  "metadata": {
    "relationships": [...],
    "queryStats": {
      "totalQueries": 10,
      "avgExecutionTime": 20,
      "errorCount": 0
    },
    "pagination": {
      "limit": 10,
      "offset": 0,
      "hasMore": true,
      "nextOffset": 10
    },
    "responseSize": {
      "maxBytes": 32768,
      "rowsBytes": 1842,
      "rowsTrimmed": false,
      "omittedRowCount": 0
    }
  }
}

Para la ruta de lectura más rápida en MariaDB/MySQL, establece "includeMetadata": false y "trackQuery": false cuando solo necesites las filas de resultados y no requieras anotaciones de relaciones, historial de consultas ni análisis de rendimiento para esa solicitud.

Controles de seguridad:

  • ✅ Las operaciones de escritura están bloqueadas por defecto (allowWrite: false)
  • ✅ Las operaciones peligrosas (DELETE, TRUNCATE, DROP) están deshabilitadas por defecto
  • ✅ Se pueden permitir operaciones específicas mediante la lista blanca allowedWriteOperations
  • ✅ Modo readOnly por base de datos

5. explain_query

Recupera el plan de ejecución de la consulta sin ejecutarla.

Parámetros de entrada:

ParámetroTipoObligatorioDescripción
dbIdstringIdentificador de la base de datos
sqlstringConsulta SQL a analizar
paramsarrayNoParámetros de la consulta (para consultas parametrizadas)

Ejemplo de solicitud:

{
  "dbId": "postgres-main",
  "sql": "SELECT * FROM users JOIN orders ON users.id = orders.user_id WHERE users.active = $1",
  "params": [true]
}

Respuesta: Plan de ejecución nativo de la base de datos (el formato varía según el tipo de base de datos).


5a. export_query

Exporta los resultados de consultas grandes de solo lectura a un archivo local en .sql-mcp-cache/exports.

Estrategia de ejecución:

  • MySQL/MariaDB utiliza transmisión de filas a nivel de adaptador para evitar cargar el conjunto completo de resultados en memoria.
  • PostgreSQL y SQLite utilizan exportación paginada reescribiendo las ventanas LIMIT/OFFSET de nivel superior.
  • La exportación en SQL Server requiere una ruta de transmisión específica del adaptador en el futuro y actualmente fallará a menos que se admita la reescritura de paginación.

Parámetros de entrada:

ParámetroTipoObligatorioDescripción
dbIdstringIdentificador de la base de datos
sqlstringConsulta SQL de solo lectura a exportar
paramsarrayNoParámetros de la consulta
formatstringNoFormato de salida: jsonl o csv (predeterminado: jsonl)
pageSizenumberNoTamaño de página para adaptadores sin transmisión (predeterminado: 1000)
fileNamestringNoNombre opcional del archivo de salida escrito dentro del directorio de exportación
timeoutMsnumberNoTiempo de espera de la consulta en milisegundos

Ejemplo de solicitud:

{
  "dbId": "mariadb-reporting",
  "sql": "SELECT id, email, created_at FROM users ORDER BY id",
  "format": "jsonl",
  "fileName": "users-export.jsonl",
  "timeoutMs": 10000
}

Respuesta:

{
  "dbId": "mariadb-reporting",
  "outputPath": "/absolute/path/to/.sql-mcp-cache/exports/users-export.jsonl",
  "format": "jsonl",
  "strategy": "stream",
  "rowsExported": 250000,
  "columns": ["id", "email", "created_at"],
  "fileSizeBytes": 18342011,
  "executionTimeMs": 8421
}

6. suggest_joins

Analiza el grafo de relaciones para recomendar rutas de unión óptimas entre múltiples tablas.

Parámetros de entrada:

ParámetroTipoObligatorioDescripción
dbIdstringIdentificador de la base de datos
tablesstring[]Matriz de nombres de tablas a unir (2-10 tablas)

Ejemplo de solicitud:

{
  "dbId": "postgres-main",
  "tables": ["users", "orders", "products"]
}

Respuesta:

[
  {
    "tables": ["users", "orders", "products"],
    "joins": [
      {
        "fromTable": "users",
        "toTable": "orders",
        "relationship": {
          "type": "one-to-many",
          "confidence": 1.0
        },
        "joinCondition": "users.id = orders.user_id"
      },
      {
        "fromTable": "orders",
        "toTable": "products",
        "relationship": {
          "type": "many-to-one",
          "confidence": 1.0
        },
        "joinCondition": "orders.product_id = products.id"
      }
    ],
    "sql": "FROM users JOIN orders ON users.id = orders.user_id JOIN products ON orders.product_id = products.id"
  }
]

7. clear_cache

Limpia la caché de esquema y las estadísticas de consultas para una o todas las bases de datos.

Parámetros de entrada:

ParámetroTipoObligatorioDescripción
dbIdstringNoBase de datos a limpiar (omite para limpiar todas)

Ejemplo de solicitud:

{
  "dbId": "postgres-main"
}

Respuesta: Mensaje de confirmación.


8. cache_status

Recupera estadísticas detalladas de la caché e información de estado.

Parámetros de entrada:

No se requiere ninguno.

Respuesta:

{
  "directory": ".sql-mcp-cache",
  "ttlMinutes": 10,
  "databases": [
    {
      "dbId": "postgres-main",
      "cached": true,
      "version": "abc123",
      "age": 120000,
      "expired": false,
      "tableCount": 15,
      "sizeBytes": 45678
    }
  ]
}

9. health_check

Prueba la conectividad de la base de datos y devuelve información de estado.

Parámetros de entrada:

ParámetroTipoObligatorioDescripción
dbIdstringNoBase de datos a verificar (omite para verificar todas)

Respuesta:

{
  "databases": [
    {
      "dbId": "postgres-main",
      "healthy": true,
      "connected": true,
      "version": "PostgreSQL 15.3",
      "responseTimeMs": 12
    }
  ]
}

10. analyze_performance

Obtén análisis completos de rendimiento en todas las consultas de una base de datos.

Parámetros de entrada:

ParámetroTipoObligatorioDescripción
dbIdstringBase de datos a analizar

Respuesta:

{
  "totalQueries": 1250,
  "slowQueries": 23,
  "avgExecutionTime": 45.67,
  "p95ExecutionTime": 234.5,
  "errorRate": 1.2,
  "mostFrequentTables": [
    { "table": "users", "count": 456 },
    { "table": "orders", "count": 234 }
  ],
  "performanceTrend": "improving"
}

11. suggest_indexes

Analiza patrones de consulta y recomienda índices óptimos para la base de datos.

Parámetros de entrada:

ParámetroTipoObligatorioDescripción
dbIdstringBase de datos a analizar

Respuesta:

[
  {
    "table": "orders",
    "columns": ["customer_id", "order_date"],
    "type": "composite",
    "reason": "Frequently used in WHERE and JOIN conditions",
    "impact": "high"
  },
  {
    "table": "products",
    "columns": ["category_id"],
    "type": "single",
    "reason": "Column category_id is frequently queried",
    "impact": "medium"
  }
]

12. detect_slow_queries

Identifica consultas que superan los umbrales de rendimiento y proporciona alertas.

Parámetros de entrada:

ParámetroTipoObligatorioDescripción
dbIdstringBase de datos a analizar

Respuesta:

[
  {
    "dbId": "postgres-main",
    "queryId": "a1b2c3",
    "sql": "SELECT * FROM large_table WHERE slow_column = ?",
    "executionTimeMs": 2500,
    "thresholdMs": 1000,
    "timestamp": "2024-01-27T10:30:00Z",
    "frequency": 5,
    "recommendations": [
      {
        "type": "add_index",
        "description": "Add index on slow_column for better performance",
        "impact": "high",
        "effort": "medium"
      }
    ]
  }
]

13. rewrite_query

Sugiere versiones optimizadas de consultas SQL con mejoras de rendimiento.

Parámetros de entrada:

ParámetroTipoObligatorioDescripción
dbIdstringID de la base de datos
sqlstringConsulta SQL a optimizar

Respuesta:

{
  "originalQuery": "SELECT * FROM users WHERE active = 1",
  "optimizedQuery": "SELECT id, name, email FROM users WHERE active = 1 LIMIT 1000",
  "improvements": [
    "Removed unnecessary SELECT *",
    "Added LIMIT clause to prevent large result sets"
  ],
  "performanceGain": 35,
  "confidence": "high"
}

14. profile_query

Perfila el rendimiento de una consulta específica con análisis detallado de cuellos de botella.

Parámetros de entrada:

ParámetroTipoRequeridoDescripción
dbIdstringID de base de datos
sqlstringConsulta SQL para perfilar
paramsarrayNoParámetros de consulta

Respuesta:

{
  "queryId": "def456",
  "sql": "SELECT u.name, COUNT(o.id) FROM users u JOIN orders o ON u.id = o.user_id GROUP BY u.id",
  "executionTimeMs": 1250,
  "rowCount": 5000,
  "bottlenecks": [
    {
      "type": "join",
      "severity": "high",
      "description": "Nested loop join on large tables",
      "estimatedCost": 150
    }
  ],
  "recommendations": [
    {
      "type": "add_index",
      "description": "Add index on orders.user_id",
      "impact": "high",
      "effort": "low"
    }
  ],
  "overallScore": 65
}

Recursos

El servidor expone esquemas en caché como recursos MCP:

  • URI: schema://{dbId}
  • Tipo MIME: application/json
  • Contenido: Metadatos completos del esquema en caché

Introspección de Esquema

Descubrimiento Automático

El servidor descubre automáticamente:

  1. Tablas y Vistas: Todas las tablas de usuario y opcionalmente vistas
  2. Columnas: Nombre, tipo de datos, nulabilidad, valores predeterminados, auto-incremento
  3. Índices: Incluyendo claves primarias y restricciones únicas
  4. Claves Foráneas: Metadatos explícitos de relaciones
  5. Relaciones: Tanto explícitas como inferidas

Inferencia de Relaciones

Cuando las claves foráneas no están definidas, el servidor infiere relaciones mediante heurísticas:

  • Nombres de columnas que coinciden con {table}_id o {table}Id
  • Compatibilidad del tipo de datos con la clave primaria objetivo
  • Puntuación de confianza para relaciones inferidas

Estrategia de Caché

  • Memoria + Disco: Caché de doble capa para rendimiento
  • Basado en TTL: Tiempo de vida configurable
  • Seguimiento de Versiones: Versionado basado en contenido (hash)
  • Seguro para Concurrencia: Previene introspección duplicada
  • Actualización Bajo Demanda: Actualización manual o automática

Seguimiento de Consultas

El servidor mantiene un historial de consultas por base de datos:

  • Marca de tiempo y texto SQL
  • Tiempo de ejecución y número de filas
  • Tablas referenciadas (extracción de mejor esfuerzo)
  • Seguimiento de errores
  • Estadísticas agregadas

Utilice estos datos para:

  • Monitorear el rendimiento de consultas
  • Identificar tablas de acceso frecuente
  • Detectar patrones de consulta
  • Depurar problemas

Desarrollo

# Install dependencies
npm install

# Run in development mode
npm run dev

# Build
npm run build

# Run tests
npm test

# Run tests with coverage
npm run test:coverage

# Lint
npm run lint

# Format code
npm run format

# Type check
npm run typecheck

Estructura del Proyecto

src/
├── adapters/          # Database adapters
│   ├── base.ts        # Base adapter class
│   ├── postgres.ts    # PostgreSQL adapter
│   ├── mysql.ts       # MySQL adapter
│   ├── sqlite.ts      # SQLite adapter
│   ├── mssql.ts       # SQL Server adapter
│   ├── oracle.ts      # Oracle adapter (stub)
│   └── index.ts       # Adapter factory
├── cache.ts           # Schema caching
├── config.ts          # Configuration loader
├── database-manager.ts # Database orchestration
├── logger.ts          # Logging setup
├── mcp-server.ts      # MCP server implementation
├── query-tracker.ts   # Query history tracking
├── types.ts           # TypeScript types
├── utils.ts           # Utility functions
└── index.ts           # Entry point

Agregar Nuevos Adaptadores de Base de Datos

  1. Implemente la interfaz DatabaseAdapter en src/adapters/
  2. Siga el patrón de los adaptadores existentes
  3. Agregue a la fábrica de adaptadores en src/adapters/index.ts
  4. Actualice las definiciones de tipos si es necesario
  5. Agregue pruebas

Ejemplo:

import { BaseAdapter } from './base.js';

export class CustomAdapter extends BaseAdapter {
  async connect(): Promise<void> { /* ... */ }
  async disconnect(): Promise<void> { /* ... */ }
  async introspect(): Promise<DatabaseSchema> { /* ... */ }
  async query(): Promise<QueryResult> { /* ... */ }
  async explain(): Promise<ExplainResult> { /* ... */ }
  async testConnection(): Promise<boolean> { /* ... */ }
  async getVersion(): Promise<string> { /* ... */ }
}

Solución de Problemas

Problemas de Conexión

  • Verifique las cadenas de conexión y las credenciales
  • Compruebe la conectividad de red y las reglas de firewall
  • Habilite el registro de depuración: "logging": { "level": "debug" }
  • Utilice la herramienta health_check para probar la conectividad

Problemas de Caché

  • Limpiar caché: Utilice la herramienta clear_cache
  • Verifique los permisos del directorio de caché
  • Verifique la configuración de TTL
  • Revise el estado de la caché con la herramienta cache_status

Rendimiento

  • Ajuste la configuración del grupo de conexiones
  • Utilice maxTables para limitar el alcance de la introspección
  • Establezca un TTL de caché apropiado
  • Habilite el modo de solo lectura cuando sea posible

Configuración de Oracle

El adaptador de Oracle requiere configuración adicional:

  1. Instale Oracle Instant Client
  2. Establezca las variables de entorno (LD_LIBRARY_PATH o PATH)
  3. Instale el paquete oracledb
  4. Implemente métodos stub en src/adapters/oracle.ts

Consideraciones de Seguridad

  • Utilice siempre el modo de solo lectura en producción a menos que se requiera acceso de escritura
  • Utilice variables de entorno para las credenciales, nunca las codifique
  • Habilite la redacción de secretos en los registros
  • Restrinja las operaciones de escritura con allowedWriteOperations
  • Utilice cifrado de cadenas de conexión donde sea compatible
  • Auditorías de seguridad periódicas de las configuraciones

Licencia

MIT

Contribuciones

¡Las contribuciones son bienvenidas! Por favor:

  1. Haga un fork del repositorio
  2. Cree una rama de funcionalidad
  3. Agregue pruebas para la nueva funcionalidad
  4. Asegúrese de que todas las pruebas pasen
  5. Envíe un pull request

Soporte

Para problemas, preguntas o solicitudes de funciones, abra un issue en GitHub.