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_capabilitiestool 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
| Operation | Tools | Needs |
|---|---|---|
| Start and stop a session | debugger_start, debugger_stop | A kit with a debugger |
| Control execution | debugger_step_over, debugger_step_in, debugger_step_out, debugger_continue, debugger_interrupt, debugger_run_to_line, debugger_wait_for_operation | A paused session, or a running one to interrupt |
| Call stack | debugger_get_call_stack, debugger_select_frame | A paused session |
| Threads | debugger_get_threads, debugger_select_thread, debugger_get_thread_stacks | A paused session |
| Variables and expressions | debugger_get_variables, debugger_get_variable, debugger_set_variable, debugger_evaluate_expression, debugger_add_watch_expression | A paused session |
| Registers | debugger_get_registers | A paused session and a debugger with register access |
| Memory | debugger_read_memory | A paused session, a debugger that can read memory, and permission (see Memory access) |
| Breakpoints | debugger_get_breakpoints, debugger_add_breakpoint, debugger_delete_breakpoint | None |
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.
| Configuration | Host | Target OS and CPU | Debugger | Connection | Qt Creator version |
|---|---|---|---|---|---|
| A | macOS 27 on Apple silicon | macOS, arm64 | LLDB (lldb-2103) | Local process, started by Qt Creator | 21.0 |
| B | Windows 11 on x86-64 | Windows, x86-64, built with MSVC 2022 | CDB (10.0.26100) | Local process, started by Qt Creator | 21.0 |
| C | Ubuntu Linux on x86-64 | Linux, x86-64, built with GCC 15 | GDB 17.1 | Local process, started by Qt Creator | 21.0 |
| D | Linux | Embedded Linux, for example on ARM | GDB | gdbserver on the device, over TCP/IP | 21.0 |
| E | Linux, macOS, or Windows | Bare metal, for example Arm Cortex-M | GDB | A GDB server, such as OpenOCD or SEGGER J-Link, and a debug probe | 21.0 |
| F | Windows | Bare metal, Arm Cortex-M | uVision (UVSC) | A debug probe through uVision | 21.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.
| Operation | A | B | C | D | E | F |
|---|---|---|---|---|---|---|
| Step over, waiting for completion | Validated | Validated | Validated | Not validated | Not validated | Not validated |
| Step in, step out, interrupt, run to line | Not validated | Not validated | Not validated | Not validated | Not validated | Not validated |
| Continue to the end of the program | Validated | Validated | Validated | Not validated | Not validated | Not validated |
| Call stack of the current thread | Validated | Validated | Validated | Not validated | Not validated | Not validated |
| Select a frame, waiting for its variables | Validated | Validated | Validated | Not validated | Not validated | Not validated |
| Call stacks of all threads | Validated | Validated | Validated | Not validated | Supported with limitations: only the threads that the GDB server reports, which are RTOS tasks only if the server is RTOS aware | Not validated |
| Local variables | Validated | Validated | Validated | Not validated | Not validated | Not validated |
| Evaluate an expression | Validated | Validated | Validated | Not validated | Not validated | Not validated |
| Registers, including those of an outer frame | Validated | Supported with limitations: for an outer frame, CDB reports the registers of the innermost frame, and the answer says so | Validated | Not validated | Not validated | Not validated |
| Read memory, including unreadable addresses | Validated | Validated | Validated | Not validated | Supported with limitations: only the configured readable ranges or with Any memory | Supported with limitations: as E |
| Report capabilities | Validated | Validated | Validated | Not validated | Not validated | Not 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).
- Build the application with a kit for the device, with debug information.
- Start
gdbserveron the device, for examplegdbserver :10000 ./app. - Call
debugger_startwithexecutableset to the host copy of the application andremote_channelset to the address of the device, such as192.168.1.10:10000. Setkitto the ID of the device kit. - Call
debugger_get_capabilities. Check thatenvironmentnames the target architecture and Linux, and thatconnection_typeisremote_server. - Call
debugger_interruptwithwait_for_completion, or set a breakpoint withdebugger_add_breakpointand calldebugger_continuewithwait_for_completion. - Call
debugger_get_thread_stacksanddebugger_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).
- Set up the device and its GDB server as described in Developing for Bare Metal devices.
- 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. - Start the GDB server, then call
debugger_startwithexecutableset to the ELF file andremote_channelset to the server, such aslocalhost:3333. - Call
debugger_get_capabilities. Check thatmemory_readreportsrestrictedwith your ranges. - Stop the target with
debugger_interruptandwait_for_completion. - Call
debugger_get_registerswithnamesset to["pc", "sp"], thendebugger_read_memoryat 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_variablechanges. - 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_stacksreads 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.