diff --git a/README.md b/README.md index 94d8c60..56f223b 100644 --- a/README.md +++ b/README.md @@ -1,35 +1,44 @@ ## truenas-mcp -MCP-сервер для управления TrueNAS через AI-ассистентов, завёрнутый через mcpo -в OpenAPI-совместимый HTTP-сервис. Внутри используется пакет truenas-mcp-server (PyPI). +MCP-сервер для управления TrueNAS SCALE через AI-ассистентов, завёрнутый через mcpo +в OpenAPI-совместимый HTTP-сервис. -Официальный Go-бинарник truenas/truenas-mcp в Docker на TrueNAS SCALE не запустился -(ошибка exec format error / ENOEXEC) - поэтому используется этот вариант на Python. +Используется пакет spranab/truenas-mcp (npm) - 278 действий в 18 категориях +(system, storage, sharing, network, account, disk, vm, app, update, certificate, +alert, data_protection, filesystem, reporting, directory, service_config, audit, api) +через один хешированный эндпоинт /truenas. + +### История выбора пакета + +1. Официальный Go-бинарник truenas/truenas-mcp в Docker на TrueNAS SCALE не запустился + (ошибка exec format error / ENOEXEC). +2. Python-пакет truenas-mcp-server (vespo92/TrueNasCoreMCP) завёлся, но оказался + ограничен: только 4 универсальные категории (users, storage, sharing, snapshots), + без system info и без SCALE-специфичных функций (apps, VM) - автоопределение + Core/SCALE ошибочно посчитало систему TrueNAS Core. +3. Итоговый выбор: spranab/truenas-mcp (npm) - полное покрытие 278 действий, + без проблем автоопределения. ### Важно: особенность сборки на TrueNAS SCALE + Dockge -Относительный build.context (например "." или "./truenas") в compose.yaml под -Dockge на TrueNAS SCALE ненадёжен - Dockge и Docker-демон видят пути по-разному, -из-за чего можно получить ошибку "unable to prepare context: path ... not found", -даже если папка физически существует. +Docker-сервис на TrueNAS SCALE может по-разному видеть пути build.context в +зависимости от того, относительный он или абсолютный (Dockge и docker-демон +видят файловую систему по-разному). Относительный context: "." иногда не находит +Dockerfile ("unable to prepare context: path ... not found") - используй абсолютный +путь на хосте. -Поэтому build.context и volume в compose.yaml указывают абсолютным путём на -отдельный датасет /mnt/ssd/apps/mcp/truenas, а не на папку самого стека Dockge. +### Важно: конфликт версий mcp/mcpo -Правильный порядок: - -1. В Dockge: "+ Compose" -> вставить compose.yaml из этого репозитория -> на - вкладке Env добавить содержимое .env (см. .env.example) со своим реальным - API-ключом TrueNAS -> Save (пока НЕ Deploy). -2. Создать датасет /mnt/ssd/apps/mcp/truenas. -3. Скопировать в этот датасет Dockerfile и config.json из этого репозитория. -4. Только теперь нажать Deploy в Dockge. +mcpo требует mcp>=1.28 (с streamablehttp_client). Если ставить mcpo без явной +фиксации версии mcp, pip может подтянуть более старую несовместимую версию - +контейнер падает в рестарт-луп с ImportError. Решение - ставить mcp отдельным +шагом ДО mcpo (см. Dockerfile). ### Файлы - compose.yaml - конфигурация сервиса (порт 8814:8000) -- Dockerfile - собирает образ на python:3.11-slim, ставит mcpo и truenas-mcp-server -- config.json - регистрирует truenas-mcp-server как stdio MCP-сервер для mcpo +- Dockerfile - образ на node:20-slim + python3/pip для mcpo, npx для truenas-mcp +- config.json - регистрирует truenas-mcp (через npx) как stdio MCP-сервер для mcpo - .env.example - шаблон; реальный .env с ключом никогда не коммитить ### Переменные окружения @@ -42,23 +51,24 @@ TRUENAS_LOG_LEVEL - уровень логирования, например INFO ### Проверка после деплоя -docker logs truenas-mcp --tail 15 +docker logs truenas-mcp --tail 40 Должно быть: Successfully connected to: truenas / Uvicorn running on http://0.0.0.0:8000 +### Использование + +Один эндпоинт POST /truenas принимает {"category": "...", "action": "...", "params": {...}}. + +Примеры: +- {"category": "help"} - список всех категорий +- {"category": "system"} - список действий в категории system +- {"category": "system", "action": "system_info"} - версия TrueNAS, hostname, uptime и т.д. + ### Подключение клиентов -Важно: mcpo регистрирует сервер под именем "truenas" (из config.json) и монтирует -его инструменты не в корне, а под этим префиксом. Корневой /openapi.json - это -только служебный индекс mcpo со списком подключённых серверов (пустой "paths":{}), -для подключения клиентов он не годится. - -- Open WebUI: Admin Panel -> Settings -> External Tools -> Type: OpenAPI -> URL: - http://truenas-ip:8814/truenas (без /openapi.json - Open WebUI сам добавляет - этот суффикс при обращении к серверу). -- Прямая ссылка на саму схему (для curl / проверки в браузере): - http://truenas-ip:8814/truenas/openapi.json -- Документация Swagger: http://truenas-ip:8814/truenas/docs +- OpenAPI-схема: http://truenas-ip:8814/truenas/openapi.json +- Документация в браузере: http://truenas-ip:8814/docs +- Open WebUI: Admin Panel -> Settings -> External Tools -> Type: OpenAPI -> URL выше. - Claude Desktop: сервис отдаёт OpenAPI, а не MCP Streamable HTTP - Custom Connectors - не примет его напрямую. Для Claude Desktop используется локальный запуск того же - truenas-mcp-server через uvx в claude_desktop_config.json. + не примет его напрямую. Для Claude Desktop используется локальный запуск + truenas-mcp через npx в claude_desktop_config.json.