VICE MCP

by barryw

Not rated
GitHub

About

MCP server embedded in the VICE Commodore 64/128/VIC-20/PET emulator, giving AI assistants direct access to read/write memory, set breakpoints, inspect VIC-II/SID/CIA registers, and debug 6502 assembly in real time with 63 tools.

Details

Author
barryw
Categories
Developer Tools

Setup

Install VICE MCP in your MCP client (Claude Desktop, Cursor, Windsurf, and others).

Repository: https://github.com/barryw/vice-mcp

Follow the installation instructions in the repository README, then restart your MCP client.

VICE MCPis a Walker Heavy Industries project.

An MCP server embedded directly inside VICE, giving AI agents and modern tools full programmatic control over the world's most iconic 8-bit computer.

Load a disk image. Set breakpoints. Inspect sprites. Read SID registers. Type on the keyboard. Take screenshots. Step through 6502 code. All through a clean JSON-RPC API that any MCP client can speak.

This isVICE— the legendary Commodore emulator — with aModel Context Protocolserver built into its core. Not bolted on. Not a wrapper.~17,000 lines of C woven into the emulator itself.

Point any MCP-compatible client - Claude Desktop, Cursor, your own agent - athttp://127.0.0.1:6510/mcpand you have a fully controllable Commodore 64. Your agent can:

- Load and run software— autostart PRGs and disk images
- Debug 6502 code— breakpoints, watchpoints, conditional breaks, single-stepping
- Inspect everything— CPU registers, memory banks, VIC-II graphics, SID audio, CIA timers
- See what's on screen— take screenshots, read sprite bitmaps as ASCII art
- Interact like a human— type text, press keys, move joysticks
- Measure performance— cycle-accurate stopwatch, execution tracing, interrupt logging
- Save and restore state— full snapshot management with metadata

If you write code for the Commodore 64, this gives you amodern debugging workflowwithout leaving your editor:

- Set breakpoints from your IDE while your program runs
- Load KickAssembler or VICE symbol files and debug by label name
- Search memory for byte patterns with wildcard support
- Compare memory regions against saved snapshots to find what changed
- Trace execution with PC-range filtering to focus on your code
- Log interrupts to understand IRQ/NMI timing
- Group breakpoints and toggle them as a set

- Automate ROM analysis and reverse engineering
- Build interactive tutorials that control a live C64
- Capture screen states for documentation
- Replay and analyze historical software

Every tool follows MCP conventions with full JSON Schema validation, meaningful errors, and consistent parameter naming.

This isn't a sidecar process or a screen-scraper. The MCP server is compiled directly into VICE as a first-class subsystem — acrossevery machine VICE emulates.

The MCP serveradapts to the running machine automatically. When an AI agent callsvice.machine.config.get, it receives the actual hardware configuration — which chips are present, what memory banks exist, valid address ranges, and available resources. An agent debugging a VIC-20 cartridge gets VIC-I registers; the same agent debugging a C128 program gets VIC-IIandthe VDC 80-column display.

┌─────────────────────────────────────────────────┐ │ VICE Emulator │ │ │ │ ┌──────────┐ ┌──────────┐ ┌──────────────┐ │ │ │ CPU │ │ Video │ │ Audio │ │ │ │ (varies) │ │ (varies) │ │ (varies) │ │ │ └────┬─────┘ └────┬─────┘ └──────┬───────┘ │ │ │ │ │ │ │ └──────────┬───┴───────────────┘ │ │ │ │ │ ┌────────┴────────┐ │ │ │ MCP Server │ │ │ │ (libmcp.a) │ │ │ │ │ │ │ │ JSON-RPC 2.0 │<---- POST /mcp -----│ │ │ libmicrohttpd │---- GET /events 501>│ │ │ Trap Dispatch │ │ │ └─────────────────┘ │ │ │ └─────────────────────────────────────────────────┘ 127.0.0.1:6510 by default

- Trap-based dispatch— HTTP requests are dispatched through VICE's trap mechanism, ensuring all tool logic executes on the emulator's main thread. No race conditions, no locking surprises.
- Zero-copy access— Tools read directly from emulator internals. When you ask for VIC-II state, you get the actual register values, not a cached approximation.
- Machine-aware responses— Tools report hardware capabilities, chip availability, and valid memory ranges for whatever machine is running. The agent always knows what it's working with.
- Monitor integration— Works alongside VICE's built-in monitor. If the emulator is paused in the monitor, MCP requests execute directly without traps.
- Reserved events endpointGET /eventsexists but currently returns501 Not Implemented. Poll state through/mcpuntil event streaming lands.

Start any VICE machine with the MCP server enabled:

# C64 (cycle-exact) x64sc -mcpserver # C128 x128 -mcpserver # VIC-20 xvic -mcpserver # Listen on all network interfaces, port 7000 x64sc -mcpserver -mcpserverhost 0.0.0.0 -mcpserverport 7000

The MCP server starts on127.0.0.1:6510by default. MCP clients connect to:

0.0.0.0is a bind address, not a client address. It means "listen on every interface". A client on the same Mac still connects to127.0.0.1; a client on another machine connects to the Mac's LAN IP address, for examplehttp://192.168.1.42:6510/mcp.

- No token configured: non-browser MCP clients can connect without anAuthorizationheader.
- Token configured: every MCP request must includeAuthorization: Bearer <token>.
- CORS configured: a token is required. Wildcard CORS () is rejected.
- Binding to0.0.0.0without a token is allowed for backwards compatibility, but VICE logs a warning because remote clients can control the emulator.

All HTTP requests go to/mcp, must useContent-Type: application/json, and should sendAccept: application/json.

# Direct JSON-RPC call curl -sS http://127.0.0.1:6510/mcp \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ --data '{ "jsonrpc": "2.0", "id": 1, "method": "vice.ping" }' # Standard MCP tools/call form, used by Claude Code and other MCP clients curl -sS http://127.0.0.1:6510/mcp \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ --data '{ "jsonrpc": "2.0", "id": 2, "method": "tools/call", "params": { "name": "vice_ping", "arguments": {} } }' # Read the BASIC ROM entry point curl -sS http://127.0.0.1:6510/mcp \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ --data '{ "jsonrpc": "2.0", "id": 3, "method": "tools/call", "params": { "name": "vice_memory_read", "arguments": { "address": "0xA000", "size": 16, "encoding": "hex" } } }'

When a token is configured, add the bearer header to every request:

curl -sS http://127.0.0.1:6510/mcp \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer secret' \ --data '{"jsonrpc":"2.0","id":1,"method":"vice.ping"}'

Add this to your Claude Desktop MCP config:

{ "mcpServers": { "vice": { "url": "http://127.0.0.1:6510/mcp" } } }

Then just talk to it:"Load the game on drive 8 and show me what's on screen."

If VICE was started with-mcpservertoken, the client must sendAuthorization: Bearer <token>on every request. If your MCP client cannot configure HTTP headers, do not use a token for local-only127.0.0.1sessions.

cd vice ./autogen.sh mkdir build && cd build ../configure --enable-mcp-server --enable-gtk3ui make -j$(nproc)
# MCP flags should appear in help output src/x64sc -help | grep mcp # Expected: # -mcpserver Enable MCP server # -mcpserverport <port> Set MCP server port (default: 6510) # -mcpserverhost <host> Set MCP server host (default: 127.0.0.1)

Pre-built binaries are available on theReleasespage.

Windows does not include a GUI build. GTK3 cross-compilation for Windows is not supported by VICE's build system. If you need a Windows GUI,build from sourcenatively using MSYS2.

A resilient Python client is included with retry logic, connection pooling, and a convenience method for every tool:

from tools.resilience.vice_mcp_resilient import ViceMCPClient with ViceMCPClient("http://127.0.0.1:6510") as vice: # Load a program vice.autostart("/path/to/game.prg") # Set a breakpoint at the main loop vice.checkpoint_add(start_address=0x0810, stop_address=0x0810) # Run until it hits vice.execution_run() # Read the screen regs = vice.registers_get() screenshot = vice.display_screenshot(format="base64") # Inspect a sprite art = vice.sprite_inspect(sprite_number=0) print(art)

167 tests across 25 test classes validate every tool, every parameter, and every error condition:

# Requires a running VICE instance with MCP enabled pytest tools/tests/test_mcp_protocol.py -v

sim6502 — Unit Testing for 6502 Assembly

sim6502is a unit testing framework for 6502/6510/65C02 assembly that uses VICE MCP as an execution backend. Write tests in a custom DSL, run them against a live VICE instance with cycle-accurate hardware:

suite "sprite collision" { load "game.prg" test "player hits enemy" { jsr setup_sprites poke $d015, #$03 ; enable sprites 0 and 1 poke $d000, #$80 ; sprite 0 x = 128 poke $d002, #$80 ; sprite 1 x = 128 jsr main_loop assert $d01e & #$03 != 0 ; collision register set } }

sim6502 connects over MCP to load programs, set breakpoints, read registers, compare memory, and snapshot/restore state between tests — bringing modern CI/CD practices to retro computing development.

Any MCP-compatible client can drive VICE directly:

- Claude Desktop / Cursor— "Load this disk image, find the main loop, and explain what the IRQ handler does"
- Custom agents— Automated ROM analysis, regression testing, screenshot capture
- Research tools— Systematic exploration of historical software behavior

The MCP server islocalhost-only by default(127.0.0.1). With the default settings, only programs on the same machine can connect.

It has no TLS. It has optional bearer-token authentication. It is designed for local development first, and network exposure should be deliberate.

If you need remote access, put it behind a reverse proxy with proper auth:

nginx/caddy -> auth -> https -> 127.0.0.1:6510

Binding to0.0.0.0is supported via-mcpserverhost. That makes VICE listen on every network interface. It does not mean clients connect to0.0.0.0; remote clients connect to the Mac/Linux/Windows host's real IP address.

- Start VICE with-mcpserverhost 0.0.0.0.
- Prefer adding-mcpservertoken <token>unless the network is already trusted.
- Configure the client URL ashttp://<host-ip>:6510/mcp.
- If a token is configured, configure the client to sendAuthorization: Bearer <token>.
- For browser-based clients, also configure one exact-mcpservercorsorigin <origin>and a token. CORS without a token is rejected.

This is a fork of theVICE SVN mirror. The MCP server is implemented as a self-contained subsystem insrc/mcp/— it touches VICE internals through well-defined interfaces but doesn't modify core emulation logic.

Themainbranch tracks upstream VICE. Themcp-serverbranch contains all MCP additions.

The goal is to contribute this work back to the VICE project. The implementation is structured to export cleanly as unified diffs for SVN submission.

Check if VICE is responding. No parameters.

Run until address or for N cycles with timeout.

Get all CPU registers (A, X, Y, SP, PC, status flags). No parameters.

Read a memory range with optional bank selection.

List available memory banks for the current machine. No parameters.

Search for byte patterns with optional wildcard mask.

Fill a memory range with a repeating byte pattern.

Compare two memory ranges or compare against a snapshot.

Add a checkpoint (breakpoint, watchpoint, or tracepoint).

Set a condition expression on a checkpoint.

Set how many hits to ignore before stopping.

Enable or disable all checkpoints in a group.

List all checkpoint groups. No parameters.

Auto-save a snapshot when a checkpoint is hit.

Visual ASCII art representation of a sprite's bitmap.

Get VIC-II internal state. No parameters.

Get SID state (voices, filter, ADSR). No parameters.

List directory contents of an attached disk.

Get machine configuration — chips, memory map, resources. No parameters.

Type text with automatic PETSCII conversion.

Press/release the RESTORE key (triggers NMI).

Direct keyboard matrix control for games.

Disassemble memory to 6502 instructions.

Show call stack from JSR return addresses.

List all snapshots with metadata. No parameters.

This is active, working software. The MCP server compiles and runs on Linux, macOS, and Windows. All 64 tools are implemented and tested. CI produces binaries for all three platforms on every push.

- Full tool suite — execution, memory, breakpoints, sprites, chip state, disk, input, debugging
- Machine-aware responses across all VICE-emulated platforms
- Python client with retry logic and full test coverage
- Cross-platform builds: Linux x86_64 (GUI + headless), macOS arm64 (GUI + headless), Windows x86_64 (headless)
- Automated CI/CD pipeline with binary releases

- Event streaming.GET /eventsis reserved but returns501 Not Implementedtoday.
- Execution tracing and interrupt logging hooks into VICE CPU core

"Cross over, children. All are welcome. All welcome."*— Tangina Barrons, speaking to contributors about this repo

No reviews yet — be the first

Sign in to leave a review

Use Google, GitHub, or an email account so ratings stay tied to real people.

Email sign in

No reviews posted yet.