- Fonts downloaded from int10h.org on first use - Cached in platform-appropriate directory (~/.cache/mcdosbox-x/fonts) - Add fonts_download() MCP tool for explicit pre-download - Wheel size reduced from 473KB to 56KB (88% smaller) - 48 tools now registered
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