Skip to main content
Glama
Read-only SQLite MCP

Read-only SQLite MCP

README.md
# Read-only SQLite MCP

**Let your AI assistant explore your SQLite databases — without ever
being able to change them.**

Anthropic's original SQLite reference server was moved to the archive.
This is a maintained replacement with a safety-first design:

- 🔒 **Read-only by default** — connections use SQLite's own read-only
  mode, and queries are restricted to `SELECT / WITH / PRAGMA / EXPLAIN`.
  Writes need an explicit `--allow-write` flag at startup.
- 📁 **Only your files** — the server can only open databases you name
  with `--db`. The AI cannot wander your disk.
- ⚡ **Zero dependencies** — pure Python standard library. No Docker,
  no Node, works offline.

Works with **Claude Code, Cursor, VS Code, Windsurf** and any MCP client.

## Install

```bash
pip install readonly-sqlite-mcp
```

## Connect it

Point the server at one or more database files:

**Claude Code**

```bash
claude mcp add sqlite -- readonly-sqlite-mcp --db /path/to/app.db --db /path/to/data.sqlite
```

**Cursor / VS Code / Windsurf** (`mcp.json`):

```json
{
  "mcpServers": {
    "sqlite": {
      "command": "readonly-sqlite-mcp",
      "args": ["--db", "/path/to/app.db"]
    }
  }
}
```

Then ask your assistant:

- *"What tables are in this database and how big is each one?"*
- *"Show me the schema of the users table"*
- *"Which products sold most last month? Give me CSV"*

## Tools

| Tool | What it does |
|---|---|
| `list_databases` | Databases this server may access |
| `list_tables` | Tables and views in a database |
| `describe_table` | Columns, types, keys, foreign keys, indexes |
| `table_stats` | Row count for every table |
| `read_query` | Read-only SQL (SELECT/WITH/PRAGMA/EXPLAIN), capped results |
| `sample_rows` | A few example rows from a table |
| `export_csv` | Run a read-only query, get CSV back |
| `write_query` | INSERT/UPDATE/DELETE/DDL — **only with `--allow-write`** |

## Safety model

1. Databases are allow-listed at startup (`--db`, repeatable, or the
   `SQLITE_MCP_DBS` environment variable).
2. Read connections are opened with SQLite URI `mode=ro` — the database
   engine itself refuses writes, not just this server's code.
3. `read_query` additionally rejects any statement that does not start
   with SELECT, WITH, PRAGMA or EXPLAIN.
4. Results are capped (default 200 rows, max 1000) so a runaway query
   can't flood the conversation.

## Development

```bash
git clone https://github.com/Deependra12349/readonly-sqlite-mcp
cd readonly-sqlite-mcp
python tests/test_mcp.py   # creates a temp DB, runs real protocol checks,
                           # including "writes are blocked" and "file unchanged"
```

## Contributing

Issues and PRs welcome — see [CONTRIBUTING.md](CONTRIBUTING.md).
The zero-dependency and read-only-by-default rules are not negotiable.

## License

MIT — see [LICENSE](LICENSE).

*Maintained by Deependra, with AI assistance for implementation.
Safety behaviour is covered by the automated tests in `tests/`.*

TDQS

B3.3/5.0

Scored across 7 tools

Disambiguation4/5

Each tool targets a distinct inspection level (databases, tables, columns, row counts, sample data) and descriptions make the boundaries clear. The only real overlap is read_query vs export_csv, which both execute a read-only query and differ only in output format, and sample_rows is a thin convenience wrapper around a SELECT.

Naming Consistency4/5

Six of seven tools follow a clear verb_noun pattern (list_databases, list_tables, describe_table, read_query, sample_rows, export_csv). table_stats breaks the pattern with a noun_noun form, but it is still readable and unambiguous.

Tool Count5/5

Seven tools is well-scoped for a read-only database inspection server. Every tool covers a distinct exploration step with no filler, and nothing feels missing from the count perspective.

Completeness4/5

The surface covers the full read-only lifecycle: discover databases, enumerate tables, inspect schema, gauge size, and pull sample or exported data. Minor gaps remain, such as finding which tables contain a given column name or dumping a full schema, but agents can work around these with read_query.

Maintenance

ActivityMaintained
ResponsivenessNo recent community issues