Skip to main content
Glama
VICE C64 Emulator MCP Server

VICE C64 Emulator MCP Server

by simen

vice-mcp

A Model Context Protocol (MCP) server for autonomous C64 debugging via the VICE emulator.

What is this?

vice-mcp bridges AI agents to the VICE Commodore 64 emulator, enabling autonomous debugging of 6502 assembly programs. Unlike raw protocol wrappers, it provides a semantic layer that interprets C64-specific data structures and returns meaningful, actionable information.

Why this exists:

  • AI agents need more than hex dumps—they need interpreted data with context

  • Debugging C64 code requires understanding VIC-II banks, PETSCII encoding, sprite pointers, and memory layouts

  • Every response includes hints suggesting next steps and related tools

Key differentiators:

  • Semantic output: readScreen returns text, not screen codes. readVicState explains graphics modes, not register bits.

  • Actionable hints: Every response suggests what to do next

  • Cross-references: Tools point to related tools for common workflows

  • Agent-friendly errors: Clear error codes and recovery suggestions

Related MCP server: pet-tools-mcp

Prerequisites

  • Node.js 18 or later

  • VICE emulator with binary monitor enabled

Starting VICE with Binary Monitor

# x64sc is the accurate C64 emulator (recommended)
x64sc -binarymonitor -binarymonitoraddress ip4://127.0.0.1:6502

# Or with x64 (faster, less accurate)
x64 -binarymonitor -binarymonitoraddress ip4://127.0.0.1:6502

The binary monitor listens on port 6502 by default.

Installation

From npm (when published)

npx @simen/vice-mcp

From GitHub

npx github:simen/vice-mcp

Local Development

git clone https://github.com/simen/vice-mcp.git
cd vice-mcp
npm install
npm run build
npm start

Claude Code Installation

The quickest way to get started with Claude Code:

1. Start VICE with binary monitor:

x64sc -binarymonitor -binarymonitoraddress ip4://127.0.0.1:6502

2. Add the MCP server:

claude mcp add vice-mcp -- npx github:simen/vice-mcp

3. Restart Claude Code to load the new MCP server.

That's it! You can now ask Claude Code to debug your C64 programs.

Manual Configuration

Alternatively, add to ~/.claude/claude_desktop_config.json:

{
  "mcpServers": {
    "vice-mcp": {
      "command": "npx",
      "args": ["github:simen/vice-mcp"]
    }
  }
}

Configuration

Add to your MCP client configuration (e.g., Claude Desktop, Cursor, or custom agent):

{
  "mcpServers": {
    "vice": {
      "command": "npx",
      "args": ["@simen/vice-mcp"]
    }
  }
}

Or for local development:

{
  "mcpServers": {
    "vice": {
      "command": "node",
      "args": ["/path/to/vice-mcp/dist/index.js"]
    }
  }
}

Tool Reference

Connection & Status

Tool

Description

connect

Connect to VICE (default: 127.0.0.1:6502)

disconnect

Disconnect from VICE

status

Get connection state and emulation status

Memory Operations

Tool

Description

readMemory

Read raw bytes with hex dump and ASCII

writeMemory

Write bytes to memory

CPU & Execution

Tool

Description

getRegisters

Get A, X, Y, SP, PC, and flags (interpreted)

step

Single-step execution (with step-over option)

continue

Resume execution

reset

Soft or hard reset

runTo

Run until specific address (temporary breakpoint)

disassemble

Disassemble 6502 code with KERNAL labels

Breakpoints & Watchpoints

Tool

Description

setBreakpoint

Set execution breakpoint

deleteBreakpoint

Remove breakpoint or watchpoint

listBreakpoints

List all breakpoints

toggleBreakpoint

Enable/disable breakpoint

setWatchpoint

Set memory read/write watchpoint

listWatchpoints

List all watchpoints

Semantic Layer (Interpreted C64 Data)

Tool

Description

readScreen

Get screen as text (PETSCII decoded) with summary mode

readColorRam

Get color RAM with color names and usage stats

readVicState

Full VIC-II state: graphics mode, colors, banks, sprites

readSprites

All 8 sprites: position, visibility, colors, pointers

Visual Feedback

Tool

Description

screenshot

Capture display buffer with palette

renderScreen

ASCII art rendering of display

State Management

Tool

Description

saveSnapshot

Save complete machine state to file

loadSnapshot

Load machine state from file

loadProgram

Load and optionally run PRG/D64/T64 files

Example Usage

Basic Debugging Session

1. connect()                    → Establish connection
2. loadProgram("game.prg")      → Load the program
3. setBreakpoint(0x0810)        → Break at main loop
4. continue()                   → Run until breakpoint
5. getRegisters()               → Check CPU state
6. readScreen()                 → See what's on screen
7. step(count: 5)               → Execute 5 instructions
8. disassemble()                → See code at current PC

Debugging Sprite Issues

1. readVicState()               → Check sprite enable bits
2. readSprites(enabledOnly: true) → Get enabled sprite details
   → Response includes visibility check and position analysis
3. If sprite not visible, hint tells you why (off-screen, wrong bank, etc.)

Memory Watchpoint Workflow

1. setWatchpoint(startAddress: 0x0400, type: "store")
   → Watch for writes to screen RAM
2. continue()
   → Execution stops when something writes to screen
3. getRegisters()
   → See PC to find the code that wrote
4. disassemble()
   → Understand what the code is doing

State Checkpoint Pattern

1. saveSnapshot("before-test.vsf")  → Save state
2. [Make changes, test things]
3. loadSnapshot("before-test.vsf")  → Restore to known state

Response Format

All responses include:

  • Structured data with value and hex representations

  • _meta block with connection state

  • hint field with contextual next steps

Example getRegisters response:

{
  "a": { "value": 65, "hex": "$41" },
  "x": { "value": 0, "hex": "$00" },
  "y": { "value": 0, "hex": "$00" },
  "sp": { "value": 243, "hex": "$f3", "stackTop": "$01f3" },
  "pc": { "value": 2049, "hex": "$0801" },
  "flags": {
    "negative": false,
    "overflow": false,
    "zero": false,
    "carry": false,
    "string": "nv-bdizc"
  },
  "hint": "CPU state looks normal",
  "_meta": {
    "connected": true,
    "running": false,
    "host": "127.0.0.1",
    "port": 6502
  }
}

Architecture Overview

┌─────────────────────────────────────────────────────────┐
│                    MCP Client (Agent)                    │
└─────────────────────────────────────────────────────────┘
                            │
                            │ MCP Protocol (stdio)
                            ▼
┌─────────────────────────────────────────────────────────┐
│                     src/index.ts                         │
│                    (MCP Server)                          │
│  ┌─────────────────────────────────────────────────┐    │
│  │              Tool Handlers (24 tools)            │    │
│  │  • Connection: connect, disconnect, status       │    │
│  │  • Memory: readMemory, writeMemory              │    │
│  │  • CPU: getRegisters, step, continue, reset     │    │
│  │  • Breakpoints: set, delete, list, toggle       │    │
│  │  • Watchpoints: set, list                       │    │
│  │  • Semantic: readScreen, readVicState, etc.     │    │
│  │  • Visual: screenshot, renderScreen            │    │
│  │  • State: saveSnapshot, loadSnapshot, loadPrg   │    │
│  └─────────────────────────────────────────────────┘    │
└─────────────────────────────────────────────────────────┘
                            │
                            │ Uses
                            ▼
┌─────────────────────────────────────────────────────────┐
│                 src/protocol/client.ts                   │
│                    (ViceClient)                          │
│  • TCP socket connection to VICE                        │
│  • Binary protocol encoding/decoding                    │
│  • Request/response correlation                         │
│  • Checkpoint (breakpoint/watchpoint) tracking          │
└─────────────────────────────────────────────────────────┘
                            │
                            │ TCP Socket
                            ▼
┌─────────────────────────────────────────────────────────┐
│                 VICE Binary Monitor                      │
│                   (Port 6502)                            │
└─────────────────────────────────────────────────────────┘

Key Files

File

Purpose

src/index.ts

MCP server, tool definitions, semantic layer

src/protocol/client.ts

VICE binary monitor client

src/protocol/types.ts

Protocol constants and types

src/utils/c64.ts

C64 utilities (PETSCII, colors, VIC banks)

src/utils/disasm.ts

6502 disassembler with all addressing modes

Design Principles

  1. Semantic over raw: Return interpreted data, not just bytes

  2. Hints everywhere: Every response suggests next actions

  3. Cross-references: Tools reference related tools

  4. Fail informatively: Errors explain what went wrong and how to fix it

  5. Agent-first: Designed for autonomous operation, not human CLI use

Protocol Reference

vice-mcp implements the VICE Binary Monitor Protocol. Key commands used:

Code

Command

Purpose

0x01

MemoryGet

Read memory

0x02

MemorySet

Write memory

0x12

CheckpointSet

Create breakpoint/watchpoint

0x13

CheckpointDelete

Remove checkpoint

0x15

CheckpointToggle

Enable/disable checkpoint

0x31

RegistersGet

Read CPU registers

0x41

Dump

Save snapshot

0x42

Undump

Load snapshot

0x81

Continue

Resume execution

0x82

Step

Single-step

0x84

DisplayGet

Capture screen

0x91

PaletteGet

Get color palette

0xdd

AutoStart

Load and run program

License

MIT

Available Tools

26 tools
connectA

Connect to a running VICE emulator instance via the binary monitor protocol.

VICE must be started with the binary monitor enabled: x64sc -binarymonitor -binarymonitoraddress ip4://127.0.0.1:6502

Default connection: 127.0.0.1:6502

Use this first before any debugging operations. Connection persists until disconnect() is called or VICE closes.

Related tools: status, disconnect

Inputs: host, port.

continueA

Resume C64 execution after a breakpoint or pause.

Starts the emulator running until the next breakpoint, manual stop, or error.

Related tools: step, status, setBreakpoint

Inputs: no named parameters.

deleteBreakpointA

Delete a breakpoint by its ID.

Use listBreakpoints to see current breakpoint IDs.

Related tools: setBreakpoint, listBreakpoints

Inputs: breakpointId (required).

disassembleA

Disassemble 6502 machine code at a memory address.

Returns human-readable assembly instructions with:

  • Address and raw bytes

  • Mnemonic and operand

  • Branch target addresses (for branch instructions)

  • Known KERNAL/BASIC labels

Options:

  • address: Start address (default: current PC)

  • count: Number of instructions (default: 10)

Related tools: readMemory, getRegisters, step

Inputs: address, count.

disconnectA

Disconnect from the VICE emulator instance.

Cleanly closes the connection. Safe to call even if not connected.

Related tools: connect, status

Inputs: no named parameters.

getRegistersA

Get current 6502/6510 CPU register state.

Returns all CPU registers with interpreted flags.

Registers:

  • A: Accumulator (arithmetic operations)

  • X, Y: Index registers (addressing, loops)

  • SP: Stack pointer ($100-$1FF range)

  • PC: Program counter (current instruction address)

  • Flags: N(egative), V(overflow), B(reak), D(ecimal), I(nterrupt), Z(ero), C(arry)

Use this to:

  • Check CPU state at breakpoints

  • Understand program flow

  • Debug crashes (check PC, SP)

Related tools: setRegister, step, continue, status

Inputs: no named parameters.

listBreakpointsA

List all active breakpoints.

Shows breakpoint IDs, addresses, and status for all breakpoints set in this session.

Note: This tracks breakpoints set through this MCP session. Breakpoints set through VICE's built-in monitor may not appear.

Related tools: setBreakpoint, deleteBreakpoint

Inputs: no named parameters.

listWatchpointsA

List all active memory watchpoints.

Shows watchpoint IDs, address ranges, type (load/store), and status.

Related tools: setWatchpoint, deleteBreakpoint, listBreakpoints

Inputs: no named parameters.

loadProgramB

Load and optionally run a program file.

Supports PRG, D64, T64, and other C64 file formats. For disk images, can specify which file to run.

Options:

  • run: If true (default), starts execution after loading

  • fileIndex: For disk images, which file to load (0 = first)

Related tools: reset, status, setBreakpoint

Inputs: filename (required), run, fileIndex.

loadSnapshotA

Load a previously saved machine state from a file.

Restores complete machine state including memory, registers, and peripheral states.

Warning: This completely replaces the current state!

Related tools: saveSnapshot

Inputs: filename (required).

readColorRamA

Read color RAM ($D800-$DBE7) and return color values with names.

Color RAM determines the foreground color of each character on screen.

Returns:

  • 25x40 grid of color values (0-15) with names

  • Summary of colors used

Related tools: readScreen, readVicState

Inputs: summary.

readMemoryA

Read memory from the C64's address space.

Returns raw bytes plus hex and ASCII representations.

C64 memory map highlights:

  • $0000-$00FF: Zero page (fast access, common variables)

  • $0100-$01FF: Stack

  • $0400-$07FF: Default screen RAM (1000 bytes)

  • $D000-$D3FF: VIC-II registers (graphics)

  • $D400-$D7FF: SID registers (sound)

  • $D800-$DBFF: Color RAM

For screen content, consider using readScreen instead for interpreted output. For sprite info, use readSprites for semantic data.

Related tools: writeMemory, readScreen, readSprites, readVicState

Inputs: address (required), length.

readScreenA

Read the C64 screen memory and return it as interpreted text.

Converts PETSCII screen codes to readable ASCII. Returns 25 lines of 40 characters.

Use this instead of readMemory($0400) when you want to see what's displayed on screen.

Note: This reads from the current screen RAM location (may not be $0400 if the program moved it). In bitmap modes, the data won't represent text.

Options:

  • format: "full" (default) returns all 25 lines, "summary" returns only non-empty lines

  • includeRaw: Also return raw screen codes (default: false)

Related tools: readColorRam, readVicState, readMemory

Inputs: format, includeRaw.

readSpritesA

Read state of all 8 hardware sprites with interpreted values.

Returns for each sprite:

  • Position (X, Y) with visibility check

  • Color (with name)

  • Enable status

  • Multicolor mode

  • X/Y expansion (double size)

  • Priority (in front of / behind background)

  • Data pointer address

Use this to debug sprite issues like:

  • "Why is my sprite invisible?" → check enabled, position, pointer

  • "Wrong colors?" → check multicolor mode and color registers

  • "Wrong size?" → check expand flags

Options:

  • enabledOnly: Only return enabled sprites (default: false)

Related tools: readVicState, readMemory (for sprite data)

Inputs: enabledOnly.

readVicStateA

Read the full VIC-II state with interpreted values.

Returns all VIC-II registers with semantic meaning:

  • Border and background colors (with names)

  • Graphics mode (text, bitmap, multicolor, etc.)

  • Screen and character memory locations

  • Scroll values

  • Raster position

  • Sprite enable bits

This is the high-level view of the video chip. Use for understanding display configuration.

Related tools: readScreen, readSprites, readMemory (for $D000-$D02E)

Inputs: no named parameters.

renderScreenA

Render the current screen as ASCII art representation.

Creates a visual representation of the screen using ASCII characters to approximate the colors and content visible on the C64 display.

This is useful for quick visual debugging without image handling. For actual screen text, use readScreen instead.

Options:

  • width: Output width in characters (default: 80)

  • height: Output height in lines (default: 50)

  • charset: Character set to use for shading (default: " .:-=+*#%@")

Related tools: readScreen, screenshot, readVicState

Inputs: width, height, charset.

resetA

Reset the C64 machine.

Options:

  • hard: If true, performs hard reset (like power cycle). If false, soft reset (like reset button).

A soft reset preserves some memory contents, hard reset clears everything.

Related tools: connect, status

Inputs: hard.

runToA

Run execution until a specific address is reached.

Sets a temporary breakpoint at the target address and continues execution. The breakpoint is automatically deleted when hit.

Use for:

  • "Run until this function" → runTo(functionAddress)

  • "Skip to the end of this loop" → runTo(addressAfterLoop)

Related tools: continue, step, setBreakpoint

Inputs: address (required).

saveSnapshotA

Save the complete machine state to a file.

Creates a VICE snapshot file containing:

  • All memory (RAM, I/O states)

  • CPU registers

  • VIC-II, SID, CIA states

  • Disk drive state (if attached)

Use to:

  • Save state before risky debugging

  • Create restore points

  • Share exact machine state

Related tools: loadSnapshot

Inputs: filename (required).

screenshotA

Capture the current VICE display as image data.

Returns the raw display buffer with:

  • Pixel data (indexed 8-bit palette colors)

  • Display dimensions and visible area

  • Current palette RGB values

The data can be used to understand what's currently on screen visually. For text mode screens, readScreen provides a simpler text representation.

Options:

  • includePalette: Also return the color palette (default: true)

Related tools: readScreen, readVicState

Inputs: includePalette.

setBreakpointA

Set an execution breakpoint at a memory address.

When the PC reaches this address, execution stops. Use to:

  • Debug code at specific points

  • Catch when routines are called

  • Analyze code flow

Returns a breakpoint ID for later management.

Related tools: deleteBreakpoint, listBreakpoints, continue, step

Inputs: address (required), enabled, temporary.

setWatchpointA

Set a memory watchpoint to stop when memory is read or written.

Watchpoints are powerful for debugging:

  • "Why is this value changing?" → Use store watchpoint

  • "What's reading this address?" → Use load watchpoint

  • "Track all access to this region" → Use both

Range can be single address or address range (e.g., $D800-$DBFF for color RAM).

Related tools: deleteBreakpoint, listWatchpoints, continue

Inputs: startAddress (required), type (required), endAddress, enabled, +1 more.

statusA

Get current VICE connection and emulation state.

Returns connection status, whether emulation is running or paused, and host/port if connected.

Use this to:

  • Check if you're connected before running other commands

  • See if emulation is running or stopped (e.g., at a breakpoint)

  • Verify connection details

Related tools: connect, disconnect

Inputs: no named parameters.

stepA

Execute one or more instructions, then stop.

Single-stepping is essential for understanding code flow and debugging.

Options:

  • count: Number of instructions to execute (default: 1)

  • stepOver: If true, treat JSR as single instruction (don't step into subroutines)

After stepping, use getRegisters to see the new CPU state.

Related tools: getRegisters, continue, setBreakpoint, status

Inputs: count, stepOver.

toggleBreakpointA

Enable or disable a breakpoint without deleting it.

Use this to temporarily disable breakpoints while keeping their configuration.

Related tools: setBreakpoint, deleteBreakpoint, listBreakpoints

Inputs: breakpointId (required), enabled (required).

writeMemoryA

Write bytes to the C64's memory.

Directly modifies memory at the specified address. Changes take effect immediately.

Common uses:

  • Poke values for testing

  • Patch code at runtime

  • Modify screen/color RAM directly

  • Change VIC/SID registers

Be careful writing to ROM areas ($A000-$BFFF, $E000-$FFFF) - you may need to bank out ROM first.

Related tools: readMemory, fillMemory

Inputs: address (required), bytes (required).

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.9/5.0

    Scored across 26 tools

    Disambiguation4/5

    Most tools have distinct purposes with clear boundaries, such as connect/disconnect for connection management, readMemory/readScreen for different memory views, and setBreakpoint/setWatchpoint for different debugging triggers. However, some tools like readScreen and renderScreen both provide screen representations, which could cause minor confusion about when to use each, though their descriptions clarify the differences.

    Naming Consistency5/5

    Tool names follow a highly consistent verb_noun pattern throughout, such as connect, disconnect, getRegisters, listBreakpoints, readMemory, and writeMemory. All names use lowercase with clear, descriptive verbs and nouns, making the set predictable and easy to understand.

    Tool Count3/5

    With 26 tools, the count is on the higher side for an emulator debugging server, which may feel heavy but is reasonable given the comprehensive coverage of debugging operations. It includes connection, execution control, memory access, breakpoints, screen rendering, and state management, though some tools could potentially be consolidated (e.g., readScreen and renderScreen).

    Completeness5/5

    The tool set provides complete coverage for C64 emulator debugging, including connection management, execution control (continue, step, runTo), breakpoint and watchpoint handling, memory and register access, screen and sprite inspection, state saving/loading, and reset functionality. There are no obvious gaps; all core debugging workflows are supported with logical tool relationships.

    Maintenance

    ActivityNo data
    ResponsivenessOutdated data

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      A
      quality
      D
      maintenance
      Enables AI-powered control and debugging of Commodore 64 programs via the VICE emulator, supporting memory operations, breakpoints, register access, and program loading.
      18
      8 npm
      MIT
    • A
      license
      B
      quality
      B
      maintenance
      Enables AI agents to code and debug Commodore PET software using the VICE emulator, with CLI and MCP tools for session control, screen reading, memory manipulation, and testing.
      44
      1
      MIT
    • A
      license
      A
      quality
      C
      maintenance
      Enables AI agents to run CP/M, MP/M, and DOS packages on Z80/x86 emulators, inspect byte-exact results and files, and debug the emulators themselves over the Model Context Protocol.
      7
      GPL 3.0
    • A
      license
      Not graded
      quality
      B
      maintenance
      Lets AI clients control and program a Commodore 64, including running programs, reading/writing memory, rendering graphics, playing sound, and switching between C64 Ultimate hardware and VICE emulation.
      220 npm
      41
      GPL 2.0