set_breakpoint
Set breakpoints in PHP code for debugging with Xdebug. Configure line breakpoints, conditional expressions, and hit counts to pause execution at specific points.
Instructions
Set a breakpoint in PHP code. Supports line breakpoints and conditional breakpoints with hit counts. Can be set before a debug session starts - breakpoints will be applied when a session connects.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| file | Yes | Full file path (use container path for Docker, e.g., /var/www/html/index.php) | |
| line | Yes | Line number for the breakpoint | |
| condition | No | Optional PHP condition expression (e.g., '$x > 10' or '$user !== null') | |
| hit_value | No | Hit count value - break after this many hits | |
| hit_condition | No | Hit condition: >= (break when hits >= value), == (break on exact hit), % (break every N hits) | |
| session_id | No | Session ID (uses active session if not specified) |
Implementation Reference
- src/tools/breakpoints.ts:47-133 (handler)The core handler function that implements the logic for setting a line breakpoint. It either applies it to an active debug session or stores it as pending if no session exists.async ({ file, line, condition, hit_value, hit_condition, session_id }) => { const session = sessionManager.resolveSession(session_id); // If no active session, store as pending breakpoint if (!session) { const pendingBp = pendingBreakpoints.addLineBreakpoint(file, line, { condition, hitValue: hit_value, hitCondition: hit_condition as HitCondition, }); return { content: [ { type: 'text', text: JSON.stringify( { success: true, pending: true, message: 'Breakpoint stored as pending - will be applied when a debug session connects', breakpoint: { id: pendingBp.id, type: 'line', file, line, condition: condition || null, hitValue: hit_value || null, hitCondition: hit_condition || null, enabled: pendingBp.enabled, }, }, null, 2 ), }, ], }; } try { const breakpoint = await session.setLineBreakpoint(file, line, { condition, hitValue: hit_value, hitCondition: hit_condition as HitCondition, }); return { content: [ { type: 'text', text: JSON.stringify( { success: true, breakpoint: { id: breakpoint.id, type: breakpoint.type, file, line, condition: condition || null, hitValue: hit_value || null, hitCondition: hit_condition || null, resolved: breakpoint.resolved, state: breakpoint.state, }, }, null, 2 ), }, ], }; } catch (error) { return { content: [ { type: 'text', text: JSON.stringify({ error: 'Failed to set breakpoint', message: error instanceof Error ? error.message : String(error), file, line, }), }, ], }; } }
- src/tools/breakpoints.ts:20-46 (schema)Zod schema defining the input parameters for the set_breakpoint tool.{ file: z .string() .describe( 'Full file path (use container path for Docker, e.g., /var/www/html/index.php)' ), line: z.number().int().positive().describe('Line number for the breakpoint'), condition: z .string() .optional() .describe("Optional PHP condition expression (e.g., '$x > 10' or '$user !== null')"), hit_value: z .number() .int() .optional() .describe('Hit count value - break after this many hits'), hit_condition: z .enum(['>=', '==', '%']) .optional() .describe( 'Hit condition: >= (break when hits >= value), == (break on exact hit), % (break every N hits)' ), session_id: z .string() .optional() .describe('Session ID (uses active session if not specified)'), },
- src/tools/breakpoints.ts:17-134 (registration)Direct registration of the 'set_breakpoint' tool using server.tool() within the registerBreakpointTools function.server.tool( 'set_breakpoint', 'Set a breakpoint in PHP code. Supports line breakpoints and conditional breakpoints with hit counts. Can be set before a debug session starts - breakpoints will be applied when a session connects.', { file: z .string() .describe( 'Full file path (use container path for Docker, e.g., /var/www/html/index.php)' ), line: z.number().int().positive().describe('Line number for the breakpoint'), condition: z .string() .optional() .describe("Optional PHP condition expression (e.g., '$x > 10' or '$user !== null')"), hit_value: z .number() .int() .optional() .describe('Hit count value - break after this many hits'), hit_condition: z .enum(['>=', '==', '%']) .optional() .describe( 'Hit condition: >= (break when hits >= value), == (break on exact hit), % (break every N hits)' ), session_id: z .string() .optional() .describe('Session ID (uses active session if not specified)'), }, async ({ file, line, condition, hit_value, hit_condition, session_id }) => { const session = sessionManager.resolveSession(session_id); // If no active session, store as pending breakpoint if (!session) { const pendingBp = pendingBreakpoints.addLineBreakpoint(file, line, { condition, hitValue: hit_value, hitCondition: hit_condition as HitCondition, }); return { content: [ { type: 'text', text: JSON.stringify( { success: true, pending: true, message: 'Breakpoint stored as pending - will be applied when a debug session connects', breakpoint: { id: pendingBp.id, type: 'line', file, line, condition: condition || null, hitValue: hit_value || null, hitCondition: hit_condition || null, enabled: pendingBp.enabled, }, }, null, 2 ), }, ], }; } try { const breakpoint = await session.setLineBreakpoint(file, line, { condition, hitValue: hit_value, hitCondition: hit_condition as HitCondition, }); return { content: [ { type: 'text', text: JSON.stringify( { success: true, breakpoint: { id: breakpoint.id, type: breakpoint.type, file, line, condition: condition || null, hitValue: hit_value || null, hitCondition: hit_condition || null, resolved: breakpoint.resolved, state: breakpoint.state, }, }, null, 2 ), }, ], }; } catch (error) { return { content: [ { type: 'text', text: JSON.stringify({ error: 'Failed to set breakpoint', message: error instanceof Error ? error.message : String(error), file, line, }), }, ], }; } } );
- src/tools/index.ts:56-56 (registration)Higher-level registration where registerBreakpointTools is invoked as part of registerAllTools, including the set_breakpoint tool.registerBreakpointTools(server, ctx.sessionManager, ctx.pendingBreakpoints);
- Helper method to add line breakpoints to pending storage when no active session is available.addLineBreakpoint( file: string, line: number, options?: { condition?: string; hitValue?: number; hitCondition?: HitCondition; } ): PendingBreakpoint { const id = `pending_${++this.breakpointIdCounter}`; const bp: PendingBreakpoint = { id, type: 'line', file, line, condition: options?.condition, hitValue: options?.hitValue, hitCondition: options?.hitCondition, enabled: true, createdAt: new Date(), }; this.pendingBreakpoints.set(id, bp); logger.info(`Pending breakpoint added: ${id} at ${file}:${line}`); this.emit('breakpointAdded', bp); return bp; }