SQL MCP Server
SQL MCP 服务器
一个由 AI 驱动的 Model Context Protocol (MCP) 服务器,允许你使用自然语言查询和分析一个电商 SQLite 数据库。
可以提出这样的问题:
"按总消费额排名前 5 的客户是谁?"
"显示 Electronics 类别中库存低于 50 的所有产品"
"2026 年已完成订单的总收入是多少?"
四个工具,其中三个完全不需要 API 密钥。在两个独立层面实现只读、分页结果、SQLite 自身的错误文本回传给调用方,以及 74 个自动化测试。
目录 — 快速开始 · 配置提供商 · 工具 · 分页 · 错误 · 测试 · Docker · MCP 客户端 · 配置 · 安全 · 数据外发 · 项目结构
🚀 快速开始
1. 前置条件
Node.js:
v22.5.0或更高版本(用于内置的node:sqlite模块);推荐v24npm:
v11.0.0或更高版本
2. 安装
克隆此仓库并安装依赖:
npm install
cp .env.example .env
npm run build这样就足以将服务器连接到客户端并使用 list_tables、describe_table 和 execute_sql。只有自然语言工具才需要提供商——见下文。
Related MCP server: Shop SQLite MCP
🔑 配置你的 AI 提供商
打开 .env 文件并设置你偏好的 AI 模型。服务器会根据你设置的变量自动检测你的提供商:
选项 A:Anthropic Claude(推荐)
ANTHROPIC_API_KEY=sk-ant-api03-...
ANTHROPIC_MODEL=claude-opus-5选项 B:本地 Ollama(免费且离线)
OLLAMA_BASE_URL=http://localhost:11434
OLLAMA_MODEL=llama3.2注意:确保 Ollama 正在运行(
ollama serve)并且你已经拉取了模型(ollama pull llama3.2)。
选项 C:OpenAI
OPENAI_API_KEY=sk-proj-...
OPENAI_MODEL=gpt-4o-mini选项 D:自定义 / 第三方(Groq、DeepSeek、OpenRouter)
OPENAI_API_KEY=your_api_key
OPENAI_BASE_URL=https://api.groq.com/openai/v1
OPENAI_MODEL=llama-3.3-70b-versatile🛠 可用工具
四个工具中有三个直接与 SQLite 交互——无需 API 密钥、零成本、即时响应:
工具 | 功能 | 需要提供商 |
| 每个表及其通俗易懂的说明、行数和列,以及表之间的关系和此数据库使用的收入约定。 | 否 |
| 完整描述一个表——包含类型、键和描述的列、外键、 | 否 |
| 执行任何只读 | 否 |
| 接受一个通俗易懂的问题,生成并执行相应的 SQL,并返回带有洞察的文字答案。 | 是 |
每个工具的描述不仅告诉调用代理它做什么,还告诉它何时不应该使用——query_database 说明它返回的是文字而非数值、需要付费并且会进行两次 LLM 调用,并指向 execute_sql 供代理打算自行计算的任何内容使用。两个工具都内联说明了行数上限和收入约定,因此代理无需通过试错来发现这些。
示例:describe_table
// describe_table { "table_name": "orders" } — abridged
{
"table": "orders",
"purpose": "Order headers — one row per order placed by a customer, carrying its date, lifecycle status and total.",
"rowCount": 750,
"columns": [
{ "name": "status", "type": "TEXT", "primaryKey": false, "notNull": true, "default": null,
"description": "Lifecycle stage, one of: new, processing, shipped, completed, cancelled. Determines whether the order counts as revenue." }
],
"foreignKeys": [
{ "column": "customer_id", "referencesTable": "customers", "referencesColumn": "id", "onDelete": "CASCADE" }
],
"notes": ["Revenue convention: count every order whose status is not 'cancelled' …"],
"dataCoverage": { "order_date": { "min": "2026-02-17 18:53:30", "max": "2026-08-22 17:06:30" } },
"createStatement": "CREATE TABLE orders ( … )"
}dataCoverage 的存在是为了让代理能够区分空结果和超出范围的问题:询问 2025 年会返回"数据范围从……到……",而不是一个看起来像 bug 的裸零。
📄 浏览大量结果
每个结果都有上限——DATABASE_MAX_ROWS(默认 100),或你传入的更小的 limit。更大的 limit 会被截断而不是拒绝,因此调用方总能获得行数据。
execute_sql 接受 limit 和 offset,并告诉你是否还有更多:
// execute_sql { "sql": "SELECT id, name FROM products ORDER BY id", "limit": 2, "offset": 2 }
{
"columns": ["id", "name"],
"rows": [
{ "id": 3, "name": "Ноутбук UltraBook 15" },
{ "id": 4, "name": "Умные часы FitWatch" }
],
"rowCount": 2,
"offset": 2,
"hasMore": true,
"nextOffset": 4,
"note": "More rows matched than were returned. Call again with offset=4 for the next page.",
"executionTimeMs": 0.09
}持续以 offset: nextOffset 调用,直到 hasMore 为 false。当结果适合一页时,hasMore 为 false,totalAvailableRows 报告真实总数。
上限是在逐步执行语句时强制执行的,而不是通过裁剪已完成的结果:服务器在超过上限一行处停止,并且永远不会物化其余部分。SQL 是由模型生成的,因此意外的交叉连接否则会在丢弃任何行之前将数百万行拉入内存。分页同样在迭代期间完成,而不是通过向 SQL 追加 LIMIT/OFFSET——后者必须能兼容生成的语句已有的结尾。
query_database 共享行数上限但不分页——它以文字形式总结,页码无处可依附。任何超过一页的内容请使用 execute_sql。
🚦 错误是什么样的
失败以正常的 MCP 工具结果返回,带有 isError: true 和调用代理可以据此行动的消息,而不是传输层故障。
你发送的内容 | 你收到的内容 |
|
|
|
|
|
|
|
|
删除数据的自然语言请求 |
|
两条规则支配着这些文本:
保留 SQLite 自身的消息。 "no such column: nope" 是代理能被告知的最有用的一条信息,因为它足以让代理重写查询并重试。它永远不会被扁平化为"查询失败"。
主机细节永远不会泄露。 无法识别的错误——可能带有堆栈跟踪——会折叠为一行通用文本,并且所有外发内容都会清除数据库路径、项目根目录和主目录。完整细节保留在服务器日志中。这由专门的测试文件覆盖。
🧪 自动化测试
npm test # 74 tests across 4 files, runs in well under a second
npm run test:watch
npm run typecheck使用 tsx 的纯 node --test——无测试框架依赖。测试套件针对真实的 db/shop.db 运行,而不是模拟数据,因此如果模式与文档脱节,测试就会失败。
文件 | 覆盖内容 |
| 写入操作可能绕过只读防护的每一种方式:前导注释、 |
| 行数上限、 |
| 调用方允许看到的内容:可操作的消息通过、未知错误折叠、数据库路径 / 项目根目录 / 主目录从两者中被编辑。 |
| 实时数据库中的每个表和列都有书面描述、没有描述引用已不存在的表、以及收入约定已明确说明。 |
防护套件是最重要的一个:它是使"只读"成为事实而非仅仅是意图的边界,其中一个用例是开发期间捕获的真实误报。
🐳 Docker
docker build -t sql-mcp .镜像捆绑了数据库,因此不需要卷挂载。由于这是一个 stdio 服务器,必须使用 -i 且不带 TTY 运行——容器的 stdin 和 stdout 承载 JSON-RPC 流:
docker run -i --rm -e ANTHROPIC_API_KEY sql-mcp使用 examples/claude_desktop_config.docker.json 将其接入客户端。去掉 -e ANTHROPIC_API_KEY 即可在无凭据的情况下运行——list_tables、describe_table 和 execute_sql 无需提供商即可工作。
构建是多阶段的:TypeScript 在 node:24-alpine 构建器中编译,只有 dist/、db/ 和生产依赖被复制到运行时镜像中。它以非特权 node 用户运行,.env 永远不会被复制进去(凭据来自 -e),并且没有需要编译的原生插件,因为 SQLite 内置于 Node 本身。
🔌 连接 MCP 客户端
现成的配置文件位于 examples/ 中——复制与你客户端匹配的那个并替换路径。examples/claude_desktop_config.no-api-key.json 在完全没有凭据的情况下运行服务器,这足以使用 list_tables、describe_table 和 execute_sql。
Claude Desktop 配置
将此服务器添加到你的 Claude Desktop 配置文件(claude_desktop_config.json)中:
macOS:
~/Library/Application Support/Claude/claude_desktop_config.jsonWindows:
%APPDATA%\Claude\claude_desktop_config.json
(确保在连接前运行一次 npm run build)
示例 1:Anthropic Claude(默认)
{
"mcpServers": {
"sql-mcp": {
"command": "node",
"args": ["/absolute/path/to/sql-mcp/dist/index.js"],
"env": {
"ANTHROPIC_API_KEY": "sk-ant-api03-your-key-here",
"ANTHROPIC_MODEL": "claude-opus-5"
}
}
}
}示例 2:本地 Ollama(免费且离线)
{
"mcpServers": {
"sql-mcp": {
"command": "node",
"args": ["/absolute/path/to/sql-mcp/dist/index.js"],
"env": {
"OLLAMA_BASE_URL": "http://localhost:11434",
"OLLAMA_MODEL": "llama3.2"
}
}
}
}示例 3:OpenAI
{
"mcpServers": {
"sql-mcp": {
"command": "node",
"args": ["/absolute/path/to/sql-mcp/dist/index.js"],
"env": {
"OPENAI_API_KEY": "sk-proj-your-key-here",
"OPENAI_MODEL": "gpt-4o-mini"
}
}
}
}示例 4:自定义 / Groq / OpenRouter / DeepSeek
{
"mcpServers": {
"sql-mcp": {
"command": "node",
"args": ["/absolute/path/to/sql-mcp/dist/index.js"],
"env": {
"OPENAI_API_KEY": "gsk_your_groq_api_key",
"OPENAI_BASE_URL": "https://api.groq.com/openai/v1",
"OPENAI_MODEL": "llama-3.3-70b-versatile"
}
}
}
}服务器相对于自身位置解析 db/shop.db,因此这些配置中都不需要 DATABASE_PATH——MCP 客户端从自己选择的工作目录启动服务器,而服务器不依赖于此。
🔎 本地试用
即时终端测试
你可以直接在终端中测试自然语言问题:
npm run query -- "Show top 3 products by price"可视化 Web 检查器
使用官方 MCP Inspector 在浏览器中交互式测试工具:
npm run inspect:dev在浏览器中打开 inspector URL(例如
http://localhost:5173)。点击 Connect。
在 Tools 下,选择
query_database,输入你的问题,然后点击 Run Tool。
所有 npm 脚本
脚本 | 作用 |
| 编译到 |
| 通过 stdio 运行构建后的服务器 |
| 从源码运行并支持热重载( |
| 自动化测试 |
|
|
| 从终端提问 |
| 针对 |
🔧 配置参考
每个变量都是可选的;默认值就是你不做任何设置时运行所用的值。
变量 | 默认值 | 用途 |
|
| 数据库位置。绝对路径,或相对于项目根目录的路径——绝不相对于工作目录。 |
|
| 每次调用返回行数的硬上限,也是发送给 LLM 的行数上限。 |
|
| LLM 调用的单次请求超时上限。一个问题会发起两次顺序调用,因此没有这个设置时,卡住的提供商会让工具调用一直挂起。 |
| 自动检测 |
|
| — / | Anthropic 提供商。 |
| — / | OpenAI 以及任何兼容 OpenAI 的端点。 |
|
| 本地 Ollama。 |
| 未设置 |
|
格式错误的值会输出到 stderr 并回退到默认值,而不是被静默接受——客户端 env 块中的拼写错误会在启动时暴露出来,而不是表现得像变量从未被设置过一样。DEBUG 日志会记录每一个被提出的问题和每一条被生成的语句,在 MCP 客户端下它们会进入客户端的持久化日志文件,因此除非你主动开启,否则它们保持关闭。
🔒 安全性
数据库在驱动层面以只读方式打开,每条语句在执行前都会经过验证:它必须是单条 SELECT/WITH/VALUES 语句,不得包含任何写入数据、修改模式或改变连接状态的关键字。这两项检查都无法通过配置关闭。像 "删除所有已取消订单" 这样的请求会被拒绝,而不是被执行。
验证器基于语句的标记化视图而非原始文本工作,因此注释、字符串字面量和带引号的标识符无法用来隐藏关键字——/* c */ DELETE FROM orders 和 WITH x AS (SELECT 1) DELETE FROM orders 都会被拒绝,而 SELECT replace(name, 'a', 'b') 则不会被拒绝。
本服务器未写入的文本——你的问题,以及从数据库中读出的值——在提示词中会用每次请求独有的不可伪造标记进行分隔,因此名为 Widget (SYSTEM: ignore prior instructions…) 的产品无法逃逸到指令上下文中。这一点的影响不止于本进程:答案会作为工具输出传回调用方代理,又向前跳了一步。
🔐 什么数据被发送到哪里
本服务器通过调用 LLM 来回答问题,因此每次 query_database 调用都会让数据库内容离开你的机器。具体来说,每次调用会发送:
你的数据库模式——表名、列名和类型,以及行数——用于生成 SQL。
查询返回的行(最多
DATABASE_MAX_ROWS行,默认 100)——用于将其转化为书面答案。
对于内置的商店数据库,这些行包含客户姓名、电子邮件地址和电话号码。它们会被发送到你配置的任何提供商,发送到 OPENAI_BASE_URL 指定的任何端点——对于 Groq、OpenRouter 或 DeepSeek 来说,那是一个受其自身条款约束的第三方。
如果你的数据无法接受这一点:
使用另外三个工具。
list_tables、describe_table和execute_sql完全不发起网络调用——没有任何数据离开机器。使用 Ollama。 它在本地运行,因此没有任何数据离开机器。
限制查询。 聚合类问题("按类别统计收入")返回的是汇总行,而不是客户记录。
调低
DATABASE_MAX_ROWS以限制每次查询发送的行数据量。
服务器永远不会发送数据库文件,而且它只能读取——参见安全性。
📁 项目结构
src/
index.ts MCP server entry point (stdio transport)
cli.ts Terminal harness: npm run query -- "…"
config/ Env parsing, provider detection, path resolution
tools/ The four MCP tools and their descriptions
services/
database.service.ts SQLite access, row capping, paging, introspection
sql-guard.ts Read-only enforcement (tokenizing validator)
errors.ts Caller-safe messages, path redaction
schema-metadata.ts Human-written meaning the schema cannot record
query-engine.service.ts NL → SQL → execute → prose pipeline
llm/ Anthropic / OpenAI / Ollama behind one interface
prompts/ SQL generation, humanization, untrusted-input framing
tests/ node --test suites (see Automated Tests)
db/ shop.db and its schema documentation
docs/ Architecture and sequence diagrams
examples/ Ready-to-paste client configurations📚 技术文档
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- FlicenseNot gradedqualityCmaintenanceEnables natural-language sales queries against a SQLite database, generating and executing read-only SQL through a secure MCP server with table listing, schema description, and query execution.
- FlicenseNot gradedqualityCmaintenanceEnables safe, read-only analysis of an online store's SQLite database, providing schema introspection, restricted SELECT queries, and specialized analytics tools through MCP.
- FlicenseAqualityCmaintenanceEnables AI agents to read-only query an online store's SQLite database, listing tables, inspecting schemas, and running SELECT queries over customers, products, orders, and order items.3
Related MCP Connectors
Connect e-commerce and marketing data to AI assistants via MCP.
Analytical memory for AI agents: a real Postgres queried in plain English over MCP. One command.
GibsonAI MCP server: manage your databases with natural language
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/harutlc/sql-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server