add: начальная реализация универсального MCP-сервера для локальных LLM
- Реализован MCP-сервер на стандартной библиотеке Python 3.12+ (main.py) - Добавлены инструменты ask_local_model, check_local_model_status, review_code_locally - Поддержка oMLX, LM Studio, Ollama, llama.cpp, vLLM и других OpenAI-совместимых бэкендов - Добавлена документация (README.md), пример конфигурации (.env.example) и файлы проекта Poetry Co-authored-by: Junie <junie@jetbrains.com>
This commit is contained in:
@@ -0,0 +1,215 @@
|
||||
# Универсальный MCP-сервер для локальных LLM (oMLX, LM Studio, Ollama, llama.cpp и др.)
|
||||
|
||||

|
||||

|
||||

|
||||
[](https://git.cube2.ru/erjemin/2026-omlx-mcp-server)
|
||||
|
||||
Сервер реализует протокол Model Context Protocol (MCP) через стандартные потоки ввода-вывода (`stdio`) и предоставляет AI-ассистентам (включая JetBrains Junie в PyCharm, Claude Desktop, Cursor и др.) доступ к локальным языковым моделям через любой OpenAI-совместимый REST API.
|
||||
|
||||
Сервер изначально оптимизирован для **oMLX** (Apple Silicon MLX), но полностью совместим со всеми популярными локальными бэкендами:
|
||||
- **[oMLX](https://omlx.ai/)**
|
||||
- **[LM Studio](https://lmstudio.ai/)**
|
||||
- **[Ollama](https://ollama.com/)**
|
||||
- **[llama.cpp / llama-server](https://github.com/ggerganov/llama.cpp)**
|
||||
- **[vLLM](https://docs.vllm.ai/)**
|
||||
- **[LocalAI](https://localai.io/)** / **[Jan](https://jan.ai/)** / **[Text Generation WebUI (oobabooga)](https://github.com/oobabooga/text-generation-webui)** и так далее.
|
||||
|
||||
Мой персональный выбор в пользу oMLX связан с тем, что в нем агент написания кода не аннулирует кэш ключ-значение (KV-cache) десятки раз за сессию, а сохраняет каждый блок кэша на SSD. Из-за этого агент, возвращаясь к предыдущему префиксу, восстанавливает контекст за миллисекунды, а не пересчитывает его с нуля.
|
||||
|
||||
Реализация выполнена на стандартной библиотеке Python 3.12+ без сторонних зависимостей во время выполнения и оптимизирована для управления окружением через `poetry`.
|
||||
|
||||
---
|
||||
|
||||
## Что такое MCP и зачем он нужен Junie
|
||||
|
||||
**Model Context Protocol (MCP)** — это открытый стандартизированный протокол взаимодействия AI-ассистентов с внешними источниками контекста и исполнительными инструментами (tools). Вместо написания уникальных плагинов под каждую модель и IDE, MCP предоставляет единый протокол обмена сообщениями на базе JSON-RPC.
|
||||
|
||||
### Почему интеграция через MCP полезна для Junie:
|
||||
|
||||
1. **Двухуровневая архитектура (Гибридный интеллект):**
|
||||
- **Junie (внешняя облачная модель)** выступает в роли главного архитектора и координатора: глубоко понимает проект, планирует шаги и ведет разработку.
|
||||
- **Локальная модель (oMLX / LM Studio / Ollama)** выступает в роли быстрого эксперта: Junie может на лету делегировать локальной модели ревью фрагментов кода, проверку гипотез, брейншторм или черновые генерации через вызовы инструментов MCP (`ask_local_model`, `review_code_locally`).
|
||||
|
||||
2. **Приватность и безопасность данных:**
|
||||
- Чувствительные части кодовой базы, конфиденциальные данные или проприетарные алгоритмы можно анализировать локально, не передавая их во внешние облачные API.
|
||||
|
||||
3. **Экономия токенов и лимитов:**
|
||||
- Перенос вспомогательных вычислений (генерация документации, ревью, форматирование, альтернативные варианты) на локальную машину снижает расход контекстного окна и квот облачных провайдеров.
|
||||
|
||||
4. **Полная независимость и автономность:**
|
||||
- Вы можете менять локальный ИИ-движок или в фоновом режиме через `.env` или меняя default-модель (Qwen, DeepSeek, Llama, Mistral) в настройках локального ИИ-движка, не меняя настройки самого агента.
|
||||
|
||||
---
|
||||
|
||||
## Возможности сервера
|
||||
|
||||
Сервер предоставляет следующие инструменты (MCP Tools):
|
||||
|
||||
1. `ask_local_model` — отправка запроса к локальной языковой модели для генерации текста, анализа, генерации альтернативных вариантов реализации или выполнения вспомогательных вычислений с сохранением приватности данных.
|
||||
- Параметры:
|
||||
- `prompt` (строка, обязательный) — основной текст запроса.
|
||||
- `system_prompt` (строка, опциональный) — системная инструкция.
|
||||
- `model` (строка, опциональный) — имя конкретной модели oMLX (по умолчанию берется активная/первая доступная).
|
||||
- `temperature` (число, опциональный, по умолчанию 0.2) — температура генерации от 0.0 до 1.0.
|
||||
- `max_tokens` (целое число, опциональный) — лимит на количество токенов в ответе.
|
||||
|
||||
2. `check_local_model_status` — проверка сетевой доступности локального сервера oMLX и получение списка загруженных моделей.
|
||||
- Параметры: отсутствуют.
|
||||
|
||||
3. `review_code_locally` — проведение локального код-ревью фрагмента кода силами модели oMLX (поиск потенциальных дефектов, узких мест и предложений по рефакторингу).
|
||||
- Параметры:
|
||||
- `code_snippet` (строка, обязательный) — исходный код для анализа.
|
||||
- `instructions` (строка, опциональный) — специальные указания для ревью.
|
||||
- `model` (строка, опциональный) — имя модели oMLX.
|
||||
|
||||
---
|
||||
|
||||
## Требования
|
||||
|
||||
- Python версии 3.12 или выше.
|
||||
- Менеджер пакетов `poetry`.
|
||||
- Любой запущенный локальный сервер моделей с OpenAI-совместимым API (oMLX, LM Studio, Ollama, llama.cpp / llama-server, vLLM, Jan, LocalAI и др.).
|
||||
- macOS, Linux или Windows.
|
||||
|
||||
---
|
||||
|
||||
## Установка и настройка
|
||||
|
||||
### 1. Клонирование и установка зависимостей
|
||||
|
||||
Перейдите в директорию проекта и установите виртуальное окружение:
|
||||
|
||||
```bash
|
||||
cd /путь/к/2026-omlx-mcp-server
|
||||
poetry install
|
||||
```
|
||||
|
||||
### 2. Настройка переменных окружения
|
||||
|
||||
Создайте файл `.env` на основе примера `.env.example`:
|
||||
|
||||
```bash
|
||||
cp .env.example .env
|
||||
```
|
||||
|
||||
Отредактируйте `.env` под разные бэкенды:
|
||||
|
||||
|
||||
```ini
|
||||
OMLX_BASE_URL=http://127.0.0.1:8008/v1
|
||||
OMLX_API_KEY=укажите_ваш_API_ключ_если_нужен
|
||||
OMLX_MODEL_NAME=default
|
||||
OMLX_TIMEOUT=120
|
||||
```
|
||||
|
||||
Сервер автоматически считывает переменные из файла `.env`, расположенного рядом со скриптом `main.py` или в текущей рабочей директории, если они не были переданы напрямую через системное окружение.
|
||||
|
||||
---
|
||||
|
||||
## Подключение к JetBrains Junie (PyCharm)
|
||||
|
||||
Для подключения MCP-сервера к агенту Junie в PyCharm укажите конфигурацию в файле `.junie/mcp.json` в корне любого вашего рабочего проекта.
|
||||
|
||||
Поскольку сервер реализован на **стандартной библиотеке Python без сторонних зависимостей**, его можно запускать напрямую через системный `python3` без накладных расходов на Poetry или виртуальные окружения.
|
||||
|
||||
### Вариант 1. Прямой запуск через python3 (Рекомендуемый и самый надежный)
|
||||
|
||||
Укажите прямой путь к скрипту `main.py` и параметры подключения в блоке `env`:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"omlx-local": {
|
||||
"command": "python3",
|
||||
"args": [
|
||||
"путь/к/omlx-mcp-server/main.py"
|
||||
],
|
||||
"env": {
|
||||
"OMLX_BASE_URL": "http://127.0.0.1:8008/v1",
|
||||
"OMLX_MODEL_NAME": "default",
|
||||
"OMLX_API_KEY": "укажите_ваш_API_ключ_если_нужен",
|
||||
"OMLX_TIMEOUT": "120"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> **Преимущество:** Работает мгновенно из любого проекта, не зависит от наличия Poetry в `PATH` фоновых процессов IDE и позволяет задавать настройки прямо в конфигурации MCP.
|
||||
> **Примечание:** Если `python3` не обнаружен в `PATH` внутри IDE или нужная версия Python находится в виртуальном окружении, укажите полный путь к исполняемому файлу (например, `/путь/к/omlx-mcp-server/.venv/bin/python` или `/usr/local/bin/python3`).
|
||||
|
||||
### Вариант 2. Запуск через Poetry
|
||||
|
||||
Если вы предпочитаете запускать сервер в изолированном окружении через Poetry:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"omlx-local": {
|
||||
"command": "poetry",
|
||||
"args": [
|
||||
"run",
|
||||
"python",
|
||||
"main.py"
|
||||
],
|
||||
"cwd": "/Users/e-serg/PRJ/2026-omlx-mcp-server"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> **Примечание:** Если `poetry` не обнаружен в `PATH` внутри IDE, укажите полный путь к исполняемому файлу (например, `/Users/e-serg/.local/bin/poetry` или `~/.local/bin/poetry`).
|
||||
|
||||
---
|
||||
|
||||
## Проверка работоспособности
|
||||
|
||||
Сервер общается по протоколу JSON-RPC через стандартные потоки ввода-вывода (`stdin`/`stdout`). При прямом запуске в терминале он ожидает входные данные.
|
||||
|
||||
### Способ 1. Быстрая проверка одной командой (через конвейер / pipe)
|
||||
|
||||
Выполните команду в терминале:
|
||||
|
||||
```bash
|
||||
echo '{"jsonrpc": "2.0", "id": 1, "method": "initialize", "params": {"protocolVersion": "2024-11-05", "capabilities": {}, "clientInfo": {"name": "test", "version": "1.0"}}}' | python3 main.py
|
||||
```
|
||||
|
||||
Сервер мгновенно вернет JSON-ответ инициализации:
|
||||
```json
|
||||
{"jsonrpc": "2.0", "id": 1, "result": {"protocolVersion": "2024-11-05", "capabilities": {"tools": {}}, "serverInfo": {"name": "omlx-local-bridge", "version": "1.0.0"}}}
|
||||
```
|
||||
|
||||
Для проверки получения списка инструментов:
|
||||
|
||||
```bash
|
||||
echo '{"jsonrpc": "2.0", "id": 2, "method": "tools/list", "params": {}}' | python3 main.py
|
||||
```
|
||||
|
||||
### Способ 2. Интерактивный запуск
|
||||
|
||||
1. Запустите скрипт:
|
||||
```bash
|
||||
python3 main.py
|
||||
```
|
||||
*(или `poetry run python main.py`)*
|
||||
|
||||
2. Скрипт перейдет в режим ожидания (курсор на пустой строке). Вставьте JSON-запрос инициализации и нажмите `Enter`:
|
||||
```json
|
||||
{"jsonrpc": "2.0", "id": 1, "method": "initialize", "params": {"protocolVersion": "2024-11-05", "capabilities": {}, "clientInfo": {"name": "test", "version": "1.0"}}}
|
||||
```
|
||||
Получите ответ:
|
||||
```json
|
||||
{"jsonrpc": "2.0", "id": 1, "result": {"protocolVersion": "2024-11-05", "capabilities": {"tools": {}}, "serverInfo": {"name": "omlx-local-bridge", "version": "1.0.0"}}}
|
||||
```
|
||||
|
||||
3. Проверка работы локального ИИ:
|
||||
```json
|
||||
{"jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": {"name": "ask_local_model", "arguments": {"prompt": "Напиши японское хокку про язык программирования Python"}}}
|
||||
```
|
||||
Ответ сервера:
|
||||
```json
|
||||
{"jsonrpc": "2.0", "id": 1, "result": {"content": [{"type": "text", "text": "Синтаксис прост — \nPython, как тихий поток, \nЛегко читать, легко писать."}], "isError": false}}
|
||||
```
|
||||
|
||||
4. Для выхода нажмите `Ctrl+C` или `Ctrl+D`.
|
||||
Reference in New Issue
Block a user