Skip to main content
Glama
simen

VICE C64 Emulator MCP Server

by simen

setBreakpoint

Set an execution breakpoint at a memory address to debug Commodore 64 programs. When the program counter reaches the address, execution stops for code analysis and debugging.

Instructions

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

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
addressYesAddress to break at (0x0000-0xFFFF)
enabledNoWhether breakpoint is active (default: true)
temporaryNoAuto-delete after hit (default: false)

Implementation Reference

  • src/index.ts:562-604 (registration)
    MCP tool registration for 'setBreakpoint', including schema and handler function
    server.registerTool(
      "setBreakpoint",
      {
        description: `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`,
        inputSchema: z.object({
          address: z.number().min(0).max(0xffff).describe("Address to break at (0x0000-0xFFFF)"),
          enabled: z.boolean().optional().describe("Whether breakpoint is active (default: true)"),
          temporary: z.boolean().optional().describe("Auto-delete after hit (default: false)"),
        }),
      },
      async (args) => {
        try {
          const id = await client.setBreakpoint(args.address, {
            enabled: args.enabled ?? true,
            temporary: args.temporary ?? false,
          });
    
          return formatResponse({
            success: true,
            breakpointId: id,
            address: {
              value: args.address,
              hex: `$${args.address.toString(16).padStart(4, "0")}`,
            },
            enabled: args.enabled ?? true,
            temporary: args.temporary ?? false,
            message: `Breakpoint ${id} set at $${args.address.toString(16).padStart(4, "0")}`,
            hint: "Use continue() to run until breakpoint is hit",
          });
        } catch (error) {
          return formatError(error as ViceError);
        }
      }
    );
  • Handler function for the 'setBreakpoint' MCP tool that validates input, calls ViceClient.setBreakpoint, formats success/error response with metadata
    async (args) => {
      try {
        const id = await client.setBreakpoint(args.address, {
          enabled: args.enabled ?? true,
          temporary: args.temporary ?? false,
        });
    
        return formatResponse({
          success: true,
          breakpointId: id,
          address: {
            value: args.address,
            hex: `$${args.address.toString(16).padStart(4, "0")}`,
          },
          enabled: args.enabled ?? true,
          temporary: args.temporary ?? false,
          message: `Breakpoint ${id} set at $${args.address.toString(16).padStart(4, "0")}`,
          hint: "Use continue() to run until breakpoint is hit",
        });
      } catch (error) {
        return formatError(error as ViceError);
      }
    }
  • Zod input schema defining parameters for setBreakpoint: address (required 0-65535), optional enabled/temporary booleans
    inputSchema: z.object({
      address: z.number().min(0).max(0xffff).describe("Address to break at (0x0000-0xFFFF)"),
      enabled: z.boolean().optional().describe("Whether breakpoint is active (default: true)"),
      temporary: z.boolean().optional().describe("Auto-delete after hit (default: false)"),
    }),
  • ViceClient.setBreakpoint method: validates address, builds VICE binary monitor protocol packet for CheckpointSet (execution breakpoint), sends command, parses ID, tracks locally
    async setBreakpoint(
      address: number,
      options: {
        enabled?: boolean;
        stop?: boolean;
        temporary?: boolean;
      } = {}
    ): Promise<number> {
      const { enabled = true, stop = true, temporary = false } = options;
    
      if (address < 0 || address > 0xffff) {
        throw this.makeError(
          "INVALID_ADDRESS",
          `Address 0x${address.toString(16)} is outside C64 memory range`,
          "C64 addresses are 16-bit (0x0000-0xFFFF)"
        );
      }
    
      // Build request: start(2) + end(2) + stop(1) + enabled(1) + op(1) + temp(1)
      const body = Buffer.alloc(8);
      body.writeUInt16LE(address, 0);
      body.writeUInt16LE(address, 2);
      body[4] = stop ? 1 : 0;
      body[5] = enabled ? 1 : 0;
      body[6] = CheckpointOp.Exec;
      body[7] = temporary ? 1 : 0;
    
      const response = await this.sendCommand(Command.CheckpointSet, body);
      const id = response.body.readUInt32LE(0);
    
      // Track locally
      this.checkpoints.set(id, {
        id,
        startAddress: address,
        endAddress: address,
        enabled,
        temporary,
        type: "exec",
      });
    
      return id;
    }
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It explains the core behavior ('execution stops') and return value ('breakpoint ID for later management'), but lacks details on permissions, error conditions, or side effects. It adds some context but doesn't fully compensate for the absence of annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the core purpose, followed by bulleted usage examples and return information, all in a compact format. Every sentence earns its place without redundancy, making it highly efficient and well-structured.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's moderate complexity (3 parameters, no output schema, no annotations), the description covers purpose, usage, and return value adequately. However, it could benefit from more behavioral details like error handling or execution context, leaving minor gaps in completeness.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, providing detailed parameter documentation. The description doesn't add any parameter-specific information beyond what's in the schema, so it meets the baseline of 3 where the schema handles the heavy lifting without additional value from the description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the specific action ('Set an execution breakpoint') and resource ('at a memory address'), distinguishing it from siblings like deleteBreakpoint, listBreakpoints, and setWatchpoint. It explicitly defines what the tool does rather than just restating the name.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit guidance on when to use this tool ('Debug code at specific points', 'Catch when routines are called', 'Analyze code flow') and lists related tools for alternative or complementary actions, including clear sibling differentiation like deleteBreakpoint for management.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/simen/vice-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server