Files
minecraft-builder-mcp/bridge/README.md
T

89 lines
17 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.
# Bridge
Локальные MCP-инструменты и игровой ACP-клиент для `minecraft-builder-mcp`.
Требуется Node.js 22.22.3+ и работающий Paper-плагин проекта. Установка воспроизводима по `package-lock.json`:
```bash
npm ci --ignore-scripts
npm test
```
Прямые зависимости закреплены: `codex-acp` 1.11.0, ACP SDK 1.4.0, MCP SDK 1.30.0, Zod 4.6.2, TypeScript 7.0.2. Закреплённая транзитивная версия Codex — 0.153.4. `npm ci` не выбирает свежие версии.
## Запуск
Секреты берутся из окружения, а не из аргументов командной строки. Плагин создаёт отдельные административный и агентский токены. Не коммитьте их. Пример конфигурации переменных — `.env.example`; сам bridge не загружает `.env` автоматически.
- `npm run doctor` проверяет `/health` Paper при наличии `MCB_TOKEN`, создаёт отдельную минимальную конфигурацию Codex и выводит JSON с настройками, ограничениями и точной командой входа.
- `npm run login` вручную запускает вход через device code в отдельный Codex home; `npm run login -- status` проверяет этот вход.
- `npm run mcp` запускает MCP по stdio для внешнего агента. Нужны `MCB_AGENT_TOKEN`, `MCB_PLAYER_ID`, `MCB_PROJECT_ID`.
- `npm run chat` запускает опрос `/ai` и ACP. Нужны `MCB_TOKEN` и `MCB_AGENT_TOKEN`.
- `node dist/rpc.js project_context` — прямой диагностический RPC с агентской областью доступа.
Для локального сервера из этого репозитория удобнее запускать из корня `python3 scripts/bridge.py doctor`, `python3 scripts/bridge.py login`, `python3 scripts/bridge.py status` и затем `python3 scripts/bridge.py chat`. Обёртка использует общую папку `.runtime/bridge-state` и сама читает приватные токены Paper. `status` эквивалентен `login status` или `login --status`; эти команды только проверяют вход и не начинают авторизацию. `doctor`, `login` и `status` можно запускать ещё до создания конфигурации Paper. Не смешивайте вход через эту обёртку с обычным `npm run chat` без соответствующего `MCB_STATE_DIR`: у них разные папки состояния по умолчанию.
`MCB_BACKEND_URL` по умолчанию `http://127.0.0.1:8765`. Разрешён только HTTP на loopback; для удалённого сервера нужен локальный SSH-туннель. UUID игрока/проекта поступают из доверенной конфигурации или ответа Paper, а сервер повторно проверяет владельца и область. В прототипе сервер поддерживает одного настроенного владельца.
Игровой мост запускает установленный локальный `codex-acp`, без `npx @latest`. Он использует отдельный Codex home в `.state/chat/codex-home`; вход и настройки обычного `~/.codex` автоматически не копируются. Один раз запустите `npm run login` из той же рабочей директории и с тем же `MCB_STATE_DIR`, что и `chat`. Помощник использует закреплённый Codex CLI с `login --device-auth`; вход начинается только при явном запуске этой команды. Мост сам не открывает браузер и не обращается к модели во время сборки/обычных тестов. Для API-ключа задайте `MCB_OPENAI_API_KEY` или `MCB_CODEX_API_KEY` и `MCB_ACP_AUTH_METHOD=api-key`; общий `OPENAI_API_KEY` из родительского окружения не наследуется.
Необязательные настройки:
- `MCB_MODEL`: ID модели; применяется через объявленный ACP model selector. Без значения выбирает адаптер.
- `MCB_ACP_COMMAND`: путь к альтернативному ACP-агенту; без него используется текущий Node и закреплённый `codex-acp`.
- `MCB_ACP_ARGS`: JSON-массив аргументов, без shell-интерпретации.
- `MCB_STATE_DIR`: папка состояния, по умолчанию `.state/chat` относительно рабочей директории.
- `MCB_CODEX_HOME`: явный путь к отдельному Codex home для входа. Если там существует отличающийся `config.toml`, мост откажется запускаться и сохранит файл; используйте отдельную пустую папку, а не обычный профиль Codex.
Дочерний процесс получает только разрешённые переменные окружения, отдельные HOME/XDG/CODEX_HOME и минимальный конфиг. Настройки запрашивают `read-only`, `on-request`, проверку пользователем, запрет сети внутри командного sandbox и отключение shell, приложений, браузера, computer use, hooks, plugins и дополнительных агентов. Источники и параметры приведены в `src/security.ts`. Проверка закреплённого CLI подтвердила отключённый `shell_tool` и перечисленные интеграции; `unified_exec` этот CLI оставляет включённым даже при явном отключении, что отражено в doctor.
Есть ограничение самого `codex-acp` 1.11.0: его режим `read-only` посылает на каждый ход sandbox `workspace-write` с выключенной сетью, а не буквальный read-only. Поэтому папка конкретной сессии и временные пути могут оставаться доступными для записи. Код не заявляет полной изоляции ОС, и ещё не проверен на настоящем ходе модели. Процессы Bridge/ACP/MCP также остаются доверенными локальными программами; права Paper проверяются отдельно сервером.
Bridge отклоняет дополнительные запросы разрешений с сообщением в игре. Интерактивное подтверждение разрешений через Minecraft пока не реализовано. ACP capabilities для файлов и терминала не объявляются. Административный токен Paper не передаётся дочернему агенту; MCP получает отдельный ограниченный агентский токен. Конфигурацию нужно проверять через doctor после смены версий или при наличии системных политик Codex. Для динамически передаваемого Minecraft MCP override `default_tools_approval_mode` не устанавливается: закреплённый адаптер передаёт только command/args/env и заменяет соответствующую таблицу конфигурации. Поэтому поведение разрешений MCP остаётся проверкой первого настоящего хода после входа пользователя; сборка и initialize не подтверждают, что строительство через модель уже работает.
## MCP
Инструменты: `project_context`, `region_inspect`, `build_prepare`, `build_apply`, `operation_status`, `operation_cancel`, `operation_undo_prepare`, `part_get`, `part_define`, `camera_list`, `camera_capture`, `asset_list`, `schematic_export`, `schematic_import_prepare`.
Рецепт первой версии:
```json
{
"version": 1,
"operations": [
{"type":"box","min":{"x":0,"y":64,"z":0},"max":{"x":4,"y":70,"z":4},"block":"minecraft:stone_bricks","hollow":true},
{"type":"line","from":{"x":0,"y":64,"z":0},"to":{"x":8,"y":64,"z":8},"block":"minecraft:stone"},
{"type":"cylinder","center":{"x":12,"y":64,"z":12},"radius":3,"height":8,"block":"minecraft:stone_bricks","hollow":true},
{"type":"repeat","count":3,"offset":{"x":6,"y":0,"z":0},"operations":[{"type":"box","min":{"x":0,"y":64,"z":20},"max":{"x":1,"y":67,"z":21},"block":"minecraft:oak_log[axis=y]"}]}
]
}
```
Необязательный `part_id` в `build_prepare` ограничивает запись точной маской зарегистрированной части; расширение задаётся отдельной частью.
Инструменты отсылают данные на Paper для финальной проверки и вычисления. Мост не хранит блоки и не пишет мир. MCP принимает один уровень `repeat`; глубоко вложенные повторения, произвольный код, арки и общие трансформации пока не объявлены. Поддерживаемые состояния блоков и лимиты берутся из `project_context`.
`build_prepare` возвращает `plan_id` и `plan_hash`. Для `build_apply` нужно передать их вместе со стабильным `idempotency_key`. При таймауте запись могла уже начаться: сначала проверьте `operation_status` и используйте тот же ключ. Мост не повторяет запись автоматически.
Локальная библиотека `.schem` поддерживает до 64 файлов, Sponge v2, плотные области до 4096 блоков и повороты 0/90/180/270°. Файлы вручную помещаются в папку `schematics` внутри данных Paper-плагина. `asset_list` возвращает метаданные без выдуманных превью; `schematic_export` сохраняет регион и возвращает ID; `schematic_import_prepare` создаёт обычный проверяемый план, который затем применяется через `build_apply`. Пути, сущности, block entities и неподдерживаемые блоки не принимаются.
`camera_capture` возвращает `pending` и `captureId`; запрос с `capture_id` читает результат. Только `completed` с настоящим изображением превращается в MCP `ImageContent`. Если камеры нет или снимок не готов, изображение не выдумывается. Обычный текстовый ответ ограничен 64 KiB; чтение слишком большой области завершается ошибкой с просьбой уменьшить область. HTTP ограничен по времени, входному объёму и размеру потокового ответа.
## Диалоги и остановка
Один активный ход на проект, до восьми сообщений в очереди. Разные проекты могут обрабатываться независимо. Сессии и папки разделены по проекту и UUID игрока. Ответы отправляются только инициатору через `chat_reply`; общий игровой чат, мысли модели, tool-аргументы и stderr адаптера не транслируются.
Каждый запрос включает переданные сервером позицию игрока, направление взгляда и целевой блок, если они доступны. Вывод сообщений ограничен до четырёх сообщений в секунду для одного игрока.
ID ACP-сессии и последняя компактная сводка сохраняются атомарной заменой `session.json` с правами `0600`. После перезапуска мост пробует `session/load`; при отказе начинает новый диалог со сводкой и явно сообщает об этом. Повтор истории при загрузке не выводится в чат. Незавершённый предыдущий ход помечается отдельно; уже начатые операции необходимо сверить на Paper. Сводка хранит последнее задание и итог, она не заменяет `project_context`.
`/ai stop` должен одновременно установить серверный флаг остановки записи и доставить мосту событие `type:"cancel"`. ACP отменяет генерацию; уже изменённые блоки остаются в журнале. Прерванный агент, не отвечающий на cancel пять секунд, завершается. При каждом запуске мост создаёт `client_id` и передаёт его в `chat_poll`. Смена ID позволяет Paper остановить активные записи и завершить оставшиеся арендованные запросы с уведомлением пользователя; такие задания автоматически не повторяются. Очередь входящих сообщений Paper пока хранится в памяти. После `/ai stop` сервер удерживает запись на паузе до нового задания владельца или `/ai resume`.
## Проверки
`npm test` выполняет HTTP-тесты и настоящий stdio MCP handshake, а также использует отдельный mock ACP-процесс для проверки сессий, резюме, скрытия истории, отказа разрешений и отмены. Проверки очередей подтверждают сериализацию внутри проекта и независимость других проектов. Реальный закреплённый `codex-acp` также прошёл бесплатный `initialize`: ACP v1, `loadSession: true`, методы входа `api-key` и `chat-gpt` до ограничения окружения. Повторная проверка в отдельном home также успешна; при `NO_BROWSER=1` адаптер объявляет только `api-key`, а ChatGPT-вход выполняется отдельным helper `login`. Это не доказывает вход ChatGPT, качество модели или поведение Minecraft: для этого требуется запуск всей системы на настоящем сервере/клиенте.
Опциональный `node test/live-paper.mjs` запускается только против отдельного настоящего тестового Paper: проверяет полый куб, повторное применение с тем же ключом, экспорт `.schem`, библиотеку ассетов, отмену, импорт в тот же anchor, вторую отмену до 27 блоков воздуха, границы и честный ответ недоступной камеры. Он оставляет экспортированный тестовый asset в локальной библиотеке. Это изменяющая мир проверка, она не входит в обычный `npm test`.
Исходные API сверены с [ACP SDK](https://github.com/agentclientprotocol/typescript-sdk), [codex-acp](https://github.com/agentclientprotocol/codex-acp), [MCP SDK](https://github.com/modelcontextprotocol/typescript-sdk) [справочником конфигурации Codex](https://learn.chatgpt.com/docs/config-file/config-reference) и [документацией MCP Codex](https://learn.chatgpt.com/docs/extend/mcp?surface=cli).