Skip to main content
Glama

dosbox-x-mcp

MCP-сервер, который управляет гостем DOSBox-X не затрагивая рабочий стол: без перехвата фокуса, без синтетических нажатий клавиш на хосте, без перемещения указателя. Модель может прогнать DOS-программу от начала до конца, пока вы продолжаете работать перед экраном.

Всё началось как рабочий процесс захвата данных для одного проекта по обратной разработке, а теперь это универсальный помощник. Для запущенного DOS-гостя он может найти этого гостя вообще без каких-либо предварительных знаний, сообщить, какие программы загружены и где они расположены, прочитать и пропатчить любой сегмент, собирать значения с течением времени, считывать экран из видеопамяти, управлять встроенными рекордерами эмулятора и наблюдать за выполнением кода — без отладчика и без изменения байтов на диске.

Возможности

Найти гость

Обнаружить DOS-гостя по одним лишь инвариантам BIOS — без профиля, без маркера, заранее ничего неизвестно. Пройти по цепочке DOS-памяти и определить каждую загруженную программу, её сегмент и путь, откуда она появилась.

Адресовать любой сегмент

Другую программу в цепочке запуска, TSR, оверлей, таблицу векторов прерываний, EMS-страницы. Читать, патчить, выгружать, искать.

Управлять им

Клавиши попадают в кольцо BIOS-клавиатуры. Клики записываются в собственные слова мыши игры после возврата из INT 33h. Ни то, ни другое не приближается к очереди ввода хоста.

Видеть его

Считывать кадровый буфер прямо из видеопамяти эмулятора: точные индексы, без окна, без масштабирования, без затрат для гостя — подтверждённые по эталонному кадру. Или сфотографировать окно, когда требуется.

Измерять его

Блокировать выполнение по условию на памяти или опрашивать список наблюдения с частотой до 200 Гц в TSV — все столбцы из одного снимка, чтобы они не расходились. Видеть в видеопамяти каждый отдельный кадр и время его появления.

Записывать его

Собственные OPL-, MIDI- и WAVE-захваты эмулятора, запускаемые без фокусировки и без маппера хоста.

Инструментировать его

Перенаправить живой CALL через код-кейв, который при каждом срабатывании записывает регистры и память, после чего её можно читать, пока гость работает на полной скорости. На диске ничего не меняется.

Related MCP server: re-winedbg

Как это работает

Здесь не задействованы ни очередь ввода хоста, ни экран.

  • Обнаружение гостя. У любого DOS-гостя есть кольцо BIOS-клавиатуры с границами 0x001E/0x003E по адресу 0040:0080, головка и хвост внутри этих границ, а также живой вектор INT 21h. Нахождение этой тройки в памяти эмулятора дает физический ноль гостя, а оттуда доступен любой сегмент. Это не требует профиля, что разрывает курино-яйцо, с которого начинается новый проект.

  • Клавиши добавляются в кольцо BIOS-клавиатуры гостя точно так же, как это сделало бы реальное прерывание клавиатуры.

  • Клики записываются в слова, которые заполняет собственный обработчик INT 33h игры — в то состояние, которое игра реально читает. Втикательные слова переписываются в течение некоторого времени, потому что игровой обработчик постоянно их затирает, а одна запись в этой борьбе проигрывает.

  • Кадры берутся из видеопамяти. DOSBox хранит chain-4 страницу так же, как это делает аппаратура — CPU-смещение o по линейному адресу 4 * (o & ~3) + (o & 3) — поэтому, берём каждую шестнадцатую группу из четырёх байт, область снова становится экраном. Понять, какие байты являются кадровым буфером, можно по эталонному кадру: в памяти эмулятора содержится много данных, похожих на изображение, но не являющихся изображением, поэтому страница либо подтверждается побайтово с эталоном, либо вывод не появляется. См. Чтение экрана.

  • Отслеживание модифицирует близкий CALL, чтобы он указывал на зону нулевого заполнения. Код-кейвваерн передаёт управление смещённой цели, сохраняет её флаги, копирует то, что нужно, в слоты после собственного кода и возвращается обратно. Эмулятор погибает вместе с запуском, унося с собой патч.

Установка

pip install "dosbox-x-mcp[all] @ git+https://github.com/md0-code/dosbox-x-mcp"

Дополнительные зависимости — их можно не устанавливать, и они названы по своему назначению:

Extra

Какая польза

window

Pillow для фотографирования окна эмулятора

fast

numpy, для ускорения de-interleave chain-4 (есть и реализация на чистом Python)

x11

python-xlib, для перечисления окон и фотографий на Linux

Зарегистрируйте сервер в ваш MCP-клиент. Для Claude Code это .mcp.json в корне проекта:

{
  "mcpServers": {
    "dosbox": {
      "command": "python",
      "args": ["-m", "dosbox_mcp.server"],
      "env": {
        "DOSBOX_MCP_PROFILE_DIR": "dosbox-x/profiles",
        "DOSBOX_MCP_EXECUTABLE": "dosbox-x/dosbox-x.exe"
      }
    }
  }
}

Variable

Парафия

DOSBOX_MCP_PROFILE_DIR

где лежат профили (по умолч., каталог profiles/ в пакете)

DOSBOX_MCP_PROFILE

имя профиля по умолчанию; none — без профиля

DOSBOX_MCP_EXECUTABLE

тот самый бинарник dosbox-x, который нужно запустить

DOSBOX_MCP_OUTPUT_DIR

куда помещаются относительные пути вывода или эталона

Для путей чтения/записи действует одно правило: абсолютный путь используется как есть, относительный — это относительно DOSBOX_MCP_OUTPUT_DIR. Инструменты возвращают выровненный путь, поэтому ни у кого никогда не возникает cомнения, куда встал каждый файл.

Инструменты

Инструмент

Что делает

dosbox_capabilities

список того, что умеет текущая платформа, и того, что не умеет

dosbox_profiles

список профилей; показать именованные смещения одного профиля

dosbox_launch

запустить DOSBox-X и дождаться, когда гость станет управляемым

dosbox_attach

присоединиться к уже запущенному эмулятору по pid

dosbox_sessions

активные сессии и все другие открытые окна DOSBox-X

dosbox_quit

завершить сеанс

dosbox_find_guest

найти гостя и вывести список всех загруженных программ — профиль не нужен

dosbox_search_memory

найти byte-паттерн, результат — как guest segment:offset

dosbox_send_keys

ввод клавиш в BH кольцо BIOS-клавиатуры

dosbox_click

клик через собственные слова мыши игры

dosbox_hold_buttons

удержать кнопки нажатыми, optionally пока не пройдёт проверка памяти

dosbox_read_memory

данные сегмента или любого другого сегмента

dosbox_write_memory

патч сегмента данных или любого сегмента

dosbox_dump_segment

выгрузка целого сегмента размером 64 КБ в файл

dosbox_wait_for

блокировать до тех пор, пока поле памяти не удовлетворяет условию

dosbox_sample

семплировать список наблюдения по времени в TSV

dosbox_view_screen

вернуть текущий кадр как картинку для показа

dosbox_capture_screen

сохранить точный кадр — из видеопамяти или окна

dosbox_read_framebuffer

прочитать страницу из видеопамяти

dosbox_watch_frames

каждый отдельный кадр за промежуток времени с таймингами

dosbox_emulator_command

выстрелить одно из собственных меню элементов DOSBox-X

dosbox_record

записать OPL, MIDI или WAVE вывод в файл

dosbox_find_cave

найти нулевые области, достаточно большие для утечки

dosbox_install_trace

перенаправить живой CALL через записывающую ловушку

dosbox_read_trace

прочитать, что сохранила такая ловушка

dosbox_remove_trace

вернуть сайт вызова к исходному виду и очистить ловушку

Везде, где принимается смещение, можно использовать и имя символа профиля — treasury вместо 0xШest.

Старт на новойстикубеременнственной без профиля

Профиль не обязателен. Ниже приведён весь первый сеанс:

dosbox_launch(config="game.conf", profile="none")     → pid
dosbox_find_guest()
   → 640 KiB, INT 21h live, and:
       JP2D     load segment 2456    1.1 MB   C:\JP\JP2D.EXE
       JP       load segment 08A1     64 KB   C:\JP\JP.EXE
       COMMAND  load segment 0801     16 KB   C:\COMMAND.COM
dosbox_search_memory(text="sprites.dbt")   → 2456:027A
dosbox_dump_segment(path="jp2d.bin", segment="0x2456")

Этот дамп как раз есть и есть маркер профиля: выбери из него 50–100 байт, которые не изменятся между запусками, добавь два-три простых проверки — и все инструменты, относительные к DS, заработают по имени.

Чтение экрана

dosbox_read_framebuffer возвращает палитровые индексы, которые записал гость в момент чтения. Он точен, не успевает поймать наполовину отрисованный кадр, и не нагружает гостя — поэтому именно этот путь наиболее предпочтителен для замеров.

Нужен эталонный кадр, и он говорит это вслух, а не угадывает. Нахождение страницы означает отыскание 64 000 байт среди сотен мегабайт, а одного только потокображения недостаточно: на живом примере слепая проверка вернула страницу с оценкой 0,999, которая на деле оказалась декодированным спрайт-банком, а не экраном. Поэтому передайте в reference= файл размером 64 000 байт, содержащий то, что сейчас показано на экране, и страница будет побайтово однаxе:

dosbox_read_framebuffer(reference="credits_logo.bin", stem="shots/logo")
   → page_offset 16, confirmed true, pages [16, 64016, 128016, 192016]

Источник эталона может быть любым:

  • Разрабатываемый сборщик порта даёт эталон бесплатно — это его собственная отрисовка того же экрана. Именно так қошмомощное сравнение: если два изображения совпадают побайтово, то рендер порта верен.

  • Любой более ранний подтверждённый захват того же экрана повторно его подтверждает.

  • Фотография окна, если в профиле есть палитра, — это автоматически и не требует аргументов.

После подтверждения позиция страницы кешируется, поэтому все последующие чтения и каждый кадр dosbox_watch_frames не стоят ничего. Опция allow_unconfirmed=true возвращает то, что дал слепой скан, для тех, кто будет проверять сам.

Страница находится не обязательно там, где вы могли бы подумать: она начинается там, куда её помещает стартовый адрес CRTC, а это граница четыре байта и никак не тоньше. На измеренной живой системе она оказалась на смежении 16.

Профили

Профиль — это один JSON-файл, описывающий игру: как распознать её сегмент данных, где она хранит состояние мыши, размер экрана и паллитра, именованные смещения, наборы наблюдении и известные области кода из лоха. profiles/example.json — аннотированный шаблон; в репозитории OpenJP есть боевые профили, написанные под коммерческую игру 1993 года.

{
  "name": "example",
  "ds_segment": "0x1234",
  "marker": { "bytes": "6578616d706c652e64617400", "offset": "0x0100" },
  "checks": [ { "kind": "cstring_via_pointer", "pointer": "0x0200", "value": "game" } ],
  "mouse": { "buttons": "0x00B2", "position": "0x00B6" },
  "screen": { "width": 320, "height": 200 },
  "symbols": { "lives": { "offset": "0x1234", "size": 1, "description": "Lives left." } },
  "watch_sets": { "player": ["lives", "score", "level"] }
}

Маркер можно встроить как bytes hex или вырезать из эталонного дампа (source_dump выmuk offset length). Доступны проверки: cstring_via_pointer, max, max_range, equals — этого достаточно, чтобы сделать ложную позитивовку почти невозможной, что крайне важно, ведь альтернатива — патчинг случайного блока памяти.

Платформы

Windows

Как брать

Память гостя, сегменты, поиск, клавиши, клики

Да

Да

Кадровый буфер и сэмплирование, техники

Да

Да

Список окон, захват, изменение размерa

Да

при наличии X11

Команды меню эмулятора

Да

нет — используйте изолированный дисплей

Ониеэкранная отрисовка

через Xvfb

dosbox_capabilities сообщает всё это о работающем хосте, так что лучше спросить, чем гадать.

В Linux kernel.yama.ptrace_scope ограничивает доступ к памяти другого процесса точно так же, как уровень целостности в Windows:

Значение

Эффект

0

любой процесс с тем же uid — dosbox_attach работает

1 (по умолчанию в Debian и Ubuntu)

только потомки — dosbox_launch работает, dosbox_attach — нет

2

только CAP_SYS_PTRACE

3

никакого attach вообще

При распространённом значении по умолчанию используйте launch, а не attach. Сервер читает sysctl и сообщает об этом, а не выдаёт голый EPERM.

В Linux нет способа сфотографировать перекрытое окно без композитного менеджера, а в Wayland межклиентского захвата нет вовсе. Ответ — не эмулировать PrintWindow, а убрать ограничение, ради которого он существует: dosbox_launch(isolated=true) помещает эмулятор на отдельный дисплей Xvfb, где нет рабочего стола, который нужно защищать, и собственные горячие клавиши эмулятора работают, не отнимая нажатие ни у кого.

В macOS понадобился бы task_for_pid, а значит, либо root, либо подписанный бинарник с entitlements. Бэкенда для этого нет.

Ограничения

  • Эмулятор должен быть доступен: тот же уровень целостности в Windows, приемлемый ptrace_scope в Linux.

  • Один эмулятор на профиль за раз. Два гостя, запустившие одну и ту же игру, делают сканирование сегментов неоднозначным, и сервер отказывается, а не гадает.

  • dosbox_capture_screen с source="window" изменяет размер окна эмулятора, чтобы получить точный целочисленный масштаб. Это единственное видимое воздействие этого сервера на рабочий стол — и причина предпочесть source="vram", который к тому же быстрее и не может поймать наполовину отрисованный кадр.

  • Фотографирование окна стоит гостю реального времени: цикл съёмки растягивает видимые гостю фазы примерно в 1.6 раза. Для всего количественного используйте framebuffer.

  • Клик может продвинуть две страницы «click to continue» в некоторых играх; при листании списков отправляйте клавишу.

  • Записи в запущенную игру необратимы, и игра может пересчитать поле сразу после того, как вы его задали — патчите в момент, когда значение будет прочитано до пересчёта.

  • Захваты памяти по трассе читаются через то, что содержит DS в момент выполнения пещеры. Для игры с одним сегментом данных это точно верно; для процедуры, переключающей DS, захватывайте ds вместе с данными и проверяйте его.

  • Из видеопамяти читается только chain-4 линейный режим 13h. Всё остальное требует source="window".

  • Слепое сканирование framebuffer — это подсказка, а не ответ, и оно помечается как неподтверждённое. Давайте опорный кадр.

Разработка

pip install -e ".[dev,all]"
pytest

Набор тестов полностью офлайн: DOS-гость, цепочка памяти, chain-4 framebuffer и трассируемый сегмент кода собираются в bytearray, так что он работает на любой платформе без эмулятора и без игры. Что он не покрывает — это два системных вызова в самом низу: чтение и запись в другой процесс — и окно.

Лицензия

MIT.

Install Server
A
license - permissive license
A
quality
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables headless debugging of Windows executables from Linux/macOS hosts by orchestrating winedbg's gdbserver and a GDB client, exposing 19 tools for launch, attach, breakpoints, stepping, register/memory access, and session lifecycle.
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Bridges AI agents to a DOSBox emulator, enabling control of DOS programs via MCP tools for typing, screen reading, video capture, Lua scripting, and memory access.
    1
    GPL 2.0
  • F
    license
    A
    quality
    B
    maintenance
    Enables an MCP client to observe and control a text-mode DOS system via a Python bridge, supporting keyboard input and screen capture.
    8

View all related MCP servers

Related MCP Connectors

  • Eyes and hands on real Windows PCs — observe, click, type via Glasswarp API.

  • Live browser debugging for AI assistants — DOM, console, network via MCP.

  • Operate Linux, macOS and Windows from your LLM. Every action runs through an auditable allowlist.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/md0-code/dosbox-x-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server