A comprehensive MCP server for the Commodore 64 Ultimate with 45+ tools for device control, file management, and machine operations
This C# MCP server for Commodore 64 emulation (C64 Ultimate) has mixed quality. While it offers 25 tools across code generation, machine control, memory access, and prompts, definition quality is hampered by: (1) inconsistent naming conventions mixing verb_noun (ultimate_generate_*) with vague patterns (ultimate_get_*, ultimate_set_*); (2) tool descriptions ranging from adequate to extremely terse (e.g., ultimate_get_version: 'GET /v1/version - Get API version' is 32 chars, below the 34-char p10 baseline); (3) visible input schemas for compilation/memory tools (AssemblyPrgGenerator, ultimate_write_memory_binary) but missing or inferred schemas for 14 prompt-based tools; (4) no documented output schemas for any tool; (5) weak error handling guidance, most tools lack recovery hints. The assembly compiler (ultimate_generate_assembly_prg, ultimate_generate_basic_prg) shows strong internal validation, but the MCP tool wrappers don't expose error details. Prompt tools (assembly_program, sid_music, etc.) lack input schemas entirely, their existence is inferred from description text in C64UltimatePrompts.cs, violating the 'must see explicit registration' rule.
Prepare MCP-compatible 6510 source and compile it with ultimate_generate_assembly_prg.
Author 6502/6510 assembly routines with precise hardware guidance.
Plan, implement, and verify Commodore BASIC v2 programs safely.
Get a specific C64 resource by category and slug
Get the index of all available C64 resources
Create VIC-II graphics demos with safe setup and validation.
Inspect or patch memory ranges with reversible steps.
Send formatted output to Commodore or Epson printers.
14 of 25 tools are prompt templates (basic_program, assembly_program, sid_music, graphics_demo, printer_job, memory_debug, etc.) with missing or undocumented input schemas. These are inferred from description text in C64UltimatePrompts.cs, not explicitly registered with schemas.
Tool descriptions are too terse (32-68 chars for tools 3-8, 12-13), below the 34-char p10 baseline and well below ideal 50-200 char range. Tools like ultimate_get_version ('GET /v1/version - Get API version', 32 chars) are HTTP endpoint documentation, not LLM-optimized descriptions. They don't explain WHEN to use the tool or what problem it solves.
Inferred effective spec: 2026-07-28+.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | F | 48 | 2026-07-28+ | v2 |
| 2026-03-09 | F | 34 | - | v1 |
Compose SID music with iterative verification.
Compiles textual 6510 assembly source into C64 PRG bytes. Supports a compact, MCP-friendly syntax: .org / *=, labels, 6502/6510 mnemonics, .byte, .word, basic expressions (+/-). Wraps with optional BASIC SYS loader.
Generates Commodore 64 BASIC PRG files from BASIC source code. Uses RetroC64 SDK C64AppBasic for standard BASIC V2 tokenization.
GET /v1/machine:debugreg - Read debug register $D7FF (U64 only)
GET /v1/version - Get API version
List files in a directory on the Ultimate device
Load and execute a PRG file on the C64
PUT /v1/machine:pause - Pause CPU by pulling DMA line low
PUT /v1/runners:sidplay - Play SID file from filesystem
PUT /v1/machine:poweroff - Power off (U64 only, may not return response)
GET /v1/machine:readmem - Read from C64 memory via DMA
PUT /v1/machine:reboot - Full reboot (reinitialize cartridge)
PUT /v1/machine:reset - Soft reset (configuration preserved)
PUT /v1/machine:resume - Resume CPU from paused state
PUT /v1/machine:debugreg - Write debug register $D7FF (U64 only)
PUT /v1/machine:writemem - Write to C64 memory via DMA (query string method, max 128 bytes)
POST /v1/machine:writemem - Write to C64 memory via DMA (binary method, supports >128 bytes)
No output schemas documented for ANY tool. LLMs cannot plan downstream tool calls or extract required fields (e.g., file paths from list_files, memory contents from read_memory) without knowing return structure. Pattern:response-shaper requires documented output.
ultimate_poweroff_machine is IRREVERSIBLE (powers off U64) but has no confirmation pattern or dry-run mode. Per pattern:confirmation-request, agents should confirm destructive operations. A single accidental call permanently disables the device.
Memory read/write tools (ultimate_read_memory, ultimate_write_memory, ultimate_write_memory_binary) lack validation guidance. No description of valid address ranges, alignment requirements, protected memory regions, or byte order. LLMs may pass invalid addresses causing crashes or incorrect behavior.
ultimate_reset_machine and ultimate_reboot_machine have nearly identical names ('reset' vs 'reboot') but different semantics ('configuration preserved' vs 'reinitialize cartridge'). Per naming rule, similar names conflate tool selection, LLMs will confuse them. Should be e.g. 'soft_reset_machine' and 'hard_reboot_machine'.
Prompt tools (basic_program, assembly_program, sid_music, graphics_demo, printer_job, memory_debug) use noun naming instead of verb_noun (e.g., 'basic_program' vs 'plan_basic_program' or 'author_basic_program'). Per naming rule, LLMs infer action from name, nouns don't signal what the tool does.
ultimate_write_memory has a hard 128-byte limit noted in description but no formal JSON Schema constraint (maxLength, pattern). Agents may not respect the limit without explicit schema validation.
Error handling lacks recovery guidance. Tools like ultimate_load_prg, ultimate_play_sid, and ultimate_generate_assembly_prg have no error descriptions (e.g., 'File not found. Check path with ultimate_list_files.' or 'Syntax error at line X: expected label'). Per pattern:recovery-guide, errors must guide next steps.
c64_get_resource_index and c64_get_resource don't document pagination or result limits. If index returns 1000+ resources, agents waste context. Per pattern:paginated-result, large result sets must support limit and cursor/offset.