dosbox-x-mcp
dosbox-x-mcp
데스크톱을 건드리지 않고 DOSBox-X 게스트를 구동하는 MCP 서버입니다. 포커스를 가로채지 않고, 호스트 키 입력을 합성하지 않으며, 포인터를 움직이지 않습니다. 모델은 DOS 프로그램을 처음부터 끝까지 실행할 수 있고, 그동안 여러분은 화면 앞에서 계속 작업할 수 있습니다.
이 도구는 하나의 리버스 엔지니어링 프로젝트를 위한 캡처 워크플로로 시작했고, 이제는 일반적인 보조 도구가 되었습니다. 실행 중인 DOS 게스트가 주어지면 아무 사전 지식 없이도 그 게스트를 찾아낼 수 있고, 어떤 프로그램이 어디에 로드되어 있는지, 어떤 세그먼트를 읽고 패치할 수 있는지, 시간에 따른 값 변화, 비디오 메모리에서 화면을 읽기, 에뮬레이터 자체 레코더 사용, 코드 실행 중 관찰까지 가능합니다. 디버거도, 디스크의 바이트 하나를 변경할 필요도 없습니다.
할 수 있는 것
게스트 찾기 | BIOS 불변식만으로 DOS 게스트를 찾아냅니다. 프로필도, 표식도, 사전 지식도 필요 없습니다. DOS 메모리 체인을 따라가며 로드된 각 프로그램, 그 세그먼트, 출처 경로를 이름으로 표시합니다. |
모든 세그먼트 주소 지정 | 런처 체인의 다른 프로그램, TSR, 오버레이, 인터럽트 벡터 테이블, EMS 페이지까지. 읽기, 패치, 덤프, 검색이 모두 가능합니다. |
조종하기 | BIOS 키보드 링에 키를 넣습니다. 게임 자체의 INT 33h 이후 마우스 단어에 클릭을 넣습니다. 둘 다 호스트 입력 큐에 닿지 않습니다. |
보기 | 에뮬레이터의 비디오 메모리에서 프레임버퍼를 직접 읽습니다. 창도, 스케일링도 없고, 게스트에 아무런 부담도 주지 않습니다. 참조 프레임으로 확인됩니다. 필요한 경우 창을 캡처할 수도 있습니다. |
측정하기 | 메모리 조건에서 대기하거나, 감시 목록을 최대 200Hz로 TSV로 샘플링합니다. 모든 열이 단일 스냅샷에서 비롯되어 서로 어긋나지 않습니다. 고유한 프레임마다 비디오 메모리를 감시하여 등장 시각을 기록합니다. |
녹음/녹화 | 에뮬레이터 자체의 OPL, MIDI, WAVE 캡처를 포커스 없이, 호스트 매퍼 없이 실행합니다. |
계측하기 | 실행 중인 |
Related MCP server: re-winedbg
동작 원리
여기에는 호스트의 입력 큐나 화면이 전혀 관여하지 않습니다.
게스트 탐지. 모든 DOS 게스트에는
0040:0080에 BIOS 키보드 링의 범위 워드0x001E/0x003E가 있고, 그 범위 안에 헤드와 테일이 위치하며, 살아있는INT 21h벡터를 갖습니다. 에뮬레이터 메모리에서 이 세 가지를 찾으면 게스트의 물리적 주소 0을 찾을 수 있고, 그 지점에서 모든 세그먼트에 주소를 지정할 수 있습니다. 이것은 프로필이 필요 없습니다. 새 프로젝트가 처음 시작할 때 맞닥뜨리는 닭과 달걀 문제를 풀어줍니다.키는 실제 키보드 인터럽트처럼 게스트의 BIOS 키보드 링에 추가됩니다.
클릭는 게임 자체 INT 33h 핸들러가 기록하는 워드에 기록됩니다. 게임이 실제로 읽는 상태입니다. 게임의 핸들러가 계속 그 값을 덮어쓰기 때문에, 단일 쓰기로는 따라잡을 수 없으므로 잠시 동안 계속 다시 기록됩니다.
프레임은 비디오 메모리에서 나옵니다. DOSBox는 하드웨어와 동일한 방식으로 chain-4 페이지를 저장합니다. CPU 오프셋
o는 선형 주소4 * (o & ~3) + (o & 3)에 있고, 각 4바이트 그룹의 열여섯 번째 그룹 하나를 취하면 영역이 화면으로 되살아납니다. 화면의 어떤 바이트가 화면인지 찾아내는 일은 참조 프레임이 있어야 합니다. 에뮬레이터 메모리에는 화면이 아닌, 화면과 비슷해 보이는 이미지류 데이터가 가득하기 때문에, 페이지는 참조 프레임과 바이트 단위로 확인되거나 확인 불가능 상태로 보고됩니다. 화면 읽기을 참조하세요.추적은 근거리
CALL을 0으로 채워진 연속 영역을 가리키도록 패치합니다. 그 케이브는 대체된 대상을 호출하고 플래그를 보존한 뒤, 요청한 것들을 케이브 코드 뒤의 슬롯에 복사하고 복귀합니다. 에뮬레이터가 실행과 함께 종료되면 패치도 함께 사라집니다.
설치
pip install "dosbox-x-mcp[all] @ git+https://github.com/md0-code/dosbox-x-mcp"추가 기능은 모두 선택 사항이며, 이름이 그 용도를 나타냅니다:
Extra | 용도 |
| Pillow. 에뮬레이터 창을 캡처할 때 사용 |
| numpy. 더 빠른 chain-4 디인터리빙 (순수 Python 대체 구현도 있음) |
| 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"
}
}
}
}변수 | 의미 |
| 프로필이 있는 위치 (기본값: 패키지의 |
| 기본 프로필 이름; 프로필을 사용하지 않으려면 |
| 실행할 |
| 상대 출력 경로 또는 참조 경로를 해석할 기준 디렉터리 |
도구가 읽거나 쓰는 모든 경로는 하나의 규칙을 따릅니다: 절대 경로는 주어진 것을 그대로 사용, 상대 경로는 DOSBOX_MCP_OUTPUT_DIR 아래로 해석됩니다. 도구는 해석된 경로를 반환하므로, 파일이 어디로 저장되었는지 의심할 필요가 없습니다.
도구
도구 | 하는 일 |
| 이 호스트가 할 수 있션과 할 수 없는 것 |
| 프로필 목록; 특정 프로필의 명명된 오프셋 표시 |
| DOSBox-X를 시작하고 게스트가 제어 가능해질 때까지 대기 |
| 이미 실행 중인 에뮬레이터에 pid로 연결 |
| 연결된 세션 + 기타 DOSBox-X 윈도우들 |
| 세션 종료 |
| 게스트를 찾고 모든 로드된 프로그램 나열하기 — 프로필 없이 가능 |
| 바이트 패턴을 찾아 게스트 |
| BIOS 키보드 링에 키를 입력 |
| 게임 자체마우스 워드로 클릭 |
| 버튼을 누른 상태를 (선택적으로 메모리 테스트가 통과할 때까지) 유지 |
| 데이터 세그먼트 또는 임ⅰ이 segment 읽기 |
| 데이터 세그먼트 또는 임으의 segment 패치 |
| 64 KiB 세그먼트 전체를 파일로 쓰기 |
| 메모리 필드가 테스트를 만족할 때까지 대기 |
| 감시 목록을 시간에 따라 TSV로 샘플링 |
| 현재 프레임을 이미지로 반환 |
| 비디오 메모리나 창에서 정확한 프레임을 저장 |
| 비디오 메모리에서 페이지를 직접 읽습니다 |
| 일정 구간 동안의 모든 고유 프레임과 타임스탬프 |
| DOSBox-X 자체 메뉴 항목 하나를 실행 |
| OPL, MIDI 또는 WAVE 출력을 파일로 기록 |
| 추적에 충분한 빈 공간(0으로 채워진 연속 구간)을 찾기 |
| 실행 중인 |
| 추적에서 기록된 내용 읽기 |
| 호출 지점을 원래대로 복원하고 케이브를 비우기 |
오프셋이 허용되는 곳이면 어디든 프로필 심볼 이름도 쓸 수 있습니다 — 0x634A 대신 treasure. 유
아직 프로필이 없는 게임에서 시작하기
프로필이 선행 조건은 아닙니다. 이것이 첫 세션 전체입니다:
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-relative 도구가 이름만으로 동작하기 시작합니다.
화면 읽기
dosbox_read_framebuffer는 호출한 순간에 게스트가 기록한 팔레트 인덱스를 반환합니다. 정확하고, 중간에 그려지다 만 프레임을 잡을 수 없으며, 게스트에게 아무 실효가 걸리지 않습니다. 따라서 측정 대상이라면 이 경로를 우선 사용하는 것이 옳습니다.
이 방식은오수 프레임이 필요하며, 그 사실을 추측이 아닌 명시적으로 알려줍니다. 페이지를 찾는 일은 수백 메가바이트 중에서 64,000 바이트를 찾는 것과 같고, 단순한 일관성만으로는 부족합니다. 실제 실행 중인게임에서 blind scan을 수행해 보면 0.999 점수를 낸 페이지가 반환되지만, 이는 화면이 아니라 디코딩된 스프라이트 뱅크일 리 있습니다. 그래서 reference=에 지금 화면에 보이는 내용을 담은 64,000바이트 파일을 넘기면, 그 페이지가 바이트 단위로 확인됩니다:
dosbox_read_framebuffer(reference="credits_logo.bin", stem="shots/logo")
→ page_offset 16, confirmed true, pages [16, 64016, 128016, 192016]참조 프레임을 입수할 곳:
개발 중인 포트라면 무료로 가진다 — 동일한 화면을 자체 렌더링한 결과가 바로 그것이다. 이것 또한 비교할 만한 가치가 있다: 두 파일이 바이트 단위로 일치한다면, 그 포트의 렌더러가 올바른 것이다.
동일 화면을 이전에 확인한 캡처가 있다면 그걸로 다시 확인할 수 있습니다.
프로필에팔레트가 있다면 window 사진을 자동으로 사용하며, 별도 인자가 필요 없습니다.
확인이 끝난 위치(name)는 캐시되므로, 이후에 읽는 모든 것과 dosbox_watch_frames의 모든 프레임은 거의 즉시 사용할 수 있습니다. 직접 검증해 보고 싶다면 allow_unconfirmed=true로, 맹목 스캔이 뽑아낸 유력 후보를 받아볼 수도 있습니다.
페이지는 반드시 예상 위치에 있는 것은 아닙니다. CRTC 시작 주소가 가리키는 곳에서 시작하며, 이는 단지 4바이트 경계일 뿐이며 그보다 더 조악한 단위는 아닙니다. 실제로 측정한 한 사례는 오프셋 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 + offset + length). 사용할 수 있는 검사는 cstring_via_pointer, max, max_range, equals입니다. 오탐지 가능성을 사실상 배제하기에 충분합니다. 이것이 중요한 이유는, 그 대안이 무작위 할당 메모리를 수정하는 것이기 때문입니다.
플랫폼
Windows | Linux | macOS | |
게스트 메모리, 세그먼트 tracked, 키, 클릭 | 예 | 예 | 백엔드 없음 |
프레임버퍼, 샘플링, 추적 | 예 | 예 | 백엔드 없음 |
창 목록, 캡처, 크기 조절 | 예 | X11 지원 | — |
에뮬레이터 메뉴 명령 | 예 | 아니오 — 격리 디스플레이 사용 | — |
오프스크린 디스플레이 | — |
| — |
dosbox_capabilities는 실행 중인 호스트에 대해 이 모든 것을 보고하므로, 추측하지 말고 물어보세요.
Linux에서 kernel.yama.ptrace_scope는 Windows의 무결성 수준(integrity level)과 똑같이 다른 프로세스의 메모리에 대한 접근을 통제합니다.
값 | 영향을 줍니다 |
| 동일 uid 프로세스 모두 가능 — |
| 자손 프로세스만 возможен — |
|
|
| attach 자체가 불가능 |
일반적인 기본값에서는 attach보다 launch를 사용하세요. 서버는 sysctl을 읽고 그 사실을 알려 주므로, 필요한 안내 없이 EPERM만 내보내지 않습니다.
Linux는 컴포짓 매니저 없이 가려진 창을 촬영할 방법이 없고, Wayland에는 클라이언트 간 캡처가 전혀 없습니다. 해답은 PrintWindow를 흉내 내는 것이 아니라, 그 함수가 존재하는 이유인 제약을 제거하는 것입니다. dosbox_launch(isolated=true)는 에뮬레이터를 전용 Xvfb 디스플레이에 띄웁니다. 그렇게 하면 보호할 데스크톱이 없어지고, 에뮬레이터 자체의 키보드 단축키도 다른 누군가의 키 입력을 빼앗지 않고 사용할 수 있습니다.
macOS는 task_for_pid가 필요하므로, 루트 권한 또는 서명되고 entitlement가 있는 바이너리가 필요합니다. 이에 해당하는 백엔드는 없습니다.
주의사항
에뮬레이터에 접근할 수 있어야 합니다. Windows에서는 동일한 무결성 수준, Linux에서는 이를 허용하는
ptrace_scope가 필요합니다.프로필당 한 번에 하나의 에뮬레이터만 존재할 수 있습니다. 같은 게임을 실행하는 게스트가 둘 이상 있으면 세그먼트 스캔이 모호해지므로, 서버는 추측하는 대신 거부합니다.
dosbox_capture_screen에서source="window"를 사용하면 정확한 정수 배율을 얻기 위해 에뮬레이터 창 크기를 조정합니다. 이것이 이 서버가 데스크톱에 미치는 유일한 보이는 영향이며, 더 빠르고 반그려진 프레임을 잡지 못하는source="vram"을 선호하는 이유입니다.창을 촬영하는 것은 게스트의 실제 시간을 소모합니다. 촬영 루프는 게스트에게 보이는 단계를 약 1.6배로 늘립니다. 정량적인 작업이 필요하면 framebuffer를 사용하세요.
일부 게임에서는 클릭 한 번으로 “클릭하며 계속하기” 페이지를 두 장 넘길 수 있습니다. 목록을 넘길 때는 키를 보내세요.
h 실행 중인 게임에 쓰는 것은 되돌릴 수 없으며, 설정 직후에 게임이 그 필드를 다시 계산할 수 있습니다. 필드가 다시 계산되기 전에 읽힐 순간에 패치하세요.
트레이스 메모리 캡처는 케이브가 실행될 때
DS가 담고 있는 값을 통해 읽습니다. 데이터 세그먼트가 하나뿐인 게임에서는 이렇게 해도 완전히 정확합니다. 그러나DS를 전환하는 루틴의 경우에는ds도 함께 캡처하고 확인하세요.비디오 메모리에서 읽어내는 것은 chain-4 linear 모드 13h뿐입니다. 그 외에는
source="window"가 필요합니다.맹검(블라인드) framebuffer 스캔은 답이 아니라 힌트이며, 미확인 상태로 보고됩니다. 기준(reference) 프레임을 제공하세요.
개발
pip install -e ".[dev,all]"
pytest이 테스트 스위트는 완전히 오프라인입니다. DOS 게스트, 메모리 체인, chain-4 framebuffer, 추적 가능한 코드 세그먼트가 모두 bytearray 안에 구성되어 있어 에뮬레이터나 게임 없이도 가능한 모든 플랫폼에서 실행됩니다. 다루지 않는 것은 맨 아래의 두 시스템 호출입니다. 다른 프로세스의 읽기와 쓰기, 그리고 창 캡처가 그것입니다.
라이선스
MIT.
Maintenance
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
- FlicenseAqualityDmaintenanceEnables programmatic control of the mGBA emulator for Game Boy, Game Boy Color, and Game Boy Advance games, including screenshot capture, memory reading, sprite data dumping, and custom Lua script execution for automated testing and game analysis.63
- AlicenseNot gradedqualityCmaintenanceEnables 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
- AlicenseNot gradedqualityCmaintenanceBridges 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.1GPL 2.0
- FlicenseAqualityBmaintenanceEnables an MCP client to observe and control a text-mode DOS system via a Python bridge, supporting keyboard input and screen capture.8
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.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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