8.1 KiB
MCP-доступ к source debugger Sprinter
toolchain/sdbg_mcp.py подключается к уже работающей sdbg_server.py через
Unix socket. Это отдельный stdio MCP-сервер для C-уровня: он использует ту же
сессию, карту сборки и журнал, что VS Code/DAP. В репозитории MAME есть две
Lua-реализации другого, raw MCP-моста: src/mame_bridge.lua
(-autoboot_script) и более новый -plugin mamebridge. Оба обслуживают
один src/mame_mcp.py и одинаковый файловый транспорт, но legacy Lua
обрабатывает только 16 из 30 публикуемых Python-команд. Plugin использует
register_periodic и отвечает даже при остановленном CPU. Ни один из этих
вариантов не должен одновременно управлять тем же MAME в обход sdbg-сессии.
src/mame_mcp.py всё ещё импортирует FastMCP по пути SDK 1.x;
наш адаптер использует MCPServer SDK 2.x. Пока raw frontend не мигрирован,
держите для него отдельное Python-окружение. Это различие касается Python
обвязки, а не Lua-плагина mamebridge.
Для MCP нужен Python 3.12 с официальным SDK 2.x. Он не требуется для сборки
приложений и работы VS Code. Например, создайте отдельное окружение и
установите toolchain/requirements-mcp.txt:
pyenv exec python -m venv /tmp/sprinter-sdbg-mcp-venv
/tmp/sprinter-sdbg-mcp-venv/bin/python -m pip install -r toolchain/requirements-mcp.txt
В профиле launch типа sprinter-mame укажите фиксированный socket,
например "socket": "/tmp/sprinter-sdbg-hello.sock". После F5 дождитесь
остановки в main. Путь должен быть коротким (у Unix socket есть лимит длины),
уникальным для этого сеанса и доступным только вашему пользователю. Затем
зарегистрируйте в MCP-клиенте stdio-сервер:
{
"command": "/tmp/sprinter-sdbg-mcp-venv/bin/python",
"args": [
"/ABS/PATH/C-Compiler/toolchain/sdbg_mcp.py",
"--socket", "/tmp/sprinter-sdbg-hello.sock"
]
}
Замените /ABS/PATH/C-Compiler абсолютным путём к toolkit. MCP-сервер при
старте проверяет подключение; если VS Code ещё не запустил MAME или socket
устарел, он завершается с понятной ошибкой в stderr. После Stop запустите
MCP-сервер заново вместе с новой DAP-сессией. Альтернатива параметру
--socket — переменная окружения SDBG_SOCKET.
Доступные инструменты: session_status, where, read_registers,
read_memory, list_variables, read_variable, recent_events,
mame_console_tail, set_line_breakpoint, set_function_breakpoint,
clear_breakpoint, clear_my_breakpoints, continue_execution,
pause_execution, step_instruction, step_source. Ответы SDK 2.x содержат
structuredContent. step_source принимает into, over или out и
возвращает принятие команды; итоговую остановку получите через
recent_events с курсором last. Логи SDBG_LOG приходят как события
output; журнал ограничен 1024 событиями и сообщает first/last/lost.
Число 16 не означает удаление возможностей более нового -plugin mamebridge:
его src/mame_mcp.py публикует 30 raw-инструментов, ориентированных на
машину MAME. Здесь инструменты сгруппированы по операциям C-сессии, а
некоторые функции (C-позиция, typed global/static, журнал с generation)
в raw MCP вообще отсутствуют. Оставшиеся группы требуют отдельного контракта:
| Группа raw MCP | Что требуется перед переносом в общую сессию |
|---|---|
setmem, raw debugger_command, watchpoints |
Проверка прав, банка, диапазона и согласование с DAP-точками; произвольная debugger-команда может нарушить состояние сессии |
| VRAM/shares, screen pixels, screenshot | Явные адресные пространства, лимиты, формат ответа и изолированный каталог снимков |
| Клавиатура, мышь, type/press | Один владелец ввода, корректное отпускание клавиш, ожидание running CPU и проверка прямого ввода с клавиатуры |
| Raw disassembly | Связать адрес/банк с проверенной C-картой; не выдавать физический адрес за logical |
Это следующий этап, а не запрет на функции raw MCP. Нельзя просто загрузить
mamebridge рядом с sdbgbridge: два независимых обработчика начнут менять
CPU и точки без общего owner ID и журнала.
Поэтапные проверки перед удалением legacy Lua и перенос всех 30 возможностей
в общую C-сессию описаны в плане сведения MCP.
Чтение памяти принимает десятичный адрес или 0xHEX, 1–256 байт logical
Z80 memory, только при остановленном CPU, без side effects. Ответ содержит
generation и страницы банков; диапазон не может пересекать границу 64 КБ.
read_variable работает с проверенными global/static размером 1, 2 или 4
байта, только когда нужный банк отображён. Локальные, стек, watchpoints,
запись переменных и произвольные выражения пока не поддерживаются.
У каждой MCP-копии свой owner ID. Она может удалить только свои точки; при
обычном закрытии stdio они очищаются. Живой тест подтвердил, что попытка
удалить DAP-точку отвергается и точка VS Code срабатывает после выхода MCP.
Удаление личной точки при running CPU отдельно проверено на ожидании
getchar(); оно не ставит CPU на паузу и не блокирует ввод.
Общий session server сериализует команды, но эксклюзивного владельца
управления CPU пока нет: не посылайте continue/step одновременно из MCP
и VS Code. При аварийном завершении MCP его точки могут остаться до конца
сессии MAME; нужна отдельная lease/cleanup-механика. Несколько одновременно
запущенных MAME с MCP не проверялись и не гарантируются; это отложенный тест.
Проверка совместной работы с DAP и реальным MAME:
MAME_HOME=/path/to/MAME/runtime pyenv exec python tests/sdbg/run_vscode_dap_probe.py \
--socket /tmp/sprinter-sdbg-mcp-probe.sock \
--mcp-python /tmp/sprinter-sdbg-mcp-venv/bin/python