pet-tools-mcp
The pet-tools-mcp server provides a comprehensive toolkit for developing, testing, and debugging Commodore PET software using the VICE emulator, controllable by AI agents.
Session Management: Start, stop, reset, and list emulated PET sessions with specific models (e.g., pet2001-4k, pet4032, pet8032), and boot with attached disk images.
Program Execution: Assemble 6502 source (ca65 syntax) or tokenize BASIC programs, then load and run them on the emulator. Type BASIC commands directly via keyboard simulation.
Screen & Output: Read the screen as plain text (preferred) or capture a PNG screenshot for pixel-level inspection.
Memory & CPU: Read/write memory by address or symbolic label, search memory for byte patterns, and read/set CPU registers (PC, A, X, Y, etc.).
Debugging: Set/list/remove breakpoints and watchpoints (with conditions, hit counts, and temporary flags), single-step instructions (with step-over), run until a specific address or subroutine return, continue after a halt, and block until a breakpoint fires, text appears on screen, or a memory value matches.
Disk Operations: Create blank d64/d80/d82 disk images, list directories, copy files to/from images, and attach/boot disk images mid-session.
ROM Analysis: Identify loaded ROM sets (names + hashes) and disassemble live memory with symbolic annotations.
Packaging & Testing: Package programs into distributable .prg or disk image files, run declarative YAML tests against a fresh PET session, and batch-test example programs as regression tests.
Every command supports --json output and works seamlessly via MCP or CLI.
Provides tools for controlling the VICE Commodore PET emulator, including running BASIC and assembly programs, reading screen content, manipulating memory, setting breakpoints, debugging, and managing disk images, enabling AI agents to code and debug software for the Commodore PET.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@pet-tools-mcp read the current screen contents"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
PET Project
PET Project is a set of tools, skills, and an MCP to enable agentic Commodore PET coding and debugging using the VICE emulator.
The Python package is imported as
petlib, installed aspet-tools, and driven by thepetcommand-line tool.
Install
Requires Python 3.11+, VICE 3.5+ (provides xpet and petcat), and
the cc65 suite (ca65/ld65, for assembling 6502 programs).
pet-tools is not on PyPI, so it installs from a checkout. Every
pip install -e . below runs from that directory:
git clone https://github.com/nschneir/PET-Project.git
cd PET-ProjectmacOS (Homebrew)
brew install vice cc65
pip install -e .Homebrew's VICE bundles the Commodore ROM images, so that is the whole setup.
If pip answers error: externally-managed-environment, Homebrew's Python is
marked externally managed (PEP 668) like Debian's — use the venv route from
step 4 below.
Debian / Ubuntu
Three things differ from macOS: the package lives outside main, the packaged
VICE ships no ROMs, and the system Python refuses pip install. Step 1 is
Debian-only.
1. Debian only — enable the contrib component. vice lives there, and
stock installs leave contrib off, so apt reports "Unable to locate package
vice". Ubuntu carries vice in multiverse, on by default — skip to step 2.
Where your sources live depends on how the machine was installed, not on its version: an in-place upgrade to Debian 13 keeps the older one-line format, while a fresh 13 install uses deb822. Edit whichever file you have:
/etc/apt/sources.list.d/debian.sources(deb822, written by the Debian 13 installer) — addcontribto theComponents:line./etc/apt/sources.list(onedebline per repo; Debian 12 and older, and machines upgraded in place) — addcontribto the end of eachdebline, or letsudo add-apt-repository contrib(fromsoftware-properties-common) make the edit for you.
2. Install VICE and cc65.
sudo apt update
sudo apt install vice cc653. Install the ROMs. This step has no macOS equivalent. Debian strips the
Commodore ROM images out of the package — which is why it sits in contrib
— and Ubuntu rebuilds from the same source. Without them, xpet exits
immediately with Couldn't load ROM and no PET ever boots.
Download and unpack the upstream VICE tarball. Nothing in it is needed
afterwards, so unpack it in /tmp rather than in the repo:
curl -L -o /tmp/vice.tar.gz https://sourceforge.net/projects/vice-emu/files/releases/vice-3.9.tar.gz/download
tar xf /tmp/vice.tar.gz -C /tmpCopy both ROM directories into place, then delete the download:
mkdir -p ~/.local/share/vice
cp -r /tmp/vice-3.9/data/PET /tmp/vice-3.9/data/DRIVES ~/.local/share/vice/
rm -rf /tmp/vice.tar.gz /tmp/vice-3.9Copy both: PET holds the machine ROMs (BASIC, kernal, editor, character
generator) and DRIVES holds the drive DOS ROMs the emulated 2031/4040/8050
units need — skipping it breaks every pet disk command and --disk boot.
~/.local/share/vice is used because it is the one search location needing no
root; VICE also checks /usr/share/vice and a PET/DRIVES pair beside the
xpet binary. Run xpet and look for its VICE system file search path: …
line to see what your build searches (xpet -directory <path> overrides it).
4. Install pet-tools in a virtualenv. Debian 12+ and Ubuntu 23.04+ mark the system Python as externally managed (PEP 668), so installing into it is refused:
sudo apt install python3-venv
python3 -m venv .venv
.venv/bin/pip install -e .
. .venv/bin/activate # puts `pet` and `pet-tools-mcp` on PATHActivate before use: the MCP configs in
docs/agent-setup.md expect pet-tools-mcp to resolve
from PATH. (pipx install -e . is a fine alternative.)
Mind the Python floor. Ubuntu 22.04 LTS ships Python 3.10, under this
project's 3.11 requirement, and a venv built from it is refused too — install a
newer interpreter and its matching -venv package (apt install python3.11 python3.11-venv where available, otherwise deadsnakes or pyenv), then build
the venv with that. Debian 12 (3.11), Debian 13 (3.13), and Ubuntu 24.04 (3.12)
are fine as they ship.
Related MCP server: C64 Debug MCP
Quickstart
Once the Install steps above are done (on Debian/Ubuntu, from the activated venv):
pet session start --model pet4032 # boot an emulated PET 4032
pet run tests/programs/hello-basic/program.bas # tokenize + load + RUN
pet run tests/programs/hello-asm/program.s # assemble + load + RUN (needs cc65)
pet screen # read the screen as text
pet basic type prog.bas --run # type a program via the keyboard
pet mem read '$8000' 64 # hex dump of screen RAM
pet break add start # symbolic breakpoint (uses .lbl symbols)
pet wait --break # block until it fires
pet step 5 && pet reg # single-step, inspect (PC annotated)
pet continue # resume
pet disk create work.d64 && pet disk put work.d64 game.prg game
pet session start --disk work.d64 # boot with the disk attached
pet disk boot work.d64 # or attach+run mid-session
pet rom info # identify the loaded ROM set
pet rom disasm CHROUT 16 # annotated live disassembly
pet session stop
pet test run mytest.yaml # declarative YAML test (format in docs/cli.md)
pet test programs # run every example program as a testEvery command takes --json for machine-readable output — the intended
interface for AI agents.
Supported machines
Every session boots a specific PET (--model, default pet4032). Pick by
what you want to target — and tell your AI agent things like "make it fit
on a 4K PET" or "use the pet8032's 80-column screen":
Model | RAM | Free at boot | BASIC | Screen | Notes |
| 4 KB | 3071 bytes | 1.0 | 40×25 | The entry-level 1977 config (PET 2001-4) — the tightest target. |
| 8 KB | 7167 bytes | 1.0 | 40×25 | The 8 KB original (2001-8). Different zero page (jiffy clock at $0200), no disk commands in BASIC. |
| 32 KB | 31743 bytes | 2.0 | 40×25 | The BASIC most 6502 books target. |
| 32 KB | 31743 bytes | 4.0 | 40×25 | The default. Disk commands in BASIC ( |
| 32 KB | 31743 bytes | 4.0 | 80×25 | The 80-column business machine. Screen math changes: a row is 80 bytes. |
| 128 KB | 31743 bytes | 4.0 | 80×25 | Banked RAM — BASIC still sees 32 KB; the rest needs bank switching. |
The screen is memory-mapped at $8000 on every model; "free at boot" is
what BASIC reports, and is the budget a BASIC program (or a SYS-stub
assembly program) actually has to fit in.
Using with AI coding agents
This toolset is built to be driven by an AI agent. Debugging state persists across commands: when the agent halts the machine at a breakpoint, it stays halted while the agent inspects memory, registers, and screen in separate tool calls. There are two ways an agent can use it — pick either or both:
The CLI — every
petcommand takes--json. Works with any agent that can run shell commands; nothing to configure.The MCP server —
pet-tools-mcpexposes the same operations as MCP tools over stdio. CLI and MCP share the same sessions, so they are interchangeable.
See docs/agent-setup.md for the two integration routes and step-by-step setup for Claude Code, OpenAI Codex, Cursor, Gemini CLI, and Google Antigravity — all instructions work on macOS and Linux (see Install for the extra Debian/Ubuntu steps).
Demos — try it with your AI agent
demos/ is a set of ready-to-paste prompts, graded from a first
BASIC program through a machine-level debug hunt and a full arcade Snake in
6502 assembly (title screen, levels, high score) up to the flagships: an
arcade-faithful Invaders with sound, waves, and a packaged disk image, and
Ms. Muncher — a four-maze arcade chase with cutscenes and a self-playing
demo mode (demos/muncher/). To use one:
Set up your agent — or use any shell agent, which needs no setup at all.
Open a demo file and copy its prompt.
Paste it into your agent and watch it write, run, and debug real PET software on the emulated machine.
Play in the browser
The two flagship demos are playable right now — no install — at
nschneir.github.io/PET-Project/play.html.
The page boots an emulated PET (ROM 4.0, 40 columns) in your browser and runs
the same .prg files checked into this repo.
The reference example programs (with expected screen output, runnable as
regression tests via pet test programs) live in
tests/programs/.
Sharing what you built
pet package turns a source file into something any VICE user can run — no
pet-tools needed on their end:
pet package snake.s -o snake.d64 --title SNAKEThat assembles the program and writes it as the first file on a fresh disk image, so it autostarts. The recipient just needs VICE installed:
xpet -model 4032 snake.d64 # boots the tested PET model, runs SNAKE(pet package prints this exact command; the -model flag matters because
stock xpet boots its own default model, and ROM behavior differs between
BASIC generations — a game reading held keys from $97 goes silently deaf on
the wrong one.) The bare .prg (also produced) works too, as does VICE's
File → Smart attach. Disk images travel better: they carry a real CBM
directory, so LOAD"SNAKE",8 then RUN works the old-fashioned way.
Neither artifact contains ROMs or anything from this toolset.
Status
Stable — current release v1.4.0. Full history: CHANGELOG.md.
Related projects
PET Project is one of three Commodore toolsets built the same way — AI-written, human-directed, and pointed at real hardware behavior rather than an approximation of it.
Project64 — tools, skills, and an MCP for agentic Commodore 64 coding and debugging through the VICE emulator, driven by a
c64command-line tool. PET Project's sibling: same shape, different machine.image64 — a native macOS app and command-line tool that converts modern images into pictures the C64 can actually display. Project64's upstream neighbor: it exports the native C64 formats plus a runnable program, so an export goes straight to
c64 run picture.prg.
AI Disclosure
PET Project is developed primarily by AI — Anthropic's Claude, working through Claude Code — under human direction: a human sets the goals, reviews the designs and plans, and approves the work; the AI writes the specs, plans, code, tests, and documentation. Every change is verified by the automated test suite, including integration tests that run against a real VICE emulator, before it lands. The project also exists for AI use — these tools are built so AI agents can write and debug Commodore PET software — making it a working example of AI-built developer tooling.
License
MIT license. Note that VICE is a separate GPLv2+ program invoked as a subprocess; it is not bundled and must be installed separately.
ROM tooling reads ROM bytes from your running emulator and ships only original label annotations — no Commodore-copyrighted code lives in this repo.
Available Tools
44 toolspet_basic_typeA
Type BASIC program text into the running PET via the keyboard (keywords may be upper or lower case; each line ends with \n). Set run=true to type RUN afterwards.
Inputs: text (required), run, session.
pet_break_addA
Set a breakpoint at an address or symbol. Machine keeps running; use pet_wait_break to block until it fires.
Inputs: ref (required), session, condition, temporary.
pet_break_clearA
Remove ALL breakpoints (exec checkpoints); watchpoints are kept. Checkpoints persist across pet_run/rebuilds — clear stale ones or duplicates accumulate.
Inputs: session.
pet_break_listB
List breakpoints/watchpoints with hit counts.
Inputs: session.
pet_break_removeC
Remove a breakpoint/watchpoint by id.
Inputs: checkpoint_id (required), session.
pet_buildB
Assemble 6502 source (ca65 syntax) to a .prg + VICE label file.
Inputs: source (required), model.
pet_callA
JSR one routine in isolation (fake return address on the stack, optional A/X/Y on entry) and stop at its RTS — the unit-test primitive: poke inputs, call, then assert registers/memory. Machine ends STOPPED on success, RUNNING on timeout.
Inputs: routine (required), a, x, y, +2 more.
pet_continueA
Resume execution after a breakpoint/step.
Inputs: session.
pet_disk_bootB
Attach a disk image to the running PET and LOAD+RUN its first file.
Inputs: image (required), session.
pet_disk_createC
Create a blank d64/d80/d82 disk image.
Inputs: image (required), label, disk_id.
pet_disk_getC
Copy a file off a disk image to the host.
Inputs: dest (required), name (required), image (required).
pet_disk_lsC
List the directory of a disk image.
Inputs: image (required).
pet_disk_putC
Copy a host file onto a disk image.
Inputs: file (required), image (required), name.
pet_finishC
Run until the current subroutine returns. Machine stays stopped.
Inputs: session.
pet_key_holdA
Hold KEY down for N game ticks by re-poking $97 before each one,
running to the frame anchor at (label or address executed once per
tick) between pokes; the machine ends STOPPED there. KEY is one
character or 'space'. BASIC 4 models only ($97 holds a matrix index
on BASIC 2).
Inputs: at (required), key (required), frames, session, +1 more.
pet_key_typeA
Type text into the running PET's keyboard buffer (\n = RETURN). Buffered keys never touch the live key-down state — games reading $97 need pet_key_hold.
Inputs: text (required), session.
pet_loadA
Load a .prg via autostart (optionally without RUN); optionally register a VICE label file for symbolic debugging.
Inputs: prg (required), run, session, symbols.
pet_mem_findB
Search memory for a byte pattern (values: one or more $hex/decimal
bytes). Returns match addresses; "truncated" is true when limit
clipped the list. Does not disturb run/stop state.
Inputs: values (required), limit, start, length, +1 more.
pet_mem_readA
Read emulated memory. addr accepts $hex, 0xhex, decimal, or a symbol from the loaded label file. Returns hex-encoded bytes plus "bytes" as a decimal int array.
Inputs: addr (required), length, session.
pet_mem_writeB
Write bytes to emulated memory. addr accepts $hex/0xhex/decimal/symbol.
Inputs: addr (required), values (required), session.
pet_packageA
Package a .s/.bas/.prg into an artifact any VICE user can run: a .prg,
or (when output ends in .d64/.d80/.d82) a disk image whose first file is
the program so xpet out.d64 autostarts it. Returns the exact run
command in "run".
Inputs: source (required), model, title, output.
pet_reg_getB
Read CPU registers. PC is annotated with the nearest symbol when a label file is loaded.
Inputs: session.
pet_reg_setC
Set a CPU register (e.g. PC, A, X, Y). value accepts $hex/0xhex/decimal.
Inputs: name (required), value (required), session.
pet_rom_disasmB
Disassemble live memory with ROM + session symbol annotations. start accepts $hex/0xhex/decimal or a symbol (e.g. CHROUT).
Inputs: start (required), length, session.
pet_rom_infoC
Identify the loaded ROM set (names + content hashes).
Inputs: session.
pet_runA
Build/tokenize a .bas/.s/.prg as needed, then load and RUN it on the running PET. Registers assembly symbols on the session automatically.
Inputs: source (required), session.
pet_screen_codesA
Read the raw screen-code matrix (rows x cols of ints) — exact values for checking glyphs without decoding ambiguity.
Inputs: session.
pet_screenshotA
Save a PNG screenshot. Prefer pet_screen_text for reading output; use this only when pixel-level appearance matters. scale gives an integer nearest-neighbour upscale (small PET screens read better at 2-3x).
Inputs: path (required), scale, session.
pet_screen_textA
Read the PET screen as plain text. This is the PREFERRED way to see program output — faster and more reliable than screenshots for AI use. Graphics decode to Unicode glyphs; style="ascii" restores the legacy conservative mapping.
Inputs: style, session, ansi_reverse.
pet_session_ensureA
Attach to a running PET session, or boot one (headless, warp) if none exists. Idempotent; "started" reports which happened.
Inputs: name, model.
pet_session_listA
List running emulated PET sessions (name, model, pid, monitor port).
Inputs: no named parameters.
pet_session_resetC
Reset the PET (soft, or hard power-cycle). Leaves the machine running.
Inputs: hard, session.
pet_session_startA
Boot a fresh emulated PET (headless, warp). Models: pet2001-4k, pet2001, pet3032, pet4032, pet8032, pet8296. Optionally attach a d64/d80/d82 disk image.
Inputs: disk, name, model.
pet_session_stopC
Stop a running PET session (the only one if name is omitted).
Inputs: name.
pet_statusB
The session and whether the machine is running or stopped right now. state is answered by the session daemon's own tracking (no emulator traffic); "unknown" without a daemon. Also reports the loaded program and any source files changed since it was loaded (stale binary!).
Inputs: session.
pet_stepA
Execute N instructions. The machine STAYS STOPPED afterwards; use pet_continue to resume.
Inputs: over, count, session.
pet_test_programsA
Run every example-program directory (program + expect.txt) as a test.
Inputs: directory.
pet_test_runC
Run a declarative YAML test (boots its own fresh PET; see spec §8).
Inputs: yaml_file (required).
pet_untilB
Run until an address/symbol is executed count times; machine stays stopped there. count>1 = deterministic frame stepping on a loop label. On timeout: raises with the machine LEFT RUNNING and the checkpoint removed.
Inputs: ref (required), count, session, timeout.
pet_wait_breakA
Block until a breakpoint/watchpoint fires; reports checkpoint id, PC, and registers. Machine is left stopped when it fires. On timeout the machine is LEFT RUNNING (your checkpoints remain set) and the result is {"fired": null, "machine": "running", ...} — data, not an error.
Inputs: session, timeout, checkpoint_id.
pet_wait_memB
Block until the byte at addr equals the value ($hex/decimal accepted).
Inputs: addr (required), equals (required), session, timeout.
pet_wait_textA
Block until TEXT appears on the screen. A timeout returns {"fired": null, "screen": ...} (not an error) so you can inspect what the program actually displayed.
Inputs: text (required), session, timeout.
pet_watch_addC
Set a watchpoint on a memory range (default: both load and store).
Inputs: ref (required), length, on_load, session, +1 more.
pet_watch_clearA
Remove ALL watchpoints (load/store checkpoints); breakpoints are kept.
Inputs: session.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 44 tools
Each tool has a clear, distinct purpose with detailed descriptions. Tools like pet_session_start and pet_session_ensure are differentiated by idempotency, and pet_key_type vs pet_key_hold are clearly separate. There is no ambiguity or overlap.
All tools follow a consistent pattern: 'pet_' + domain + verb_noun (e.g., pet_break_add, pet_mem_read, pet_disk_ls). The naming is uniform and predictable across all 44 tools.
44 tools is on the high side, but the domain of PET emulation and debugging is complex, justifying many specific operations. However, it exceeds the 25+ threshold indicated in calibration, making it borderline.
The tool surface covers the full lifecycle: session management, memory/register access, break/watchpoints, stepping, waiting, disk operations, ROM analysis, and testing. Only a minor gap (no watchpoint list) is present, but overall very comprehensive.
Maintenance
Related MCP Connectors
Persistent memory, knowledge graph, task management and more for AI agents via MCP.
Shared memory MCP server for Claude Code, Codex, Gemini CLI and Cursor. Cited, editable.
Persistent memory and cross-session learning for AI coding assistants (hosted remote MCP).
Self-hosted AI workspace: semantic RAG document search, long-term memory, and AI chat via MCP.
Related MCP Servers
- AlicenseAqualityDmaintenanceEnables autonomous debugging of Commodore 64 programs through the VICE emulator with semantic interpretation of C64-specific data structures, memory layouts, VIC-II states, and PETSCII encoding for AI-assisted 6502 assembly debugging.261MIT
- AlicenseAqualityDmaintenanceEnables AI-powered control and debugging of Commodore 64 programs via the VICE emulator, supporting memory operations, breakpoints, register access, and program loading.188 npmMIT
- AlicenseNot gradedqualityBmaintenanceLets 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.342 npm41GPL 2.0
- FlicenseNot gradedqualityBmaintenanceEnables AI agents to control an MSX emulator for debugging and reverse-engineering, including memory and code inspection, execution control, and saving annotations via MCP.-