Metadata-Version: 2.5
Name: mcdosbox-x
Version: 2026.9.12
Summary: MCP server for debugging DOS binaries in DOSBox-X via GDB protocol
Author-email: Ryan Malloy <ryan@supported.systems>
License: MIT
License-File: LICENSE
Keywords: debugging,dos,dosbox,gdb,mcp,reverse-engineering
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Debuggers
Classifier: Topic :: System :: Emulators
Requires-Python: >=3.11
Requires-Dist: fastmcp>=2.0.0
Requires-Dist: pillow>=10.0.0
Provides-Extra: dev
Requires-Dist: pytest-asyncio>=0.24.0; extra == 'dev'
Requires-Dist: pytest>=8.0.0; extra == 'dev'
Requires-Dist: ruff>=0.8.0; extra == 'dev'
Description-Content-Type: text/markdown

# 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](https://github.com/ryanmalloy/rpmesh).

## Quick Start

### Installation from PyPI

```bash
# Install with uvx (recommended)
uvx mcdosbox-x

# Or install with pip
pip install mcdosbox-x
```

### Register with Claude Code

```bash
# Add to Claude Code
claude mcp add mcdosbox-x -- uvx mcdosbox-x

# Verify registration
claude mcp list
```

### Development Installation

```bash
# 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

```bash
# 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

```bash
# 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:

```python
# 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](https://github.com/lokkju/dosbox-x-remotedebug) fork adds:

- `--enable-remotedebug` build 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`)

```ini
[dosbox]
memsize=16
gdbserver=true
gdbserver port=1234
qmpserver=true
qmpserver port=4444

[autoexec]
MOUNT C /dos
C:
```

### Environment Variables (`.env`)

```bash
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

```bash
# 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](https://sourceware.org/gdb/current/onlinedocs/gdb.html/Remote-Protocol.html):

| 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

```bash
# 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

```bash
# Allow Docker X11 access
xhost +local:docker

# Or use headless mode
docker compose --profile headless up -d dosbox-headless
```

## Related Projects

- [RIPscrip Research (rpmesh)](https://github.com/ryanmalloy/rpmesh) — Parent project
- [lokkju/dosbox-x-remotedebug](https://github.com/lokkju/dosbox-x-remotedebug) — DOSBox-X fork with GDB
- [FastMCP](https://gofastmcp.com/) — MCP server framework
- [GDB Remote Protocol](https://sourceware.org/gdb/current/onlinedocs/gdb.html/Remote-Protocol.html)

## License

MIT License
