Skip to content

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

sqlite-mcp-server

A small, production-minded Model Context Protocol server that safely exposes a SQL (SQLite) database to Claude and other MCP clients.

It's the pattern most teams actually want first — "let our AI read (and carefully write to) our database" — done with the guardrails that make that safe: schema introspection, validated read-only queries, and fully-parameterized guarded writes.

Tools

Tool Description
list_tables List all tables and views in the database.
describe_table Column schema for a table/view — name, type, nullability, PK, default.
query Run a single read-only statement (SELECT / WITH … SELECT). Writes are rejected. Results capped at 200 rows.
insert_row Insert one row via fully-parameterized values. Disabled in read-only mode.

Safety design

  • Reads can't write. query compiles the statement and checks better-sqlite3's Statement.reader flag, so anything that mutates data (INSERT/UPDATE/DELETE/DROP) is refused — no fragile keyword regex.
  • Side-effecting statements blocked even when they return rows. PRAGMA, ATTACH, DETACH, and VACUUM are rejected by leading keyword, because some (e.g. PRAGMA journal_mode=WAL) do return a row and would otherwise pass the reader check while mutating database state.
  • No SQL injection on writes. insert_row validates the table against sqlite_master, whitelists columns from PRAGMA table_info, quotes identifiers, and binds every value as a parameter.
  • Single-statement only. Batched/stacked statements are rejected — and the check ignores comments and string-literal contents, so SELECT ';' AS x is allowed while SELECT …; DROP … is not.
  • Bounded output. Query results are capped and flagged when truncated.
  • Read-only mode. Start with SQLITE_READONLY=1 to disable all writes.

Quick start

npm install
npm run build
npm run seed        # creates a demo database at ./data/sample.db
npm start           # runs the server on stdio

The smoke test drives the server through a real MCP client:

node test/smoke.mjs

Configuration

Env var Default Purpose
SQLITE_DB_PATH ./data/sample.db (auto-seeded) Path to the SQLite database file.
SQLITE_READONLY 0 1/true disables insert_row.

Use with Claude Desktop

Add to claude_desktop_config.json:

{
  "mcpServers": {
    "sqlite": {
      "command": "node",
      "args": ["/absolute/path/to/sqlite-mcp-server/dist/index.js"],
      "env": { "SQLITE_DB_PATH": "/absolute/path/to/your.db" }
    }
  }
}

Use with Claude Code

claude mcp add sqlite -- node /absolute/path/to/sqlite-mcp-server/dist/index.js

Example

Ask Claude: "Which customers have spent the most?" → it calls list_tables, describe_table, then:

SELECT c.name, SUM(o.amount_cents) AS cents
FROM customers c JOIN orders o ON o.customer_id = c.id
GROUP BY c.id ORDER BY cents DESC;

Stack

TypeScript · @modelcontextprotocol/sdk · better-sqlite3 · zod

License

MIT © Tim McVicker

About

MCP server that safely exposes a SQL database to Claude — schema introspection, read-only query guard, parameterized guarded writes

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages