Shop MCP Server
# Shop MCP Server
Локальный MCP-сервер для аналитики SQLite-базы интернет-магазина. AI-агент вызывает MCP-инструмент, сервер преобразует запрос в безопасный SQL `SELECT`, напрямую читает `shop.db` и возвращает структурированный результат.
```text
Host-приложение
├── AI-агент / LLM
└── MCP-клиент
│ JSON-RPC / stdio
▼
Shop MCP Server
│ read-only SQLite
▼
data/shop.db
```
## Возможности
- прямое подключение к SQLite без HTTP и отдельного DB-сервера;
- MCP-транспорт `stdio`;
- обнаружение `query_shop` и `inspect_database` через `tools/list`;
- восемь примеров задания в описании и JSON Schema инструмента;
- обычный текст, JSON intent или готовый безопасный `SELECT`;
- исключение заказов `cancelled` из всей аналитики;
- пагинация и ограничение результата;
- многоуровневая read-only защита.
## Установка
Требуется Python 3.11 или новее.
```bash
python3 -m venv .venv
.venv/bin/python -m pip install -e '.[dev]'
```
Подготовленная база уже находится в `data/shop.db`. В ней 150 клиентов, поле `customers.country` заполнено у всех клиентов, а 45 клиентов относятся к `Germany`.
## Повторная подготовка базы
Исходная база не изменяется. Команда создаёт новую рабочую копию и добавляет `country TEXT NOT NULL` с воспроизводимыми синтетическими значениями:
```bash
.venv/bin/shop-prepare-db /path/to/original/shop.db ./data/shop.db
```
Распределение зависит только от `customers.id`, поэтому повторная подготовка даёт те же значения. Страны являются тестовыми данными и не описывают реальное местонахождение клиентов.
## Настройка пути
Путь определяется в таком порядке:
1. `SHOP_DB_PATH`;
2. JSON-файл из `SHOP_MCP_CONFIG` или `config/shop_mcp.json`;
3. `data/shop.db` относительно рабочей директории.
Пример переменной окружения находится в `.env.example`, а конфигурация MCP-клиента — в `config/mcp.example.json`. Замените `/absolute/path/to/MCPDeveloper` на абсолютный путь к проекту.
## Запуск
Обычно сервер запускает MCP-клиент из своей конфигурации. Для ручного запуска процесса:
```bash
SHOP_DB_PATH=./data/shop.db .venv/bin/python -m shop_mcp.server
```
`stdout` зарезервирован для MCP JSON-RPC. Диагностика не выводится в протокольный поток.
## Инструменты
### `inspect_database`
Аргументы:
```json
{"action": "list_tables"}
```
или:
```json
{"action": "describe_table", "table": "customers"}
```
### `query_shop`
Аргументы:
```json
{
"request": "Сколько клиентов из Германии?",
"limit": 100,
"offset": 0
}
```
Примеры, объявляемые через `tools/list`:
1. Какие таблицы есть в базе и какие в них поля?
2. Сколько клиентов из Германии?
3. В какой стране больше всего клиентов?
4. Какой клиент потратил больше всего? Верни имя, email и общую сумму.
5. Покажи топ-5 товаров по проданному количеству и выручке.
6. Покажи топ-3 категории по выручке.
7. Какая выручка была в 2025 году?
8. Какой клиент сделал больше всего заказов?
Можно передать структурированный intent:
```json
{
"request": "{\"intent\": \"revenue_by_year\", \"year\": 2025}"
}
```
Или готовый запрос:
```json
{
"request": "SELECT name, category FROM products ORDER BY name"
}
```
## Бизнес-правила
- `orders.status = 'cancelled'` не участвует в метриках.
- Расходы клиентов и годовая выручка считаются по `orders.total_amount`.
- Выручка товаров и категорий считается как `quantity * unit_price`.
- Интервал года полуоткрытый: от 1 января включительно до 1 января следующего года исключительно.
- В поставленной базе все заказы относятся к 2026 году, поэтому выручка за 2025 год равна `0`.
## Безопасность
Сервер открывает SQLite через `mode=ro`, включает `query_only`, устанавливает SQLite authorizer, запрещает несколько выражений, DML, DDL, `ATTACH`, изменяющие `PRAGMA`, загрузку расширений и ограничивает время выполнения.
Любая попытка выполнить операцию, отличную от `SELECT`, возвращает точный ответ:
```text
Не доступный вариант запроса
```
Внутренние ошибки SQLite, stack trace и локальные пути клиенту не возвращаются.
## Проверка
```bash
.venv/bin/pytest
.venv/bin/ruff check .
.venv/bin/ruff format --check .
```
Тесты включают реальный запуск MCP-сервера как subprocess, подключение `ClientSession` через `stdio`, `tools/list`, вызов обоих инструментов, аналитические сценарии и попытки изменения базы.
Полная утверждённая спецификация находится в `docs/specification.md`.
TDQS
Scored across 2 tools
The two tools have clearly distinct purposes: one handles database schema inspection (list tables/describe fields), the other executes analytical queries. There is no overlap in their functional boundaries, making selection unambiguous for an agent.
Both tools follow a consistent verb_noun snake_case pattern ('inspect_database', 'query_shop'), using clear, descriptive verbs. Naming style is uniform and predictable.
With only 2 tools, the server feels minimal for a shop analytics domain. While the query tool is versatile, a more granular set (e.g., get_customers, get_orders) might be expected. The count is borderline, not excessive but thin.
The tool surface fully covers the stated purpose: schema discovery via inspect_database and arbitrary read-only analytical queries via query_shop. There are no obvious gaps for a read-only analytics server, as the query tool can address any data retrieval need.