Skip to main content
Glama
msharsha565-create

SQLite Explorer MCP

sqlite-mcp-explorer

A sandboxed text-to-SQL stack for AI agents: a read-only SQL server over MCP, a natural-language interface, and a benchmark that scores any text-to-SQL model on syntax validity, schema adherence and execution accuracy. Giving an agent a database is risky; the sandbox is built so a bad, hallucinated or hostile query cannot change data or run away.

demo

Safety model

Several independent layers, so one failure does not open the door:

  1. Read-only connection: the file is opened with mode=ro; SQLite itself refuses writes.

  2. Authorizer allow-list: only SELECT, column reads, functions and recursive CTEs are permitted. DROP, DELETE, UPDATE, INSERT, CREATE, ALTER, PRAGMA, ATTACH, VACUUM and load_extension are denied.

  3. One statement per call, so SELECT 1; DELETE ... is rejected.

  4. Bounded cost: results are capped at 200 rows (the response says if it was truncated), and a query is aborted after 2 seconds.

The tests exercise each layer, including attack queries, and check that data is unchanged afterwards.

Related MCP server: sqlite-analyst

Text-to-SQL and benchmark

Ask in plain English; a generator writes SQL, and that SQL runs through the same sandbox as everything else. Plug in any OpenAI-compatible model (OpenAI, Ollama, vLLM, LM Studio):

TEXT2SQL_MODEL="openai:llama3@http://localhost:11434/v1" sqlite-explorer-web

Gemini works through Google's OpenAI-compatible endpoint; keep the key under its own name:

GEMINI_API_KEY=... TEXT2SQL_API_KEY_ENV=GEMINI_API_KEY \
TEXT2SQL_MODEL="openai:gemini-3.1-flash-lite@https://generativelanguage.googleapis.com/v1beta/openai" \
sqlite-explorer-web
GEMINI_API_KEY=... sqlite-explorer-bench --api-key-env GEMINI_API_KEY \
  --generator "openai:gemini-3.1-flash-lite@https://generativelanguage.googleapis.com/v1beta/openai"

Use a current model name from the provider's docs (Gemini 2.5 models are already retired for new users). The generator retries 429/5xx responses, but gives up at once on a daily quota.

Live result (gemini-3.1-flash-lite, free tier, run 2026-10-22, one run): 53 questions, 100% produced SQL, 100% syntax validity, 100% schema adherence, 100% execution accuracy; latency p50 13.1 s, p95 52.2 s. A first run scored 98% (52/53): q50 ("average product price in each category") failed because the reference rounds to 2 decimals and the question did not say so. The question now says "rounded to 2 decimals". This is a small, easy benchmark, so 100% shows the pipeline works end to end rather than ranking models.

Benchmark any generator on 53 questions across 10 categories (counts, aggregates, joins, group-by, subqueries, top-N, dates). Reference answers are executed SQL, not text:

sqlite-explorer-bench --generator template                          # baseline, no LLM
sqlite-explorer-bench --generator "openai:llama3@http://localhost:11434/v1" --out run.json
sqlite-explorer-bench --generator ... --min-accuracy 0.8            # exit 1 below 80%, for CI

Metric

Meaning

Syntax validity

The SQL parses

Schema adherence

Every table and column exists (hallucinations fail here)

Execution accuracy

The result set matches the reference query's (order ignored unless the reference has ORDER BY)

Unsafe SQL (for example a generated DROP TABLE) is flagged and never executed.

The bundled template generator is a regex baseline, not an LLM. It scores about 45% (simple counts and filters pass; every join, group-by and subquery fails), which gives a real model something to beat. Its produced SQL rate shows how often it declined to answer.

Demo (no API key)

pip install -e ".[dev]"
sqlite-explorer-web                # http://127.0.0.1:8000

It opens a synthetic shop database (customers, products, orders, order items) generated from a fixed seed; it contains no real data. The page has buttons that attempt DROP TABLE, a two-statement query and an infinite recursive query, so you can watch each get rejected.

Use your own database:

SQLITE_DB=/path/to/app.db sqlite-explorer-web

MCP tools

{ "mcpServers": { "sqlite": { "command": "sqlite-explorer-mcp",
                              "env": { "SQLITE_DB": "/path/to/app.db" } } } }

Tool

Does

list_tables()

Tables and views

describe_table(table)

Columns, types, keys, foreign keys, row count

get_schema_ddl()

CREATE TABLE statements; read first, then write SQL against them

run_query(sql)

One read-only SELECT; errors if rejected or timed out

Tests

python -m pytest
ruff check src tests

Verified vs not verified

  • Verified: the sandbox and benchmark logic (51 tests, including attack queries and a perfect "oracle" generator that scores 100%); the OpenAI-compatible generator against a mocked transport; and the benchmark CLI end to end against a local fake OpenAI-compatible server.

  • Verified live: the benchmark against Gemini gemini-3.1-flash-lite (result above).

  • Not verified: runs against a live Ollama/vLLM/OpenAI model, and the web UI with a live model.

Limitations

  • The benchmark's reference answers are tied to the seeded sample database; use --cases with your own questions for another database.

  • Vector / hybrid search is not included.

  • SQLite only.

  • A read-only query can still read anything in the file. Point it at a database (or a copy) that contains only data the agent may see.

  • The 2-second limit stops runaway queries, but it is a per-query guard, not a rate limiter.

  • No authentication on the web console; keep it on localhost.

Available Tools

4 tools
describe_tableB

Columns, types, primary keys, foreign keys and row count of a table.

ParametersJSON Schema
NameRequiredDescriptionDefault
tableYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It does disclose the shape of the result (including row count, which implies the tool actually reads table statistics), but says nothing about read-only safety, behavior on a missing table, or permission requirements. Enumerating returned fields is the main value added, and it partly duplicates the output schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single tight sentence fragment with no filler, and the most useful information (what you get back) is front-loaded. It reads as a noun phrase rather than a statement of action, which is a minor structural weakness.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be explained, and the description is adequate for a simple one-parameter introspection tool. What is missing is how to specify the table identifier and how this differs from get_schema_ddl, both of which an agent needs to pick and call correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The single 'table' parameter has 0% schema description coverage and the description adds nothing about its expected form — bare name vs. schema-qualified, case sensitivity, or quoting rules. With one undocumented parameter, the description should have compensated and does not.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description enumerates exactly what the tool returns (columns, types, PKs, FKs, row count) for a table, which is a precise statement of purpose beyond the name alone. It does not, however, differentiate itself from the overlapping sibling get_schema_ddl or position itself against list_tables.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to call this versus get_schema_ddl (which likely returns similar DDL information) or list_tables. The agent must infer the choice from the name alone, with no stated preconditions or alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_schema_ddlA

CREATE TABLE statements for the whole database. Read this first, then write a SELECT for run_query: every table and column you use must appear here.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It discloses the return content (DDL text) and implicitly that the call is a read, but says nothing about output size or cost despite covering the whole database, nor about schema freshness or failure modes.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences, front-loaded with what the tool returns and followed by the workflow constraint. Every sentence earns its place; nothing is repeated from structured fields.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be explained, and the description still names the output form (CREATE TABLE statements). With no parameters and no annotations, the only remaining gap is guidance for very large databases where dumping the whole DDL may be impractical.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so the baseline is 4. The description correctly implies no inputs are needed and points the agent to run_query for the actual parameterized work.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific resource — CREATE TABLE statements for the entire database — which distinguishes it from the per-table siblings list_tables and describe_table by scope. It does not explicitly name those siblings, so the differentiation is implied rather than stated.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit sequencing ('Read this first, then write a SELECT for run_query') and states a hard constraint that every table and column used must appear here. It does not say when to prefer list_tables or describe_table instead, which would be useful for large schemas.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_tablesB

Names of the tables and views in the database.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full behavioral burden; it does not state that the operation is a non-mutating read, nor whether system/catalog tables are included or which schema/connection scope applies. The gap is partially offset by the tool taking zero parameters and having an output schema, making behavior largely predictable.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

It is short and waste-free, but it is not front-loaded with an action verb, which weakens scannability. Brevity here reflects under-specification rather than disciplined economy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a trivial no-param enumerator with an output schema, the description is minimally sufficient, but it omits scope information (which database/schema/connection the listing covers) and whether views are separated from tables. Without annotations, a sentence covering read-only nature and scope would complete it.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so the baseline applies; there is no parameter semantics to explain and the description correctly spends no words on it.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names the resource (tables and views in the database) but is a noun fragment with no verb, so the operation (list/enumerate) is inferred rather than stated. It is distinguishable from describe_table and get_schema_ddl mainly because those siblings have their own explicit names, not because the description differentiates.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to use this versus describe_table or get_schema_ddl, even though all three inspect schema metadata. An agent must guess that this is the enumeration entry point before drilling into columns or DDL.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

run_queryA

Run ONE read-only SELECT statement. Writes, PRAGMA, ATTACH and multiple statements are rejected. Results are capped at 200 rows (check truncated) and queries time out after 2s.

ParametersJSON Schema
NameRequiredDescriptionDefault
sqlYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.1/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations present, the description carries the full behavioral burden and does so: it discloses the row cap of 200, the existence of a `truncated` indicator, and a 2-second timeout. It also declares the rejection set, so an agent knows which statements will fail before attempting them.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, front-loaded with the primary constraint and every sentence adding a distinct operational fact. Nothing is redundant.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be explained, and the description still flags `truncated` as worth checking. The only remaining gap is the absence of dialect or parameter-binding guidance, which is minor for a single-argument tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% for the single `sql` parameter, and the description says only that it must be one SELECT statement, implying no semicolon-separated statements. It adds no dialect or binding information beyond that constraint.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Run ONE read-only SELECT statement') and immediately constrains it to a single read query. Siblings (list_tables, describe_table, get_schema_ddl) are schema-introspection tools, so the contrast is implicit rather than stated, which keeps it just short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Enumerates what is rejected (writes, PRAGMA, ATTACH, multiple statements), which tells an agent when NOT to use it, and the SELECT-only framing implies it should be used to retrieve data rather than inspect schema. It does not name a preferred sibling when a schema question arises.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 4 tool updatesv0.1.0
    • First observeddescribe_table
    • First observedget_schema_ddl
    • First observedlist_tables
    • First observedrun_query

TDQS

A3.7/5.0

Scored across 4 tools

Disambiguation4/5

The tools have mostly distinct purposes: listing tables, describing one table, fetching full DDL, and running a query. There is some conceptual overlap between describe_table and get_schema_ddl, but the descriptions make the intended scope of each clear.

Naming Consistency5/5

All tool names use snake_case with a clear verb_noun pattern: list_tables, describe_table, get_schema_ddl, run_query. The convention is predictable throughout.

Tool Count5/5

Four tools are well-scoped for a read-only SQLite exploration server. Each tool has a clear role and there is no unnecessary surface area.

Completeness5/5

The read-only exploration domain is fully covered: list tables/views, inspect a table, retrieve full schema, and execute SELECT queries. No obvious operational gap exists given the intentionally read-only scope.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    Exposes a SQLite database to AI assistants with structured, read-safe access. Includes five tools for schema exploration, querying, and sampling data.
    -
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables AI assistants to explore and query SQLite databases through read-only tools, with defense-in-depth sandboxing preventing any data modifications.
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables AI agents to safely query and explore SQLite databases through read-only, guard-protected tools that block writes, sensitive table access, and runaway queries.
    1
    MIT