ToolMesh (MCP-сервер)
Даёт Claude инструменты для работы с вики через Model Context Protocol. Проксирует JSON-RPC API DokuWiki, описанный декларативно в DADL-файле. Планируется инструмент для доступа к QoE.
Публичный адрес: https://mcp.ve-playground.ai.zevgen.com/mcp
(через 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 не включён, см. 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, его права описаны в
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.<tool>(). Результат execute_code ограничен примерно 55 000 символов.
Подключение
Диагностика
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 покажет только результат.