====== ToolMesh (MCP-сервер) ======
Даёт Claude инструменты для работы с вики через Model Context Protocol.
Проксирует JSON-RPC API DokuWiki, описанный декларативно в DADL-файле.
Планируется инструмент для доступа к QoE.
Публичный адрес: ''https://mcp.ve-playground.ai.zevgen.com/mcp''
(через [[tech:server:nginx|nginx]], внутри — ''127.0.0.1:8123'')
===== Версия =====
Готовых образов проект **не публикует** под тем именем, что предполагалось изначально
(''ghcr.io/dunkelcloud/toolmesh''), и тегов/релизов в репозитории нет — только ветка
''main''. Поэтому образ собирается локально из исходников, а версия фиксируется
commit SHA.
^ Параметр ^ Значение ^
| Источник | https://github.com/DunkelCloud/ToolMesh |
| Зафиксированный commit | ''fb965bc69ef850a3e939751c72e5e554c485f6e1'' |
| Путь на сервере | ''/opt/ve-playground/ToolMesh'' |
| Контейнер | ''toolmesh-toolmesh-1'' |
Обновление — осознанно, не ''git pull'':
После обновления обязательно проверить лог загрузки бэкендов.
===== Конфигурация =====
^ Файл ^ Содержимое ^
| ''.env'' | секреты, порт, issuer, CORS, лимиты |
| ''config/backends.yaml'' | подключённые бэкенды |
| ''dadl/dokuwiki.dadl'' | описание инструментов DokuWiki |
| ''docker-compose.yml'' | сборка, сеть, volume'ы |
==== Ключевые параметры .env ====
^ Параметр ^ Значение ^ Комментарий ^
| ''TOOLMESH_PORT'' | 8123 | хостовый порт; внутри контейнера — 8080 |
| ''TOOLMESH_ISSUER'' | ''https://mcp.ve-playground.ai.zevgen.com/'' |
| ''TOOLMESH_AUTH_PASSWORD'' | секрет | OAuth (Simple mode) |
| ''TOOLMESH_API_KEY'' | секрет | Bearer — основной способ подключения |
| ''TOOLMESH_CORS_ORIGINS'' | ''https://claude.ai'' | без явного значения политика открытая |
| ''REDIS_URL'' | ''redis://keydb:6379/0'' | база 0; у бота — база 1 |
| ''OPENFGA_MODE'' | ''bypass'' | fine-grained authz не включён, см. [[tech:risks]] |
| ''AUDIT_STORE'' | ''log'' | пишет в stdout; ''sqlite'' даёт запросы по журналу |
| ''DO_NOT_SEND_ANONYMOUS_STATISTICS'' | ''yes'' | телеметрия отключена |
| ''LOG_LEVEL'' | ''info'' | ''debug'' логирует полные запросы, включая чувствительные данные — только для разбора инцидентов |
===== Бэкенд DokuWiki =====
- name: dokuwiki
transport: rest
dadl: dokuwiki.dadl
url: "https://entrypoint.ve-playground.ai.zevgen.com/lib/exe/jsonrpc.php"
credentials:
dokuwiki_username: "${CREDENTIAL_DOKUWIKI_USERNAME}"
dokuwiki_password: "${CREDENTIAL_DOKUWIKI_PASSWORD}"
Учётные данные — пользователь ''claude'', его права описаны в
[[tech:server:dokuwiki]]. Авторизация — HTTP Basic.
Путь ''dadl:'' относительный, ищется в ''TOOLMESH_DADL_DIR'' (по умолчанию
''/app/dadl'' внутри контейнера, смонтирован из ''./dadl'').
===== DADL и инструменты =====
^ Параметр ^ Значение ^
| Файл | ''dadl/dokuwiki.dadl'' |
| Источник | @zevgen |
| sha256 | ''bfc7dd4ef447e390b732b7c9e606f8409eb42d8eca9ebd2add4d7e21c1be81e7'' |
| Инструментов | 30 базовых + 3 композита = 33 |
| Покрытие API | 31 из 33 методов JSON-RPC |
Хэш фиксируется по той же причине, что и commit SHA: файл получен извне, содержимое
должно быть воспроизводимым. ToolMesh печатает ''content_hash'' в логе при загрузке.
==== Базовые инструменты (30) ====
Страницы: ''get_page'', ''get_page_html'', ''get_page_info'', ''get_page_history'',
''get_page_links'', ''get_page_backlinks'', ''list_pages'', ''search_pages'',
''save_page'', ''append_page'', ''lock_pages'', ''unlock_pages'',
''get_recent_page_changes''
Медиа: ''list_media'', ''get_media'', ''get_media_info'', ''save_media'',
''delete_media'', ''get_recent_media_changes''
Метаданные и права: ''who_am_i'', ''acl_check'', ''get_api_version'',
''get_wiki_version'', ''get_wiki_title'', ''get_wiki_time''
Администрирование: ''list_acls'', ''add_acl'', ''delete_acl'', ''create_user'',
''delete_user''
==== Композиты ====
Выполняются на стороне ToolMesh: полный текст страницы не покидает сервер, наружу
уходит только небольшой результат.
^ Композит ^ Что делает ^
| ''page_search_and_replace'' | замена подстроки (литерал, не regex) с сохранением |
| ''page_append_section'' | вставка в конец секции перед следующим заголовком того же или высшего уровня — то, что ''append_page'' не умеет (он пишет только в конец страницы) |
| ''chunked_save_page'' | посекционная сборка большой страницы в буфере с записью одной ревизией; промежуточные операции помечаются minor, чтобы не засорять Recent Changes |
==== Служебные ====
''echo_echo'', ''echo_add'', ''echo_time'' — встроенные, удобны для проверки
живости связки без обращения к вики.
===== Code Mode =====
Помимо прямых вызовов инструментов всегда доступны ''discover_tools'' и
''execute_code'': модель пишет JavaScript, который вызывает инструменты через
''api.()''. Результат ''execute_code'' ограничен примерно 55 000 символов.
===== Подключение =====
Способы и пошаговая инструкция — [[tech:connect]].
Механика аутентификации и известный дефект OAuth — [[tech:server:toolmesh:auth]].
===== Диагностика =====
curl -s http://127.0.0.1:8123/health # {"status":"ok"}
docker logs toolmesh-toolmesh-1 --tail 50
**''/health'' недостаточно.** Он отвечает ''ok'' даже если DADL не распарсился и
бэкенд молча не загрузился. Признак успешной загрузки — строка в логе:
"msg":"REST proxy backend loaded","name":"dokuwiki","tools":30,"content_hash":"bfc7dd..."
Нормальные предупреждения при старте, не требующие действий:
* ''SSRF base_url validation skipped (allow_private_url)'' — наш backend URL
публичный HTTPS-домен, а не приватный адрес
* ''authorization is BYPASSED'' — следствие ''OPENFGA_MODE=bypass''
Аудит вызовов инструментов виден в том же логе:
docker logs toolmesh-toolmesh-1 --since 24h | grep '"msg":"audit"'
Каждая запись содержит инструмент, пользователя, длительность, статус и
''tool_access'' (''read''/''write''). Это единственный способ узнать, что именно
модель делала с вики — журнал изменений DokuWiki покажет только результат.
----
[[tech:server|← Сервер]]