Skip to main content
Glama
Processori7

SQL MCP Server

by Processori7
README.md
# SQL MCP Сервер

MCP (Model Context Protocol) сервер для выполнения запросов к базам данных на естественном языке. Поддерживает SQLite, MySQL, PostgreSQL и MongoDB.

## Возможности

- **Запросы на естественном языке**: Пишите запросы к БД на русском языке
- **Поддержка нескольких БД**: SQLite, MySQL, PostgreSQL, MongoDB
- **MCP протокол**: Stdio-коммуникация с LLM клиентами
- **Интеграция с LLM**: Включает промпты для помощи LLM в использовании сервера
- **SQL операции**: SELECT, INSERT, UPDATE, DELETE, ALTER, CREATE DATABASE
- **Bulk операции**: Множественные INSERT, UPDATE, DELETE за один запрос
- **Просмотр схемы**: Список таблиц и структура таблиц
- **Защита данных**: UPDATE, DELETE, DROP и ALTER требуют явного подтверждения пользователя
- **Пакетные операции**: Одно подтверждение для нескольких изменяющих операций

## Установка

1. **Клонируйте репозиторий:**
    ```bash
    git clone https://github.com/Processori7/SQL-MCP.git
    cd SQL-MCP
    ```

2. **Создайте и активируйте виртуальное окружение (рекомендуется):**
    ```bash
    # Windows
    python -m venv venv
    venv\Scripts\activate

    # Linux/macOS
    python3 -m venv venv
    source venv/bin/activate
    ```

3. **Установите зависимости:**
    ```bash
    pip install -r requirements.txt
    ```

## Интеграция с MCP

### Настройка MCP клиента

Добавьте в конфигурацию вашего MCP клиента (например, `cline_mcp_settings.json`):

```json
{
  "mcpServers": {
    "sql-stdio": {
      "disabled": false,
      "timeout": 60,
      "type": "stdio",
      "command": "python",
      "args": ["-X", "utf8", "-m", "src.main"],
      "env": {
        "PYTHONPATH": "C:\\path\\to\\SQL-MCP",
        "PYTHONIOENCODING": "utf-8"
      }
    }
  }
}
```

**Примечание:** Замените `C:\\path\\to\\SQL-MCP` на реальный путь к папке проекта.

**Важно для Windows:** Флаг `-X utf8` и переменная `PYTHONIOENCODING` обеспечивают корректную работу с кириллицей.

## Доступные инструменты

### 1. execute_query
Выполняет запросы к базе данных на естественном языке или SQL.

**Параметры:**
- `db_type` (обязательный): Тип БД - `'sqlite'`, `'mysql'`, `'postgresql'` или `'mongodb'`
- `query` (обязательный): Запрос на русском языке ИЛИ SQL/MongoDB запрос
- `db_config` или `config_file` (один из них обязателен): Настройки подключения к БД
- `confirm_changes` (опциональный): Подтверждение для операций изменения/удаления данных

### 2. list_tables
Получает список всех таблиц или коллекций в базе данных.

**Параметры:**
- `db_type` (обязательный): Тип базы данных
- `db_config` или `config_file` (один из них обязателен): Настройки подключения к БД

### 3. get_table_schema
Получает схему таблицы (колонки, типы, ограничения).

**Параметры:**
- `db_type` (обязательный): Тип БД (не поддерживается для MongoDB)
- `table_name` (обязательный): Имя таблицы
- `db_config` или `config_file` (один из них обязателен): Настройки подключения к БД

## Примеры использования

### Конфигурации подключения

Есть два способа указать параметры подключения:

#### Способ 1: Параметр db_config (JSON объект)

##### MySQL
```json
{
  "host": "localhost",
  "port": 3306,
  "user": "root",
  "password": "mypassword",
  "database": "mydb"
}
```

##### PostgreSQL
```json
{
  "host": "localhost",
  "port": 5432,
  "user": "postgres",
  "password": "mypassword",
  "dbname": "mydb"
}
```

##### SQLite
```json
{
  "db_name": "mydata.db"
}
```

##### MongoDB
```json
{
  "uri": "mongodb://localhost:27017",
  "database_name": "mydb"
}
```

#### Способ 2: Параметр config_file (путь к файлу)

Укажите путь к файлу конфигурации. Поддерживаются форматы JSON и TXT.

**Пример JSON файла (mysql_config.json):**
```json
{
  "host": "localhost",
  "port": 3306,
  "user": "root",
  "password": "mypassword",
  "database": "mydb"
}
```

**Пример TXT файла (mysql_config.txt):**
```ini
# Конфигурация MySQL
host=localhost
port=3306
user=root
password=mypassword
database=mydb
```

**Использование config_file:**
```json
{
  "db_type": "mysql",
  "query": "SELECT * FROM users",
  "config_file": "C:/configs/mysql_config.json"
}
```

Или с относительным путём:
```json
{
  "db_type": "mysql",
  "query": "SHOW TABLES",
  "config_file": "mysql_config.txt"
}
```

### Примеры запросов

#### Создание базы данных (MySQL/PostgreSQL)
```json
{
  "db_type": "mysql",
  "query": "CREATE DATABASE my_new_db",
  "db_config": {"host": "localhost", "port": 3306, "user": "root", "password": ""}
}
```

Или на естественном языке:
```json
{
  "db_type": "mysql",
  "query": "Создай БД my_new_db",
  "db_config": {"host": "localhost", "port": 3306, "user": "root", "password": ""}
}
```

#### Переключение базы данных
```json
{
  "db_type": "mysql",
  "query": "USE my_new_db",
  "db_config": {"host": "localhost", "port": 3306, "user": "root", "password": "", "database": "my_new_db"}
}
```

#### Создание таблицы
```json
{
  "db_type": "mysql",
  "query": "CREATE TABLE users (id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(100), email VARCHAR(100), age INT)",
  "db_config": {"host": "localhost", "port": 3306, "user": "root", "password": "", "database": "my_new_db"}
}
```

#### Bulk INSERT (множественная вставка)
```json
{
  "db_type": "mysql",
  "query": "INSERT INTO users (name, email, age) VALUES ('Иван', 'ivan@mail.ru', 25), ('Мария', 'maria@mail.ru', 30), ('Алексей', 'alex@mail.ru', 28)",
  "db_config": {"host": "localhost", "port": 3306, "user": "root", "password": "", "database": "my_new_db"}
}
```

#### SELECT с условиями
```json
{
  "db_type": "mysql",
  "query": "SELECT * FROM users WHERE age > 25",
  "db_config": {"host": "localhost", "port": 3306, "user": "root", "password": "", "database": "my_new_db"}
}
```

Или на естественном языке:
```json
{
  "db_type": "mysql",
  "query": "Покажи всех пользователей где возраст больше 25",
  "db_config": {"host": "localhost", "port": 3306, "user": "root", "password": "", "database": "my_new_db"}
}
```

#### Bulk UPDATE (множественное обновление)
```json
{
  "db_type": "mysql",
  "query": "UPDATE users SET status='active' WHERE id IN (1, 2, 3)",
  "db_config": {"host": "localhost", "port": 3306, "user": "root", "password": "", "database": "my_new_db"},
  "confirm_changes": true
}
```

#### Bulk DELETE (множественное удаление)
```json
{
  "db_type": "mysql",
  "query": "DELETE FROM users WHERE status='inactive'",
  "db_config": {"host": "localhost", "port": 3306, "user": "root", "password": "", "database": "my_new_db"},
  "confirm_changes": true
}
```

### Примеры для MongoDB

#### Поиск документов
```json
{
  "db_type": "mongodb",
  "query": "db.users.find({age: {$gt: 25}})",
  "db_config": {"uri": "mongodb://localhost:27017", "database_name": "mydb"}
}
```

#### Bulk INSERT (insertMany)
```json
{
  "db_type": "mongodb",
  "query": "db.users.insertMany([{name: 'Иван', age: 25}, {name: 'Мария', age: 30}, {name: 'Алексей', age: 28}])",
  "db_config": {"uri": "mongodb://localhost:27017", "database_name": "mydb"}
}
```

#### Bulk UPDATE (updateMany)
```json
{
  "db_type": "mongodb",
  "query": "db.users.updateMany({status: 'pending'}, {$set: {status: 'active'}})",
  "db_config": {"uri": "mongodb://localhost:27017", "database_name": "mydb"},
  "confirm_changes": true
}
```

#### Bulk DELETE (deleteMany)
```json
{
  "db_type": "mongodb",
  "query": "db.users.deleteMany({status: 'inactive'})",
  "db_config": {"uri": "mongodb://localhost:27017", "database_name": "mydb"},
  "confirm_changes": true
}
```

#### findOneAndUpdate
```json
{
  "db_type": "mongodb",
  "query": "db.users.findOneAndUpdate({\"_id\": {\"$oid\": \"692c2012253e01f8b4ac2b23\"}}, {\"$set\": {\"name\": \"Новое имя\"}}, {\"returnNewDocument\": true})",
  "db_config": {"uri": "mongodb://localhost:27017", "database_name": "mydb"},
  "confirm_changes": true
}
```

### Запросы на естественном языке

#### SELECT
- `"Покажи все пользователи"` → SELECT * FROM users
- `"Покажи имя и email из users"` → SELECT name, email FROM users
- `"все сотрудники где возраст больше 30"` → SELECT * FROM сотрудники WHERE возраст > 30
- `"Покажи первые 10 записей из orders"` → SELECT * FROM orders LIMIT 10

#### INSERT
- `"Добавь пользователя имя Иван возраст 25"` → INSERT INTO users (имя, возраст) VALUES ('Иван', 25)
- `"Вставь в таблицу orders запись: товар Ноутбук, цена 50000"` → INSERT INTO orders (товар, цена) VALUES ('Ноутбук', 50000)

#### UPDATE
- `"Обнови в users где id=5 установи name Пётр"` → UPDATE users SET name='Пётр' WHERE id=5
- `"Измени статус на active где id 10"` → UPDATE ... SET статус='active' WHERE id=10

#### DELETE
- `"Удали из users где id=5"` → DELETE FROM users WHERE id=5
- `"Удали все записи из orders где статус cancelled"` → DELETE FROM orders WHERE статус='cancelled'

#### CREATE/DROP
- `"Создай таблицу products с колонками: id INT PRIMARY KEY, name VARCHAR(100)"` → CREATE TABLE products (...)
- `"Создай БД new_database"` → CREATE DATABASE new_database
- `"Удали таблицу old_data"` → DROP TABLE old_data

## Защита данных

Операции, изменяющие данные, **блокируются по умолчанию** и требуют явного подтверждения:
- `UPDATE` - изменение данных
- `DELETE` - удаление данных
- `DROP` - удаление таблиц/коллекций
- `ALTER` - изменение структуры

Для выполнения этих операций LLM должен:
1. Получить ответ `"status": "blocked"`
2. Спросить пользователя о подтверждении
3. После подтверждения повторить запрос с `confirm_changes: true`

## Конвертация SQL в MongoDB

Сервер автоматически конвертирует SQL запросы в MongoDB операции:

| SQL запрос | MongoDB эквивалент |
|-----------|-------------------|
| `SELECT * FROM users` | `db.users.find({})` |
| `SELECT * FROM users WHERE id = 5` | `db.users.find({id: 5})` |
| `SELECT * FROM users WHERE age > 18` | `db.users.find({age: {$gt: 18}})` |
| `SELECT * FROM users WHERE name LIKE '%Иван%'` | `db.users.find({name: {$regex: 'Иван'}})` |
| `SELECT * FROM users WHERE status IN ('a', 'b')` | `db.users.find({status: {$in: ['a', 'b']}})` |
| `INSERT INTO users (name) VALUES ('Иван')` | `db.users.insertOne({name: 'Иван'})` |
| `UPDATE users SET name = 'Пётр' WHERE id = 5` | `db.users.updateMany({id: 5}, {$set: {name: 'Пётр'}})` |
| `DELETE FROM users WHERE id = 5` | `db.users.deleteMany({id: 5})` |

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

- **`src/main.py`**: Точка входа MCP сервера, обработка MCP протокола
- **`src/db_connector.py`**: Управление подключениями и делегирование адаптерам
- **`src/query_parser.py`**: Парсер запросов на естественном языке
- **`src/adapters/`**: Адаптеры баз данных
  - **`sql_adapter.py`**: SQLite, MySQL, PostgreSQL
  - **`mongo_adapter.py`**: MongoDB

## Запуск

### Прямой запуск
```bash
python -X utf8 -m src.main
```

### Через MCP клиент
После настройки MCP клиента сервер автоматически обрабатывает запросы.

---

# SQL MCP Server (English)

MCP (Model Context Protocol) server for executing database queries using natural language. Supports SQLite, MySQL, PostgreSQL, and MongoDB.

## Features

- **Natural Language Queries**: Write database queries in plain English or Russian
- **Multiple Database Support**: SQLite, MySQL, PostgreSQL, MongoDB
- **MCP Protocol**: Stdio communication with LLM clients
- **LLM Integration**: Includes prompts to help LLM use the server
- **SQL Operations**: SELECT, INSERT, UPDATE, DELETE, ALTER, CREATE DATABASE
- **Bulk Operations**: Multiple INSERT, UPDATE, DELETE in a single query
- **Schema Inspection**: List tables and table structure
- **Data Protection**: UPDATE, DELETE, DROP, and ALTER require explicit user confirmation
- **Batch Operations**: Single confirmation for multiple modifying operations

## Installation

1. **Clone the repository:**
    ```bash
    git clone https://github.com/Processori7/SQL-MCP.git
    cd SQL-MCP
    ```

2. **Create and activate a virtual environment (recommended):**
    ```bash
    # Windows
    python -m venv venv
    venv\Scripts\activate

    # Linux/macOS
    python3 -m venv venv
    source venv/bin/activate
    ```

3. **Install dependencies:**
    ```bash
    pip install -r requirements.txt
    ```

## MCP Integration

### MCP Client Configuration

Add to your MCP client configuration (e.g., `cline_mcp_settings.json`):

```json
{
  "mcpServers": {
    "sql-stdio": {
      "disabled": false,
      "timeout": 60,
      "type": "stdio",
      "command": "python",
      "args": ["-X", "utf8", "-m", "src.main"],
      "env": {
        "PYTHONPATH": "C:\\path\\to\\SQL-MCP",
        "PYTHONIOENCODING": "utf-8"
      }
    }
  }
}
```

**Note:** Replace `C:\\path\\to\\SQL-MCP` with the actual path to the project folder.

**Important for Windows:** The `-X utf8` flag and `PYTHONIOENCODING` variable ensure proper handling of non-ASCII characters.

## Available Tools

### 1. execute_query
Executes database queries using natural language or SQL.

**Parameters:**
- `db_type` (required): Database type - `'sqlite'`, `'mysql'`, `'postgresql'`, or `'mongodb'`
- `query` (required): Natural language query OR SQL/MongoDB query
- `db_config` or `config_file` (one is required): Database connection settings
- `confirm_changes` (optional): Confirmation for data modification/deletion operations

### 2. list_tables
Gets a list of all tables or collections in the database.

**Parameters:**
- `db_type` (required): Database type
- `db_config` or `config_file` (one is required): Database connection settings

### 3. get_table_schema
Gets the table schema (columns, types, constraints).

**Parameters:**
- `db_type` (required): Database type (not supported for MongoDB)
- `table_name` (required): Table name
- `db_config` or `config_file` (one is required): Database connection settings

## Usage Examples

### Connection Configuration

There are two ways to specify connection parameters:

#### Method 1: db_config parameter (JSON object)

##### MySQL
```json
{
  "host": "localhost",
  "port": 3306,
  "user": "root",
  "password": "mypassword",
  "database": "mydb"
}
```

##### PostgreSQL
```json
{
  "host": "localhost",
  "port": 5432,
  "user": "postgres",
  "password": "mypassword",
  "dbname": "mydb"
}
```

##### SQLite
```json
{
  "db_name": "mydata.db"
}
```

##### MongoDB
```json
{
  "uri": "mongodb://localhost:27017",
  "database_name": "mydb"
}
```

#### Method 2: config_file parameter (path to file)

Specify the path to a configuration file. JSON and TXT formats are supported.

**JSON file example (mysql_config.json):**
```json
{
  "host": "localhost",
  "port": 3306,
  "user": "root",
  "password": "mypassword",
  "database": "mydb"
}
```

**TXT file example (mysql_config.txt):**
```ini
# MySQL Configuration
host=localhost
port=3306
user=root
password=mypassword
database=mydb
```

**Using config_file:**
```json
{
  "db_type": "mysql",
  "query": "SELECT * FROM users",
  "config_file": "C:/configs/mysql_config.json"
}
```

### Query Examples

#### Create Database (MySQL/PostgreSQL)
```json
{
  "db_type": "mysql",
  "query": "CREATE DATABASE my_new_db",
  "db_config": {"host": "localhost", "port": 3306, "user": "root", "password": ""}
}
```

#### Create Table
```json
{
  "db_type": "mysql",
  "query": "CREATE TABLE users (id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(100), email VARCHAR(100), age INT)",
  "db_config": {"host": "localhost", "port": 3306, "user": "root", "password": "", "database": "my_new_db"}
}
```

#### Bulk INSERT
```json
{
  "db_type": "mysql",
  "query": "INSERT INTO users (name, email, age) VALUES ('John', 'john@mail.com', 25), ('Mary', 'mary@mail.com', 30)",
  "db_config": {"host": "localhost", "port": 3306, "user": "root", "password": "", "database": "my_new_db"}
}
```

#### SELECT with Conditions
```json
{
  "db_type": "mysql",
  "query": "SELECT * FROM users WHERE age > 25",
  "db_config": {"host": "localhost", "port": 3306, "user": "root", "password": "", "database": "my_new_db"}
}
```

#### Bulk UPDATE
```json
{
  "db_type": "mysql",
  "query": "UPDATE users SET status='active' WHERE id IN (1, 2, 3)",
  "db_config": {"host": "localhost", "port": 3306, "user": "root", "password": "", "database": "my_new_db"},
  "confirm_changes": true
}
```

#### Bulk DELETE
```json
{
  "db_type": "mysql",
  "query": "DELETE FROM users WHERE status='inactive'",
  "db_config": {"host": "localhost", "port": 3306, "user": "root", "password": "", "database": "my_new_db"},
  "confirm_changes": true
}
```

### MongoDB Examples

#### Find Documents
```json
{
  "db_type": "mongodb",
  "query": "db.users.find({age: {$gt: 25}})",
  "db_config": {"uri": "mongodb://localhost:27017", "database_name": "mydb"}
}
```

#### Bulk INSERT (insertMany)
```json
{
  "db_type": "mongodb",
  "query": "db.users.insertMany([{name: 'John', age: 25}, {name: 'Mary', age: 30}])",
  "db_config": {"uri": "mongodb://localhost:27017", "database_name": "mydb"}
}
```

#### Bulk UPDATE (updateMany)
```json
{
  "db_type": "mongodb",
  "query": "db.users.updateMany({status: 'pending'}, {$set: {status: 'active'}})",
  "db_config": {"uri": "mongodb://localhost:27017", "database_name": "mydb"},
  "confirm_changes": true
}
```

## Data Protection

Data-modifying operations are **blocked by default** and require explicit confirmation:
- `UPDATE` - data modification
- `DELETE` - data deletion
- `DROP` - table/collection deletion
- `ALTER` - structure modification

To execute these operations, the LLM must:
1. Receive a `"status": "blocked"` response
2. Ask the user for confirmation
3. After confirmation, retry the query with `confirm_changes: true`

## SQL to MongoDB Conversion

The server automatically converts SQL queries to MongoDB operations:

| SQL Query | MongoDB Equivalent |
|-----------|-------------------|
| `SELECT * FROM users` | `db.users.find({})` |
| `SELECT * FROM users WHERE id = 5` | `db.users.find({id: 5})` |
| `SELECT * FROM users WHERE age > 18` | `db.users.find({age: {$gt: 18}})` |
| `SELECT * FROM users WHERE name LIKE '%John%'` | `db.users.find({name: {$regex: 'John'}})` |
| `SELECT * FROM users WHERE status IN ('a', 'b')` | `db.users.find({status: {$in: ['a', 'b']}})` |
| `INSERT INTO users (name) VALUES ('John')` | `db.users.insertOne({name: 'John'})` |
| `UPDATE users SET name = 'Peter' WHERE id = 5` | `db.users.updateMany({id: 5}, {$set: {name: 'Peter'}})` |
| `DELETE FROM users WHERE id = 5` | `db.users.deleteMany({id: 5})` |

## Architecture

- **`src/main.py`**: MCP server entry point, MCP protocol handling
- **`src/db_connector.py`**: Connection management and adapter delegation
- **`src/query_parser.py`**: Natural language query parser
- **`src/adapters/`**: Database adapters
  - **`sql_adapter.py`**: SQLite, MySQL, PostgreSQL
  - **`mongo_adapter.py`**: MongoDB

## Running

### Direct Run
```bash
python -X utf8 -m src.main
```

### Via MCP Client
After configuring the MCP client, the server automatically handles requests.