Skip to main content
Glama

start_debugging

Launch a script under a debugger and determine whether it paused, stopped, or is still running, returning the stop reason, breakpoint location, and source context.

Instructions

Start debugging a script. Answers when the launched program stops, when it ends, or after a short hold — whichever comes first, and the same way in every language: "paused" with a reason and, as wait_for_stop answers a stop, the location, its source context and a note (a breakpoint reached as the program starts is answered here), "stopped" with the exit code, or "running" with pending:true when the program has not stopped yet; the message says what is armed. The hold is not a limit on the program — nothing is cancelled when it passes and breakpoints stay armed: call wait_for_stop to block until the program stops or ends (for a server, after sending the request that reaches your breakpoint). A stopOnEntry launch is answered at its entry stop

Input Schema

NameRequiredDescriptionDefault
argsNo
sessionIdYes
scriptPathYesPath to the script to debug. Use absolute paths or paths relative to your current working directory
testRunnerNoRun scriptPath under a test runner the language declares a preset for (list_supported_languages shows testRunners per language; python: "pytest"). The preset builds the launch — for pytest: python -m pytest <scriptPath>[::testTarget] -x, run from pytest's rootdir (the nearest pytest.ini, pyproject.toml with a [tool.pytest.ini_options] table, tox.ini or setup.cfg with a pytest section above the file, else setup.py), with pytest-xdist and pytest-cov turned off — -p no:<plugin>, or the plugin's inert switch (-n0 / --no-cov) when the project's own addopts turns it on — unless your args ask for them, and the debugger armed to pause on the first failing assert or escaping exception with the test frame live (uncaught + userUnhandled). The answer is the autopsy: snapshot.exception, frames and locals; a passing test runs to completion. Your args are appended as pytest arguments. An undeclared runner is refused by name before anything starts
testTargetNoWith testRunner: the test inside scriptPath to run — "test_name", "Class::test_name", "test_name[param]" — or a full node id of that file. Omit to run the whole file
dryRunSpawnNoCheck the launch without starting anything: resolves the adapter and the program (compiling a source-file program where the language needs it), runs the launch transform, and answers with the adapter command the launch would run plus any configuration warnings. The session is left exactly as it was: the answer's state is the session's current state, a running or paused program keeps running, and the previous run's output, exit code and last stop stay readable. Not available for attach-shaped configs
dapLaunchArgsNoDAP launch arguments. Beyond the three below, adapter keys pass through (program, cwd, env, …). Python: module runs `python -m <module>` instead of scriptPath (the pytest shape: module "pytest", args [<test file>::<test>, "-x"]) and code runs a code string; scriptPath then only names the file the launch is about, and cwd — which `python -m` puts on sys.path — defaults to the directory above the top-most package containing scriptPath
breakOnExceptionsNoBreak when exceptions are thrown: "uncaught" pauses at uncaught exceptions at the crash site instead of terminating the session; "all" also pauses on caught/raised exceptions (language-dependent). Launch sessions default to "uncaught" (Ruby is the exception — rdbg has no uncaught-only filter, so it stays "none"); pass "none" to opt out and let crashing scripts run to termination
adapterLaunchConfigNoOptional adapter-specific launch configuration overrides

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed5 schema fields changedv0.26.0
    • addedInput schema / properties / dapLaunchArgs / description
      Added value: +"DAP launch arguments. Beyond the three below, adapter keys pass through (program, cwd, env, …). Python: module runs `python -m <module>` instead of scriptPath (the pytest shape: module \"pytest\", args [<test file>::<test>, \"-x\"]) and code runs a code string; scriptPath then only names the file the launch is about, and cwd — which `python -m` puts on sys.path — defaults to the directory above the top-most package containing scriptPath"
    • changedInput schema / properties / dapLaunchArgs / properties / noDebug / description
      Previous value: -"DAP's launch-without-debugging flag (default false). Where the adapter honours it (js-debug, debugpy, Delve and CodeLLDB) no breakpoint binds, no exception filter arms, no entry stop lands and no breakpoint, exception or entry stop ever arrives (a pause may still land where the runtime allows one) — the response warns when breakpoints, an explicit breakOnExceptions or stopOnEntry are set alongside it, and while the launch runs the session reports debuggerDisabled and every later surface says the debugger is off. rdbg, netcoredbg and the Java bridge ignore the flag, and the rust launch never forwards it: their debugger stays on and the response says so"New value: +"DAP's launch-without-debugging flag (default false). Where the adapter honours it (js-debug, debugpy, Delve, CodeLLDB and the Dart SDK adapters) no breakpoint binds, no exception filter arms, no entry stop lands and no breakpoint, exception or entry stop ever arrives (a pause may still land where the runtime allows one) — the response warns when breakpoints, an explicit breakOnExceptions or stopOnEntry are set alongside it, and while the launch runs the session reports debuggerDisabled and every later surface says the debugger is off. rdbg, netcoredbg and the Java bridge ignore the flag, and the rust launch never forwards it: their debugger stays on and the response says so"
    • addedInput schema / properties / dryRunSpawn / description
      Added value: +"Check the launch without starting anything: resolves the adapter and the program (compiling a source-file program where the language needs it), runs the launch transform, and answers with the adapter command the launch would run plus any configuration warnings. The session is left exactly as it was: the answer's state is the session's current state, a running or paused program keeps running, and the previous run's output, exit code and last stop stay readable. Not available for attach-shaped configs"
    • addedInput schema / properties / testRunner
      Added value: +{
      +  "description": "Run scriptPath under a test runner the language declares a preset for (list_supported_languages shows testRunners per language; python: \"pytest\"). The preset builds the launch — for pytest: python -m pytest <scriptPath>[::testTarget] -x, run from pytest's rootdir (the nearest pytest.ini, pyproject.toml with a [tool.pytest.ini_options] table, tox.ini or setup.cfg with a pytest section above the file, else setup.py), with pytest-xdist and pytest-cov turned off — -p no:<plugin>, or the plugin's inert switch (-n0 / --no-cov) when the project's own addopts turns it on — unless your args ask for them, and the debugger armed to pause on the first failing assert or escaping exception with the test frame live (uncaught + userUnhandled). The answer is the autopsy: snapshot.exception, frames and locals; a passing test runs to completion. Your args are appended as pytest arguments. An undeclared runner is refused by name before anything starts",
      +  "type": "string"
      +}
    • addedInput schema / properties / testTarget
      Added value: +{
      +  "description": "With testRunner: the test inside scriptPath to run — \"test_name\", \"Class::test_name\", \"test_name[param]\" — or a full node id of that file. Omit to run the whole file",
      +  "type": "string"
      +}
  2. Changed4 schema fields changedv0.25.1
    • addedInput schema / properties / breakOnExceptions
      Added value: +{
      +  "description": "Break when exceptions are thrown: \"uncaught\" pauses at uncaught exceptions at the crash site instead of terminating the session; \"all\" also pauses on caught/raised exceptions (language-dependent). Launch sessions default to \"uncaught\" (Ruby is the exception — rdbg has no uncaught-only filter, so it stays \"none\"); pass \"none\" to opt out and let crashing scripts run to termination",
      +  "enum": [
      +    "uncaught",
      +    "all",
      +    "none"
      +  ],
      +  "type": "string"
      +}
    • addedInput schema / properties / dapLaunchArgs / properties / justMyCode / description
      Added value: +"Only debug user code (default true). JavaScript launch: true blackboxes node_modules via skipFiles and keeps js-debug's smart-stepper on, so a pause or step that lands in skipped code (Node internals, node_modules) is stepped through and may never land; false drops node_modules from skipFiles and turns the stepper off, so pauses and steps land inside dependencies"
    • addedInput schema / properties / dapLaunchArgs / properties / noDebug
      Added value: +{
      +  "description": "DAP's launch-without-debugging flag (default false). Where the adapter honours it (js-debug, debugpy, Delve and CodeLLDB) no breakpoint binds, no exception filter arms, no entry stop lands and no breakpoint, exception or entry stop ever arrives (a pause may still land where the runtime allows one) — the response warns when breakpoints, an explicit breakOnExceptions or stopOnEntry are set alongside it, and while the launch runs the session reports debuggerDisabled and every later surface says the debugger is off. rdbg, netcoredbg and the Java bridge ignore the flag, and the rust launch never forwards it: their debugger stays on and the response says so",
      +  "type": "boolean"
      +}
    • addedInput schema / properties / dapLaunchArgs / properties / stopOnEntry / description
      Added value: +"Pause at the first line before running. Default false — the opposite of attach, which pauses unless stopOnEntry is false"
  3. First observed

TDQS

A3.8/5.0
Behavior4/5

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

With no annotations, the description carries the full burden, and it delivers the most important behavioral fact: this call waits only briefly and answers in one of three states ('paused', 'stopped', 'running' with pending:true). It also discloses that the short hold cancels nothing and keeps breakpoints armed, and that stopOnEntry has its own answer. It does not mention side effects on an existing process or error behavior against an invalid session.

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

Conciseness3/5

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

The purpose is front-loaded, but the body is a single semicolon-chained sentence that is hard to parse, packing return states, hold semantics, and follow-up routing into one run-on clause. There is little filler, but the structure undercuts the density.

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?

For a nine-parameter, nested-schema launch tool with no annotations, the description covers the async return contract, which is the piece an agent most needs and which the schema cannot express. Missing pieces are error and failure behavior, and whether a debug session must be created first, although the required sessionId hints at it.

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 78%, so the schema largely documents the parameters itself, and testRunner, testTarget, dryRunSpawn, breakOnExceptions and the dapLaunchArgs sub-keys each have rich descriptions. The tool description adds almost nothing parameter-specific beyond the stopOnEntry note, so the baseline applies.

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

Purpose4/5

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

The opening sentence gives a specific verb and resource: 'Start debugging a script'. It also distinguishes itself from wait_for_stop by naming that tool as the blocking follow-up. However, it never explicitly contrasts with the other obvious siblings in this list, attach_to_process and restart_debugging, so the agent must infer that boundary from the schema.

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

Usage Guidelines4/5

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

It states a clear usage rule for the alternative: 'The hold is not a limit on the program... call wait_for_stop to block until the program stops or ends', even giving the server-specific case of sending a request first. It stops short of naming when not to use this tool, such as why to choose attach_to_process or restart_debugging instead.

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