first commit
This commit is contained in:
@@ -0,0 +1,154 @@
|
||||
# forge-tools-lexicomai
|
||||
|
||||
MCP-сервер для **обслуживания продуктов Lexicom AI** на серверах компании.
|
||||
Даёт AI-ассистенту (агенту) инструменты: посмотреть статус продукта, его
|
||||
конфигурацию и лицензию, логи, здоровье, диагностику и список доступных
|
||||
версий в репозитории. Позволяет администратору быстро разбираться с
|
||||
развёрнутыми сервисами и сокращать рутину.
|
||||
|
||||
> **Что такое MCP-сервер коротко.** MCP — стандартный протокол подключения
|
||||
> AI-ассистентов к инструментам. Этот сервер — небольшая отдельная программа:
|
||||
> она читает запросы от ассистента, выполняет действия (по SSH на боевые
|
||||
> машины) и возвращает результат. Ассистент вызывает его инструменты по
|
||||
> имени — например «покажи статус продукта ups».
|
||||
|
||||
---
|
||||
|
||||
## Что умеет (текущая версия)
|
||||
|
||||
| Инструмент | Что делает |
|
||||
|---|---|
|
||||
| `products_list` | Сводка по всем машинам: продукт → машина, состояние, порт, лицензия, версия |
|
||||
| `service_status` | Краткий статус конкретного продукта (unit, порт, состояние, лицензия) |
|
||||
| `repo_catalog` | Список доступных версий продукта в репозитории (ветки release/beta) |
|
||||
| `base_status` | Полнота базовой среды `/opt/pve` на машине |
|
||||
| `service_config_get` | Top-level ключи `config.json` продукта (+ наличие примера схемы) |
|
||||
| `license_get` | Содержимое `license.json` (service, срок, ключ) |
|
||||
| `license_verify` | Проверка лицензии: поля + живой ответ `/license/check` продукта |
|
||||
| `service_logs` | Хвост журнала продукта (опц. фильтр) |
|
||||
| `service_health` | Живой статус + `/openapi.json` (жив/версия) + `/license/check` |
|
||||
| `service_diagnose` | Чек-лист: юнит, порт, лицензия, база `/opt/pve` |
|
||||
| `errors_search` | Поиск ошибок в журнале продукта за окно времени |
|
||||
|
||||
### Изменения (только при `read_only=false` + `allow_mutate` + одобрение)
|
||||
|
||||
| Инструмент | Что делает |
|
||||
|---|---|
|
||||
| `service_install` | Установка продукта (асинхронно, возвращает id); по умолчанию последняя версия |
|
||||
| `service_update` | Обновление до последней версии в ветке (backup инсталлятором) |
|
||||
| `service_uninstall` | Удаление продукта |
|
||||
| `base_ensure` | Создание минимальной базы `/opt/pve` (идемпотентно) |
|
||||
| `service_config_set` | Изменение ключей `config.json` (точечный путь) + рестарт |
|
||||
| `license_apply` | Запись `license.json` + проверка через `/license/check` |
|
||||
| `service_restart` | Перезапуск службы продукта |
|
||||
| `service_install_status` | Прогресс установки по id |
|
||||
|
||||
Установка идёт асинхронно (возвращает `id`, прогресс — `service_install_status`),
|
||||
чтобы не блокировать агента. Для GPU-продуктов (crs, spr) автоматически
|
||||
подхватывается ускоритель (cu13) через `nvidia-smi`.
|
||||
|
||||
## Поддерживаемые продукты
|
||||
|
||||
`acs, ams, cls, crs, llm, qas, res, sbs, see, ses, ses-sip, smc, spr, tts, ups, vds`
|
||||
|
||||
Не поддерживаются: `vllm` (open-source), `spr5` (легаси),
|
||||
`ses-sip-gateway-api` (вспомогательные).
|
||||
|
||||
## Как сервер узнаёт о продуктах
|
||||
|
||||
Ничего не «зашито» в код. Все данные берутся из живой системы:
|
||||
|
||||
- **порт, движок (uvicorn/gunicorn/python/bwrap) и venv** — из действующего
|
||||
systemd-юнита (`ExecStart`) продукта;
|
||||
- **живость и версия** — по `GET /openapi.json` (продукты на FastAPI его отдают);
|
||||
- **лицензия** — из `license.json` + живой проверки `GET /license/check`;
|
||||
- **версии в репозитории** — по web-API SFTPGo (каталог `/repos/<продукт>/<ветка>`).
|
||||
|
||||
Поэтому добавлять/обновлять продукты можно без правки кода — только в конфиге
|
||||
указать, какие продукты на какой машине.
|
||||
|
||||
## Сборка
|
||||
|
||||
```bash
|
||||
go build -o forge-tools-lexicomai .
|
||||
./forge-tools-lexicomai --health # → ok (проверка, что сервер живой)
|
||||
go test -race ./...
|
||||
```
|
||||
|
||||
Зависимости минимальны: общая библиотека `forge-toolkit` + официальный Go-SDK
|
||||
MCP. Собранный бинарь `forge-tools-lexicomai` в репозиторий не коммитится
|
||||
(в `.gitignore`).
|
||||
|
||||
## Подключение сервера
|
||||
|
||||
Сервер запускается как **stdio-процесс** (читает/пишет MCP-протокол через
|
||||
стандартные ввод/вывод). В конфиге MCP-хоста указывается команда запуска и флаг
|
||||
`-config`:
|
||||
|
||||
```json
|
||||
{ "command": "/opt/lexicomai/forge-tools-lexicomai",
|
||||
"args": ["-config", "/etc/lexicomai/lexicomai.json"] }
|
||||
```
|
||||
|
||||
То же самое подходит для любого MCP-клиента.
|
||||
|
||||
## Конфигурация
|
||||
|
||||
Файл `lexicomai.json`. Реальные адреса, ключи и пароли в репозиторий **не
|
||||
попадают** — подставляются переменными окружения `${VAR}` (или берутся из
|
||||
локального файла, который не коммитится).
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"targets": [
|
||||
{
|
||||
"alias": "prod",
|
||||
"ssh": { "host": "${LEXICOMAI_HOST}", "user": "${LEXICOMAI_USER}",
|
||||
"key": "${LEXICOMAI_SSH_KEY}", "port": 22 },
|
||||
"products": ["ups", "spr", "cls"],
|
||||
"allow_mutate": false
|
||||
}
|
||||
],
|
||||
"default": "prod",
|
||||
"read_only": true,
|
||||
"timeout_seconds": 15,
|
||||
"max_output_bytes": 4194304,
|
||||
"repo": { "base": "https://cloud.connect2ai.net",
|
||||
"user": "${SFTPGO_USER}", "pass": "${SFTPGO_PASS}" }
|
||||
}
|
||||
```
|
||||
|
||||
| Поле | Смысл |
|
||||
|---|---|
|
||||
| `targets[]` | Управляемые машины: `alias` (имя), `ssh` (host/user/key/port), `products` (что на ней живёт), `allow_mutate` (разрешены ли изменения) |
|
||||
| `default` | Машина по умолчанию |
|
||||
| `read_only` | Полный запрет мутаций (по умолчанию `true`) |
|
||||
| `timeout_seconds` | Таймаут одного SSH-вызова/пробы |
|
||||
| `max_output_bytes` | Ограничение размера результата |
|
||||
| `repo` | Доступ к репозиторию дистрибутивов (web-клиент SFTPGo) |
|
||||
|
||||
Требования: у машины должен быть SSH-доступ по ключу (пользователь с `sudo -n`);
|
||||
`products[]` объявляет продукты на машине.
|
||||
|
||||
## Безопасность
|
||||
|
||||
- По умолчанию — **только чтение**; мутации включаются явно (`read_only=false`
|
||||
+ `allow_mutate` на конкретной машине) и дополнительно требуют одобрения.
|
||||
- Никаких адресов/подсетей/ключей в коде — всё из конфига/окружения.
|
||||
- Команды на машине выполняются через `sudo -n`; пользовательский ввод
|
||||
экранируется; ключ лицензии в выводе маскируется.
|
||||
- Инструменты ограничены по времени (таймаут) и размеру результата.
|
||||
|
||||
## Проверено
|
||||
|
||||
- `go build`, `go vet`, `go test -race` — зелёные; `gofmt` — чисто.
|
||||
- Ручная проверка MCP (T1): `initialize` → сервер отвечает именем `lexicomai`,
|
||||
`tools/list` возвращает инструменты с корректными обязательными параметрами.
|
||||
|
||||
## Статус
|
||||
|
||||
- **M1 (готово):** каркас + read-only инструменты.
|
||||
- **M3–M5 (готово):** установка/обновление/удаление, изменение конфигурации,
|
||||
применение лицензий, база `/opt/pve`, управление службой — для всех
|
||||
поддерживаемых продуктов. Написано по архитектуре остальных MCP-серверов
|
||||
компании. Live-проверка на боевых машинах — только на стейджинге.
|
||||
Reference in New Issue
Block a user