Skip to main content
Glama
RayaanKaz

mcp-sqlite-insights

by RayaanKaz

mcp-sqlite-insights

Let Claude explore any SQLite database without ever being able to change it.

tests Python 3.10 to 3.13 MCP Python SDK v2 Read-only License: MIT

Quick start · Connect to Claude · Tools · Security model · Configuration


A Model Context Protocol server that gives Claude Desktop, Claude Code and any other MCP client two tools: one that maps a SQLite database's structure and one that runs read-only SQL. Point it at a .db file and ask questions in plain English:

Which product category brought in the most revenue this year? Find customers who signed up but never placed an order. Is orders.customer_id indexed? Show me the query plan for looking up one customer's orders.

  • Read-only by construction. Four independent layers, including SQLite's own read-only mode and a native authorizer, so a write is refused even if the model tries one.

  • Context-friendly. Results are Markdown tables capped at 50 rows, long values are truncated, and slow queries are cancelled after 10 seconds.

  • Zero config. With no database configured it creates a realistic demo database, so you can try it immediately.

  • One dependency. Just the official MCP Python SDK; SQLite support ships with Python.

Why read-only matters

Agents like Claude Code increasingly run tools on their own. A database tool that can write is one mistaken DELETE away from data loss, and an instruction in a prompt is not a security boundary. This server makes writes impossible at the SQLite level, so you can let Claude explore a database without reviewing every query first.


Quick start

Requires Python 3.10 or newer.

With uv (no virtual environment needed; dependencies are declared inside server.py):

git clone https://github.com/RayaanKaz/mcp-sqlite-insights.git
cd mcp-sqlite-insights
uv run server.py --check

With pip:

git clone https://github.com/RayaanKaz/mcp-sqlite-insights.git
cd mcp-sqlite-insights
python3 -m venv .venv
source .venv/bin/activate          # Windows: .venv\Scripts\activate
python -m pip install -r requirements.txt
python server.py --check

--check creates the demo database, runs both tools, and proves that a DELETE is blocked. It ends with Self-check passed.


Related MCP server: sqlite-mcp-local

Connect to Claude

Claude Desktop

Open Settings → Developer → Edit Config and add the server to claude_desktop_config.json. Use absolute paths: Claude Desktop does not use your shell's PATH or activate virtual environments.

macOS / Linux (pip install):

{
  "mcpServers": {
    "sqlite-insights": {
      "command": "/absolute/path/to/mcp-sqlite-insights/.venv/bin/python",
      "args": ["/absolute/path/to/mcp-sqlite-insights/server.py"]
    }
  }
}
{
  "mcpServers": {
    "sqlite-insights": {
      "command": "C:\\Users\\you\\mcp-sqlite-insights\\.venv\\Scripts\\python.exe",
      "args": ["C:\\Users\\you\\mcp-sqlite-insights\\server.py"]
    }
  }
}

Backslashes must be doubled inside JSON strings.

Find uv's full path with which uv (macOS/Linux) or where uv (Windows), then:

{
  "mcpServers": {
    "sqlite-insights": {
      "command": "/absolute/path/to/uv",
      "args": ["run", "/absolute/path/to/mcp-sqlite-insights/server.py"]
    }
  }
}

Use your own database by adding an env block (or "--db", "/path/to/file.db" at the end of args):

      "env": { "SQLITE_INSIGHTS_DB": "/absolute/path/to/your.db" }

Quit Claude Desktop completely and reopen it. The two tools appear under the tools menu in the chat box.

Claude Code

claude mcp add --transport stdio sqlite-insights -- \
  /absolute/path/to/mcp-sqlite-insights/.venv/bin/python \
  /absolute/path/to/mcp-sqlite-insights/server.py --db /absolute/path/to/your.db

Leave out --db ... to use the demo database.


Tools

Tool

Arguments

Returns

inspect_schema

table_name (optional)

Overview of every table and view (row and column counts), then each table's columns, types, primary keys, NOT NULL, defaults, foreign keys and indexes. With table_name: that table only, plus 3 sample rows showing real data formats.

execute_query

sql

Result as a Markdown table: at most 50 rows, with a note when more rows matched, plus timing.

Both tools declare MCP annotations readOnlyHint: true, destructiveHint: false, idempotentHint: true and openWorldHint: false. The server also sends instructions telling Claude to inspect the schema first and to prefer aggregates over raw rows.

Example execute_query result:

| month | orders | revenue |
|---|---|---|
| 2025-01 | 9 | 3114.43 |
| 2025-02 | 8 | 1538.38 |
| 2025-03 | 12 | 4353.85 |

_3 row(s) returned (0.6 ms)._

Security model

flowchart LR
    C["Claude Desktop / Claude Code"] -- "MCP over stdio" --> S1
    subgraph SRV["server.py"]
        S1["1. Query sanitizer"] --> S2["2. Open file with mode=ro"]
        S2 --> S3["3. PRAGMA query_only = ON"]
        S3 --> S4["4. SQLite authorizer"]
    end
    S4 --> DB[("your.db")]
    DB -- "max 50 rows, 10 s limit" --> C

Layer

Mechanism

Stops

1. Query sanitizer

Exactly one statement, starting with SELECT, WITH, VALUES or EXPLAIN, with no write or admin keywords. String literals and comments are masked first, so WHERE note = 'DELETE' is not a false positive.

DROP TABLE, SELECT 1; DELETE ..., WITH x AS (...) DELETE ...

2. Read-only open

The file is opened through a file:...?mode=ro URI.

Any write to the file, and creating a file that does not exist

3. query_only

PRAGMA query_only = ON on every connection.

Writes to the main database and to anything attached

4. Authorizer

A native SQLite callback that allows only read operations while each statement is compiled.

Anything unexpected that gets past layer 1, including load_extension

The test suite attacks each native layer with the others disabled, and checks the database file's hash before and after.

Additional hardening: trusted_schema = OFF; SQLite defensive mode (Python 3.12+); ATTACH disabled outright (Python 3.11+); a fresh connection for every call; a 10-second query timeout; memory-bounded fetching (at most 51 rows are ever read from a result); 300-character cell truncation; logs on stderr only.

What it does not do:

  • Read-only is not private. Every row a query returns becomes part of your conversation with the model. Don't connect a database containing data you are not allowed to share with your AI provider.

  • It can read every table in the file. There is no per-table or per-column allowlist yet (contributions welcome).

  • It is built for local, single-user use over stdio, with no network transport or authentication.


Configuration

Setting

How

Default

Database file

--db PATH or the SQLITE_INSIGHTS_DB environment variable (--db wins)

demo.db, created next to server.py

Row cap

MAX_ROWS in server.py

50

Query timeout

QUERY_TIMEOUT_SECONDS

10 seconds

Cell length

MAX_CELL_CHARS

300 characters

The demo database is a small shop: customers (40), products (15), orders (200), order_items (508) and a monthly_revenue view, with foreign keys, indexes and a few NULLs. It is generated from a fixed seed, so every machine gets identical data.


Development

python -m unittest -v

29 tests cover sanitizer bypass attempts, each read-only layer on its own, the timeout, the row cap, Markdown escaping, awkward file names and identifiers, and a full stdio round trip through an MCP client. CI runs them on Linux, Windows, and macOS (Apple Silicon and Intel) with Python 3.10 to 3.13.

Contributing

Issues and pull requests are welcome. Some ideas:

  • Per-table and per-column allowlists (for example, hiding an email column)

  • Publishing to PyPI so the server can be launched with uvx

  • Support for more than one database at a time

Please include a test with any change to the read-only layers.

License

MIT. Built on the official MCP Python SDK. This is a community project and is not affiliated with or endorsed by Anthropic.

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    B
    maintenance
    Enables AI agents to query a SQLite database using natural language through the Model Context Protocol (MCP). Includes security guardrails that block destructive SQL operations.
    -
  • F
    license
    Not graded
    quality
    B
    maintenance
    Enables read-only querying of a local SQLite database via MCP, with tools to list tables, retrieve schema, and execute SELECT/WITH/EXPLAIN queries.
    -
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables Claude to safely explore and query a SQLite database through natural language, including listing tables, inspecting schemas, and running read-only SELECT queries.
    1,040 npm
    MIT