MCP debugging support

MCP clients, such as AI agents, can use the debugger tools of the Qt Creator MCP server to start a debug session, control execution, and inspect call stacks, variables, registers, and memory. This page tells which of these operations work with which debugger and target, and which of them have actually been tested.

That you can debug a target manually in Qt Creator does not mean that the same workflow has been validated over MCP. Consider the following:

  • Is the tool exposed? The MCP server offers it, and it is turned on in the MCP server settings.
  • Is the operation supported? The debugger of the session can do it and the session is in a state for it. The debugger_get_capabilities tool answers this for the current session, together with the debugger, target architecture, and connection type that Qt Creator knows of.
  • Has the operation been validated? Has someone tested it with that host, target, and debugger, as listed below.

Operations

OperationToolsNeeds
Start and stop a sessiondebugger_start, debugger_stopA kit with a debugger
Control executiondebugger_step_over, debugger_step_in, debugger_step_out, debugger_continue, debugger_interrupt, debugger_run_to_line, debugger_wait_for_operationA paused session, or a running one to interrupt
Call stackdebugger_get_call_stack, debugger_select_frameA paused session
Threadsdebugger_get_threads, debugger_select_thread, debugger_get_thread_stacksA paused session
Variables and expressionsdebugger_get_variables, debugger_get_variable, debugger_set_variable, debugger_evaluate_expression, debugger_add_watch_expressionA paused session
Registersdebugger_get_registersA paused session and a debugger with register access
Memorydebugger_read_memoryA paused session, a debugger that can read memory, and permission (see Memory access)
Breakpointsdebugger_get_breakpoints, debugger_add_breakpoint, debugger_delete_breakpointNone

The execution tools return an operation ID and a status: accepted, in_progress, completed, failed, or timed_out. With wait_for_completion, they wait until the target has stopped and its call stack and local variables have been refreshed. A timed_out status means that the wait ended first. The operation is not cancelled and can still complete. The tools that return data wait for the data of the current stop and report it as not ready instead of returning data of an earlier stop. Their results carry a context object with the session ID, stop ID, thread ID, and frame level that the data belongs to.

Memory access

Reading memory can have side effects on some targets: on a bare metal device, an address may belong to memory-mapped I/O, where reading a register can change the state of a peripheral. Therefore, go to Preferences > Debugger > General > MCP Server to set which memory MCP clients may read:

  • None does not allow reading memory.
  • Process memory, the default, allows reading the memory of applications that run on an operating system. On bare metal targets and targets of unknown kind, it allows reading only the address ranges that you list in Readable ranges on other targets, such as 0x20000000-0x2001ffff.
  • Any memory allows reading any address, including memory-mapped I/O.

Maximum bytes per read limits how much one call reads. A longer read returns the first part and the address to continue from. Unreadable bytes are reported as unreadable ranges with a reason, never as zeros.

These settings apply to reading memory only. MCP clients cannot write memory or registers directly, but debugger_set_variable writes the memory or the register that holds the variable it changes, wherever that is. Evaluating an expression with debugger_evaluate_expression can call functions in the target if Allow inferior calls in debugging helper is selected, and those functions can change the target's state.

Validation matrix

The following configurations are described here. Configurations A, B, and C were tested with both Qt Creator's own debugger engines and Use the new debugger backends.

ConfigurationHostTarget OS and CPUDebuggerConnectionQt Creator version
AmacOS 27 on Apple siliconmacOS, arm64LLDB (lldb-2103)Local process, started by Qt Creator21.0
BWindows 11 on x86-64Windows, x86-64, built with MSVC 2022CDB (10.0.26100)Local process, started by Qt Creator21.0
CUbuntu Linux on x86-64Linux, x86-64, built with GCC 15GDB 17.1Local process, started by Qt Creator21.0
DLinuxEmbedded Linux, for example on ARMGDBgdbserver on the device, over TCP/IP21.0
ELinux, macOS, or WindowsBare metal, for example Arm Cortex-MGDBA GDB server, such as OpenOCD or SEGGER J-Link, and a debug probe21.0
FWindowsBare metal, Arm Cortex-MuVision (UVSC)A debug probe through uVision21.0

Each operation is classified as validated (tested over MCP with that configuration), not validated (expected to work, but not tested over MCP with that configuration), supported with limitations (works within the stated limits), or unsupported.

OperationABCDEF
Step over, waiting for completionValidatedValidatedValidatedNot validatedNot validatedNot validated
Step in, step out, interrupt, run to lineNot validatedNot validatedNot validatedNot validatedNot validatedNot validated
Continue to the end of the programValidatedValidatedValidatedNot validatedNot validatedNot validated
Call stack of the current threadValidatedValidatedValidatedNot validatedNot validatedNot validated
Select a frame, waiting for its variablesValidatedValidatedValidatedNot validatedNot validatedNot validated
Call stacks of all threadsValidatedValidatedValidatedNot validatedSupported with limitations: only the threads that the GDB server reports, which are RTOS tasks only if the server is RTOS awareNot validated
Local variablesValidatedValidatedValidatedNot validatedNot validatedNot validated
Evaluate an expressionValidatedValidatedValidatedNot validatedNot validatedNot validated
Registers, including those of an outer frameValidatedSupported with limitations: for an outer frame, CDB reports the registers of the innermost frame, and the answer says soValidatedNot validatedNot validatedNot validated
Read memory, including unreadable addressesValidatedValidatedValidatedNot validatedSupported with limitations: only the configured readable ranges or with Any memorySupported with limitations: as E
Report capabilitiesValidatedValidatedValidatedNot validatedNot validatedNot validated

The validated operations are covered by the Debugger plugin tests whose names start with testMcp. Run them with qtcreator -test "Debugger,testMcp*". They build a small program with the compiler of the kit, debug it, and call the MCP tools.

Set up and verify an embedded Linux target

This procedure has not been validated over MCP (configuration D).

  1. Build the application with a kit for the device, with debug information.
  2. Start gdbserver on the device, for example gdbserver :10000 ./app.
  3. Call debugger_start with executable set to the host copy of the application and remote_channel set to the address of the device, such as 192.168.1.10:10000. Set kit to the ID of the device kit.
  4. Call debugger_get_capabilities. Check that environment names the target architecture and Linux, and that connection_type is remote_server.
  5. Call debugger_interrupt with wait_for_completion, or set a breakpoint with debugger_add_breakpoint and call debugger_continue with wait_for_completion.
  6. Call debugger_get_thread_stacks and debugger_get_variables, and compare the result with the Stack and Locals views of Qt Creator.

Set up and verify a bare metal target

This procedure has not been validated over MCP (configuration E).

  1. Set up the device and its GDB server as described in Developing for Bare Metal devices.
  2. In Preferences > Debugger > General > MCP Server, list the RAM ranges of the device in Readable ranges on other targets, such as 0x20000000-0x2001ffff. Do not list peripheral ranges.
  3. Start the GDB server, then call debugger_start with executable set to the ELF file and remote_channel set to the server, such as localhost:3333.
  4. Call debugger_get_capabilities. Check that memory_read reports restricted with your ranges.
  5. Stop the target with debugger_interrupt and wait_for_completion.
  6. Call debugger_get_registers with names set to ["pc", "sp"], then debugger_read_memory at the stack pointer.

Boundaries

Over MCP, Qt Creator offers what its debugger front end offers, not everything that a target-specific debugger can do. In particular, MCP clients cannot:

  • Write memory or registers, other than those that hold a variable that debugger_set_variable changes.
  • Read peripheral registers from SVD descriptions.
  • Use trace data, such as ETM or SWO, or debug several cores at once.
  • Flash the device or reset it.
  • Rely on RTOS awareness: threads are what the debugger and its server report.
  • Get an atomic snapshot of all threads: debugger_get_thread_stacks reads them one after another while the target stays stopped.

See also Set up Qt Creator MCP server, MCP server tools, Debug remotely with GDB, and Developing for Bare Metal devices.