sql-specialist-mcp
sql-specialist-mcp
Un modelo pequeño, de pesos abiertos y ajustado finamente que responde preguntas en lenguaje natural sobre una base de datos SQLite, expuesto como herramienta MCP que cualquier cliente MCP (Claude Desktop, Claude Code, agentes personalizados) puede llamar directamente. Está respaldado por un banco de pruebas de evaluación basado en exactitud de ejecución que compara al especialista con la técnica de prompting a un modelo frontera en exactitud, latencia y coste.
El objetivo de este proyecto no es «hacer una demo de texto a SQL»; es mostrar las partes de la ingeniería de LLM que están por debajo del prompting: tomar un modelo pequeño, adaptarlo a una tarea mediante LoRA, servirlo de forma eficiente y demostrar con una evaluación real basada en ejecución que un especialista barato es competitivo con (o mejor que) el prompting de un modelo frontera para esta tarea concreta.
Prueba la demo interactiva — recorre las 28 preguntas reales de la evaluación y mira el SQL real generado por el especialista, la latencia y las filas de resultado junto a la línea base del modelo frontera. No requiere instalación.
Por qué existe esto
La mayoría de los proyectos «text-to-SQL» de portafolio de IA son guías de inicio rápido de LangChain. Hay dos cosas que aquí pretenden ser diferentes:
La evaluación es rigurosa, no una cuestión de impresiones. Cada consulta de referencia (gold) se ejecuta contra la base de datos al construir el conjunto de datos (139/139 validadas), y la puntuación compara conjuntos de resultados, no el texto de la consulta: una consulta semánticamente correcta con un orden de columnas distinto sigue puntuando como correcta. Un predictor que solo repite la SQL de referencia puntúa un 100%; un predictor que siempre devuelve una consulta trivialmente incorrecta puntúa un 0%. Ambos están incluidos como pruebas de cordura (
tests/test_harness_oracle.py) para que la corrección del propio banco de pruebas no se dé por supuesta.Se distribuye como algo utilizable, no solo un repositorio de demostración. El modelo ajustado se expone como una herramienta MCP real (
nl_to_sql): apunta Claude Desktop o Claude Code amcp_server/server.pyy puede consultar realmente la base de datos como parte de una conversación.
Related MCP server: mcp-sqlite-chat
Resultados
El pipeline completo se ha ejecutado de extremo a extremo en hardware real, en ambos lados: ajuste fino LoRA real, fusión real, cuantización GGUF real, servicio con Ollama real, evaluación real — y una línea base real de modelo frontera contra la API de Claude en vivo. Modelo base: Qwen/Qwen2.5-Coder-0.5B-Instruct (elegido por su bucle de iteración rápido en un portátil; consulta Ajuste fino más abajo para la ruta de 1.5B).
Predictor | Exactitud | n | latencia p50 | latencia p95 | Coste / 1k llamadas |
frontera: Claude Haiku 4.5 (con prompting) | 53.6% | 28 | 1055ms | 1884ms | $1.06 |
sql-specialist (ajustado, cuantizado, local) | 92.9% | 28 | 207ms | 371ms | $0.00 |
Léelo teniendo en cuenta la advertencia, no solo el titular. Audité manualmente cada uno de los 13 «fallos» medidos de Claude Haiku con este conjunto de evaluación: cero eran errores de lógica SQL. Los 13 eran desajustes de convención en la selección de columnas o en el orden de las filas — p. ej., devolver (name, email) cuando la respuesta de referencia era solo (name), o filas correctas en un orden distinto al de un ORDER BY que la pregunta original nunca especificaba. La estricta métrica de exactitud de ejecución (eval/execution.py compara filas de resultados columna por columna) puntúa esos casos igual que una consulta realmente errónea, algo que el especialista ajustado nunca produce porque ha memorizado las convenciones exactas de este conjunto de datos a partir de 111 ejemplos de entrenamiento — algo que un modelo frontera con prompting zero-shot no tiene forma de saber. Taxonomía completa fallo por fallo en COMPARISON.md.
Así que: la brecha de exactitud es real, pero en parte es un artefacto de lo que la evaluación premia, no puramente una brecha de razonamiento. La brecha de latencia y coste no es un artefacto — 207ms/local/gratis frente a 1055ms/$1.06-por-cada-1000-llamadas es el resultado real y sin edulcorar de ejecutar un modelo cuantizado de 0.5B en local en lugar de llamar a una API, y es la comparación sobre la que realmente se sustenta la premisa de este proyecto.
Los 2 fallos propios del especialista (de 28) fueron errores lógicos genuinos, no desajustes de formato: alucinar una columna orders.total que no existe en este esquema, y omitir un calificador de tabla en un SELECT de varias tablas. El entrenamiento convergió limpiamente en 3 épocas (pérdida de evaluación 0.060 → 0.048 → 0.008), y el modelo cuantizado (988MB f16 → 373MB q4_k_m) se sirve a través de Ollama en ~200ms.
Qué es real aquí
Ser transparente sobre esto importa más de lo que parece: es la diferencia entre un proyecto en el que un reclutador puede confiar y uno que suena a marketing.
La base de datos y el conjunto de datos sintéticos son demostrablemente correctos.
shopsphere.dbse siembra de forma determinista (seed=42); cada uno de los 139 pares (pregunta, SQL) de referencia endata/*.jsonlse genera a partir de plantillas parametrizadas y se ejecuta contra la base de datos real en tiempo de construcción: una plantilla que produce SQL inválido hace fallar la construcción; no envía silenciosamente una etiqueta incorrecta.La corrección del banco de pruebas de evaluación está a su vez probada, no se da por supuesta:
tests/test_harness_oracle.pyverifica que un predictor oráculo (que devuelve la SQL de referencia tal cual) puntúe exactamente un 100% y que un predictor deliberadamente incorrecto puntúe ~0%, antes de confiar en la cifra de cualquier predictor real.Exactitud de ejecución, no coincidencia de cadenas.
eval/execution.pycompara conjuntos de resultados (insensible al orden salvo que la consulta de referencia tengaORDER BY), de modo que una consulta escrita de forma distinta pero semánticamente equivalente sigue puntuando como correcta.El ajuste fino es real, en esta máquina, y se verificó su convergencia. LoRA (8.8M de parámetros entrenables, el 1.75% del modelo) durante 3 épocas, con la pérdida de evaluación descendiendo de forma monótona en cada época. Consulta Notas de ingeniería más abajo para ver dos errores reales encontrados y corregidos en el camino.
La ejecución SQL está realmente aislada (sandboxed), no solo se le pide que se comporte bien: las consultas de lectura se validan contra una lista blanca de regex y se ejecutan contra una conexión SQLite realmente de solo lectura a nivel de sistema operativo (
mode=ro) — un fallo en la protección regex no puede acabar en una escritura. Esto importa más allá del banco de pruebas de evaluación, porque la misma protección se ejecuta en el servidor MCP, donde el SQL proviene de un modelo que responde a la pregunta de un agente, no de un conjunto de evaluación curado.El servidor MCP es una herramienta real e invocable que sirve el modelo ajustado real, verificado de extremo a extremo:
nl_to_sql("Which employees have no manager assigned?")→ genera SQL mediante el modelo cuantizado a través de Ollama → lo ejecuta en solo lectura → devuelve filas reales → registra latencia/coste en observabilidad.La observabilidad está construida a medida y sin dependencias —
observability/logger.pyregistra cada llamada (latencia, tokens, coste estimado, éxito/fallo) en un archivo SQLite local, sin necesidad de cuenta externa, con el mismo patrón quepr-review-agent.La línea base del modelo frontera también es real —
eval/baseline_frontier.pyse ejecutó contra la API de Claude en vivo (Claude Haiku 4.5), no solo se importó sin problemas. Sus «fallos» resultaron revelar un hallazgo real de metodología de evaluación; consulta Resultados más arriba yCOMPARISON.mdpara la auditoría manual completa de fallos.
Notas de ingeniería: dos errores reales encontrados al ejecutar esto de verdad
Ejecutar de verdad el ajuste fino (en lugar de dejarlo como «debería funcionar en teoría») sacó a la luz dos errores reales de memoria de PyTorch, ambos corregidos en el código actual:
Crecimiento descontrolado del asignador de caché de MPS. Entrenar en el backend MPS de Apple Silicon mediante
transformers.Trainerhacía que el proceso se inflara hasta 23GB de RSS y se colgara, con el padding dinámico por lote: cada forma distinta (batch, seq_len) recibe su propio grupo de memoria en el asignador MPS de PyTorch, que no devuelve la memoria liberada al sistema operativo. Solución:--device cpuenfinetune.pyy, más de fondo, padding de longitud fija (más abajo) para que esta clase de error no pueda repetirse en ningún backend.Sobrecarga de
Trainer/DataLoader, no del modelo. Un pase directo de forward+backward se cronometró en 1.6s/ejemplo; el mismo cálculo a través detransformers.Trainerdejaba el proceso inactivo durante minutos entre pasos registrados, sin cómputo correspondiente. Se encontró la causa raíz aislando el forward/backward real del modelo+LoRA con cronometraje manual antes de asumir que el error estaba en el código del modelo. Solución: se sustituyóTrainerpor un bucle de entrenamiento manual de ~40 líneas (training/finetune.py): misma configuración LoRA, control directo sobre el bucle de lotes, sin sobrecarga inexplicable. También se cambió la colación de lotes de dinámica por lote a padding de longitud fija (todos los lotes con la misma forma), lo que por separado corrigió el patrón de fragmentación del asignador del error n.º 1.
Ninguna de las dos soluciones es un parche colocado encima: ambas aparecen en training/finetune.py como la única implementación, no como un camino alternativo.
Arquitectura
data/build_dataset.py ──▶ data/{train,eval}.jsonl (139 examples, template-generated,
every gold SQL executed at build time)
│
┌─────────────────────┼─────────────────────┐
▼ ▼ ▼
training/finetune.py eval/baseline_frontier.py tests/test_harness_oracle.py
(LoRA on a small (prompt Claude Haiku/ (sanity-checks the harness
open model) Sonnet as the baseline) itself before trusting scores)
│ │
▼ │
training/merge_and_quantize.py
│ │
▼ ▼
serving/ollama_predictor.py ──┴──▶ eval/harness.py ──▶ eval/report.py ──▶ COMPARISON.md
│ (execution-accuracy scoring,
│ same logic for every predictor)
▼
mcp_server/server.py (nl_to_sql tool -- installable in Claude Desktop/Code)
│
▼
observability/logger.py (latency, tokens, cost -- local SQLite, no external account)Estructura del proyecto
schema/ synthetic "ShopSphere" e-commerce DB (7 tables) + seeded generator
data/ templated gold (question, SQL) dataset -- every query build-time validated
eval/ execution-accuracy harness, frontier baseline, comparison report
training/ LoRA fine-tuning pipeline + LoRA-merge/quantize script
serving/ Ollama-backed and in-process HF predictors, Ollama Modelfile template
mcp_server/ the installable MCP tool (nl_to_sql)
observability/ self-built call logging (latency/tokens/cost), no external account
tests/ harness sanity checks (oracle predictor must score 100%)Configuración
python3.11 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt # base: anthropic, mcp, requests
python schema/generate_data.py # build the seeded database
python data/build_dataset.py # build + validate the gold dataset
python tests/test_harness_oracle.py # confirm the eval harness itself is soundrequirements-train.txt añade torch/transformers/peft/trl para la ruta de ajuste fino: es más pesado y se mantiene separado para que la ruta de evaluación/servicio/MCP se instale rápido.
Ejecutar el pipeline completo
1. Línea base del modelo frontera (necesita ANTHROPIC_API_KEY):
export ANTHROPIC_API_KEY="..."
python -m eval.baseline_frontier --model claude-haiku-4-5
# writes eval/results_claude-haiku-4-5.json2. Ajuste fino del especialista (esto es lo que se ejecutó realmente para producir los resultados anteriores: tarda ~15 min de cómputo activo en una CPU de portátil, aunque el tiempo real transcurrido varía mucho con la carga del sistema; una GPU es mucho más rápida, ver más abajo):
pip install -r requirements-train.txt
python -m training.finetune --base-model Qwen/Qwen2.5-Coder-0.5B-Instruct --device cpu
python -m training.merge_and_quantize --base-model Qwen/Qwen2.5-Coder-0.5B-Instruct
# then follow the printed llama.cpp + ollama create instructions3. Puntúa al especialista de la misma manera que a la línea base:
python -c "
from eval.harness import run_eval, report_to_dict
from serving.ollama_predictor import OllamaPredictor
import json
report = run_eval(OllamaPredictor())
json.dump(report_to_dict(report), open('eval/results_specialist.json', 'w'), indent=2)
"4. Genera el informe de comparación:
python -m eval.report eval/results_claude-haiku-4-5.json eval/results_specialist.jsonAjuste fino: cómo escalar
Los resultados anteriores usan Qwen2.5-Coder-0.5B-Instruct en CPU, para un bucle de iteración local rápido. training/finetune.py --base-model acepta cualquier repositorio de HF de LM causal (o un directorio local): Qwen2.5-Coder-1.5B-Instruct es un cambio directo para mejor calidad, y una sola GPU en la nube (una T4 es suficiente para este tamaño de conjunto de datos) entrena cualquiera de los dos tamaños en un par de minutos en lugar de ~15:
pip install -r requirements-train.txt
python -m training.finetune \
--base-model Qwen/Qwen2.5-Coder-1.5B-Instruct \
--epochs 3--device {cuda,mps,cpu} anula la detección automática. MPS se detecta automáticamente en Apple Silicon, pero todavía no se recomienda para esta tarea; consulta Notas de ingeniería más arriba.
Servidor MCP
# Backend defaults to a locally-served model via Ollama:
python -m mcp_server.server
# Or run against a prompted frontier model instead (no fine-tune needed --
# useful for trying the tool before training anything):
SQL_SPECIALIST_BACKEND=frontier SQL_SPECIALIST_MODEL=claude-haiku-4-5 \
ANTHROPIC_API_KEY=... python -m mcp_server.serverAñade lo siguiente a la configuración MCP de Claude Desktop (claude_desktop_config.json):
{
"mcpServers": {
"sql-specialist": {
"command": "/absolute/path/to/sql-specialist-mcp/.venv/bin/python",
"args": ["-m", "mcp_server.server"],
"cwd": "/absolute/path/to/sql-specialist-mcp"
}
}
}Después pídele a Claude algo como «Usando la herramienta sql-specialist, ¿qué clientes nunca han realizado un pedido?»: llamará a nl_to_sql, recibirá filas reales de la base de datos y responderá basándose en los datos reales.
Notas de seguridad
La ejecución SQL es de solo lectura en dos capas independientes: una protección regex que rechaza cualquier cosa que no sea
SELECT/WITH, y una conexión SQLite realmente de solo lectura a nivel de sistema operativo (file:...?mode=ro) como respaldo final.El servidor MCP nunca ejecuta nada que la protección rechace, sin importar lo que hayan pedido el modelo o el agente que llama.
No se almacenan secretos en este repositorio.
ANTHROPIC_API_KEYse lee únicamente de las variables de entorno.
Qué construiría a continuación
Normalizar la evaluación para superconjuntos de columnas: puntuar como correcta una predicción si están presentes los valores de las columnas solicitadas en la referencia, en lugar de exigir una coincidencia exacta columna por columna. Esta es la corrección que implica la taxonomía de fallos de
COMPARISON.md; muy probablemente cerraría la mayor parte de la brecha medida del 53.6%→92.9% y daría una comparación que aísle la capacidad real de razonamiento del seguimiento de convenciones.Ejecutar también
eval/baseline_frontier.pycontra Claude Sonnet, como punto de comparación con un modelo más potente (Haiku es el nivel barato/rápido; Sonnet responde a la pregunta de «cuánto cierra la brecha la potencia del modelo por sí sola»).Ajustar finamente
Qwen2.5-Coder-1.5B-Instructen una GPU y comparar su exactitud con el resultado de 0.5B (92.9%) para cuantificar directamente la compensación tamaño/calidad.Aplicar DPO dirigido a los dos modos de fallo conocidos del especialista (columnas alucinadas, calificadores de tabla omitidos en multi-joins), ahora que existen datos reales de fallos.
Ruta de servicio con vLLM para comparar el rendimiento con la ruta Ollama/GGUF.
This server cannot be installed
Maintenance
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
- FlicenseNot gradedqualityCmaintenanceEnables natural language database queries by combining Ollama's language models with SQLite database access through an MCP server.
- FlicenseNot gradedqualityCmaintenanceEnables querying and managing a SQLite database using natural language, with an MCP server and Groq LLM.
- FlicenseNot gradedqualityBmaintenanceEnables AI agents to query a SQLite database using natural language through the Model Context Protocol (MCP). Includes security guardrails that block destructive SQL operations.
- AlicenseNot gradedqualityDmaintenanceMCP tool server providing SQLite database access for AI agents.MIT
Related MCP Connectors
GibsonAI MCP server: manage your databases with natural language
Analytical memory for AI agents: a real Postgres queried in plain English over MCP. One command.
Free OpenAI-compatible inference with signed provenance receipts and 3 focused MCP tools.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/Eshanya1/sql-specialist-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server