MCP GraphQL Server Multi-Fuente
Allows querying and mutating data in Google Sheets through a dynamically generated GraphQL schema, including support for multiple sheets/tabs such as employee records and departments.
Allows querying and mutating collections in MongoDB with filtering, ordering, pagination, and CRUD operations through GraphQL.
Allows querying and mutating tables in MySQL databases with filtering, ordering, pagination, and CRUD operations through GraphQL.
Allows querying and mutating tables in PostgreSQL databases with filtering, ordering, pagination, and CRUD operations through GraphQL.
Allows querying and mutating records in SQLite databases with filtering, ordering, pagination, and CRUD operations through GraphQL.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@MCP GraphQL Server Multi-Fuente consulta los empleados con salario mayor a 50000 ordenados por salario"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
📄 README.md
# MCP GraphQL Server Multi-Fuente
Servidor MCP (Model Context Protocol) que expone una API GraphQL dinámica sobre múltiples fuentes de datos: CSV, Google Sheets, SQLite, PostgreSQL, MySQL, MongoDB y Oracle.
## ✨ Características
- 🔌 **Adaptadores múltiples**: CSV, Google Sheets, SQLite, PostgreSQL, MySQL, MongoDB, Oracle (preparado).
- 🧠 **Esquema GraphQL dinámico**: genera automáticamente el esquema según los datos.
- 🔍 **Consultas flexibles**: filtros avanzados (`where` con operadores), ordenamiento, paginación, selección de campos.
- ✍️ **Mutaciones**: crear, actualizar y eliminar registros con confirmación para eliminaciones.
- 🚀 **Batching**: ejecuta varias consultas en una sola petición.
- 💾 **Persisted Queries**: guarda consultas frecuentes y reutilízalas por hash.
- 📊 **Métricas**: seguimiento de rendimiento de consultas y mutaciones.
- 🛡️ **Seguridad**: límite de complejidad, errores personalizados, directiva `@auth` de ejemplo.
- 🔄 **Cambio de fuente dinámico**: alterna entre bases de datos sin reiniciar.
## 🏗️ Arquitectura
Cliente MCP (LM Studio, Claude Desktop) │ (stdio) ▼ Servidor MCP (index.ts) │ ├── Herramientas: graphql_query, graphql_mutation, switch_source, list_sources, etc. │ ▼ Capa GraphQL (schema.ts + resolvers.ts) │ ├── Adaptadores (BaseAdapter) │ ├── CSVAdapter │ ├── GoogleSheetsAdapter │ ├── SQLiteAdapter │ ├── PostgresAdapter │ ├── MySQLAdapter │ ├── MongoDBAdapter │ └── OracleAdapter │ ▼ Fuentes de datos (CSV, Google Sheets, SQLite, ...)
## 📦 Requisitos
- Node.js 18 o superior
- npm 9+
- Para SQLite: `better-sqlite3`
- Para PostgreSQL: `pg`
- Para MySQL: `mysql2`
- Para MongoDB: `mongodb`
- Para Oracle: `oracledb` (requiere cliente nativo)
## 🛠️ Instalación
```bash
# Clonar o descargar el proyecto
git clone <url-del-repo>
cd mcp-graphql-server
# Instalar dependencias base
npm install
# Instalar dependencias específicas según adaptadores a usar
npm install better-sqlite3 # SQLite
npm install pg # PostgreSQL
npm install mysql2 # MySQL
npm install mongodb # MongoDB
npm install oracledb # Oracle (requiere Oracle Instant Client)⚙️ Configuración
Crea un archivo .env en la raíz con las variables de entorno:
# Fuente activa por defecto: csv, google-sheets, sqlite, postgres, mysql, mongodb, oracle
DEFAULT_SOURCE=google-sheets
# CSV
CSV_FILE_PATH=./src/data/sample.csv
# Google Sheets
GOOGLE_SHEETS_API_URL=https://script.google.com/macros/s/TU_ID/exec
GOOGLE_SHEETS_NAME=Empleados
# SQLite
SQLITE_DB_PATH=./src/data/sample.db
SQLITE_TABLE=empleados
# PostgreSQL
PG_CONNECTION_STRING=postgres://user:password@localhost:5432/dbname
PG_TABLE=empleados
# MySQL
MYSQL_HOST=localhost
MYSQL_USER=root
MYSQL_PASSWORD=secret
MYSQL_DATABASE=test
MYSQL_TABLE=empleados
# MongoDB
MONGO_URI=mongodb://localhost:27017
MONGO_DB_NAME=test
MONGO_COLLECTION=empleados
# Oracle
ORACLE_USER=system
ORACLE_PASSWORD=oracle
ORACLE_CONNECT_STRING=localhost:1521/XEPDB1
ORACLE_TABLE=empleadosRelated MCP server: BaseQL MCP Server
🚀 Uso
Compilar
npm run buildIniciar el servidor
node dist/index.jsEl servidor se conecta por stdio, listo para que un cliente MCP (como LM Studio o Claude Desktop) lo utilice.
Configurar en LM Studio
Abre LM Studio y carga un modelo (ej. Gemma).
Ve a la configuración del chat y agrega un servidor MCP.
Comando:
nodeArgumentos:
H:\deepseek-graphql-mcp\dist\index.jsVariables de entorno: copia las de tu
.env.
Reinicia la conversación para que el modelo reconozca las herramientas.
Herramientas disponibles
graphql_query– Ejecuta consultas GraphQL.graphql_batch– Ejecuta varias consultas en una llamada.graphql_mutation– Crea, actualiza o elimina registros. Aceptasourcepara declarar sobre qué fuente crees estar trabajando; si no coincide con la activa, la operación se cancela sin tocar nada.switch_source– Cambia la fuente de datos activa.list_sources– Lista las fuentes disponibles.register_persisted_query– Registra una consulta persistida.get_metrics– Obtiene métricas de rendimiento.get_schema– Muestra el esquema de la fuente activa, derivado del esquema real.
Agregaciones
{ aggregate(field: "salario") { avg min max sum countNoNulos aviso } }Devuelve las cinco operaciones a la vez, con nombres fijos (no alias dinámicos del
tipo salario_avg). El campo aviso aparece cuando hay algo que el usuario debería
saber: filas sin dato, o un campo que no es numérico.
Evita que el modelo se traiga todos los registros para calcular una media él mismo.
🧪 Ejemplos de consultas
Obtener todos los registros
{
records {
id
nombre
email
}
}Filtrar y ordenar
{
records(
where: { salario: { operator: gt, value: "50000" } },
orderBy: [{ field: "salario", direction: "desc" }]
) {
nombre
salario
}
}Obtener departamentos (solo Google Sheets)
{
departamentos {
id
nombre
ubicacion
}
}Crear registro
mutation {
createRecord(input: { nombre: "Nuevo", email: "nuevo@email.com" }) {
id
nombre
}
}Eliminar con confirmación
mutation {
deleteRecord(id: "11")
}La primera llamada devuelve un aviso con el registro concreto que se va a borrar. La
segunda debe llevar confirm: true y el mismo id.
La confirmación está atada al objetivo, no al texto de la consulta: el modelo puede reescribir la mutación, pero no puede confirmar el borrado de otro registro. Es de un solo uso y caduca a los 120 segundos.
Declarar la fuente en las mutaciones
{
"query": "mutation { deleteRecord(id: \"1\") }",
"source": "sqlite",
"confirm": true
}Si source no coincide con la fuente activa, la operación se cancela sin modificar
nada y el error dice qué hacer. Existe porque la fuente activa es un estado invisible
para quien llama, y una suposición equivocada puede escribir en la base de datos que no
era.
🔌 Adaptadores incluidos
Adaptador | Archivo | Dependencia | Estado |
CSV |
|
| ✅ Probado |
Google Sheets |
|
| ✅ Probado |
SQLite |
|
| ✅ Probado |
PostgreSQL |
|
| 📦 Catálogo |
MySQL |
|
| 📦 Catálogo |
MongoDB |
|
| 📦 Catálogo |
Oracle |
|
| 📦 Catálogo |
Consulta EXTRA.md para más detalles sobre los adaptadores de base de datos.
🧰 Solución de problemas
El modelo escribe en la fuente equivocada: pasa cuando asume que ya cambió de fuente sin llamar a
switch_source. Desde la v0.5 las mutaciones aceptansourcey el servidor lo verifica antes de ejecutar. Revisa que el modelo lo esté declarando.Compilar no despliega: tras
npm run buildhay que reiniciar el proceso del servidor. Cerrar la ventana del cliente no siempre lo mata. Si arreglas algo y el comportamiento no cambia, empieza por aquí.El servidor probado no es el que usa el cliente:
dotenvbusca el.enven el directorio de trabajo actual, que no es el de tu proyecto cuando lo lanza el cliente. Pon todas las variables en la configuración del cliente MCP, con rutas absolutas.Un visor de base de datos muestra datos viejos: los visores cachean al abrir el archivo y no se enteran de los cambios de otros procesos. Recarga antes de concluir que algo no se guardó.
Error de tipos en GraphQL: revisa los logs de inicialización para ver el esquema inferido.
Google Sheets no carga: verifica que la URL de Apps Script sea accesible y que el nombre de la hoja coincida.
SQLite no funciona: comprueba que la base de datos exista y tenga la tabla indicada.
Error de compilación TS5055: revisa que
tsconfig.jsonincluya solosrc/**/*.
📝 Cambios recientes
v0.5 — correcciones de integridad
Salieron de probar el servidor contra un modelo local y observar qué hacía. Todas compilaban sin error antes del arreglo.
Datos
Las comparaciones y la ordenación se hacían sobre texto: en CSV y Google Sheets todo llega como cadena, así que
"9" > "50000"era verdadero. Un salario de nueve mil apareciendo en un filtro de "mayor que cincuenta mil". Añadidocoaccionar(), que convierte según el tipo declarado antes de comparar.La caché podía servir datos de antes de una modificación. Ahora la clave lleva un número de versión que sube en cada cambio: una entrada vieja no puede servirse.
clearCacheestaba duplicado en los siete adaptadores. Ahora hay uno solo enBaseAdapter.Un filtro sin valor devolvía lista vacía en silencio, y el modelo entraba en bucle reescribiendo la consulta. Ahora lanza un error que explica la sintaxis correcta.
Esquema
Todos los tipos se llamaban
Record, en todas las fuentes. Con dos fuentes de campos parecidos, el modelo no tenía nada con que distinguirlas. Ahora el nombre incluye la fuente:RecordSqliteEmpleados.get_schemallevaba su propia lista de consultas escrita a mano. Al añadiraggregateal esquema, ahí no aparecía, y el modelo seguía diciendo que no había agregaciones. Ahora se deriva del esquema real.Cada campo se podía filtrar de dos maneras: por
wherey por un argumento suelto. Se pagaba dos veces en el esquema. Eliminados los sueltos.La consulta
departamentosse declaraba siempre, incluso en fuentes sin tabla de departamentos. Ahora solo donde existe.Expuestas las agregaciones, que ya estaban implementadas y no se podían usar.
Seguridad
La confirmación de borrado no estaba atada a nada:
confirm: truevalía para cualquier mutación. Se podía aprobar el borrado del registro 11 y ejecutar el del 12. Ahora se ata al id, es de un solo uso y caduca.Las mutaciones aceptan
sourcey el servidor lo verifica. Evita escribir en la fuente equivocada cuando el modelo asume mal.
Adaptadores de base de datos
MongoDB comparaba
_idcomo cadena contra unObjectId: no coincidía nunca.deleteRecordde MongoDB devolvíatrueaunque no borrara nada.Oracle no compilaba por falta de tipos. Añadido
src/types/oracledb.d.ts.
Estado de los adaptadores
Los cuatro de base de datos compilan pero no se han ejecutado contra un servidor real. En el único que se revisó a fondo, MongoDB, aparecieron dos bugs de lógica que solo se ven al conectarse. Es razonable esperar más en los otros.
📄 Licencia
MIT – Libre uso y modificación.
Available Tools
8 toolsget_metricsC
Obtiene métricas de rendimiento
Inputs: no named parameters.
get_schemaA
Devuelve el esquema de la fuente ACTIVA: nombre de la fuente, campos con su tipo, consultas disponibles y ejemplos. LLAMA A ESTA HERRAMIENTA ANTES DE LA PRIMERA CONSULTA Y CADA VEZ QUE USES switch_source. Los campos cambian de una fuente a otra.
Inputs: no named parameters.
graphql_batchB
Ejecuta múltiples consultas GraphQL en una sola llamada
Inputs: queries (required), variables.
graphql_mutationA
Ejecuta una mutacion GraphQL (createRecord, updateRecord, deleteRecord) contra la fuente ACTIVA. Para eliminar, llama primero sin confirm para obtener el aviso, y despues con confirm: true y el MISMO id. DECLARA SIEMPRE el parametro "source" con la fuente sobre la que crees que estas trabajando: si no coincide con la activa, la operacion se rechaza en vez de escribir donde no debe.
Inputs: query (required), source, confirm, variables.
graphql_queryA
Ejecuta una consulta GraphQL contra la fuente de datos ACTIVA. IMPORTANTE: llama primero a get_schema para saber que campos existen; cada fuente tiene campos distintos y una consulta con un campo que no existe falla. La consulta principal es records(...). No existe ningun argumento "tabla" ni "coleccion": cada fuente expone UNA sola tabla, y para cambiar de tabla hay que cambiar de fuente con switch_source.
Inputs: query (required), hash, variables.
list_sourcesA
Lista todas las fuentes de datos disponibles y cuál está activa actualmente
Inputs: no named parameters.
register_persisted_queryC
Registra una consulta persistida y devuelve su hash
Inputs: query (required).
switch_sourceA
Cambia la fuente de datos activa. Solo hay UNA activa a la vez, y todas las consultas van contra ella. Cada fuente tiene sus propios campos, asi que DESPUES de cambiar hay que llamar a get_schema otra vez: el esquema anterior ya no vale. Fuentes: "csv", "google-sheets" y "sqlite".
Inputs: source (required).
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 8 tools
Each tool targets a distinct action: query, batch, mutation, source switching/listing, schema, persisted queries, and metrics. The only mild overlap is graphql_query vs graphql_batch and get_schema vs list_sources, but the descriptions clearly distinguish single vs multi and schema-vs-inventory. No real risk of misselection.
All names use consistent snake_case with clear verb_noun intent (switch_source, list_sources, get_schema, get_metrics). The graphql_* prefix group (query/batch/mutation) is a minor stylistic deviation but still readable and predictable. No mixed conventions.
Eight tools is well-scoped for a multi-source GraphQL server: core query/mutation, source management, schema discovery, and auxiliary features. Each tool earns its place with no redundancy.
Full lifecycle is covered: schema discovery, query, batch, and create/update/delete mutations across switchable sources. Minor gaps exist around managing persisted queries (no list/delete of registered hashes) and no explicit mutation confirmation helpers beyond the documented pattern.
Maintenance
Related MCP Connectors
Query Postgres, MySQL, SQL Server, Oracle, BigQuery, ClickHouse and Redshift from your AI client.
Read, write, and combine connected apps and databases with shared code and per-person permissions.
A collaborative substrate over your data: vector, knowledge graph, SQL, geospatial, streaming.
Query your Google Sheets as structured JSON: list sheets and tabs, read schemas, filter rows.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceAutomatically discovers GraphQL APIs through introspection and generates table-formatted queries with pagination, filters, and sorting. Supports multiple authentication types and provides both CLI and REST API interfaces for seamless integration.1MIT
- AlicenseAqualityDmaintenanceProvides GraphQL access to Airtable and Google Sheets data, enabling natural language queries for data exploration, schema introspection, and record management.6MIT
- AlicenseNot gradedqualityDmaintenanceEnables interaction with multiple databases (MySQL, PostgreSQL, SQLite, Supabase) through a unified interface with security features like SQL injection detection and rate limiting.259 npmMIT
- AlicenseNot gradedqualityCmaintenanceEnables querying, sampling, and exporting datasets from over twenty keyless free public data sources spanning the EU, Switzerland, Germany, the US, and global providers through one uniform set of tools. A single consistent interface lets users list databases and tables, inspect schemas and query guides, run queries, and export results as CSV or JSON without per-API clients.Apache 2.0