sqlite-mcp-server
Connects LLM assistants to local SQLite databases, enabling schema discovery, table inspection, read-only SELECT and EXPLAIN queries, and direct access to database schema and table context through MCP resources and prompts.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@sqlite-mcp-serverlist all tables and describe the users table"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
sqlite-mcp-server
An open-source Model Context Protocol (MCP) server connecting LLM assistants (such as Claude Desktop and Cursor) to local SQLite databases with strict read-only security, context overflow protection, and structured AI error handling.
๐ Key Features
Automated Schema Discovery: Automatically inspect table lists, object types (tables/views), row count estimates, columns, primary keys, foreign keys, and complete DDL definitions.
Strict Read-Only Query Security:
Parser-Level Validation: Rejects all mutation statements (
INSERT,UPDATE,DELETE,DROP,ALTER,CREATE,ATTACH,VACUUM,REINDEX, etc.).Statement Chaining Prevention: Blocks execution of multiple chained statements separated by
;.Restricted PRAGMAs: Prohibits dangerous PRAGMAs (
writable_schema, permissions, and configuration mutation).Engine-Level Enforcement: SQLite connections are opened using read-only URI mode (
file:path?mode=ro) withPRAGMA query_only = ON;.
Context Overflow Protection (
max_rows): Safely truncates large query results with an informative warning advising AI models to useLIMITandOFFSETclauses.Structured Error Handling for AI: Returns standardized JSON error envelopes (
error_type,message,query, andsuggestion) to allow AI models to self-correct queries without hallucinations.Full MCP Capabilities: Exposes Tools, direct Resources (
sqlite://schema,sqlite://tables), and guided Prompts (schema_analysis,safe_query_assistant).Flexible Configuration: Set the database path via CLI argument (
--db-path), environment variable (SQLITE_DB_PATH), or dynamically per tool invocation (db_path).
Related MCP server: DB Insights MCP Server
๐ ๏ธ MCP Tools
Tool Name | Description | Key Arguments |
| Lists all tables and views in the database with estimated row counts. |
|
| Retrieves column definitions, data types, nullability, default values, primary keys, foreign keys, and indexes for a specific table. |
|
| Returns the complete DDL schema definition for all tables, views, and indexes. |
|
| Safely executes a read-only |
|
๐ฆ MCP Resources & Prompts
MCP Resources (Direct Context Access)
Clients that support MCP Resources can inspect the database context directly without invoking a tool:
sqlite://schema: Returns the full formatted SQL DDL schema of the database.sqlite://tables: Returns a concise list of all tables, views, and their respective row counts.
MCP Prompts (Interactive Assistant Guides)
schema_analysis: Prompts the AI model to inspect database structure, relationships, normalization, and optimization opportunities.safe_query_assistant(user_goal): Guides the AI model in formulating an optimized, safeSELECTquery tailored to the user's objective.
๐ Structured Error Format
When a syntax or validation error occurs, the server responds with a structured JSON object designed for LLM consumption:
{
"success": false,
"error_type": "DisallowedQueryError",
"message": "Forbidden modification keyword 'DROP' detected. Only read operations are allowed.",
"query": "DROP TABLE employees;",
"suggestion": "Remove any data modification or schema alteration commands. Only SELECT queries are permitted."
}Supported error categories:
DisallowedQueryError: Query attempts data modification or invokes forbidden SQL operations.SyntaxError: SQLite syntax error.TableNotFoundError: Table was not found (includes advice to runlist_tables).ColumnNotFoundError: Column was not found (includes advice to rundescribe_table).DatabaseNotFoundError: Database file does not exist at the specified path.DatabaseConfigError: No database path was provided or configured.ValidationError: Invalid input parameter (e.g. empty table name ormax_rows < 1).
๐ Installation & Getting Started
Option 1: Run with uvx (Recommended)
If you have uv installed, run the server instantly without cloning:
uvx sqlite-mcp-server --db-path "/path/to/database.db"Option 2: Install from Source
# 1. Clone repository
git clone https://github.com/Aderali06/sqlite-mcp-server.git
cd sqlite-mcp-server
# 2. Create virtual environment
python -m venv .venv
# Windows
.venv\Scripts\activate
# macOS / Linux
source .venv/bin/activate
# 3. Install package and development dependencies
pip install -e ".[dev]"โ๏ธ Claude Desktop Configuration
Add the server to your claude_desktop_config.json:
Windows:
%APPDATA%\Claude\claude_desktop_config.jsonmacOS:
~/Library/Application Support/Claude/claude_desktop_config.jsonLinux:
~/.config/Claude/claude_desktop_config.json
Configuration Example:
{
"mcpServers": {
"sqlite": {
"command": "uvx",
"args": [
"sqlite-mcp-server",
"--db-path",
"C:/Users/A2/Documents/database.db"
]
}
}
}Or using local Python:
{
"mcpServers": {
"sqlite": {
"command": "python",
"args": [
"-m",
"src.server",
"--db-path",
"C:/Users/A2/Documents/database.db"
],
"env": {
"PYTHONIOENCODING": "utf-8"
}
}
}
}๐ป Cursor Integration
Method 1: Via Cursor Settings UI
Open Cursor Settings (
Ctrl + Shift + Jon Windows/Linux orCmd + ,on macOS).Navigate to Features > MCP Servers.
Click + Add New MCP Server.
Fill in:
Name:
sqlite-mcp-serverType:
commandCommand:
python -m src.server --db-path "C:/path/to/database.sqlite"
Method 2: Project-Level Configuration (.cursor/mcp.json)
Create .cursor/mcp.json in your project root:
{
"mcpServers": {
"sqlite": {
"command": "python",
"args": [
"-m",
"src.server",
"--db-path",
"${workspaceFolder}/data/app.db"
]
}
}
}๐งช Testing
Run the automated test suite with pytest:
# Run all tests
pytest
# Run tests with test coverage reporting
pytest --cov=src --cov-report=term-missing๐ Project Structure
sqlite-mcp-server/
โโโ .github/
โ โโโ workflows/
โ โโโ ci.yml # Multi-OS CI testing (Linux & Windows)
โ โโโ publish.yml # Automated PyPI release workflow
โโโ src/
โ โโโ __init__.py # Package version & metadata
โ โโโ server.py # FastMCP server, tools, resources, prompts & SQL validation
โโโ tests/
โ โโโ test_server.py # 29 unit & integration pytest tests
โโโ .gitignore # Git ignore rules
โโโ LICENSE # Official MIT License
โโโ pyproject.toml # Build system, CLI entrypoint, & package metadata
โโโ README.md # Project documentation & configuration guide
โโโ requirements.txt # Python dependencies๐ License
This project is licensed under the MIT License.
Available Tools
4 toolsdescribe_tableA
Get detailed schema information for a specific table or view, including columns, primary keys, foreign keys, and indexes.
Args: table_name: The name of the table or view to inspect. db_path: Optional path to SQLite file. If omitted, uses default database path.
| Name | Required | Description | Default |
|---|---|---|---|
| db_path | No | ||
| table_name | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description must carry the full behavioral burden. It does disclose the content of the result (columns, keys, indexes), which signals a read-only inspection operation, but it never states that the operation is non-mutating, what happens when the table does not exist, or whether it errors versus returning empty. Adequate but with clear gaps for a zero-annotation tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose sentence is front-loaded and the Args block is compact with one line per parameter. Slightly wasteful to repeat 'table_name' and 'db_path' labels for only two parameters, but nothing is padded or off-topic.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so the description need not detail return formatting, and it does not need to; it still usefully names the result elements. For a two-parameter read tool the coverage is nearly complete, with only error/edge-case behavior left unstated.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate, and it does: it explains table_name as the table or view to inspect and db_path as an optional SQLite file path whose omission falls back to the default database path. This adds the default-fallback semantics that the bare schema (anyOf string/null, default null) does not convey.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (Get) and resource (schema information) scoped to 'a specific table or view', and enumerates the returned elements (columns, primary keys, foreign keys, indexes). This clearly separates it from the sibling get_database_schema (whole database) and list_tables without needing either schema opened.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by the scope ('a specific table or view'), so an agent can infer it is for inspecting one object's structure rather than listing or querying. However, there is no explicit when-to-use guidance, no named alternative such as get_database_schema for whole-database introspection, and no statement of prerequisites or failure conditions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_database_schemaA
Get the full CREATE DDL statements and schema definitions for all tables, views, and indexes.
Args: db_path: Optional path to SQLite file. If omitted, uses default database path.
| Name | Required | Description | Default |
|---|---|---|---|
| db_path | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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 what is returned (DDL for tables, views, indexes) and that it is a read-style retrieval, but says nothing about cost, permissions, or behavior on a missing/invalid db_path. Reasonable for a simple read, but not rich.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One sentence of purpose followed by a compact Args block; the core behavior is front-loaded and there is no filler. The 'Args:' formatting is slightly boilerplate but not wasteful.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return-value detail is not required, and the description still summarizes the returned content. For a zero-required-param read tool this is essentially complete; only the missing sibling routing keeps it from a 5.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate, and it does: it explains that db_path is an optional SQLite file path and that omitting it falls back to the default database path. That fully covers the single parameter's meaning and default behavior.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Get the full CREATE DDL statements and schema definitions') and scopes it to 'all tables, views, and indexes', which implicitly separates it from describe_table (single table) and list_tables (names only). It does not explicitly name the siblings, so it falls 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.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by 'full ... for all tables' โ an agent can infer this is the whole-database dump versus per-table inspection โ but there is no explicit when-to-use or when-not-to-use guidance and no named alternative. Adequate but leaves routing to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_tablesB
List all user tables and views in the SQLite database with their row count.
Args: db_path: Optional path to SQLite file. If omitted, uses default database path.
| Name | Required | Description | Default |
|---|---|---|---|
| db_path | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the burden. It does disclose useful behavior โ user tables plus views, scoped to a specific database, with row counts โ but says nothing about permissions, cost on large databases, or read-only semantics beyond what 'List' implies.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One lead sentence covering purpose, then a compact Args block for the single parameter. Front-loaded and efficient; the Args block mildly duplicates the schema but adds the default-fallback detail that justifies its presence.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-optional-parameter read tool with an output schema, the description covers the resource, the scope, and the parameter's default behavior. Only miss is any mention of how this relates to the sibling schema/introspection tools.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate, and it does: it explains db_path is an optional path to the SQLite file and that omitting it falls back to a default database path. That is exactly the semantics an agent needs and the schema does not supply.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('List') plus resource ('user tables and views in the SQLite database') and adds output scope ('with their row count'). It does not explicitly distinguish itself from siblings like get_database_schema or describe_table, so it stops 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.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to pick this over get_database_schema or describe_table, and no stated prerequisites. The only usage context is the implicit meaning of db_path's default.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
read_queryA
Execute a safe, read-only SELECT query against the SQLite database.
Args: query: The SQL SELECT query to execute. Mutation queries (INSERT, UPDATE, DELETE, DROP, etc.) are strictly rejected. params: Optional list of query parameters for prepared statements (? placeholders). max_rows: Maximum number of rows to return (default: 1000). Protects against context overflow. db_path: Optional path to SQLite file. If omitted, uses default database path.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | ||
| params | No | ||
| db_path | No | ||
| max_rows | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden and does disclose the key traits: read-only safety, strict rejection of INSERT/UPDATE/DELETE/DROP, a default 1000-row cap that protects against context overflow, and default database fallback. It omits error/transaction behavior, which keeps it short of a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose sentence is front-loaded and the Args block is compact and scannable. Every line earns its place; the docstring formatting is conventional but not wasteful.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
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. Combined with full parameter documentation, mutation rejection, and row-cap rationale, the definition gives an agent enough to call the tool correctly; only edge-case behavior (errors, transactions) is unaddressed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate, and it documents all four parameters with meaning: query semantics plus mutation rejection, params as prepared-statement '?' placeholders, max_rows default and overflow rationale, and db_path default behavior. It stops short of examples or type/format details.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Execute a safe, read-only SELECT query against the SQLite database') and the safety constraint up front. This is clearly distinguishable from the introspection siblings (list_tables, describe_table, get_database_schema), which return metadata rather than rows.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied rather than stated: an agent infers it should call this when it needs actual data. The rejection of mutation queries is a useful negative boundary, but the description never routes the agent to a sibling (e.g., use get_database_schema first to discover tables) or states prerequisites.
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.
4 tool updates
v0.1.0- First observed
describe_table - First observed
get_database_schema - First observed
list_tables - First observed
read_query
TDQS
Scored across 4 tools
list_tables, describe_table, and get_database_schema have some overlap in scope (schema/table inspection), but each operates at a clearly different granularity: table list with counts, single-table detail, and full DDL. read_query is cleanly distinct as the data-retrieval tool. An agent can reasonably pick the right one.
Names are snake_case verb_noun throughout (list_tables, describe_table, get_database_schema, read_query), which is readable and predictable. Minor deviation in that three verbs (list/describe/get) are used for closely related inspection tasks rather than one consistent verb.
Four tools is well-scoped for a read-only SQLite inspection server, with each tool earning its place and no redundancy. Nothing feels padded or thin for the stated purpose.
The read-only inspection surface (list tables, describe table, full DDL, run SELECT) covers the core discovery and query workflow with no dead ends. Gaps exist around write/mutation operations and query-plan/explain introspection, but those are plausibly out of scope for a deliberately read-only server.
Maintenance
Related MCP Connectors
Query 40 databases from Claude, ChatGPT, or Cursor โ on any device. Read-only, encrypted, audited.
Safe, read-only Postgres and MySQL access for AI agents. Audit log + column-level controls.
Query your Postgres from ChatGPT or Claude without exposing the database or handing over credentials. Run npx boltschema connect next to your database and it dials out over HTTPS โ no inbound firewall rule, no open port, works with localhost and VPC-private databases. Read-only is enforced by a SQL guard, a Postgres READ ONLY transaction, and a scoped role generated for you.
Query PostgreSQL databases in plain English โ LLM-generated, safety-validated SQL.
Related MCP Servers
- AlicenseAqualityDmaintenanceEnables safe, read-only SQL access to SQLite databases for AI agents, allowing schema exploration and SELECT queries with defense-in-depth protections.3MIT
- FlicenseNot gradedqualityDmaintenanceEnables AI assistants to query SQL databases safely with read-only access, allowing schema discovery and SELECT queries while blocking writes and DDL operations.-
- AlicenseNot gradedqualityCmaintenanceEnables AI assistants to explore and query SQLite databases through read-only tools, with defense-in-depth sandboxing preventing any data modifications.MIT
- FlicenseAqualityBmaintenanceEnables AI assistants to query SQLite databases using plain language, with strict read-only enforcement and column-level access control to prevent damage or unauthorized data reads.4-