Skip to content

Servidor MCP para tu base de datos, con Claude Code

Actualizado:

Quieres que Claude Code trabaje con tus datos de verdad. No con un esquema que adivinó leyendo tus migraciones, sino con las filas: qué clientes se fueron, qué productos encajan con una descripción vaga, qué dispositivos comparten demasiadas cuentas. Para eso existe MCP. Aquí vas a ver el camino más corto entre Claude Code y una base de datos que el agente puede consultar, buscar por significado y recorrer como grafo.

Construimos SynapCores, una base de datos nativa para IA. Todos los comandos y resultados de esta página corrieron en SynapCores 2.4.8-ce con Claude Code 2.1.319.

Qué es un servidor MCP (y qué hace con tu base de datos)

MCP (Model Context Protocol) es la forma en que un agente como Claude Code usa herramientas que no son suyas. Un servidor MCP publica una lista de herramientas. Cada una tiene un nombre, una descripción y los parámetros que acepta. El agente lee esa lista, decide cuál le sirve y la llama. El servidor ejecuta la llamada y le devuelve el resultado como texto.

Cuando el servidor está frente a una base de datos, las herramientas son cosas como "listar tablas", "describir esta tabla" o "ejecutar esta consulta". El agente nunca recibe una cadena de conexión. Recibe herramientas, atadas a una sola credencial.

Lo normal es que ese servidor lo corras tú: un proceso o paquete aparte que se conecta a la base de datos con un driver. En SynapCores no hay proceso aparte. La base de datos es el servidor MCP.

Por qué importa que venga dentro de la base de datos

Cada instancia de SynapCores sirve MCP en POST /v1/mcp. Está siempre activo y no hay nada que configurar. Es el mismo proceso que ejecuta tu SQL, así que las herramientas llegan a todo lo que hace el motor:

  • SQL con IA adentro. La herramienta query ejecuta SQL de SynapCores. Un solo SELECT puede llamar a EMBED() para convertir texto en vector, ordenar filas con COSINE_SIMILARITY(), puntuar filas con ANOMALY_SCORE() usando un modelo entrenado en la base de datos y filtrar por columnas normales. Todo en una llamada.
  • Un grafo en el mismo motor. La herramienta graph_query ejecuta Cypher sobre los mismos datos. "¿Qué dispositivos comparten tres clientes o más?" es una sola llamada.
  • Un solo esquema de permisos. El agente actúa como el usuario dueño de la clave de API. Las reglas de acceso que pusiste para REST valen igual para MCP.

Para el agente esto significa un servidor y una credencial para filtrar, buscar por significado, puntuar anomalías y recorrer el grafo. No necesitas otro servidor para vectores ni una API de embeddings aparte. Si quieres la idea completa, lee qué es una base de datos para IA.

Cuándo NO lo necesitas

  • Tus datos viven en Postgres y solo necesitas SQL normal. Si el agente solo lee y escribe filas, un servidor MCP para tu base de datos actual es lo más simple. SynapCores vale la pena cuando las preguntas del agente necesitan búsqueda por significado, puntuación de anomalías o recorrer un grafo junto a las filas.

Conecta Claude Code con un comando

1. Arranca SynapCores y consigue una clave de API

Descarga la Community Edition y arráncala. El motor escucha en http://127.0.0.1:8080. Inicia sesión como admin y crea una clave de API para el agente. La respuesta trae la clave una sola vez, en raw_key, así que guárdala directo en una variable de entorno:

bash
TOKEN=$(curl -s -X POST http://127.0.0.1:8080/v1/auth/login \
  -H 'Content-Type: application/json' \
  -d '{"username":"admin","password":"<tu contraseña>"}' | jq -r .access_token)

export SYNAPCORES_API_KEY=$(curl -s -X POST http://127.0.0.1:8080/v1/api-keys \
  -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
  -d '{"name":"claude-code"}' | jq -r .raw_key)

2. Agrega el servidor a Claude Code

bash
claude mcp add --transport http synapcores http://127.0.0.1:8080/v1/mcp \
  --header "Authorization: Bearer $SYNAPCORES_API_KEY"

Eso es toda la instalación. Claude Code habla con el motor por HTTP, así que no hay nada más que descargar.

La clave va en un encabezado Authorization: Bearer. Usa una clave de API y no un token de sesión: los tokens de sesión vencen a las 24 horas y la clave de API sigue funcionando.

Si trabajas en equipo, agrega el servidor con alcance de proyecto y deja la clave fuera de git. Las comillas simples evitan que tu shell expanda la variable, así que .mcp.json guarda el marcador ("Authorization": "Bearer ${SYNAPCORES_API_KEY}") y cada quien usa su propia clave:

bash
claude mcp add --scope project --transport http synapcores http://127.0.0.1:8080/v1/mcp \
  --header 'Authorization: Bearer ${SYNAPCORES_API_KEY}'

3. Revisa la conexión

bash
claude mcp list

Entre los servidores que lista, debe aparecer este:

text
synapcores: http://127.0.0.1:8080/v1/mcp (HTTP) - ✔ Connected

Las herramientas que recibe Claude Code

Claude Code lee 15 herramientas del servidor y las nombra mcp__synapcores__<herramienta>:

describe_table, execute, list_tables, query, sql_manual, validate_query, train_model, predict, list_models, describe_model, semantic_search, embed_text, graph_query, generate_text, agent_soul

Casi nunca las vas a llamar por nombre. Haces una pregunta y el agente elige la herramienta.

Pruébalo: tres preguntas, un servidor

Puedes escribirle a Claude Code en español. Las consultas SQL, los resultados y los textos de prueba quedan en inglés porque así corrieron.

Carga un dataset de prueba pequeño

Las preguntas necesitan algunos datos: diez productos con descripción y unos clientes que comparten dispositivos. Pídele a Claude Code que lo ejecute con la herramienta execute (acepta las cuatro sentencias de una vez) o mándalo a POST /v1/query/execute. Crea la tabla products, inserta diez filas y llena la columna embedding con EMBED(), dentro de la base de datos:

sql
CREATE TABLE products (id INT PRIMARY KEY, name TEXT, category TEXT, price_cents INT, description TEXT, embedding VECTOR(384));

INSERT INTO products (id, name, category, price_cents, description) VALUES
(1, 'Shift-Long Work Clog', 'Footwear', 8900, 'A clog-style work shoe built for nurses, chefs and line cooks who are on their feet through twelve-hour shifts. A rocker sole, anti-fatigue memory-foam footbed and slip-resistant outsole ease pressure on heels and arches from clock-in to clock-out.'),
(2, 'Floor Shift Cushioned Mule', 'Footwear', 7900, 'A cushioned slip-on shoe with plush dual-density foam and arch support for retail associates and baristas who spend the whole day behind the counter. Easy slip-on fit, non-marking grippy sole.'),
(3, 'Afterhours Recovery Slide', 'Footwear', 4900, 'Soft foam slide sandal that relieves sore, tired feet after a long day on your feet at work. Contoured footbed cradles the arch and absorbs impact.'),
(4, 'Warehouse Pro Cushioned Sneaker', 'Footwear', 11900, 'A work sneaker with a shock-absorbing midsole and supportive insole for warehouse pickers walking concrete floors eight hours a day. Lightweight, breathable and easy on the knees.'),
(5, 'Redwood Rain Boot', 'Footwear', 7099, 'A rain boot with a fully sealed rubber shell that keeps puddles and slush out.'),
(6, 'Sierra Chelsea Boot', 'Footwear', 4899, 'A chelsea boot with elastic side gussets and a pull tab for quick on and off.'),
(7, 'Juniper Leather Loafer', 'Footwear', 11299, 'A leather loafer with full-grain leather and a slim profile that dresses up for the office.'),
(8, 'All-Shift Compression Socks', 'Base Layers', 2400, 'Graduated compression and cushioned merino soles reduce leg fatigue for people on their feet at work all day.'),
(9, 'Cobalt Tech Tee', 'Base Layers', 5699, 'A tech tee with a quick-dry polyester knit for hot runs.'),
(10, 'Tundra Insulated Bottle', 'Accessories', 8399, 'An insulated bottle with double-wall vacuum steel that holds ice for 24 hours.');

UPDATE products SET embedding = EMBED(description);

Las descripciones van en inglés a propósito: el modelo de embeddings que trae el motor está entrenado en inglés.

Ahora el grafo: seis clientes y tres dispositivos. La herramienta graph_query acepta el bloque completo (sentencias separadas por ;):

cypher
MERGE (:Customer {id: 101});
MERGE (:Customer {id: 102});
MERGE (:Customer {id: 103});
MERGE (:Customer {id: 104});
MERGE (:Customer {id: 105});
MERGE (:Customer {id: 106});
MERGE (:Device {id: 'DEV-7F3A'});
MERGE (:Device {id: 'DEV-7F3B'});
MERGE (:Device {id: 'DEV-0042'});
MATCH (c:Customer {id: 101}), (d:Device {id: 'DEV-7F3A'}) MERGE (c)-[:USES]->(d);
MATCH (c:Customer {id: 102}), (d:Device {id: 'DEV-7F3A'}) MERGE (c)-[:USES]->(d);
MATCH (c:Customer {id: 103}), (d:Device {id: 'DEV-7F3A'}) MERGE (c)-[:USES]->(d);
MATCH (c:Customer {id: 104}), (d:Device {id: 'DEV-7F3A'}) MERGE (c)-[:USES]->(d);
MATCH (c:Customer {id: 103}), (d:Device {id: 'DEV-7F3B'}) MERGE (c)-[:USES]->(d);
MATCH (c:Customer {id: 104}), (d:Device {id: 'DEV-7F3B'}) MERGE (c)-[:USES]->(d);
MATCH (c:Customer {id: 105}), (d:Device {id: 'DEV-7F3B'}) MERGE (c)-[:USES]->(d);
MATCH (c:Customer {id: 106}), (d:Device {id: 'DEV-0042'}) MERGE (c)-[:USES]->(d);

Pregunta qué hay

En Claude Code:

text
Lista las tablas de mi base de datos SynapCores y luego ejecuta SELECT 1 + 1 AS two.

Claude Code llamó a list_tables, luego a query (SELECT 1 + 1 AS two), y respondió:

text
Listo. Tu base de datos `main` en SynapCores tiene 4 tablas:

- `automl_experiments`
- `automl_models`
- `automl_trials`
- `products`

Y la consulta `SELECT 1 + 1 AS two` devolvió `two = 2` (en 1 ms).

Las tres tablas automl_* son el catálogo de AutoML del propio motor; products es la del dataset. Con tus datos vas a ver tus tablas.

Busca por significado, con filtros, en una sola llamada

Pregúntale:

text
Busca en mi base de datos SynapCores calzado de menos de 100 dólares que sirva para estar de pie todo el día. Usa la búsqueda vectorial en SQL (EMBED y COSINE_SIMILARITY).

El agente revisa la tabla con describe_table y responde con una llamada a query. Escribe su propio SQL, así que el tuyo puede variar. Esta es la forma base: el WHERE es SQL de siempre; EMBED() y COSINE_SIMILARITY() corren dentro de la misma sentencia:

sql
SELECT name, price_cents,
       ROUND(COSINE_SIMILARITY(embedding, EMBED('comfortable shoes for standing all day')), 3) AS score
FROM products
WHERE category = 'Footwear' AND price_cents < 10000
ORDER BY score DESC LIMIT 3

Resultado en 2.4.8-ce:

name price_cents score
Shift-Long Work Clog 8900 0.583
Floor Shift Cushioned Mule 7900 0.537
Afterhours Recovery Slide 4900 0.443

Ninguna descripción del seed dice "comfortable" ni "standing all day". Los zapatos de trabajo hablan de turnos de doce horas, espuma antifatiga y pies cansados. Encontrarlos igual es justo lo que hace la búsqueda por significado. Sin el LIMIT, la bota chelsea (0.265) y la bota de lluvia (0.226), que también pasan el filtro, quedan más abajo.

Aunque le escribas en español, Claude Code le pasa a EMBED() el texto en inglés ("comfortable shoes for standing all day, all-day comfort, cushioned support" en nuestra corrida), y eso importa: el modelo de embeddings es inglés. Con esa consulta, el agente puso primero el Floor Shift Cushioned Mule (0.63) y el Shift-Long Work Clog (0.62).

Recorre el grafo

Pregúntale:

text
¿Qué dispositivos comparten tres clientes o más?

El agente usa graph_query con Cypher. La consulta directa es esta:

cypher
MATCH (d:Device)<-[:USES]-(c:Customer)
WITH d, count(c) AS accounts
WHERE accounts >= 3
RETURN d.id AS device, accounts
ORDER BY accounts DESC

Resultado en 2.4.8-ce:

device accounts
DEV-7F3A 4
DEV-7F3B 3

DEV-0042 (un solo cliente) queda fuera. En nuestra corrida, Claude Code primero miró qué etiquetas tiene el grafo y luego respondió:

text
Dos dispositivos son compartidos por tres o más clientes, según el grafo de SynapCores (relación `USES` entre `Customer` y `Device`):

| Dispositivo | Nº de clientes | Clientes (id) |
|---|---|---|
| DEV-7F3A | 4 | 101, 102, 103, 104 |
| DEV-7F3B | 3 | 103, 104, 105 |

Dos dispositivos compartidos entre cuentas que se cruzan (103 y 104 usan los dos). Es el tipo de red que un analista de fraude quiere ver primero.

Qué puede ver el agente

El agente se conecta como el usuario dueño de la clave de API. La herramienta query corre como ese usuario, así que los permisos de esa clave aplican aquí también. Dale al agente la clave de un usuario con justo el acceso que quieres que tenga.

Con una clave de solo lectura ("permission": "ReadOnly" al crearla), el agente se queda en consultas SELECT: query responde y execute devuelve Read-only credentials cannot execute SQL with write or unproven function effects.

Siguiente paso

Preguntas frecuentes

¿Qué es un servidor MCP y para qué sirve?

MCP (Model Context Protocol) es un protocolo para que un agente de IA use herramientas externas. Un servidor MCP publica una lista de herramientas, cada una con nombre, descripción y parámetros. El agente lee la lista, elige la que necesita y la llama. Un servidor MCP para base de datos ofrece herramientas como listar tablas, describir una tabla o ejecutar una consulta.

¿Tengo que instalar un servidor MCP aparte para SynapCores?

No. El servidor MCP es parte de la base de datos. Cada instancia de SynapCores lo sirve en /v1/mcp, siempre activo, así que conectas Claude Code directo al motor con un comando claude mcp add y una clave de API.

¿Qué herramientas recibe Claude Code?

Quince: describe_table, execute, list_tables, query, sql_manual, validate_query, train_model, predict, list_models, describe_model, semantic_search, embed_text, graph_query, generate_text y agent_soul.

¿El agente puede hacer búsqueda vectorial por MCP?

Sí. La herramienta query ejecuta SQL de SynapCores, así que un SELECT puede llamar a EMBED() y COSINE_SIMILARITY() y seguir usando filtros WHERE normales. El agente busca por significado y filtra en una sola llamada, sin una base de datos vectorial ni una API de embeddings aparte.

¿Qué datos puede ver el agente?

Los mismos que el usuario dueño de la clave de API. Las consultas corren como ese usuario, así que los permisos que aplican por REST aplican igual por MCP. Con una clave de solo lectura, el agente solo puede hacer SELECT.

¿Dónde guarda Claude Code la clave?

Con el alcance local por defecto, claude mcp add guarda el encabezado, clave incluida, en ~/.claude.json en tu máquina. Para un repositorio compartido usa --scope project y el marcador ${SYNAPCORES_API_KEY} entre comillas simples: así el .mcp.json que subes a git guarda el nombre de la variable, no la clave.