text-to-sql-mcp
Provides read-only access to a PostgreSQL database, enabling listing tables, retrieving schema details (columns, types, keys), and running safe SQL queries with row limits.
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., "@text-to-sql-mcpwhat are the top 5 best-selling genres by revenue?"
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.
Agent text-to-SQL via serveur MCP
Un agent qui traduit des questions métier en langage naturel en requêtes SQL sûres, exposé à Claude via un serveur MCP maison, avec un harnais d'évaluation comparant prompts et modèles.
Statut : en construction, jalon 3. Le serveur MCP en lecture seule, ses garde-fous, l'agent (boucle tool use + CLI) et le harnais d'évaluation sont en place et testés ; première évaluation à lancer (
notebooks/06_evaluation.ipynb).
Feuille de route
✅ Serveur MCP minimal (
list_tables,get_schema,run_query) en lecture seule sur Chinook✅ Agent text-to-SQL + garde-fous (rôle lecture seule, validation sqlglot,
LIMIT, timeout)🚧 Harnais d'évaluation : gold set, execution accuracy, comparaison de variantes, mini red-team
Documentation, rapport d'évaluation et démo (Claude Desktop / Claude Code)
Related MCP server: PostgreSQL MCP Server
Stack
Python 3.13 · SDK MCP officiel v2 · PostgreSQL 17 + Chinook · sqlglot · psycopg 3 · SDK Anthropic · uv · ruff · pytest · pre-commit
Installation (développement)
Prérequis : uv (il installe lui-même Python 3.13 si besoin).
uv sync # crée .venv, installe les dépendances et les commandes
uv run pre-commit install # active les hooks de qualité au commit
uv run pytest # lance les testsLes tests marqués integration utilisent la base Docker (voir ci-dessous) et sont sautés,
avec un message explicite, si elle n'est pas joignable. Pour ne lancer que les tests unitaires :
uv run pytest -m "not integration".
Les tests de l'agent remplacent l'API Anthropic par un faux client qui rejoue des réponses
écrites à l'avance : ils sont gratuits et déterministes. Les tests marqués api appellent la
vraie API (payant) et sont sautés par défaut : uv run pytest --api -m api.
Base de données (Docker)
Prérequis : Docker et le plugin docker compose.
cp .env.example .env # puis remplacer les mots de passe
docker compose up -d # premier démarrage : chargement de Chinook + rôle lecture seule
docker compose ps # attendre l'état « healthy »
docker compose down -v # tout supprimer, données comprises (repartir de zéro)La base chinook est exposée sur 127.0.0.1 uniquement. L'agent s'y connecte avec le rôle
agent_lecteur, qui n'a que des droits de lecture (SELECT) et des transactions en lecture
seule par défaut.
Données
Chinook v1.4.5, script PostgreSQL officiel
(identifiants en snake_case), versionné sans modification dans docker/initdb/01_chinook.sql.
Source :
https://github.com/lerocha/chinook-database/releases/download/v1.4.5/Chinook_PostgreSql.sqlSHA-256 :
e3fde5c1a5b51a2a91429a702c9ca6e69ba56e6c7f5e112724d70c3d03db695eLicence : MIT, © Luis Rocha (voir
docker/LICENSE-chinook.md)
Serveur MCP
Trois outils en lecture seule : list_tables, get_schema (colonnes, types, clés) et
run_query (une requête de lecture, résultat plafonné à ROW_CAP lignes).
uv run text-to-sql-mcp # lance le serveur sur stdio
npx @modelcontextprotocol/inspector uv run text-to-sql-mcp # interface de test (Node requis)La commande text-to-sql-mcp est déclarée dans [project.scripts] du pyproject.toml et
installée par uv sync. Équivalent sans la commande : uv run python -m text_to_sql_mcp.server.
Garde-fous (défense en profondeur)
Couche | Où | Ce qu'elle bloque |
Privilèges | rôle PostgreSQL | toute écriture, DDL, escalade |
Transaction | connexion ( | écriture, même après un |
Validation sqlglot |
| plusieurs instructions, écriture cachée (CTE, |
|
| résultats massifs, tris coûteux |
Curseur côté serveur |
| tout ce qui n'est pas une lecture unique (seconde barrière) |
| connexion (5 s) et rôle (30 s) | requêtes trop longues |
Le SQL exécuté est celui régénéré par sqlglot à partir de l'arbre validé (renvoyé dans
executed_sql) : on exécute exactement ce qui a été vérifié.
Logs
Une ligne JSON par appel d'outil sur stderr (stdout est réservé au protocole MCP), avec le
client appelant (clientInfo), l'outil, le statut (ok, refus, erreur, echec), la durée,
le nombre de lignes, le SQL soumis et le SQL exécuté.
Agent
Une boucle tool use écrite à la main (src/text_to_sql_mcp/agent/boucle.py) : l'agent envoie
la question à Claude avec les trois outils du serveur, exécute chaque demande d'outil sur le
serveur MCP (lancé en sous-processus stdio), renvoie les résultats, et recommence jusqu'à la
réponse finale.
uv run text-to-sql-agent "Quels sont les 5 artistes qui ont publié le plus d'albums ?"
uv run text-to-sql-agent "…" --model claude-haiku-5-5 --max-turns 5
uv run text-to-sql-agent "…" --json 2> trace.jsonl # résultat complet en JSON, logs à partLa clé ANTHROPIC_API_KEY et les réglages par défaut (AGENT_MODEL, AGENT_PROMPT,
AGENT_MAX_TURNS, AGENT_MAX_TOKENS) sont lus dans le .env. La commande se lance depuis la
racine du repo : le serveur MCP y lit lui aussi le .env.
Prompts versionnés : un fichier par variante dans
agent/prompts/(v0.md), choisi par son nom (--prompt v0) et tracé dans les logs.Plafond de tours : au dernier appel autorisé, l'agent est prévenu qu'il n'a plus d'outil et les outils sont désactivés (
tool_choice: none) ; il répond avec ce qu'il a obtenu, ou dit qu'il ne peut pas répondre en aussi peu de tours.Erreurs d'outils (refus des garde-fous, erreur SQL) renvoyées à Claude avec
is_error: il corrige sa requête ; le nombre d'erreurs est tracé.Résultat observé (
AgentResult) : SQL exécuté, colonnes et lignes de la dernière requête réussie, appels d'outils, tours, tokens, durée. Construit par le code à partir de ce qu'il observe, jamais à partir du texte du modèle.Statut de fin :
ok, ou lestop_reasonde l'API pour toute autre fin (max_tokens,refusal,pause_turn,model_context_window_exceeded,stop_sequence),max_toursen filet,arret_inattendupour unstop_reasoninconnu.
Codes de sortie du CLI : 0 statut ok, 1 autre statut, 2 erreur (arguments,
configuration, API ou base injoignable).
Logs : une ligne JSON tour_api par appel à l'API (tour, stop_reason, tokens, durée) et
une ligne fin_agent (bilan), sur stderr. Leur champ client
(text-to-sql-agent:<modèle>:<prompt>/<version>) est le même que celui des lignes appel_outil
du serveur : une question se suit d'un flux à l'autre.
Évaluation
Le harnais (src/text_to_sql_mcp/evaluation/) pose chaque question du gold set à l'agent, note
la réponse et écrit un enregistrement JSONL par réponse dans evals/resultats/. Le notebook
06_evaluation.ipynb lance les évaluations et affiche les résultats (plotly).
Gold set (evaluation/gold_chinook.toml) : 44 questions en français, adaptées du dataset
Chinook gold du projet nl2sql (licence MIT, voir
evaluation/LICENSE-gold-nl2sql.md) : 39 questions répondables (faciles, moyennes,
difficiles) et 5 questions sans réponse. Le SQL a été traduit vers PostgreSQL snake_case, les
dates décalées de +12 ans (Chinook v1.4.5), et chaque traduction vérifiée contre le résultat
publié par la source.
Métriques
Execution accuracy : on compare le résultat de l'agent à celui d'une requête de référence, pas le texte SQL. Même nombre de lignes, sauf pour les questions de classement où des lignes en plus à la fin sont tolérées (un top 3 dont le premier est le bon répond à « quel artiste… ? ») ; chaque colonne de la référence présente (colonnes en plus tolérées) ; ordre comparé seulement si la question l'implique ; valeurs normalisées (
"10",10et10.00égaux, arrondi à 2 décimales). Le résultat noté est celui de la requête que l'agent présente dans sa réponse, retrouvée parmi les requêtes réellement exécutées (à défaut, la dernière réussie) : une requête de vérification lancée après coup ne la remplace pas.Abstention : sur une question sans réponse, l'agent (prompt
v1) doit commencer sa réponse par[SANS_REPONSE]; le marqueur sur une question répondable est un faux refus.Latence et coût par question (tarifs publics, réflexion comprise).
pass^k (et pass@k) sur les questions difficiles posées k fois : la fiabilité.
Un oracle simulé (OracleAnthropic) permet une répétition à blanc du harnais et du notebook,
sans API ni coût. Chaque enregistrement garde la trace complète de l'agent : regrade() re-note
une évaluation passée après un changement de règle, sans rappeler l'API.
Notebooks (playgrounds)
Le dossier notebooks/ contient les essais qui précèdent chaque incrément de code, avec le kernel
du .venv :
Notebook | Sujet |
| premiers pas avec le SDK MCP |
| connexion psycopg et rôle lecture seule |
| validation sqlglot et contournements testés |
| boucle tool use, |
| boucle avec dépendances injectées, faux client, statuts |
| évaluation 1 (justesse, abstention, latence, coût) et 2 (pass^k) |
Les notebooks 04 à 06 appellent l'API Anthropic : ils attendent ANTHROPIC_API_KEY dans le
.env (jamais commité) et consomment des tokens.
Licence
This server cannot be deployed
Maintenance
Related MCP Connectors
Query PostgreSQL databases in plain English — LLM-generated, safety-validated SQL.
Query 40 databases from Claude, ChatGPT, or Cursor — on any device. Read-only, encrypted, audited.
Query Postgres, MySQL, SQL Server, Oracle, BigQuery, ClickHouse and Redshift from your AI client.
Query your Postgres from ChatGPT or Claude without exposing the database or handing over credentials. Run npx boltschema connect next to your database and it dials out over HTTPS — no inbound firewall rule, no open port, works with localhost and VPC-private databases. Read-only is enforced by a SQL guard, a Postgres READ ONLY transaction, and a scoped role generated for you.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceProvides authenticated access to PostgreSQL databases for Claude AI, enabling users to browse database tables, discover schemas, and execute custom SQL queries through natural language interaction.MIT
- AlicenseNot gradedqualityDmaintenanceEnables Claude to interact with PostgreSQL databases by executing SQL queries, exploring schemas, and monitoring database health. It provides tools for data manipulation and schema management via a secure SSE connection.115 npmMIT
- FlicenseNot gradedqualityDmaintenanceEnables Claude Desktop to interact with PostgreSQL databases through natural language for schema exploration, data analysis, and query execution. Users can search schemas, describe tables, and perform read or write operations without needing to write manual SQL.-
- AlicenseNot gradedqualityDmaintenanceEnables AI agents to query a PostgreSQL database through a small set of controlled, read-only tools for schema inspection, row lookup, and aggregate statistics.1MIT