shop-sql-mcp
shop-sql-mcp
Небольшой MCP-сервер, который даёт ИИ-агенту только чтение аналитический доступ к базе SQLite shop.db через stdio.
Сервер делает три вещи и больше ничего: перечисляет таблицы, описывает их схему и выполняет один запрос (только чтение) за вызов с принудительной пагинацией на стороне сервера. Все рассуждения — какие соединения выполнять, как агрегировать, когда смотреть схему — остаются за агентом.
AI Agent
|
| MCP over stdio
v
shop-sql-mcp
|
+-- list_tables
+-- describe_table
+-- query_database
|
v
read-only SQLite connection
|
v
shop.dbТребования
Node.js 22.5 или новее (рекомендуется 24+). Сервер использует встроенный модуль
node:sqlite, поэтому не нужно собирать нативное расширение SQLite.Других требований к окружению нет.
Related MCP server: mcpserve-py
Установка
npm installНастройка
Настройка необязательна. По умолчанию сервер открывает shop.db в корне проекта.
Переменная | Значение по умолчанию | Описание |
|
| Путь к файлу SQLite. Относительные пути разрешаются относительно корня проекта, чтобы сервер не зависел от рабочей директории, где его запускают. |
Скопируйте .env.example в .env, если хотите оставить локальные изменения. Сам сервер читает обычные переменные окружения; ANTHROPIC_API_KEY, EVAL_MODEL и EVAL_MAX_STEPS из .env.example используются только при запуске npm run eval.
Сборка
npm run buildКомпилирует src/ в dist/.
Запуск
npm start # runs the built server (dist/index.js)
npm run dev # runs src/index.ts directly, no build stepСервер общается по MCP на stdin/stdout и пишет на stderr только диагностику, поэтому в терминале запуск будет выглядеть как зависший — это нормально. Его должен запускать MCP-хост.
Подключение к MCP-агенту
Добавьте это в конфигурацию MCP-хоста (claude_desktop_config.json для Claude Desktop, .mcp.json для Claude Code или эквивалентный файл своего хоста), используя абсолютный путь к проекту:
{
"mcpServers": {
"shop-sql": {
"command": "node",
"args": ["/absolute/path/to/shop-sql-mcp/dist/index.js"]
}
}
}Чтобы запустить из исходников без сборки, укажите вместо этого точку входа TypeScript — Node выполнит её напрямую:
{
"mcpServers": {
"shop-sql": {
"command": "node",
"args": ["/absolute/path/to/shop-sql-mcp/src/index.ts"]
}
}
}Чтобы читать базу в другом месте:
{
"mcpServers": {
"shop-sql": {
"command": "node",
"args": ["/absolute/path/to/shop-sql-mcp/dist/index.js"],
"env": { "DATABASE_PATH": "/absolute/path/to/other.db" }
}
}
}Для Claude Code можно также зарегистрировать сервер из командной строки:
claude mcp add shop-sql -- node /absolute/path/to/shop-sql-mcp/dist/index.jsИнструменты
list_tables
Без аргументов. Возвращает пользовательские таблицы; внутренние таблицы sqlite_* скрыты.
{
"tables": [
{ "name": "customers" },
{ "name": "order_items" },
{ "name": "orders" },
{ "name": "products" }
]
}describe_table
{ table: string }Читает схему напрямую из SQLite — ничего не зашито в код — и возвращает колонки, типы, допустимость NULL, первичные и внешние ключи:
{
"table": "order_items",
"columns": [
{ "name": "id", "type": "INTEGER", "nullable": false, "primaryKey": true },
{ "name": "order_id", "type": "INTEGER", "nullable": false, "primaryKey": false }
],
"foreignKeys": [
{ "column": "order_id", "referencesTable": "orders", "referencesColumn": "id" },
{ "column": "product_id", "referencesTable": "products", "referencesColumn": "id" }
]
}Неизвестное имя — это обрабатываемая ошибка, а не падение:
{ "error": { "code": "TABLE_NOT_FOUND", "message": "TABLE_NOT_FOUND: Table \"foo\" does not exist." } }Примечание: колонка, которая является INTEGER PRIMARY KEY, возвращается как nullable: false. Функция SQLite table_info говорит иначе, но такая колонка — псевдоним rowid и никогда не может содержать NULL.
query_database
{ sql: string; limit?: number; offset?: number }Выполняет один запрос только на чтение — SELECT ... или WITH ... SELECT ... — с поддержкой JOIN, WHERE, GROUP BY, HAVING, ORDER BY, подзапросов, агрегатов и фильтрации по датам.
{
"columns": ["category", "revenue"],
"rows": [["Electronics", 1234567.89]],
"returnedRows": 1,
"limit": 100,
"offset": 0,
"hasMore": false
}Строки — это массивы значений в порядке колонок columns. Это сохраняет компактность ответа и позволяет избежать неоднозначности, когда запрос возвращает две колонки с одинаковыми именами.
Ошибки возвращаются обычным результатом инструмента с флагом isError и понятным коротким сообщение, чтобы агент мог исправить SQL и повторить:
{ "error": { "code": "SQL_ERROR", "message": "no such column: total" } }Коды ошибок: SQL_ERROR, READ_ONLY_VIOLATION, MULTIPLE_STATEMENTS, TABLE_NOT_FOUND, INVALID_ARGUMENT, DATABASE_UNAVAILABLE. Стек-трейсы никогда не возвращаются.
Пагинация
Пагинация принудительно выбирающая сервером, а не SQL в запросе.
limitпо умолчанию — 100, максимум — 500;offsetпо умолчанию — 0.Запрос агента оборачивается как
SELECT * FROM (<ваш sql>) LIMIT ? OFFSET ?, так что даже запрос с собственнымLIMIT 100000не сможет вернуть больше строк, чемlimit.Сервер внутри загружает
limit + 1строк, чтобы определитьhasMore, без повторного запроса счётчика, и возвращает не болееlimitстрок.Один вызов никогда не вернёт более 500 строк — благодаря этому широкий
SELECT *не переполняет контекст модели.
Для листания результатов оставьте SQL без изменений (с детерминированным ORDER BY) и увеличивайте offset на limit, пока hasMore равно true.
Безопасность только для чтения
Два независимых уровня защиты, так что ни один из них не обязан работать сам по себе.
1. Валидация SQL(src/sqlSafety.ts). Небольшой лексический анализ пропускает комментарии, строковые литералы и идентификаторы в кавычках, после чего требует, чтобы:
выражение начиналось с
SELECTилиWITH— наивныйstartsWith("SELECT")отклонил бы смелые read-only CTE;там был ровно один оператор (любой лишний
;отклоняется, при этом;внутри литерала или комментария это не разделитель);нигде не встретилось запрещённого ключевого слова, включая содержимое CTE:
INSERT,UPDATE,DELETE,CREATE,DROP,ALTER,REPLACE,ATTACH,DETACH,VACUUM,REINDEX,PRAGMA,ANALYZE,BEGIN,COMMIT,ROLLBACK,SAVEPOINT,load_extension,writable_schema.
Запрещённый SQL всегда отклоняется явной ошибкой — никогда не игнорируется молча и никогда не выполняется частично. При этом REPLACE(a, b, c) разрешён как скалярная функция, потому что записывающим является только оператор REPLACE INTO.
Само подключение SQLite. shop.db открывается через new DatabaseSync(path, { readOnly: true }). Даже если запись просочилась мимо валидации, SQLite откажется с ошибкой "attempt to write a readonly database". Набор тестов проверяет это напрямую, выполняя запросы записи в обход валидатора.
Неверные или запрещённые запросы возвращаются инструментом как ошибки и никогда не завершают процесс, поэтому сессия переживает любое количество неудачных попыток.
Запуск тестов
npm testВыполняет детерминированный набор тестов — без сети, без ключей API, без LLM. Встроенный тестовый раннер Node выполняет исходники TypeScript напрямую. Покрытие включает: list_tables, describe_table (колонки, типы, допустимость NULL, первичные ключи, внешние ключи, неизвестные таблицы), простые выборки, фильтрацию, агрегацию, joins, GROUP BY, read-only CTE, фильтрацию по дате, пагинацию (лимит по умолчанию, максимальный лимит, offset, границы hasMore), неверный SQL, неизвестные колонки и таблицы, отказ INSERT/UPDATE/DELETE/CREATE/DROP/ALTER/REPLACE/ATTACH/DETACH/VACUUM/REINDEX/PRAGMA и нескольких запросов, подтверждение того, что база побайтово не меняется после каждого отклонённого запроса на запись, а также полные вызовы MCP через stdio, которые подтверждают, что сервер остаётся рабочим после ошибок.
Запуск оценки вручную
export ANTHROPIC_API_KEY=sk-...
npm run evalЗапускайте это вручную. Целевая фраза исключена из npm test, потому что этап вызывает реальную LLM против реального MCP-сервера через stdio и требует платных API-вызовов.
Она запускает сервер, предоставляет модели три MCP-инструмента и инструмент submit_answer, JSON-схема которого зафиксирована для каждой задачи, и сравнивает структурированный ответ с эталонным значением, которое вычислено напрямую из SQLite — не с анализом естественного языка. Задачи охватывают обнаружение таблиц, определение схемы, фильтрацию, агрегирование, joins, затраты клиентов, количество заказов клиентов, продажи товара и выручку категорий; выручку за 2025 год и деструктивный запрос, который должен быть отклонён (проверяется также, что база после этого не изменилась).
Необязательно: EVAL_MODEL (по умолчанию claude-sonnet-5) и EVAL_MAX_STEPS (по умолчанию 12). Ненулевой кодзультата, если хотя бы одна задача провалится.
Структура
src/
index.ts MCP server: tool registration, stdio wiring, error shaping
db.ts read-only connection, path resolution, row/value normalisation
tools.ts the three tools: list_tables, describe_table, query_database
sqlSafety.ts single-statement read-only SQL validation
tests/
sqlSafety.test.ts validator, allowed and forbidden SQL
tools.test.ts tools against the real shop.db
mcp.test.ts end-to-end over stdio with a real MCP client
eval/
tasks.ts eval tasks and their SQLite reference values
run.ts LLM + MCP eval runner (manual)
shop.dbЗависимости
Package | Назначение |
| Официальный MCP TypeScript SDK (v2). Предоставляет |
| Требуется SDK для схем входа/выхода инструментов; именно он предоставляет машиночитаемые типы аргументов агенту. |
| Только для разработки: сборка и проверка типов. |
| Только для разработки: официальный MCP-клиент для сквозных тестов stdio и тестирования. |
SQLite — это встроенный node:sqlite; тесты — встроенный раннер Node; HTTP для оценки это обычный fetch — без драйверов, ORM, query builder’ов, веб-фреймворков, логирования, тестовой среды, разборки SQL или LLM SDK.
This server cannot be installed
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
- AlicenseAqualityCmaintenanceEnables safe, read-only SQL access to SQLite databases for AI agents, allowing schema exploration and SELECT queries with defense-in-depth protections.3MIT
- AlicenseNot gradedqualityDmaintenanceExposes SQLite database query tools and markdown document resources over JSON-RPC 2.0 stdio transport, enabling AI assistants to read and search documents and execute read-only SQL queries.1MIT
- AlicenseAqualityBmaintenanceLets AI agents query local SQLite database files read-only using Node's built-in sqlite module, providing tools for listing tables, describing schemas, and running SQL queries.315MIT
- FlicenseNot gradedqualityCmaintenanceExposes any SQLite database as read-only MCP tools for AI assistants, enabling listing tables, describing schemas, and running SELECT queries with filtering, ordering, and pagination.
Related MCP Connectors
Explore, query, and inspect SQLite databases with ease. List tables, preview results, and view det…
Analytical memory for AI agents: a real Postgres queried in plain English over MCP. One command.
Query PostgreSQL databases in plain English — LLM-generated, safety-validated SQL.
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/lampmaster/shop-sql-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server