Инструменты MCP
Из этой страницы вы узнаете:
- какие инструменты видит ассистент после подключения MMW и чем они отличаются;
- как устроен сервер: адрес, транспорт, авторизация;
- как вызвать инструмент напрямую по HTTP — без ассистента, например из скрипта или для диагностики.
Сквозной пример: команда хранит в MMW договорённость «staging выкатывается через systemd-юнит app-staging» и проверяет её запросом search из терминала.
Все инструменты
Заголовок раздела «Все инструменты»| Инструмент | Откуда | Назначение | Аннотации |
|---|---|---|---|
remember | сервер | Сохранить факт, решение или заметку | изменяет данные, не разрушающий |
search | сервер | Найти записи с источником и статусом | только чтение, идемпотентный |
forget | сервер | Мягко удалить запись или все записи источника | разрушающий |
validate_memory | сервер | Проверить свежесть записей одного источника | только чтение, идемпотентный |
gateway_call | сервер | Вызвать инструмент подключённой интеграции | изменяет данные, внешний мир |
github_readonly.* и другие | сервер, интеграции проекта | Инструменты интеграций, включённых в проекте ключа | только чтение, идемпотентный, внешний мир |
mmw_sync_status | локальный агент mmw-agent | Состояние синхронизации истории сессий | только чтение, идемпотентный |
Аннотации — это подсказки MCP (readOnlyHint, destructiveHint, idempotentHint, openWorldHint), которые сервер передаёт клиенту. По ним клиент решает, спрашивать ли подтверждение перед вызовом. Точные значения:
| Инструмент | Заголовок (title) | readOnly | destructive | idempotent | openWorld |
|---|---|---|---|---|---|
remember | Save memory | нет | нет | нет | нет |
search | Search memories | да | нет | да | нет |
forget | Delete memory | нет | да | нет | нет |
validate_memory | Check memory freshness | да | нет | да | нет |
gateway_call | Call a connected integration | нет | нет | нет | да |
github_readonly.* | GitHub (read-only): … | да | нет | да | да |
mmw_sync_status | — | да | — | да | — |
Инструменты интеграций появляются в списке, только если интеграция включена в кабинете для проекта, к которому привязан ключ. Например, при подключённой GitHub-интеграции это github_readonly.get_file_contents, github_readonly.pull_request_read, github_readonly.get_me.
| Параметр | Значение |
|---|---|
| Адрес | https://mcp.mmwhub.ru/mcp |
| Транспорт | Streamable HTTP |
| Сессии | нет (stateless): каждый запрос самостоятельный, после паузы или перезапуска сервера переподключаться не нужно |
| Формат ответа | JSON (application/json) |
| Авторизация | заголовок Authorization: Bearer mmw_… (API-ключ из кабинета) или OAuth — для claude.ai и ChatGPT |
| Версия API в ответах | поле api_version, сейчас 1.0 |
Ключ привязан к проекту: все вызовы работают с памятью этого проекта. Подробнее о ключах и OAuth — в разделе API-ключи и OAuth.
Как это устроено
Заголовок раздела «Как это устроено» Ассистент (Claude Code, Cursor, Codex…) │ stdio ▼ mmw-agent (локально, необязательно) ── mmw_sync_status отвечает сам │ HTTPS, Bearer mmw_… ▼ https://mcp.mmwhub.ru/mcp ── remember / search / forget / validate_memory │ gateway_call и инструменты интеграций ▼ память проекта ключа (+ правила видимости в организации)Локальный агент пересылает все вызовы на сервер без изменений: клиент видит ровно тот список инструментов, который вернул сервер, плюс mmw_sync_status. Клиенты без агента (claude.ai, ChatGPT, прямое HTTP-подключение) работают с сервером напрямую и mmw_sync_status не видят.
Прямой вызов по HTTP
Заголовок раздела «Прямой вызов по HTTP»Сервер не хранит сессий, поэтому initialize перед вызовом не обязателен: достаточно одного POST-запроса JSON-RPC. Заголовок Accept должен содержать оба типа — application/json, text/event-stream.
curl -s https://mcp.mmwhub.ru/mcp \ -H "Authorization: Bearer $MMW_API_KEY" \ -H "Content-Type: application/json" \ -H "Accept: application/json, text/event-stream" \ -d '{ "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { "name": "search", "arguments": { "query": "staging systemd", "limit": 3 } } }'Ответ (сокращён):
{ "jsonrpc": "2.0", "id": 1, "result": { "content": [ { "type": "text", "text": "{\"id\": \"4d428a41-e7b0-4f81-a886-f40c6f6c766c\", ...}" } ], "structuredContent": { "result": [ { "id": "4d428a41-e7b0-4f81-a886-f40c6f6c766c", "workspace": "default", "scope": "shared", "content": "staging выкатывается через systemd-юнит app-staging", "fact_key": "deploy-staging", "status": "unverified", "score": 2 } ] }, "isError": false }}Список инструментов — тем же способом, с "method": "tools/list" и пустыми params.
Как выглядят ошибки
Заголовок раздела «Как выглядят ошибки»Ошибка инструмента приходит как обычный ответ с "isError": true, а текст причины — в content. Для серверных инструментов памяти текст имеет вид Error executing tool remember: content must not be empty. Ошибка авторизации приходит раньше, на уровне HTTP: статус 401. Все тексты и что с ними делать — на странице Ошибки.