Files
minecraft-builder-mcp/docs/PROTOCOL.md
T

74 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Протокол прототипа
Версия: 1. Точный реализованный каталог инструментов доступен через MCP `tools/list`, а возможности установленного Paper — через `project_context`.
## Соединение с Paper
Сервис слушает только loopback, по умолчанию `127.0.0.1:8765`. `GET /health` возвращает состояние и версию без приватных данных. `POST /v1/rpc` принимает JSON и заголовок `Authorization: Bearer <token>`.
Запрос: `{ "method": "project_context", "params": { "player_id": "UUID", "project_id": "default" }, "requestId": "correlation-id" }`.
Успех: `{ "ok": true, "result": { ... } }`. Ошибка: `{ "ok": false, "error": { "code": "...", "message": "..." } }`. Ошибка может сопровождаться HTTP 400/403; клиент обязан читать структурированное тело. Токены в результатах не возвращаются.
Административный ключ обязателен для `chat_poll`, `chat_reply`, `recovery_review` и `recovery_abandon`. Ключ агента допускает инструменты мира в проекте связанного владельца, но не административное восстановление. `player_id/project_id` добавляются MCP-процессом из настроек, а не предлагаются модели. Плагин повторно проверяет владельца и его действующие права. Для изолированного тестового мира есть явно включаемый `allow-local-automation` и принципал `console`; административные операции восстановления также проходят проверку этой области полномочий.
## Чтение и запись
`region_inspect` требует `min/max` как `{x,y,z}` и `detail: "summary" | "blocks"`. Координаты включительные, целочисленные. Лимит прототипа — 4096 позиций. Ответ содержит палитру с количеством, а для `blocks` — точные состояния. Данные берутся из загруженных чанков без неявной генерации мира.
`build_prepare` принимает `recipe: {version: 1, operations: [...]}`, необязательный массив `dependencies` и необязательный `part_id` для точной маски части. Геометрия: `box(min,max,block,hollow?)`, `line(from,to,block)`, `cylinder(center,radius,height,block,hollow?)`, `repeat(count,offset,operations)`. Используется JSON-описание, не исполняемый JavaScript.
Результат подготовки: `plan_id`, `plan_hash`, `changed_blocks`, `region`, `expires_at`. Полный план и исходные блоки остаются в журнале. `build_apply` принимает этот ID, хеш и постоянный для данного вызова `idempotency_key`. Повтор того же вызова возвращает ту же операцию. Для другого плана нужен другой ключ.
`operation_status(operation_id)` возвращает состояние, счётчики и ограниченные примеры конфликтов. `operation_cancel` останавливает следующие порции. `operation_undo_prepare` создаёт обратный план; он проходит обычный `build_apply` и проверки. Потеря ответа на применение не даёт права создать другой ключ и повторить запись: сначала проверить `project_context` или повторить исходный вызов с тем же ключом.
`part_define(name,operation_id)` регистрирует только фактически записанные блоки завершённой операции. `part_get(part_id)` возвращает имя, границы, количество и защиту. Границы не равны маске: `build_prepare(part_id)` проверяет каждый блок по точной маске. Расширение создаётся отдельной частью.
Перед записью проверяются реальные состояния целевых блоков и объявленных зависимостей; проверка повторяется после сохранения намерения. Несовпадение не перезаписывается автоматически. Для undo также учитываются известные последующие записи наших операций, даже когда значение блока снова совпадает с прежним результатом.
Плагин наблюдает неотменённые `BlockPlaceEvent` и `BlockBreakEvent` в настроенном мире. Такое событие лишает прежнюю операцию права на undo данного блока, включая случай «изменили и вернули обратно» (ABA). Эти уведомления хранятся только в памяти текущего процесса. После перезапуска и для внешних путей без наблюдаемого события остаётся проверка текущего содержимого; полная история действий других плагинов не обещается.
Полный серверный журнал внешних изменений пока не реализован. `region_changes` отвечает `resync_required`; агент использует свежие ограниченные чтения. Это явное ограничение прототипа.
## Восстановление после сбоя
Незавершённая операция после перезапуска получает `recovery_required` и запрещает начало новых записей. Автоматического повторения незавершённых порций нет. Административные RPC ниже не входят в MCP-инструменты агента и не являются откатом мира.
`recovery_review` принимает `operation_id`. Результат использует имена полей Java-записи: `operationId`, `planId`, `positions`, `matchesBefore`, `matchesAfter`, `foreignStates`, `currentDigest`, `sampledAtMillis`. Проверяемая маска объединяет фактически подтверждённые записи предыдущих порций и потенциальные записи незавершённой порции; пропуски без записи не включаются. Счётчики описывают совпадение текущих значений с `before/after`, а `currentDigest` — SHA-256 для этого снимка. Совпадение содержимого не доказывает авторство изменения.
`recovery_abandon` принимает `operation_id` и `expected_digest`, полученный из `currentDigest` последнего обзора. Сервер заново читает маску и отклоняет запрос, если её содержимое изменилось. При совпадении он оставляет все блоки мира на месте, переводит операцию в `failed` и сохраняет решение до успешного ответа. Ответ имеет обычную форму `operation_status`.
Отказ от неопределённой истории навсегда запрещает undo этой операции и сохраняет аннулирование прежнего права на undo для блоков затронутой маски. Новые записи разрешаются только после постоянного сохранения решения по всем незавершённым операциям. Сбой до сохранения оставляет необходимость восстановления; потеря ответа требует проверки `operation_status`, а не предположения, что произошёл откат. Устаревший или неверный digest возвращается как RPC-ошибка `invalid_request` с причиной.
Статус `applied` подтверждает наблюдавшийся результат записи и проверки в работающем сервере. Файлы чанков и журнал не образуют общую транзакцию; автоматической проверки сохранности всех ранее завершённых операций после аварии пока нет.
## Локальные схемы
Реализованные имена RPC — `asset_list`, `schematic_export` и `schematic_import_prepare`. Отдельных маршрутов `schematic_list` и немедленного `schematic_import` нет. Наличие этих возможностей проверяется через `project_context`.
`asset_list` принимает необязательный `query` для поиска по имени без учёта регистра и возвращает `{ "assets": [...] }`. Каждый элемент содержит `assetId`, `name`, `width`, `height`, `length`, `blockCount`, `dataVersion`, `offset`, `sha256`, `bytes`. Каталог содержит до 64 файлов; каждый файл проверяется при чтении, поэтому повреждённая схема может привести к отказу всего запроса списка.
`schematic_export` принимает `name`, включительные `min/max` и необязательный `origin`. Имя содержит 1–64 печатных символа. `origin` задаёт точку привязки схемы; по умолчанию она равна `min`. Сервер читает плотный прямоугольный участок, включая воздух, в текущей области проекта и в пределах `max_plan_blocks` (не более 4096). Неподдерживаемые блоки и сущности, кроме игроков, приводят к отказу; игроки в схему не записываются. Результат — один объект с теми же полями метаданных, что у `asset_list`. Файл остаётся в подкаталоге `schematics` каталога данных плагина; RPC не возвращает его содержимое или произвольный путь.
`schematic_import_prepare` принимает `asset_id`, `target: {x,y,z}` и необязательный `rotation: 0 | 90 | 180 | 270` (по умолчанию 0). Поворот выполняется по часовой стрелке при взгляде сверху вокруг точки привязки `target`; сохранённый `offset` учитывается. Изменяются также поддерживаемые направления ступеней и оси брёвен/столбов. Результат — обычный `plan_id/plan_hash/changed_blocks/region/expires_at`; для записи нужен отдельный `build_apply`. Воздух схемы входит в план и может удалять существующие поддерживаемые блоки. Область, исходное содержимое, окружение, политика блоков и конфликты проверяются обычным путём подготовки и применения.
Поддерживается ограниченное подмножество Sponge Schematic v2: gzip и NBT с палитрой ванильных строительных состояний. Лимиты — 4096 позиций, 1 МиБ сжатого файла и 4 МиБ распакованного NBT. Сущности, block entities, биомы, неизвестные поля верхнего уровня, требуемые модификации и другие версии формата отклоняются. `DataVersion` новее текущего сервера не принимается; преобразования через DataFixer нет. Полная совместимость со всеми схемами WorldEdit не заявляется.
Внешний `.schem` можно заранее поместить локально в каталог схем под именем `[A-Za-z0-9][A-Za-z0-9_-]{0,63}.schem`, после чего его основание используется как `asset_id`. Произвольные пути, сетевые URL и символические ссылки не принимаются. Загрузки файла через RPC в прототипе нет.
## Чат
`chat_poll` принимает стабильный на время жизни Bridge `client_id`. Ответ — `messages` с полями `id`, `playerId`, `projectId`, `text`, `type`, сведениями о положении и блоке под прицелом при наличии. `type` — `prompt` либо `cancel`. Ключ администратора обязателен.
`chat_reply` принимает `id`, `playerId`, `text`, `done`, необязательный `error`. Ответ маршрутизируется только инициатору исходного запроса. На смену Bridge-процесса незавершённые запросы не проигрываются автоматически: плагин останавливает изменения и просит проверить мир. `/ai stop` приостанавливает новые записи независимо от того, успел ли завершиться ACP-ход.
## Камера
`camera_capture` принимает `camera_id` либо `pose: {x,y,z,yaw,pitch,fov?,width?,height?}`. Позиция соответствует ногам наблюдателя; Worker отдельно возвращает координаты глаз. `after_operation_id` проверяет завершение серверной операции, но не гарантирует получения её всех пакетов клиентом.
Paper сериализует запросы, перемещает настроенного spectator-наблюдателя и отправляет запрос локальному Camera Worker на `127.0.0.1:8766` с отдельным ключом. Pending-ответ содержит `captureId`; для проверки вызывается `camera_capture` с `capture_id`. Готовый результат содержит `imageBase64` и `mimeType`, которые Bridge превращает в MCP image content, не в текстовую base64-строку.
Снимок имеет эвристическую оценку готовности чанков/кадров. `serverRevisionVerified: false` сохраняется до реализации строгого клиентского подтверждения. Отсутствие камеры, таймаут и невозможность получить свежий кадр не считаются визуальным успехом.
Подробности Worker: [camera-mod/README.md](../camera-mod/README.md). Потоки и журнал: [world-core/README.md](../world-core/README.md). ACP и изоляция: [bridge/README.md](../bridge/README.md).