mcpmine
by Z1ppzy
README.md
# mcpmine
[](https://github.com/Z1ppzy/mcpmine/actions/workflows/ci.yml)
Два MCP App для Minecraft-разработки. Оба рисуются прямо в чате Claude (claude.ai, Claude Desktop,
мобильное приложение): сервер отдаёт инструменты и HTML-панель, человек правит мышкой, Claude теми
же инструментами, состояние одно на двоих.
| Приложение | Что делает |
| --- | --- |
| **Пиксельный холст** (`pixel/`) | Холст 16×16 с палитрой ресурспака: иконки предметов рисуются вручную и инструментами Claude, импортируются из PNG и экспортируются обратно с удвоением пикселя, как ждёт пак. |
| **Тест-игрок** (`tester/`) | Бот на [mineflayer](https://github.com/PrismarineJS/mineflayer) заходит на тестовый сервер, выполняет команды, читает GUI-инвентари и диалоги (1.21.6+), нажимает кнопки и слоты, показывает мир радаром. Claude получает всё это текстом и картинками. |
## Как это устроено
MCP Apps — расширение протокола MCP: инструмент указывает в `_meta.ui.resourceUri` ресурс `ui://…`
с HTML, хост рисует его в песочном iframe под сообщением и прокидывает мост. Страница вызывает
инструменты того же сервера (`callServerTool`), получает результаты (`ontoolresult`) и сообщает
модели о действиях пользователя (`updateModelContext`). Поэтому клик по холсту и команда «отзеркаль»
идут одной дорогой: оба становятся вызовом инструмента, сервер держит состояние, страница
перерисовывается по ответу. Правки Claude страница подтягивает опросом.
Все инструменты снабжены аннотациями (`readOnlyHint`, `destructiveHint`, `idempotentHint`,
`openWorldHint`), ошибки валидации и ошибки бота возвращаются текстом результата, а не падением
сервера. В HTTP-режиме есть `GET /health`.
## Требования
- Node.js 22+ (проверено на 22 и 24). Тестовый хост запускается как `node serve.ts`, без сборки TypeScript.
- Хост с поддержкой MCP Apps: claude.ai, Claude Desktop, Claude на телефоне. В Claude Code окна нет,
инструменты работают, картинки приходят как изображения.
- Для тест-игрока: **тестовый** Paper/Spigot-сервер в `online-mode=false` на версии, которую знает
mineflayer. Версия подбирается автоматически по ping сервера; список известных:
`node -p "require('minecraft-protocol').supportedVersions"`.
## Быстрый старт
```bash
npm install
npm run build # собирает обе панели в dist/
```
**Claude Desktop** (локальный stdio-сервер). В `claude_desktop_config.json`:
```json
{
"mcpServers": {
"pixel": { "command": "node", "args": ["C:\\path\\to\\mcpmine\\pixel\\server.mjs"] },
"mc-tester": { "command": "node", "args": ["C:\\path\\to\\mcpmine\\tester\\server.mjs"] }
}
}
```
Потом Developer → Reload MCP Configuration (Developer Mode включается в Help → Troubleshooting) и в
новом чате: «открой пиксельный холст» или «открой тест-игрока».
**Claude Code.** В репозитории лежит `.mcp.json` с HTTP-адресами. Подними серверы и они появятся в
проекте:
```bash
npm run pixel:http # http://localhost:3311/mcp
npm run tester:http # http://localhost:3312/mcp
```
**claude.ai** (веб). Нужен публичный адрес: `npx cloudflared tunnel --url http://localhost:3311`,
затем Settings → Connectors → Add custom connector.
## Пиксельный холст
Панель: холст 16×16 с сеткой, палитра пака, превью в слоте инвентаря 1:1, 2:1 и 3:1, действия
(отмена, зеркало, очистка, экспорт) и подсказки на каждом элементе.
- ЛКМ рисует выбранным цветом, ПКМ стирает, протяжка красит. Ctrl+Z отменяет последнюю правку,
свою или Claude, история до 50 шагов.
- Палитра ограничена цветами пака: имена цветов те же, что принимают инструменты.
- Каждая ручная правка уходит в контекст модели картой символов, пересказывать ничего не нужно.
| Инструмент | Что делает |
| --- | --- |
| `open_canvas` | Показать панель и вернуть состояние |
| `get_canvas` | Состояние без панели, для опроса |
| `set_pixels` | Пиксели по координатам, (0,0) слева сверху; цвет именем, символом карты или индексом |
| `fill` | Прямоугольник или весь холст одним цветом |
| `mirror` | `x`: левую половину направо, `y`: верхнюю вниз |
| `clear`, `undo` | Очистить; откатить последнюю правку |
| `set_map` | Загрузить карту: 16 строк по 16 символов, `.` прозрачно, `legend` сопоставляет символ имени цвета |
| `import_png` | Загрузить `<name>.png` из каталога вывода: квадрат со стороной, кратной 16, цвета вне палитры заменяются ближайшими |
| `export_png` | Записать `<name>.png` в каталог вывода с масштабом (2 даёт 32×32) и вернуть картинку |
Окружение: `PIXEL_OUT_DIR` — каталог PNG (по умолчанию `out/`), `PIXEL_PALETTE_FILE` — своя палитра
в JSON, массив `{ "name", "char", "hex" }`, первый элемент прозрачный (`"hex": null`, `"char": "."`).
## Тест-игрок
Панель: форма входа, чипы статуса (позиция, здоровье, режим, кто рядом), открытое окно сеткой слотов
с тултипами (имя, лор, модель предмета), диалог с кнопками, радар, чат с полем команд.
**Безопасность.** Бот входит без аккаунта (`auth: offline`), поэтому сервер должен быть тестовым и в
`online-mode=false`. Не направляй его на боевой сервер.
**Подготовка сервера.** В `server.properties`: `online-mode=false`, `enforce-secure-profile=false`,
для спокойных прогонов `difficulty=peaceful`. Выдай боту права через консоль: `op QaBot`. Для
быстрых проверок GUI хватает плоского мира (`level-type=minecraft:flat`).
| Инструмент | Что делает |
| --- | --- |
| `open_tester` | Показать панель и вернуть состояние |
| `bot_state` | Статус, окно, диалог, инвентарь и сообщения после `since` |
| `bot_join`, `bot_leave` | Подключиться (версия по ping или явная, ждёт spawn и чанки) и отключиться |
| `bot_command` | Отправить текст или команду, подождать `waitMs` и вернуть ответы, окно и диалог |
| `bot_window`, `bot_click`, `bot_close_window` | Слоты открытого окна; клик левой/правой, обычный или shift; закрыть |
| `bot_open_block` | Правый клик по контейнеру рядом с ботом (сундук, ящик кейса) |
| `bot_dialog`, `bot_dialog_click`, `bot_dialog_close` | Диалоги `show_dialog`: заголовок, тело, поля, кнопки; нажать по индексу; закрыть |
| `bot_inventory` | Предметы бота с именами и лором |
| `bot_radar` | Вид сверху вокруг бота: PNG в ответе и в панели |
**Окна.** Для каждого слота: `name`, `count`, `displayName`, `lore`, `model` (компонент `item_model`),
`customModelData`, список типов компонентов. Этого достаточно, чтобы проверить состояние иконки
кастомного предмета без клиента.
**Диалоги.** mineflayer не знает пакет `show_dialog`, разбор написан здесь: типы `notice`,
`confirmation`, `multi_action`, `dialog_list`, поля ввода, `exit_action`. Кнопки `run_command`
выполняются как команды (подстановка `$(key)` из `inputs` для динамических). Кнопки `custom`
пока недоступны: в minecraft-data нет пакета `custom_click_action`.
**Радар.** Верхний непустой блок каждого столбца в радиусе (по умолчанию 24), высота светлотой,
цвет по имени блока, белый маркер бота со штрихом направления, пурпурные маркеры игроков. Замена
3D-viewer: prismarine-viewer знает версии только до 1.21.4.
**Ограничения.**
- Версия сервера должна быть в списке mineflayer. Если по ping ничего не подошло, `bot_join`
объясняет, какие версии известны.
- Текст длиннее 256 символов сервер отбрасывает с киком, бот отказывает заранее: длинные `setblock`
и `give` выполняй через консоль.
- Эмодзи и глифы ресурспака в текстах заменяются на `▯`: Java пишет их в NBT как modified UTF-8,
а библиотека читает как UTF-8. У игрока они видны нормально.
- Если сервер пришлёт `clear_dialog`, которого нет в minecraft-data, бот отвалится с ошибкой в чате.
- Ключи переводов вида `item.minecraft.coal` подставляются английскими названиями из minecraft-data,
остальные ключи остаются как есть.
## Тестовый хост без Claude
Для отладки панелей есть basic-host из репозитория ext-apps. Он не хранится здесь (смешанные
лицензии), а скачивается:
```bash
npm run host:setup # sparse-клон examples/basic-host в host/basic-host и npm install
npm run host:build
npm run pixel:http # в отдельных окнах
npm run tester:http
npm run host # http://localhost:8080
```
Прямые ссылки: `http://localhost:8080/?server=pixel&tool=open_canvas&call=true` и
`http://localhost:8080/?server=mc-tester&tool=open_tester&call=true`. На странице видно то, что
видит хост: панель в iframe, Model Context (что панель сообщила модели) и Tool Result.
## Разработка
```bash
npm test # node:test: юнит-тесты и интеграция обоих серверов по stdio
npm run lint # eslint
npm run smoke:pixel # stdio: инструменты, ресурс, правки, undo, экспорт
npm run smoke:tester -- --port 25565 --command /help # живой сервер: вход, сундук, команда, радар
npm run smoke:tester -- --port 25565 --command /menu --button OK # плюс нажать кнопку диалога по подстроке
npm run probe -- --port 25565 --command /menu # сырые пакеты сервера в ответ на команду
npm run e2e:pixel # панель холста в тестовом хосте через Playwright и системный Edge/Chrome
npm run e2e:tester -- --port 25565 --command /menu --dialog Меню --button OK
```
Сценарии e2e ждут запущенные `pixel:http`, `tester:http` и `host`; браузер берётся системный
(`--browser msedge` или `chrome`), скриншоты складываются в `out/`.
CI на GitHub Actions гоняет lint, сборку и тесты на Node 22 и 24. Интеграционные тесты поднимают
настоящие серверы по stdio; тесту-игроку Minecraft-сервер для этого не нужен: проверяются
объявления инструментов, ошибки без бота и отказ на закрытый порт.
## Структура
```
pixel/ сервер холста: canvas.mjs (состояние, история, PNG), palette.mjs, tools.mjs, server.mjs, ui/
tester/ сервер бота: bot.mjs (сессия), version.mjs, chat-log.mjs, items.mjs, dialog.mjs, radar.mjs, text.mjs, translate.mjs, tools.mjs, server.mjs, ui/
shared/ тема (светлая и тёмная от хоста) и общие стили панелей
host/ установка, сборка и запуск тестового хоста
scripts/ smoke-прогоны и отладка пакетов
tests/ node:test
```
## Дальше
- Конструктор окна 9×6 с подложкой пака и записью YAML для меню.
- Запись иконок прямо в ресурспак и проверка правил пака (рамка, минимум видимых пикселей).
- Декодирование modified UTF-8 в NBT, чтобы эмодзи доходили целыми.
- Кнопки `custom` в диалогах, когда пакет появится в minecraft-data.
- 3D-вид, когда prismarine-viewer догонит текущие версии.
Собрано на [ext-apps](https://github.com/modelcontextprotocol/ext-apps),
[mineflayer](https://github.com/PrismarineJS/mineflayer) и остальном PrismarineJS.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues