mcp-sql-agent
Can connect to a MySQL database to provide schema-aware, read-only SQL querying, including tools for inspecting schema and running SELECT queries.
Can connect to a PostgreSQL database to provide schema-aware, read-only SQL querying, including tools for inspecting schema and running SELECT queries.
Provides schema-aware, read-only SQL access to a SQLite database, with tools for retrieving table schema details and executing SELECT queries.
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-sql-agentShow me the top 5 customers by total order value in 2024."
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.
Autonomous SQL-Agent & MCP Server
A Python MCP server that gives an LLM schema-aware, read-only access to a SQL database, so non-technical users can ask business questions in plain English and get back the exact data table.
Built as a portfolio version of a production pattern used in real client data-pipeline work — same architecture, demo data.
Why this exists
Naively dumping an entire database schema into an LLM prompt wastes tokens and increases hallucinated column/table names on anything but a toy schema. This server instead exposes two tools and lets the model decide when to use them:
get_db_schema(table_names=None)— called with no arguments, returns just the list of table names. Called with specific table names, returns those tables' columns, primary/foreign keys, and 3 sample rows. The model only pulls in the schema detail it actually needs for the question at hand.run_sql_query(query)— executes a read-only SQL query (anything that isn't aSELECTis rejected before it touches the database) and returns the result set as text.
Related MCP server: mcp-db-server
The self-healing loop
If run_sql_query returns a SQL error (bad column name, syntax issue, etc.),
that error text is fed straight back to the model on the next turn instead
of failing the request. The model reads the error and retries with a
corrected query. agent.py caps this at MAX_RETRIES = 3 — an important
edge case to flag in review, since an uncapped retry loop on a persistently
malformed query would burn tokens indefinitely without ever getting a useful
answer back to the user.
Architecture
User question
│
▼
Claude 3.5 Sonnet (agent.py) ── system prompt instructs: always check
│ schema before writing SQL
├──> get_db_schema tool ──> server.py ──> demo.db (SQLite)
│
├──> run_sql_query tool ──> server.py ──> demo.db (SQLite)
│ │
│ └── on ERROR, error text returned to model → retry (≤3x)
│
▼
Final answer + SQL usedThe demo database (db/demo.db) is SQLite for portability; server.py is
written so the connection layer is the only thing that would need to change
to point at PostgreSQL/MySQL in production (this project's production
counterpart ran against PostgreSQL).
Evaluation methodology
eval/benchmark.json contains a set of natural-language business questions
mapped to hand-written ground-truth SQL (15 questions are included in this
public repo as a representative sample of the original 50-question internal
benchmark).
Accuracy is measured as execution/result accuracy, not string accuracy. The generated query does not need to match the ground-truth query character-for-character — it's scored correct if executing it returns the identical result set as the ground truth. A query using a different but equivalent JOIN structure, alias names, or column order that still returns the same rows counts as correct.
Run it yourself:
pip install -r requirements.txt
python db/seed.py
export ANTHROPIC_API_KEY=sk-...
python eval/run_eval.pyThis writes eval/results.json with per-question pass/fail and retry counts.
Project structure
mcp-sql-agent/
├── server.py # MCP server: schema + query tools
├── agent.py # Claude orchestration + self-healing retry loop
├── db/
│ ├── schema.sql # demo retail schema
│ └── seed.py # generates db/demo.db with 4,000 synthetic orders
├── eval/
│ ├── benchmark.json # sample text-to-SQL evaluation set
│ └── run_eval.py # runs the benchmark, computes execution accuracy
└── requirements.txtHonest limitations
The retry loop can still get stuck retrying the same category of error if the model misdiagnoses the root cause — the cap prevents runaway cost, but doesn't guarantee eventual success.
run_sql_queryblocks non-SELECTstatements at the string level (regex on the leading keyword). A production deployment against a real database should additionally run the connection itself under a read-only DB role, rather than relying on the guard in this layer alone.The demo dataset is synthetic; the accuracy figure is meaningful for this benchmark and schema, not as a general text-to-SQL benchmark claim.
This server cannot be deployed
Maintenance
Related MCP Connectors
Safe, read-only Postgres and MySQL access for AI agents. Audit log + column-level controls.
Query PostgreSQL databases in plain English — LLM-generated, safety-validated SQL.
Query your org's data in natural language — read-only MCP access to SQL, NoSQL, files & warehouses.
Ask business questions in plain English. Get instant answers from your database, no SQL needed.
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceEnables AI assistants to safely query and explore SQL Server and PostgreSQL databases with read-only access, supporting schema discovery, relationship exploration, and query execution.15 npm3MIT
- AlicenseNot gradedqualityDmaintenanceEnables LLM clients to query SQL databases via natural language with read-only, AST-validated, and capped queries, ensuring safety guarantees.2MIT
- FlicenseNot gradedqualityCmaintenanceEnables AI tools to understand a database, inspect schema, and run safe SELECT queries with SQL guardrails, plus optional codebase reading.-
- FlicenseNot gradedqualityDmaintenanceEnables natural language querying of SQL databases with robust safety guarantees including read-only enforcement, AST validation, and row caps.-