Skip to main content
Glama
MarkIvor

DataSearcher MCP

by MarkIvor
README.md
# DataSearcher MCP

![Python](https://img.shields.io/badge/Python-3.10+-blue?logo=python&logoColor=white)
![MCP](https://img.shields.io/badge/MCP-1.28-purple)
![DuckDB](https://img.shields.io/badge/DuckDB-Lazy-orange)
![License](https://img.shields.io/badge/License-MIT-green)
![Language](https://img.shields.io/badge/Язык-Русский-red)

> Подключи базу данных к Claude или Cursor — и спрашивай на русском:
> «какие товары продаются хуже всего», «найди аномалии в продажах», «прогноз на 3 месяца».
> 46 инструментов: SQL, статистика, ML, графики, дашборды + enterprise: read-only guard,
> PII masking, аудит-логи, Knowledge Base, dbt, DataHub, semantic search.

---

## Что это такое?

**DataSearcher MCP** — это мост между вашей базой данных и ИИ-ассистентом (Claude Desktop, Cursor, VS Code).

Обычно, чтобы проанализировать данные из БД, нужно писать SQL-запросы вручную или открывать BI-систему. С этим MCP-сервером вы просто **разговариваете с ИИ на обычном русском языке**, а он сам:

- пишет и выполняет SQL к вашей базе (read-only, с защитой от изменений)
- строит графики и дашборды
- находит аномалии, корреляции, инсайты
- прогнозирует тренды (ML)
- генерирует HTML-отчёты и XLSX-экспорты
- маскирует PII (email, телефон, ИНН) в результатах
- логирует все запросы для аудита

### Пример диалога

```
Вы: Подключись к моей PostgreSQL и покажи топ-5 регионов по выручке

ИИ: [вызывает sql_query → SQL выполняется прямо в вашей PostgreSQL]
    Вот топ-5 регионов по выручке:
    | Регион       | Выручка     | Заказов |
    |--------------|-------------|---------|
    | Москва       | 1 358 468 ₽ | 55      |
    | Новосибирск  | 1 036 564 ₽ | 45      |
    ...

Вы: Найди аномалии в суммах заказов

ИИ: [вызывает detect_anomalies → z-score + IQR]
    Обнаружено 3 выброса в колонке amount:
    - Заказ #1047: 49 870 ₽ (z-score = 4.2)
    - Заказ #2891: 48 200 ₽ (z-score = 3.8)
    ...

Вы: Построй дашборд и сохрани как HTML

ИИ: [вызывает create_public_dashboard → генерирует HTML с графиками и фильтрами]
    Дашборд создан! Откройте файл:
    /tmp/datasearcher_mcp_dashboards/abc123/dashboard.html
```

### Почему это круто?

| Без DataSearcher MCP | С DataSearcher MCP |
|---------------------|-------------------|
| Пишешь SQL вручную | ИИ сам пишет и выполняет SQL |
| Открываешь BI-систему для графиков | Графики и дашборды прямо в чате |
| Excel для сводных таблиц | `pivot_table` одним вызовом |
| Python + Jupyter для ML | Прогнозы и кластеризация через чат |
| Каждая БД — свой диалект SQL | Пишешь на DuckDB SQL — сервер переводит |
| Нет защиты от случайного DROP | Read-only guard блокирует DML/DDL |
| PII в открытом виде | Авто-маскирование email/телефон/ИНН |
| Нет аудита кто что запросил | Полный лог запросов и ошибок |

---

## Чем отличается от других MCP-серверов?

### 1. SQL выполняется в вашей базе, а не во встроенной

Когда вы спрашиваете «покажи продажи по регионам», SQL выполняется **напрямую в вашей PostgreSQL/MySQL/ClickHouse** — с индексами, оптимизатором, кешем. DuckDB подключается **только для ML-задач** (кластеризация, прогнозы), выгружая только нужные колонки.

### 2. Пишешь на одном SQL — работает в любой БД

Написали `DATE_TRUNC('month', date_col)` (DuckDB-синтаксис)? Сервер автоматически переведёт под диалект source DB через [sqlglot](https://github.com/tobymao/sqlglot).

### 3. Кросс-БД JOIN через federated-режим

Прицепите PostgreSQL и MySQL к DuckDB одновременно и сделайте JOIN между ними — без выгрузки данных.

### 4. Enterprise-безопасность

- **Read-only guard** — блокирует INSERT/UPDATE/DELETE/DROP/TRUNCATE
- **PII auto-detection + masking** — автоматически находит email, телефон, ИНН, СНИЛС, паспорт и маскирует в результатах
- **Schema ACL** — фильтрация raw/staging таблиц, `allowed_schemas`/`blocked_tables`
- **Rate limiting** — ограничение SQL/ML запросов в минуту
- **HTTP Bearer auth** — для удалённого доступа
- **Query timeout** — защита от тяжёлых запросов

### 5. Knowledge Base + метаданные

SQLite-хранилище бизнес-описаний: что значит каждая таблица и колонка, кто владелец данных, какие метрики как считаются. Наполняется из:
1. Схемы БД (автоматически)
2. dbt manifest (описания, тесты, теги)
3. DataHub (lineage, глоссарий)
4. Ручной правки через `update_metadata`

### 6. Семантический поиск + Example Store

- `semantic_search` — поиск по текстовым данным через LLM embeddings
- Example Store — база пар «NL-запрос → SQL» для few-shot обучения
- `search_knowledge` — поиск по метаданным и примерам

### 7. REST API как источник данных

Подключайте не только БД, но и REST API — данные выгружаются в DuckDB и доступны всем 46 инструментам анализа.

### 8. BI link builder

Генерация URL для Superset, Grafana, Yandex Datalens, Tableau, Power BI с предзаполненными фильтрами.

---

## Быстрый старт

### Шаг 1. Установка

```bash
git clone https://github.com/MarkIvor/mcp-datasearcher.git
cd mcp-datasearcher
pip install -e ".[all]"
```

### Шаг 2. Настройка подключений

```bash
cp connections.example.yaml connections.yaml
```

```yaml
connections:
  - name: my_db
    db_type: postgresql          # postgresql | mysql | clickhouse | sqlite | api
    host: localhost
    port: 5432
    database: mydb
    username: ${DB_USER}
    password: ${DB_PASSWORD}
    mode: auto                   # auto | remote | dump | federated
    # ── Семантический слой ──
    allowed_schemas: [mart, analytics]
    blocked_tables: [raw_*, stg_*, tmp_*]

  # REST API тоже можно:
  - name: crm_api
    db_type: api
    base_url: https://api.company.com/v1
    auth_header: "Authorization: Bearer ${CRM_TOKEN}"
    endpoints:
      - path: /customers
        table_name: customers
    mode: dump

# dbt (опционально):
# dbt:
#   manifest_path: ./target/manifest.json

# DataHub (опционально):
# datahub:
#   server_url: http://datahub.company.com:8080
#   token: ${DATAHUB_TOKEN}
```

### Шаг 3. Подключение к Claude Desktop

```json
{
  "mcpServers": {
    "datasearcher": {
      "command": "datasearcher-mcp",
      "args": ["--config", "/path/to/connections.yaml"]
    }
  }
}
```

<details>
<summary><b>Cursor / Docker / HTTP — альтернативы</b></summary>

**Cursor** (`.cursor/mcp.json`):
```json
{"mcpServers": {"datasearcher": {"command": "datasearcher-mcp", "args": ["--config", "/path/to/connections.yaml"]}}}
```

**Docker**:
```bash
cp connections.example.yaml connections.yaml
docker compose up -d    # → http://localhost:8000/mcp
```

**HTTP**:
```bash
datasearcher-mcp --transport http --host 0.0.0.0 --port 8000 --auth-token secret123
```
</details>

---

## 46 инструментов

### SQL и подключения

| Инструмент | Что делает |
|-----------|----------|
| `sql_query` | SQL-запрос (read-only, markdown/json/csv, авто-трансляция диалектов) |
| `query_explain` | План выполнения SQL (EXPLAIN) |
| `get_schema` | Структура таблицы (remote или DuckDB) |
| `attach_database` | Подключить новую БД в рантайме |
| `refresh_schema` | Обновить схему после изменений в БД |
| `test_connection` | Проверить доступность подключения |
| `load_file` | Загрузить CSV/Excel/Parquet |

### Аналитика данных

| Инструмент | Что делает |
|-----------|----------|
| `smart_summary` | Умное саммари таблицы |
| `profile_data` | Статистика по колонкам |
| `data_quality_report` | Аудит качества (пропуски, дубликаты) |
| `auto_insights` | Топ-5 инсайтов автоматически |
| `sample_data` | Выборка строк |
| `find_duplicates` | Дубликаты (точные и fuzzy) |
| `detect_anomalies` | Выбросы (z-score, IQR) |
| `detect_patterns` | Паттерны в тексте (email, ИНН, телефон) |
| `sql_query` | SQL с форматами markdown/json/csv |

### Статистика и связи

| Инструмент | Что делает |
|-----------|----------|
| `correlation_analysis` | Корреляции (Пирсон/Спирмен) |
| `distribution_analysis` | Форма распределения |
| `cross_tab` | Кросс-табуляция + Хи-квадрат |
| `pivot_table` | Сводная таблица (Excel PIVOT) |
| `statistical_test` | t-тест, Mann-Whitney, KS, Хи-квадрат |
| `segment_data` | Сегментация, RFM-анализ |
| `compare_tables` | Сравнение двух таблиц |
| `time_analysis` | Тренды, сезонность, скользящее среднее |

### ML и прогнозы

| Инструмент | Что делает |
|-----------|----------|
| `predict_trend` | Прогноз тренда (регрессия) |
| `cluster_analysis` | Кластеризация K-Means/DBSCAN |
| `feature_importance` | Важность признаков (Random Forest) |
| `classify_rows` | Классификация строк через LLM |
| `semantic_search` | Семантический поиск через embeddings |
| `generate_sql` | Генерация SQL из описания на русском |

### Визуализация и отчёты

| Инструмент | Что делает |
|-----------|----------|
| `visualize_data` | График → PNG + JSON |
| `build_dashboard` | Дашборд 4-6 графиков |
| `create_public_dashboard` | Standalone HTML с фильтрами |
| `data_story` | Нарратив с графиками |
| `export_data` | Экспорт в CSV |
| `export_xlsx` | Экспорт в XLSX с форматированием |
| `build_bi_link` | URL для Superset/Grafana/Datalens |

### Управление данными

| Инструмент | Что делает |
|-----------|----------|
| `transform_data` | Нормализация, one-hot, извлечение дат |
| `merge_tables` | JOIN (с авто-определением ключей по FK) |
| `update_metadata` | Обновить метаописание в Knowledge Base |
| `list_metrics` | Список расчётных метрик с формулами |
| `scan_pii` | Скан PII в таблице |
| `get_logs` | Логи запросов/ошибок/аудита |
| `add_example` | Добавить эталон «NL→SQL» в Example Store |
| `search_knowledge` | Поиск по базе знаний и примерам |
| `load_dbt` | Импорт метаданных из dbt manifest |
| `sync_datahub` | Синхронизация с DataHub |

### Ресурсы (5)

- **`schema://tables`** — таблицы с типами, бизнес-описаниями, PII-метками
- **`schema://diagram`** — Mermaid ER-диаграмма
- **`knowledge://tables`** — метаданные, владельцы, метрики
- **`connection://list`** — подключения и режимы
- **`reasoning://last`** — Chain of Thought (история запросов)

### Промпты (2)

- **`analyze_table`** — системный промпт аналитика
- **`weekly_report`** — шаблон еженедельного отчёта

---

## Enterprise-фичи

### Read-only guard

Все SQL-запросы проверяются: INSERT/UPDATE/DELETE/DROP/TRUNCATE/ALTER — заблокированы.
Разрешены только SELECT/WITH/EXPLAIN/SHOW/DESCRIBE.

```python
# Настройка
DATASEARCHER_MCP_READ_ONLY=true   # false = отключить guard
```

### PII auto-detection + masking

При загрузке схемы сервер сканирует текстовые колонки и автоматически определяет:
email, телефон (РФ), ИНН, СНИЛС, паспорт, банковскую карту, IP-адрес.

В результатах SQL-запросов PII маскируется: `a***@company.com`, `+7(912)***-**-89`, `7710******`.

```python
DATASEARCHER_MCP_PII_MASKING=true
```

### Knowledge Base (SQLite)

Бизнес-метаданные в SQLite: описания таблиц, колонок, владельцы, теги, расчётные метрики.
Наполняется из 4 источников (fallback-цепочка):

1. **Схема БД** — автоматически (DESCRIBE, information_schema, FK)
2. **dbt manifest** — `load_dbt` инструмент (описания, тесты, теги, слои)
3. **DataHub** — `sync_datahub` инструмент (lineage, глоссарий, владельцы)
4. **Ручная правка** — `update_metadata` инструмент

### Логирование и аудит

Каждый SQL-запрос, ML-вызов, ошибка — логируется в SQLite (append-only):

- **query_log**: timestamp, tool, SQL, таблица, длительность, статус
- **error_log**: тип ошибки, сообщение, SQL, stack trace
- **audit_log**: действия (attach, refresh, load_file, update_metadata)

```python
DATASEARCHER_MCP_LOG_ENABLED=true
```

### Rate limiting

Per-tool throttling: SQL — 60/мин, ML — 10/мин (настраивается).

### Schema ACL

Фильтрация таблиц по бизнес-слою:
```yaml
allowed_schemas: [mart, analytics]    # только эти схемы
blocked_tables: [raw_*, stg_*, tmp_*]  # glob-паттерны исключений
```

### REST API connector

Подключение данных из REST API как обычных таблиц:
```yaml
- name: crm_api
  db_type: api
  base_url: https://api.company.com/v1
  auth_header: "Authorization: Bearer ${CRM_TOKEN}"
  endpoints:
    - path: /customers
      table_name: customers
  pagination: offset    # offset | cursor | none
  mode: dump            # выгрузить в DuckDB
```

---

## Режимы работы подключений

| Режим | Как работает | Когда использовать |
|-------|-------------|-------------------|
| `auto` (по умолч.) | SQL → source DB, ML → DuckDB (лениво) | Универсальный |
| `remote` | Всё SQL в source DB, без DuckDB | БД быстрая, ML не нужен |
| `dump` | Таблицы выгружаются в DuckDB при старте | Файлы, маленькие БД |
| `federated` | Source DB прицепляется к DuckDB | Кросс-БД JOIN |

---

## Поддерживаемые БД

| БД | db_type | Remote SQL | Federated |
|----|---------|-----------|-----------|
| PostgreSQL | `postgresql` | ✅ | ✅ |
| MySQL / MariaDB | `mysql` | ✅ | ✅ |
| ClickHouse | `clickhouse` | ✅ | — |
| SQLite | `sqlite` | ✅ | ✅ |
| REST API | `api` | — | — |
| CSV | файл | — | — |
| Excel (.xlsx) | файл | — | — |
| Parquet | файл | — | — |

---

## LLM для классификации и поиска

| `llm_mode` | Как работает | Когда использовать |
|-----------|-------------|-------------------|
| `builtin` | LLM-клиент (`LLM_BASE_URL`/`LLM_MODEL`) | Ollama, vLLM, OpenAI |
| `sampling` | Модель хоста через MCP sampling | Claude Desktop |
| `none` | Инструкция для хоста | Без LLM |

Работает на бюджетных LLM — достаточно 7B-14B.

---

## Переменные окружения

Префикс `DATASEARCHER_MCP_`:

| Переменная | По умолчанию | Описание |
|-----------|-------------|----------|
| `DATASEARCHER_MCP_CONNECTIONS_FILE` | `connections.yaml` | Файл подключений |
| `DATASEARCHER_MCP_READ_ONLY` | `true` | Read-only guard (блок DML/DDL) |
| `DATASEARCHER_MCP_PII_MASKING` | `true` | Авто-маскирование PII |
| `DATASEARCHER_MCP_LOG_ENABLED` | `true` | Логирование запросов/ошибок |
| `DATASEARCHER_MCP_RATE_LIMIT_ENABLED` | `true` | Rate limiting |
| `DATASEARCHER_MCP_RATE_LIMIT_SQL` | `60` | SQL-запросов в минуту |
| `DATASEARCHER_MCP_RATE_LIMIT_ML` | `10` | ML-запросов в минуту |
| `DATASEARCHER_MCP_QUERY_TIMEOUT` | `60` | Таймаут SQL (сек) |
| `DATASEARCHER_MCP_AUTO_TRANSLATE` | `true` | Трансляция SQL между диалектами |
| `DATASEARCHER_MCP_AUTH_TOKEN` | `` | Bearer token для HTTP auth |
| `DATASEARCHER_MCP_DUCKDB_ENABLED` | `false` | DuckDB при старте |
| `DATASEARCHER_MCP_DEFAULT_MODE` | `auto` | Режим по умолчанию |
| `DATASEARCHER_MCP_EXAMPLE_STORE_ENABLED` | `true` | Example Store (few-shot) |
| `LLM_BASE_URL` | — | URL LLM API (OpenAI-compatible) |
| `LLM_MODEL` | — | Модель LLM |

---

## Архитектура

```
datasearcher-mcp/
  src/datasearcher_mcp/
    __main__.py             # CLI: --transport, --config, --auth-token
    config.py               # 30+ настроек (pydantic-settings)
    engine.py               # движок: remote/dump/auto/federated, ACL, KB, PII
    server.py               # FastMCP: 46 tools + 5 resources + 2 prompts
    session.py              # DuckDB-сессия (ленивая)
    sql_guard.py            # read-only enforcement (блок DML/DDL)
    error_handler.py        # человекочитаемые SQL-ошибки
    logging_db.py           # SQLite append-only логи (query/error/audit)
    pii_detector.py         # авто-детекция + маскирование PII
    rate_limiter.py         # per-tool throttling
    knowledge_base.py       # SQLite KB (описания, владельцы, метрики)
    dbt_loader.py           # парсинг dbt manifest.json
    datahub_client.py       # DataHub GraphQL клиент
    example_store.py        # NL→SQL пары + semantic search
    bi_linker.py            # URL builder для BI-инструментов
    llm_client.py           # LLM-клиент (OpenAI-compatible)
    embeddings.py           # semantic search через embeddings
    connectors/
      base.py, sqlalchemy_base.py
      postgres.py, mysql.py, clickhouse.py, sqlite_conn.py
      api.py                # REST API коннектор
    tools/                  # 30 аналитических инструментов
    render/                 # matplotlib PNG + парсинг маркеров
    prompts/                # системный промпт аналитика
```

### Ключевые решения

| Решение | Почему так |
|---------|-----------|
| DuckDB выключен по умолчанию | Source DB умнее (индексы, оптимизатор) |
| sqlglot для трансляции SQL | Один SQL — работает в любой БД |
| Federated через DuckDB extensions | Кросс-БД JOIN без ETL |
| Read-only guard | Защита production-данных от случайных изменений |
| PII auto-detection | Compliance без ручной разметки |
| SQLite для KB и логов | Zero-dependency, embedded, не требует сервера |
| Example Store | Few-shot обучение из прошлых запросов |

### Технологии

| Слой | Технология |
|------|-----------|
| MCP | mcp[cli] 1.28 (FastMCP, stdio/SSE/HTTP) |
| SQL | Source DB (push-down) или DuckDB (lazy/federated) |
| Трансляция SQL | sqlglot |
| ML | scikit-learn, scipy, numpy |
| Графики | matplotlib (PNG) |
| KB / логи | SQLite (embedded) |
| Embeddings | OpenAI-compatible /v1/embeddings |
| Драйверы БД | psycopg2, pymysql, clickhouse-connect, aiosqlite |
| Файлы | CSV/Parquet (DuckDB), Excel (openpyxl) |
| Дашборды | HTML + DuckDB-WASM + Chart.js |
| Auth | Bearer token (Starlette) |

---

## Лицензия

MIT

TDQS

C2.4/5.0

Scored across 46 tools

Disambiguation2/5

Many tools occupy adjacent analytical niches—smart_summary, auto_insights, data_story, build_dashboard, and create_public_dashboard all produce summary/insight outputs, while profile_data and data_quality_report overlap and export_data/export_xlsx differ mostly by format. Although descriptions are detailed, an agent would frequently struggle to pick between near-equivalent options.

Naming Consistency4/5

The vast majority of tools follow a verb_noun snake_case pattern like get_schema, transform_data, and build_dashboard. A few noun-based names such as sql_query, query_explain, correlation_analysis, and data_story are minor deviations, but the overall convention is predictable.

Tool Count2/5

With 46 tools, the surface is heavily overloaded for a single MCP server. Many tools could be consolidated, such as the export pair, dashboard/story/summary family, or the many statistical analysis tools, and the large count increases selection cost and maintenance burden.

Completeness3/5

Core data connection, query, analysis, visualization, and metadata workflows are broadly covered, so most agent tasks can be completed. However, the knowledge-base lifecycle lacks delete operations, and connection management has attach/test/refresh but no list/detach, creating some dead ends.

Maintenance

ActivitySlowing
ResponsivenessNo issues