mcdosbox-x
AI-assisted debugging of DOS binaries via the Model Context Protocol (MCP).
This MCP server enables Claude to programmatically debug DOS programs running in DOSBox-X by providing tools for:
- Setting breakpoints and tracing execution
- Reading/writing CPU registers and memory
- Disassembling code at any address
- Step-by-step instruction execution
- Sending keyboard/mouse input
- Capturing screenshots and screen text
- Serial port communication for BBS/terminal programs
Primary Use Case
Reverse engineering classic DOS programs — specifically, tracing the unpublished Bezier curve algorithm in RIPTERM.EXE for the RIPscrip graphics protocol research project.
Quick Start
Installation from PyPI
# Install with uvx (recommended)
uvx mcdosbox-x
# Or install with pip
pip install mcdosbox-x
Register with Claude Code
# Add to Claude Code
claude mcp add mcdosbox-x -- uvx mcdosbox-x
# Verify registration
claude mcp list
Development Installation
# Clone the repository
git clone https://git.supported.systems/MCP/mcdosbox-x.git
cd mcdosbox-x
# Install dependencies
uv sync
# Build Docker image (uses lokkju/dosbox-x-remotedebug fork)
docker compose build
# Create DOS directory for your binaries
mkdir -p dos
Running
# Allow X11 access for Docker (Linux)
xhost +local:docker
# Start DOSBox-X with GDB server
docker compose up -d
# Verify GDB port is listening
nc -zv localhost 1234
# View logs
docker compose logs -f
Running with Docker
# Allow X11 access for Docker (Linux)
xhost +local:docker
# Start DOSBox-X with GDB server
docker compose up -d
# View logs
docker compose logs -f
Usage with Claude
Once registered, Claude can debug DOS binaries:
# Connect to the running DOSBox-X GDB server
attach("localhost", 1234)
# Read current CPU state
registers()
# Read memory at CS:IP
memory_read("CS:IP", 64)
# Set a breakpoint at the boot sector
breakpoint_set("0x7C00")
# Continue execution until breakpoint
continue_execution()
# Step through instructions
step(10)
# Disassemble at current location
disassemble("CS:IP", 20)
# Disconnect when done
quit()
Tools Reference
Execution Control (6 tools)
| Tool | Description |
|---|---|
launch |
Start DOSBox-X container with optional binary |
attach |
Connect to GDB stub at host:port |
continue_execution |
Run until breakpoint or signal |
step |
Step N instructions (default: 1) |
step_over |
Step over CALL instructions |
quit |
Disconnect and optionally stop DOSBox-X |
Breakpoints (3 tools)
| Tool | Description |
|---|---|
breakpoint_set |
Set software breakpoint at address |
breakpoint_list |
List all active breakpoints |
breakpoint_delete |
Remove breakpoint by ID or all |
Inspection (6 tools)
| Tool | Description |
|---|---|
registers |
Read all CPU registers (32-bit, 16-bit, segments, flags) |
memory_read |
Read memory in hex/ASCII/dump format |
memory_write |
Write hex or ASCII data to memory |
disassemble |
Disassemble instructions with opcode hints |
stack |
Dump stack contents from SS:SP |
status |
Get debugger connection status |
Peripheral (2 tools — stubs)
| Tool | Description |
|---|---|
screenshot |
Capture DOSBox-X display (not yet implemented) |
serial_send |
Send data to serial port (not yet implemented) |
Address Formats
The server supports multiple address formats:
| Format | Example | Description |
|---|---|---|
| Segment:offset | 1234:5678 |
Standard DOS format |
| Flat hex | 0x12345 or 12345 |
Physical address |
| Decimal | #65536 |
Decimal address |
| Register-based | CS:IP, DS:SI |
Uses current register values |
Architecture
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ Claude Code │────▶│ DOSBox-X MCP │────▶│ DOSBox-X │
│ │ MCP │ Server │ GDB │ Container │
└─────────────────┘ └──────────────────┘ └─────────────────┘
│ │ │
│ │ │
▼ ▼ ▼
FastMCP 2.x GDB Remote lokkju/dosbox-x-
(stdio) Protocol remotedebug fork
(TCP :1234) (--enable-remotedebug)
Why lokkju/dosbox-x-remotedebug?
Mainline DOSBox-X doesn't include a GDB server. The lokkju/dosbox-x-remotedebug fork adds:
--enable-remotedebugbuild flag- GDB server on port 1234 (configurable)
- QMP server on port 4444 for machine control
- Config options in
[dosbox]section:gdbserver=true,gdbserver port=1234
Project Structure
mcdosbox-x/
├── src/mcdosbox_x/
│ ├── server.py # FastMCP server entry point
│ ├── gdb_client.py # GDB Remote Serial Protocol client
│ ├── dosbox.py # DOSBox-X process/container management
│ ├── fonts.py # Bundled TrueType font utilities
│ ├── resources.py # MCP resources (screenshots, screen)
│ ├── state.py # Shared global state (manager, client)
│ ├── types.py # Type definitions (Registers, Breakpoint, etc.)
│ ├── utils.py # Address parsing, format conversion
│ ├── fonts/ # Bundled IBM PC TTF fonts (CC BY-SA 4.0)
│ └── tools/ # MCP tool implementations (47 tools)
│ ├── execution.py # launch, attach, continue, step, quit, fonts_list
│ ├── breakpoints.py # breakpoint_set, list, delete
│ ├── inspection.py # registers, memory, disassemble, stack, screen
│ ├── peripheral.py # screenshot, keyboard, mouse, joystick, serial
│ ├── control.py # pause, resume, reset, savestate, loadstate
│ ├── logging.py # DOSBox logging control
│ └── network.py # port mapping, modem dial/hangup
├── tests/ # pytest test suite
├── dos/ # Mount point for DOS binaries
├── Dockerfile # Multi-stage build for dosbox-x-remotedebug
├── docker-compose.yml # Container orchestration
└── pyproject.toml # Python package definition
Configuration
DOSBox-X Config (config/dosbox.conf)
[dosbox]
memsize=16
gdbserver=true
gdbserver port=1234
qmpserver=true
qmpserver port=4444
[autoexec]
MOUNT C /dos
C:
Environment Variables (.env)
GDB_PORT=1234 # Host port for GDB
QMP_PORT=4444 # Host port for QMP
DOS_DIR=./dos # DOS files mount point
CONFIG_FILE=./config/dosbox.conf
Development
# Run tests
uv run pytest
# Run tests with coverage
uv run pytest --cov=mcdosbox_x
# Lint code
uv run ruff check src/
# Format code
uv run ruff format src/
# Type check (optional)
uv run mypy src/
Technical Details
GDB Remote Serial Protocol
The server implements a client for the GDB Remote Serial Protocol:
| Command | Description |
|---|---|
qSupported |
Capability negotiation (handshake) |
g / G |
Read/write all registers |
p / P |
Read/write single register |
m / M |
Read/write memory |
Z0 / z0 |
Set/clear software breakpoint |
c / s |
Continue / step |
? |
Query stop reason |
Packets use format: $<command>#<2-digit checksum>
Real Mode Addressing
DOS uses real mode with segment:offset addressing:
Physical Address = (Segment << 4) + Offset
This gives a 20-bit address space (1MB). The Registers class provides helpers like cs_ip and ss_sp for common address calculations.
Troubleshooting
GDB Connection Refused
# Check if container is running
docker ps | grep dosbox
# Check if GDB port is listening
docker exec dosbox-mcp nc -zv localhost 1234
# Check logs for GDB server startup
docker logs dosbox-mcp 2>&1 | grep -i gdb
Container Shows "unhealthy"
The healthcheck uses nc which may not be installed in the slim image. This is cosmetic — the GDB server still works. To fix, add netcat-openbsd to the Dockerfile runtime stage.
X11 Display Issues
# Allow Docker X11 access
xhost +local:docker
# Or use headless mode
docker compose --profile headless up -d dosbox-headless
Related Projects
- RIPscrip Research (rpmesh) — Parent project
- lokkju/dosbox-x-remotedebug — DOSBox-X fork with GDB
- FastMCP — MCP server framework
- GDB Remote Protocol
License
MIT License
Metadata
Release files for mcdosbox-x 2026.9.12.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| mcdosbox_x-2026.9.12.2.tar.gz | 55.4 kB | Without provenance | Details for mcdosbox_x-2026.9.12.2.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| mcdosbox_x-2026.9.12.2-py3-none-any.whl | Python 3 | none | any | Details for mcdosbox_x-2026.9.12.2-py3-none-any.whl |
Total release size: 112.4 kB
Release files / mcdosbox_x-2026.9.12.2.tar.gz
| Download URL | mcdosbox_x-2026.9.12.2.tar.gz |
|---|---|
| Size | 55.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e1e16101f7f1ec3d30332ecd090f99cf3d5f274c43f1ee5db64da2050b62e1be
|
|
BLAKE2b-256 checksum How to use checksums |
c462ef55199967af614d2322b8161ef70461ae9381386bc1c513f0aac266a839
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.3 {"installer":{"name":"uv","version":"0.11.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"EndeavourOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / mcdosbox_x-2026.9.12.2-py3-none-any.whl
| Download URL | mcdosbox_x-2026.9.12.2-py3-none-any.whl |
|---|---|
| Size | 57.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
61ad66e8f79de25c82c00bb20c1b28c69d21af69369bb0c54e57d35dc535bd54
|
|
BLAKE2b-256 checksum How to use checksums |
09bfceb7304e647b67b6134cb94b7dd6814c67e9032acb1b7730b7e5455cf045
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.3 {"installer":{"name":"uv","version":"0.11.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"EndeavourOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Security for mcdosbox-x 2026.9.12.2
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.