SkillAgentSearch skills...

mcp-server-sqlite

An MCP server for SQLite with fine-grained access control

Install / Use

claude mcp add 0xOmarA -- npx -y github:0xOmarA/mcp-server-sqlite

If the server publishes to npm under a different name, use that package instead — check the repo README.

About this skill
🔌

MCP Server

Model Context Protocol server

Quality Score

71/100

Supported Platforms

Claude Code
Claude Desktop

Tags

Our assessment of mcp-server-sqlite

mcp-server-sqlite scores 71/100 on our quality scale, 552nd of 597 Data & Analytics skills we index.

Its MCP Server is 18 KB long, well organised into 38 sections with 25 code examples: a thorough specification that gives an agent plenty to work with.

It has 3 GitHub stars, so there is little community track record yet; judge it on its content.

Substance
30/30
Structure
20/20
Description
8/15
Adoption
3/20
Freshness
11/15

Maintenance, license and trust

  • The repository was last updated about 7 months ago. That is recent enough to be usable, but agent tooling moves fast, so check the instructions against your agent's current version.
  • It is released under the Apache-2.0 license, a permissive license that allows use, modification and commercial use with attribution.
  • Its trust signals score 81/100, with 3 cautions from licensing, adoption, age or documentation. These come from repository metadata, not a code audit — read the skill file before letting an agent act on it.

mcp-server-sqlite compared with similar skills

All 4 of these similar skills score higher than mcp-server-sqlite; compare them before choosing.

SkillScoreStarsUpdatedFormat
mcp-server-sqlite (this skill)by 0xOmarA7137mo agoMCP Server
claude-memby thedotmack100110.6ktodayCLAUDE.md
Agent-Reachby Panniantong100108.0k1d agoCLAUDE.md
headroomby headroomlabs-ai10078.7ktodayCLAUDE.md
CowAgentby zhayujie10047.8ktodayCLAUDE.md

Frequently asked questions

How do I install mcp-server-sqlite?
Run claude mcp add 0xOmarA -- npx -y github:0xOmarA/mcp-server-sqlite. The install tabs above show the steps for each supported agent.
Which AI agents does mcp-server-sqlite work with?
It is written for Claude Code and Claude Desktop, as a MCP Server file. Other agents that read the same format can often use it too.
Is mcp-server-sqlite safe to use?
It is Apache-2.0-licensed and scores 81/100 on trust signals. Skills are instructions an agent will follow, so read the file before installing it and do not approve commands you do not understand.
Is mcp-server-sqlite still maintained?
The repository was last updated about 7 months ago. That is recent enough to be usable, but agent tooling moves fast, so check the instructions against your agent's current version.
<div align="center"> <h1><code>mcp-server-sqlite</code></h1> <p> <strong>A production-grade MCP server for SQLite with fine-grained access control</strong> </p> <p> <a href="https://github.com/0xOmarA/mcp-server-sqlite/actions/workflows/ci.yml"><img src="https://github.com/0xOmarA/mcp-server-sqlite/actions/workflows/ci.yml/badge.svg" alt="CI"></a> <a href="https://crates.io/crates/mcp-server-sqlite"><img src="https://img.shields.io/crates/v/mcp-server-sqlite.svg" alt="crates.io"></a> <a href="https://crates.io/crates/mcp-server-sqlite"><img src="https://img.shields.io/crates/d/mcp-server-sqlite.svg" alt="downloads"></a> <a href="LICENSE-APACHE"><img src="https://img.shields.io/badge/license-Apache--2.0%20OR%20MIT-blue.svg" alt="License"></a> </p> </div>

Why this exists

Every existing MCP server for SQLite falls short in at least one critical way. The official reference server from Anthropic is a ~300-line Python script with known unpatched SQL injection vulnerabilities, no parameterized queries, no transactions, no read-only mode, and a hardcoded demo prompt. It was archived in May 2025 with Anthropic declining to fix the security issues, yet it was forked over 5,000 times. The community alternatives each solve one or two problems but none solves them comprehensively.

This server was built to be the SQLite MCP server you can actually trust in production. It is written in Rust, ships as a single binary with no runtime dependencies, and uses SQLite's own sqlite3_set_authorizer API to enforce access control at the query-preparation level, before any SQL ever executes. The access control system supports column-level granularity, specificity-based rule resolution, and five built-in presets ranging from deny-everything to allow-everything.

Features

  • Authorizer-based access control. Uses SQLite's native authorizer callback to intercept every operation at prepare time. Supports 30+ selector types covering reads, writes, DDL, pragmas, functions, transactions, attach/detach, and virtual tables, all with per-table, per-column, and per-function granularity.
  • Five permission presets. deny-everything, read-only (default), read-write, full-ddl, and allow-everything. Layer --allow and --deny overrides on top with a specificity-based resolution algorithm where deny wins ties.
  • 13 tools. A single execute tool for arbitrary SQL, plus purpose-built tools for schema introspection, full-text search, query planning, backups, and database maintenance.
  • Full-text search. First-class FTS5 support with dedicated tools for creating indexes and searching with BM25 ranking and highlighted snippets.
  • Query timeouts. Optional per-server timeout that uses SQLite's progress handler to abort runaway queries before they can tie up resources.
  • Connection pooling. Built on r2d2 for connection reuse with per-connection authorizer and timeout installation.
  • Init scripts. Seed schemas and data on first run with --init-sql files that are skipped when the database already exists.
  • Single binary. Compiles SQLite statically via rusqlite's bundled feature. No Python, no Node, no runtime dependencies.

Installation

From crates.io

cargo install mcp-server-sqlite

From source

git clone https://github.com/0xOmarA/mcp-server-sqlite.git
cd mcp-server-sqlite
cargo install --path .

Quick start

Start a read-only server with an in-memory database:

mcp-server-sqlite

Start a read-write server on a persistent database with a schema init file:

mcp-server-sqlite --database ./app.db --preset read-write --init-sql schema.sql

Claude Desktop configuration

Add the following to your Claude Desktop MCP config file:

{
  "mcpServers": {
    "sqlite": {
      "command": "mcp-server-sqlite",
      "args": [
        "--database", "./my-database.db",
        "--preset", "read-only"
      ]
    }
  }
}

Tools

The server exposes 13 tools over MCP. Each tool validates inputs, enforces the configured access control policy, and returns structured typed output.

execute

Runs any SQL query against the database. This is the primary tool. It handles SELECT, INSERT, UPDATE, DELETE, DDL, and everything else SQLite supports. Returns typed result rows (preserving NULL, Integer, Real, Text, and Blob types) and a count of rows changed.

execute({ "query": "SELECT name, age FROM students WHERE age > 20" })

Access control is enforced at the SQLite authorizer level, so denied operations never execute. If the configured policy denies any part of the query (a table read, a column access, a function call), the entire statement is rejected with a clear error message.

list_tables

Lists all tables in the database with their names and CREATE TABLE definitions.

describe_table

Returns column metadata for a specific table: column name, declared type, NOT NULL constraint, default value, and whether it is part of the primary key.

describe_table({ "table_name": "students" })

list_indexes

Lists indexes in the database. Optionally filter by table. Returns the index name, table name, uniqueness flag, ordered column list, and the WHERE clause for partial indexes.

list_indexes({ "table_name": "students" })

list_foreign_keys

Returns foreign key constraints for a given table, including the local column, referenced table and column, and the ON UPDATE/ON DELETE actions.

list_foreign_keys({ "table_name": "enrollments" })

list_views

Lists all views with their names and defining SQL.

list_triggers

Lists triggers in the database. Optionally filter by table. Returns the trigger name, attached table, event (INSERT/UPDATE/DELETE), timing (BEFORE/AFTER/INSTEAD OF), and full SQL definition.

list_triggers({ "table_name": "students" })

explain_query

Returns the EXPLAIN QUERY PLAN output for a query without executing it. Shows how SQLite will access tables, which indexes it will use, and how it will join data. Useful for understanding query performance.

explain_query({ "query": "SELECT * FROM students WHERE name = 'Omar'" })

backup

Creates a full backup of the database to a file path using SQLite's online backup API. Runs incrementally in pages so it does not block other operations for long. Returns the number of pages copied and the destination path.

backup({ "destination": "/tmp/app-backup.db" })

create_fts_index

Creates an FTS5 virtual table over specified columns of an existing table. The virtual table name defaults to {table}_fts but can be customized.

create_fts_index({
  "table_name": "articles",
  "columns": ["title", "body"]
})

search_fts

Runs a full-text search query against an FTS5 virtual table. Returns results ranked by BM25 relevance with highlighted snippets showing where the query matched. Configurable result limit, snippet length, and highlight markers.

search_fts({
  "fts_table": "articles_fts",
  "query": "sqlite AND indexing",
  "limit": 5
})

vacuum

Runs the SQLite VACUUM command to rebuild the database file, reclaim unused space, and defragment storage.

database_info

Returns database metadata: SQLite version, page size, page count, total size in bytes, journal mode, WAL checkpoint status (when in WAL mode), freelist page count, and the number of tables and indexes.

Access control

The access control system is the core differentiator of this server. It is built on SQLite's sqlite3_set_authorizer callback, which means SQLite itself parses every query and reports every operation it will perform. The server then evaluates each operation against the configured policy. Denied operations cause the entire statement to be rejected at prepare time, before any data is read or modified.

This approach has several important properties:

  • Zero parsing gaps. SQLite does the parsing, not a third-party SQL parser. Every valid SQLite statement is handled correctly, including edge cases like triggers, views, CTEs, and virtual tables.
  • Column-level granularity. The Read and Update selectors accept both a table name and a column name, so you can deny access to specific columns (e.g. --deny Read(Users.ssn)).
  • Indirect operation tracking. If a trigger on table A fires an INSERT into table B, the authorizer catches the INSERT on table B. Operations hidden inside triggers and views are not invisible to the policy.
  • Fail-closed by default. The default preset is read-only. When allow and deny rules conflict at the same specificity level, deny wins.

Presets

Presets define the baseline permissions before any --allow/--deny overrides are applied.

| Preset | Allows | Denies | |---|---|---| | deny-everything | Nothing | Everything | | read-only (default) | Read, Select, Transaction, Function, Recursive, Pragma | Insert, Update, Delete, all DDL, Attach, Detach | | read-write | Extends read-only with Insert, Update, Delete, Savepoint, Analyze, Reindex, temp objects | Permanent DDL, Attach, Detach | | full-ddl | Extends read-write with CreateTable, DropTable, AlterTable, CreateIndex, DropIndex, CreateTrigger, DropTrigger, CreateView, DropView | Attach, Detach, virtual tables | | allow-everything | Everything | Nothing |

Selectors

Selectors identify the operation and, optionally, the exact resources a rule applies to. The syntax is Action or Action(field1.field2) where * is a wildcard.

Data operations:

| Selector | Fields | Example | |---|---|---| | Read | table_name.column_name | Read(Users.email) | | Insert | table_name | Insert(AuditLog) | | Update | table_name.column_name | Update(Users.password) | | Delete | table_name | Delete(Sessions) | | Select | (none) | Select |

Transactions:

| Selector | Fields | Example | |---|---|---| | Transaction | operation | Transaction(BEGIN) | | Savepoint | operation.savepoint_name | Savepoint(*.my_sp) |

DDL (permanent):

| Selector | Fields | Example | |---|---|---| | CreateTable | table_name | CreateTable(TempData) | | DropTable | table_name | DropTable(OldRecords) | | AlterTable | database_name.table_name | AlterTable(*.Users) | | CreateIndex | table_name.index_name | CreateIndex(Users.idx_email) | | DropIndex | table_name.index_name | DropIndex | | CreateView | view_name | CreateView(ActiveUsers) | | DropView | view_name | DropView | | CreateTrigger | table_name.trigger_name | CreateTrigger(Users.*) | | DropTrigger | table_name.trigger_name | DropTrigger |

DDL (temporary):

| Selector | Fields | Example | |---|---|---| | CreateTempTable | table_name | CreateTempTable | | DropTempTable | table_name | DropTempTable | | CreateTempIndex | table_name.index_name | CreateTempIndex | | DropTempIndex | table_name.index_name | DropTempIndex | | CreateTempView | view_name | CreateTempView | | DropTempView | view_name | DropTempView | | CreateTempTrigger | table_name.trigger_name | CreateTempTrigger | | DropTempTrigger | table_name.trigger_name | DropTempTrigger |

Other operations:

| Selector | Fields | Example | |---|---|---| | Pragma | pragma_name | Pragma(journal_mode) | | Function | function_name | Function(count) | | Attach | filename | Attach | | Detach | database_name | Detach | | Reindex | index_name | Reindex | | Analyze | table_name | Analyze(Users) | | CreateVtable | `table_name.modul

Truncated for display — read the full file on GitHub.

Related Skills

View on GitHub
GitHub Stars3
CategoryData
Updated7mo ago
Forks0

Languages

Rust

Trust signals

81/100

From repository metadata: license, adoption, age and documentation. Not a code audit — see the Safety scan above for what the skill file itself contains.

3 low