ADAM
Integrates with SAP systems through the ABAP Development Tools (ADT) REST API to debug ABAP code. It can set breakpoints, run the code via ABAP Unit tests or OData GET triggers, capture stops with call stack, variables and steps, and support interactive stepping. Works with on-premise SAP NetWeaver/S/4HANA and SAP BTP ABAP Environment, with each user debugging as their own SAP user.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@ADAMDebug why ZCL_ORDER=>GET_TOTAL returns 0 for order 4711"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
ADAM
ADAM is an MCP server that lets an AI assistant — Claude, GitHub Copilot, Cursor… — debug ABAP code in SAP's own debugger: set breakpoints, run the code, read the variables, step through it. It speaks the ABAP Development Tools (ADT) REST API, as Eclipse does, so nothing has to be installed on the SAP system.
You: Why does ZCL_ORDER=>GET_TOTAL return 0 for order 4711?
Claude: abap_source {type: "CLAS", name: "ZCL_ORDER", method: "get_total"}
abap_debug {type: "CLAS", name: "ZCL_ORDER", breakpoints: [{line: 42, hits: 3}],
variables: ["LS_ITEM-NETWR", "LV_TOTAL"], steps: 2}
→ three iterations of the loop in one run, each with both values and two stepsFeatures
Two modes. One-shot: a single tool call arms the breakpoints, runs the code, records every stop and releases the program. Interactive: the program waits at its first stop and the assistant drives it — step in, over or out, continue, inspect — deciding each move from what it sees.
Breakpoints on lines and methods of classes, programs and function modules (RAP behavior pools included), with ABAP conditions and hit counts; on messages, statement kinds (
COMMIT WORK, …) and exceptions. Watchpoints: stop wherever a variable changes — or becomes a given value.From a Fiori app to its code: find the service binding, follow it to the service definition, the CDS views, the behavior definition and the handler methods to debug.
Triggers: the object's ABAP Unit tests, an OData
GET, or your own run of a Fiori app or report.Long runs stay readable: thousands of steps fold into a compact trace (
(9-12)×497) with the values only where they changed, anduntilstops on a line or a changed variable.Safe by design: observes without changing anything, debugs only your own SAP user, never takes over another debugger, always cleans up, bounded in time and result size.
Local or shared: next to the assistant (stdio), or as a server on SAP BTP Cloud Foundry where each user signs in and debugs as their own SAP user.
Related MCP server: DebugMCP
Quick start
You need Node.js 22.12+ and git, an SAP system with ADT (on-premise SAP_BASIS 7.50 or later, or the
SAP BTP ABAP Environment), and an SAP user with ADT access (S_ADT_RES) and debug authorization
(S_DEVELOP with OBJTYPE = DEBUG, ACTVT = 03).
Claude Code
claude mcp add adam \
-e SAP_URL=https://my-sap-host:44300 -e SAP_CLIENT=100 \
-e SAP_USER=DEVELOPER -e SAP_PASSWORD=secret \
-- npx -y --allow-git=root github:ClementRingot/ADAMClaude Desktop, Cursor, VS Code and other clients — claude_desktop_config.json,
.cursor/mcp.json or .vscode/mcp.json (in VS Code the top-level key is servers):
{
"mcpServers": {
"adam": {
"command": "npx",
"args": ["-y", "--allow-git=root", "github:ClementRingot/ADAM"],
"env": {
"SAP_URL": "https://my-sap-host:44300",
"SAP_CLIENT": "100",
"SAP_USER": "DEVELOPER",
"SAP_PASSWORD": "secret"
}
}
}
}Then ask, for instance: "Debug ZCL_ORDER=>GET_TOTAL with its unit tests and show me LV_TOTAL at line 42."
Single sign-on cookies, the BTP ABAP Environment, a corporate proxy and every other setting: Configuration.
npx fetches the repository from GitHub and builds it once: the first start takes a while. Run
npx -y --allow-git=root github:ClementRingot/ADAM --versiononce in a terminal first, so the client does not wait for the build.--allow-git=root: npm 12 refuses to install from git unless allowed; earlier versions accept the flag too.Pin a version by appending
#<tag or commit>to the repository name.On Windows, some clients start
npxonly through the shell:"command": "cmd"with"args": ["/c", "npx", "-y", "--allow-git=root", "github:ClementRingot/ADAM"].From a clone:
git clone https://github.com/ClementRingot/ADAM.git, thennpm ci(it also builds), and registernode /path/to/ADAM/dist/index.jsas the command.Instead of an
envblock, the server can read a file: add"--env-file", "/path/to/.env"toargs(see .env.example).
Tools
Tool | What it does |
| Arms breakpoints, runs the code and records every stop of that run: position, call stack, variables, steps. With |
| Drives a held program one move at a time: |
| Lists what the debugger holds or left behind for your SAP user — breakpoints a crashed capture could not remove, a stale listener — and removes it |
| The active source of a class, program or function module, with the line numbers breakpoints use — and of interfaces, includes, CDS views, behavior and service definitions; a service binding's service definitions: the way from a Fiori app to its code |
| Finds objects of every type by name, name start or pattern — service bindings and definitions included, with SAP's generated service objects left out |
abap_debug {type: "CLAS", name: "ZCL_ORDER", breakpoints: [{method: "get_total"}]}
stop in GET_TOTAL while the class's unit tests run: stack and local variables
abap_debug {type: "CLAS", name: "ZCL_ORDER", breakpoints: [{line: 42, condition: "sy-tabix = 500"}], variables: ["LS_ITEM"]}
only the 500th pass of the loop
abap_debug {type: "CLAS", name: "ZCL_ORDER", line: 42, until: {changed: "LV_STATUS"}}
step until LV_STATUS changes, and show where
abap_debug {type: "PROG", name: "ZREPORT", line: 30, trigger: "none", timeoutSeconds: 120}
run ZREPORT yourself, as the same SAP user, while the capture waits
abap_debug {type: "CLAS", name: "ZCL_ORDER", line: 42, interactive: true}
abap_debug_session {action: "step", stepMode: "into", variables: ["LV_TOTAL"]}
abap_debug_session {action: "inspect", variables: ["LS_HEAD"], stack: true}
abap_debug_session {action: "end"}
an interactive session, one move per callParameters, results and more examples: Tool reference.
How it works
1. Resolve the breakpoints against the active source — input errors stop here
2. Arm external breakpoints for your SAP user, and SAP's debugger listener
3. Run the trigger: ABAP Unit, an OData GET, or your own run
4. Follow attach where the program stopped; record each stop, step, continue
5. Release let the program finish; remove the breakpoints and the listener — alwaysThe program runs once, however many stops you ask for: a breakpoint in a loop with hits: 5
shows five iterations of the same run. A one-shot capture never leaves a program suspended. An
interactive session holds it — and its SAP work process — until end, two minutes without a call, or
fifteen minutes in all (both adjustable).
More in the tool reference and in the ADT debugger protocol, which also records what has been verified on real systems.
Safety
Observes, never changes: no variable writes, no jumps, no system debugging. The one exception is on request: ending an interactive session with
terminate: trueaborts the program. When SAP can only attach in non-exclusive mode, where every debugger step commits the program's database work, the capture lets the program go at once instead of inspecting it.Only your own SAP user: the user SAP itself names for the session, never a name passed in a call.
No takeover: if Eclipse, VS Code or another capture debugs the same user, the call refuses.
Harmless triggers: ABAP Unit runs harmless tests only; the HTTP trigger only reads an OData path on the connected system.
Always cleaned up: on every path, errors and timeouts included, the breakpoints and the listener are removed and the program is released. If the server itself is killed mid-capture, the next capture of the same user removes what was left — and
abap_breakpointsshows and removes it on request.Bounded: 20 breakpoints and 50 stops per call; steps as far as the call's time (default 120 s) and result size (default 40 KB) allow, both capped by the server's ceilings; a few captures and sessions at once per server, since each held program takes an SAP work process.
Fits the client's patience: a call answers within 50 s (many clients give up after 60); longer work goes on in the background, and
abap_debug_sessionwaitpicks up its answer.
On SAP BTP
Deploy the MTA on Cloud Foundry (mbt build, cf deploy), point it at a destination, assign the role
collection, and connect the clients to https://<route>/mcp. They sign in through XSUAA in the
browser, and each user debugs as their own SAP user: principal propagation through the Cloud
Connector for an on-premise system, a user token for the BTP ABAP Environment. See the
deployment guide.
Documentation
Page | Contents |
Parameters, results, examples, limits | |
Connecting to SAP, every setting | |
XSUAA, destinations, Cloud Connector, MTA | |
When a capture does not stop where expected | |
How SAP's debugger is driven, and what was verified live | |
Ideas and open checks |
Status
Version 0.1. On the SAP BTP ABAP Environment, the server has run live — over HTTP, as a remote connector: attaching across application servers, several stops in one run, steps, conditions, long step runs, statement kinds and an interactive session. The newest parts — answers that outlast a call, watchpoints, the removal of leftovers, the wider search — are tested against a simulated SAP so far, like every on-premise release (7.50, 7.58, 8.16): see the roadmap.
Development
npm ci # installs, then builds (the prepare script)
npm test # unit tests (vitest)
npm run typecheck # tsc over sources and tests
npm run lint # biome
npm run dev # run from source (tsx)Folder | Contents |
| ADT HTTP client, debugger protocol, ABAP Unit, repository reads, BTP ABAP login |
| Object types, method locator |
| The tools: |
| Per-user SAP connections through the Destination service |
|
|
Logs go to stderr only: over stdio, stdout carries the MCP protocol.
License and attribution
MIT — see LICENSE. This server is derived from ARC-1 (MIT), from which the ADT HTTP conventions, the BTP login, the method locator and the ABAP Unit parsing were ported. The ADT debugger contract was corroborated against abap-adt-api, vscode_abap_remote_fs and vibing-steampunk.
Available Tools
5 toolsabap_breakpointsList or remove what the debugger left for your SAP userAIdempotent
list: your capture or interactive session on this server, the breakpoints a capture could not remove (its server process was killed, or SAP refused the removal — the next capture removes them too), and whether a debugger listener is registered for your SAP user on SAP. delete: end your capture or session and remove those leftovers; listener: true also removes the listener — SAP removes it by user, Eclipse's included. Use it when a capture is refused because a debugger listens, or the user's requests stop at odd places. SAP has no request that lists every breakpoint of a user: Eclipse's own are in Eclipse.
| Name | Required | Description | Default |
|---|---|---|---|
| action | Yes | list: your capture or interactive session on this server, the breakpoints a capture could not remove (its server process was killed, or SAP refused), and whether a debugger listens for your SAP user. delete: end your capture or session, and remove those leftovers. | |
| listener | No | delete: also remove the debugger listener registered for your SAP user — SAP removes it by user, so Eclipse's or VS Code's goes too if one debugs as you. A capture that crashed leaves its listener for up to two minutes, and every capture is refused meanwhile. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare non-readonly, idempotent, non-destructive, open-world. The description adds real substance on top: leftovers exist because the capture's server process was killed or SAP refused removal, the next capture clears them anyway, a crashed capture leaves a listener for up to two minutes during which every capture is refused, and 'listener: true' removes the listener by SAP user, including Eclipse's or VS Code's if someone debugs as you. That is exactly the blast-radius info an agent needs before calling delete. Note it does soften the picture versus destructiveHint=false — delete ends the user's capture/session and can knock out another IDE's listener — but that is state cleanup rather than data destruction, so it is a nuance rather than a contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with per-action labels and zero filler sentences; every clause carries information. The prose is densely packed with em-dashes and nested parentheticals, which makes it harder to scan than it needs to be, so it is efficient but not clean.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, and the description does describe what 'list' returns (capture/session breakpoints, unremovable leftovers, listener presence). It also flags the external-scope caveat about Eclipse-local breakpoints. What is missing is anything about failure modes or required permissions for delete — e.g. what happens if the capture is already gone.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the enum values are already documented in the schema with nearly the same wording, so the description is largely restating structured data. The 'listener' explanation (two-minute stale listener window, removal by user affects other IDEs) mirrors the schema text rather than extending it. Baseline 3 applies when the schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names the concrete resource (breakpoints a capture could not remove, plus debugger listener registration for the user) and separates the two actions with explicit 'list:' and 'delete:' prefixes. It also states a real limitation ('SAP has no request that lists every breakpoint of a user: Eclipse's own are in Eclipse'), which keeps an agent from expecting this tool to surface IDE-local breakpoints — something the sibling names (abap_debug, abap_debug_session) don't make obvious.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The trigger conditions are explicit and operational: 'Use it when a capture is refused because a debugger listens, or the user's requests stop at odd places.' That maps a symptom to the tool. It does not explicitly say when NOT to use it or name sibling tools like abap_debug_session as the alternative once the leftovers are cleared, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
abap_debugCapture one ABAP run in the debuggerA
Debug ABAP code on the connected SAP system in ONE call: arm breakpoints (lines or class methods in CLAS, PROG or FUNC objects, optionally with an ABAP condition; or where a message is issued, a statement kind runs, an exception is raised; watchpoints, set at the first stop, then stop wherever a variable changes), run the code (its harmless ABAP Unit tests, an OData GET, or wait while you run it yourself as the same SAP user), and at every stop of that one run record the position, the call stack, the variables and optional steps — then release the program and remove the breakpoints. The program runs once, however many stops you ask for: a breakpoint in a loop with hits 5 shows five iterations of the same run. Nothing stays stopped after the call returns, so name every variable you need up front; to look again, run another capture — or start an interactive session (interactive: true) and decide each move with abap_debug_session. Lines are numbered as abap_source shows the ACTIVE source. Per capture: at most 20 breakpoints and 50 stops, and as many steps as the budgets allow — the run is followed until its result size (maxResultKB, default 40 KB) or inspection time (maxSeconds, default 120 s) runs out, then goes on without stopping. Past 20 steps from one stop, the steps come back as a compact trace; until ends them at a line or once a variable changed. Result: hit; breakpoints (set, with the hits they made, or refused with SAP's reason); debuggee; stops (at, stoppedAt, stack and variables on a breakpoint's first stop — its later stops carry only values, unchanged structures and tables marked so; steps, or a trace of a long run: path = the lines executed per frame, (9-12)×300 = a loop, changes = values where they changed); release; trigger; warnings. Without a stop: reason and hint. A call answers within ABAP_DEBUGGER_CALL_SECONDS (default 50 s). A capture still waiting for its stop or following its run then answers running: true with its session id, and goes on: abap_debug_session action wait picks up its result, action end stops it. It never changes variables or the program flow, never debugs system code, and only debugs the session's own SAP user; it refuses when Eclipse or VS Code already debugs that user.
| Name | Required | Description | Default |
|---|---|---|---|
| url | No | trigger=http: a host-relative OData path on the connected system, e.g. /sap/opu/odata4/sap/zui_travel/srvd/sap/ztravel/0001/Travel?$top=1. GET only: saves and actions need a unit test or trigger=none. | |
| line | No | Shorthand for one breakpoint at this 1-based line of type + name. | |
| name | No | Object name of `line`, and the default of every breakpoint and of the unit-test trigger. | |
| type | No | Object type of `line`, and the default of every breakpoint: CLAS, PROG or FUNC. | |
| steps | No | Steps after each stop (default 0; with until and no steps: step until it holds). Up to 20 come back one entry each (position and variables); more come back as a compact trace — the lines executed, loops folded as (9-12)×300, the variables only where they changed. Only maxSeconds and maxResultKB bound how far it goes. | |
| until | No | End the steps early: once the run stands on a line of the source the steps started in, and/or once a variable changed. | |
| watch | No | Watchpoints (max 5), set in the run at its first stop, after that stop's steps: the run then also stops wherever a variable changes — where does LV_STATUS change, or become 'E' with a condition? Each stop says from and to. The variable must be visible at that first stop (a local of its method, an attribute ME->…, a global); SAP refuses it otherwise. | |
| trigger | No | What runs the code. unittest (default): the harmless ABAP Unit tests of triggerName, else of type + name, else of the first breakpoint object (FUNC: its function group). http: a GET of url. none: the capture only waits timeoutSeconds while you run the code yourself (Fiori app, SE38, Postman) as the SAME SAP user. | |
| stepMode | No | over (default): stay in the method; into: follow calls into the called method; out: return to the caller. | |
| variables | No | Read at every stop and after every step: LV_TOTAL, LS_HEAD-VBELN, LT_ITEMS, LT_ITEMS[3], ME->MV_STATE, SY-SUBRC (max 20). Structures expand one level, tables show their first 5 rows. Default: every variable of the stopped frame (up to 60). The run is released when the call returns, so ask for everything up front. | |
| maxSeconds | No | Time budget of the inspection once the run stopped (default 120): long step runs need more — each step costs two or three requests to SAP. The server's ceiling applies (ABAP_DEBUGGER_MAX_SECONDS, default 600). The program waits in a work process meanwhile. | |
| breakpoints | No | The stops of the run (max 20): each a line, a CLAS method, a message, a statement kind or an exception class. One run can stop in several objects. | |
| interactive | No | true: an interactive session — return at the first stop and keep the program waiting there, then drive it call by call with abap_debug_session (step, continue, inspect, end), deciding each move from what you see. steps, if given, run before this call returns. The program holds a work process until the session ends; it is released after a while without a call. Default false: the whole capture in this one call. | |
| maxResultKB | No | Size budget of the result in KB of JSON (default 40, about 10k tokens); the server's ceiling applies (ABAP_DEBUGGER_MAX_RESULT_KB, default 200). | |
| triggerName | No | trigger=unittest: the class, program or function group whose unit tests run the code, when it is not the breakpoint object. | |
| exceptionClass | No | Also (or only) stop where this exception class is raised, e.g. CX_SY_ZERODIVIDE. | |
| timeoutSeconds | No | How long to wait for the first stop (1-900, default 60). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations: budgets (20 breakpoints, 50 stops), how hits in a loop replay one run, that the program is released and breakpoints removed after return, the 50 s call timeout with a running:true handoff, step-trace compaction, and the safety limits (never mutates variables or flow, never debugs system code). Nothing here contradicts readOnlyHint=false / destructiveHint=false.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded: the first sentence states the entire arm-run-inspect-release cycle, and the paragraphs move from model to limits to result to the timeout handoff. It is dense and a few clauses restate schema content (e.g. the abap_source line-numbering rule), but for a 17-parameter tool with no output schema the length is largely earned.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, so the description compensates with a full "Result:" breakdown (hit, breakpoints, debuggee, stops, stack/variables, steps vs trace, release, trigger, warnings) plus the no-stop failure shape and the running:true partial-result contract. Combined with 100% schema coverage, an agent has everything needed to call and interpret it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so field-level meaning is already carried; the description still adds cross-parameter semantics the schema cannot, e.g. that variables must be declared up front because the run is released, how steps/until/maxSeconds/maxResultKB interact, and that breakpoint hits are what produce multiple stops. It stops short of explaining every field, which the schema already does.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb and resource ("Debug ABAP code on the connected SAP system in ONE call") and explicitly frames the one-shot capture model against the sibling interactive model (abap_debug_session). An agent can distinguish it from abap_debug_session and abap_breakpoints without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly names when to use it (one-shot capture), when to use the alternative (interactive: true plus abap_debug_session for per-move decisions), and points to abap_source for line numbering. It also states preconditions and refusals: only the session's own SAP user, refuses if Eclipse or VS Code is already debugging that user.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
abap_debug_sessionDrive an interactive ABAP debug sessionA
One move of the program an interactive capture holds (abap_debug with interactive: true), then where it stands — its position, the code around it, the watched variables — so you decide the next move from what you see. step: statement by statement — stepMode over (default), into a call, out to the caller; count steps at once (past 20 they come back as a compact trace), until a line or until a variable changed. continue: run to the next breakpoint or watchpoint (each stop as in abap_debug), or to toLine. inspect: read any variables where it stands (or the whole frame), and the call stack. watch: set a watchpoint on a variable visible here — continue then also stops where it changes (optionally where a condition holds). end: let the program run to its end — or terminate: true to abort it, e.g. before it commits. wait: a move (or a capture) that outlasts its call — ABAP_DEBUGGER_CALL_SECONDS, default 50 s — answers running: true and goes on in the background; wait returns its answer once it is done. The program waits in a work process between calls, so end the session when you are done; it is also released after a while without a call (ABAP_DEBUGGER_IDLE_SECONDS, default 120 s) and after ABAP_DEBUGGER_SESSION_SECONDS (default 15 min). Every answer says how long it has left. Apart from terminate, it never changes variables or the program's flow.
| Name | Required | Description | Default |
|---|---|---|---|
| hits | No | watch: how many of its changes stop the run (1-50, default 1). | |
| count | No | step: how many steps (default 1; with until and no count: until it holds). More than 20 come back as a compact trace; maxSeconds and maxResultKB bound the run. | |
| stack | No | inspect: include the call stack. | |
| until | No | step: end the steps early, once the program stands on a line of the source they started in, and/or once a variable changed. | |
| action | Yes | step: run statement by statement (stepMode, count, until). continue: run on to the next breakpoint or watchpoint, or to toLine. inspect: read variables or the call stack where the program stands. watch: set a watchpoint — continue then also stops where the variable changes. wait: the answer of a capture or move that outlasted its call (it said running: true). end: let the program run to its end (or terminate it) and close the session; on a capture still running, stop it. | |
| toLine | No | continue: run to this line of the source the program stands in instead of the next breakpoint (it still stops at a breakpoint on the way). | |
| session | No | The session id abap_debug returned (default: your current capture or session). | |
| stepMode | No | step: over (default) stays in the method; into follows a call; out returns to the caller. | |
| variable | No | watch: the variable whose change stops the run (visible where the program stands), e.g. LV_STATUS. | |
| condition | No | watch: stop only where this ABAP condition holds once it changed, e.g. lv_status = 'E'. | |
| terminate | No | end: abort the program where it stands instead of letting it run to its end — e.g. so that it does not commit. Its open database changes are rolled back. | |
| variables | No | step / continue: the variables to watch from now on, read after every step and at every stop (replacing the ones named before). inspect: read these now, structures expanded and tables' first rows (default: every variable of the frame). | |
| maxSeconds | No | step: time budget of this call (default 120); the server's ceiling applies. | |
| maxResultKB | No | Size budget of this answer in KB (default 40); the server's ceiling applies. | |
| timeoutSeconds | No | continue: how long to wait for the next stop (1-900, default 60). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations, the description discloses the critical runtime traits: the program waits in a work process between calls, calls exceeding ABAP_DEBUGGER_CALL_SECONDS return running: true and continue in the background, sessions are released after ABAP_DEBUGGER_IDLE_SECONDS (120 s) and ABAP_DEBUGGER_SESSION_SECONDS (15 min), and every answer reports remaining time. It also scopes side effects precisely — 'Apart from terminate, it never changes variables or the program's flow' — and notes that terminate aborts before commit and rolls back open database changes, which is consistent with readOnlyHint=false / destructiveHint=false.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose and the action menu are front-loaded and each action line earns its place for a six-action, fifteen-parameter tool. It is dense and uses line-broken em-dash fragments that make the first sentence harder to parse than necessary, but there is little filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the burden well: it explains what each answer contains (position, surrounding code, watched variables, remaining session time, running: true for backgrounded calls) and covers the full session lifecycle including expiry and termination consequences. Nothing an agent needs to drive the session correctly appears to be missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is already 100%, so the baseline is 3, but the description adds genuine cross-parameter meaning: count above 20 returns a compact trace, until ends stepping early on a line or a variable change, variables 'replacing the ones named before' across step/continue, and terminate causing rollback. It does not restate the numeric defaults for every bound (maxSeconds, maxResultKB, timeoutSeconds), leaving those entirely to the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource — advancing an interactive ABAP debug session one move and returning position, surrounding code and watched variables — and explicitly ties it to the sibling that creates the capture ('abap_debug with interactive: true'), so an agent can tell the two apart. The opening sentence is convoluted ('One move of the program an interactive capture holds'), which slightly obscures the purpose until the per-action list clarifies it.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Every action is given an explicit when-to-use: step for statement-by-statement (with stepMode/count/until), continue for running to the next breakpoint/watchpoint or toLine, inspect for reading variables and the call stack, watch for setting a watchpoint, wait for retrieving an answer that returned running: true, end for closing the session. It also states the operational rule 'end the session when you are done', naming the alternative (idle/session expiry) if you don't.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
abap_searchFind ABAP objectsARead-onlyIdempotent
Find repository objects of any type by name, name start or pattern: classes, interfaces, programs and includes, function groups and modules, CDS views, behavior definitions, service definitions and bindings, UI5 apps… — each with its exact name, type, what it is, package and description. E.g. the service binding and definition behind a Fiori app (then the CDS views and behavior pools they lead to), or the unit-test class to use as triggerName.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | Object name or its start (ZUI_TRAVEL also finds ZUI_TRAVEL_O4), or a pattern with * anywhere (*TRAVEL*). Case-insensitive; exact names come first. | |
| types | No | Only these types, e.g. ["SRVB", "SRVD"] for the service binding and definition behind a Fiori app, ["CLAS"], ["PROG"], ["DDLS", "BDEF"]. Slash types such as PROG/I (includes) work too. Default: every type. | |
| package | No | Only objects of this package, or of the packages a pattern with * matches (ZTRAVEL*). | |
| maxResults | No | At most this many results (default 30). | |
| includeTechnical | No | Also list the objects SAP generates around an OData service (IWMO, IWSG, OA2S, SIA6, STOB, …), left out by default. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare read-only, idempotent, non-destructive, and open-world behavior. The description adds useful return-value context ('exact name, type, what it is, package and description') and search examples, though it does not discuss rate limits, auth, or pagination.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The definition is front-loaded and has only two sentences, but the first sentence is a dense enumeration of object types and return fields. The examples earn their place, though the description could be slightly easier to scan.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given rich annotations, full schema coverage, and no output schema, the description supplies what an agent needs: search scope, object-type coverage, return fields, and representative use cases. Nothing essential for correct invocation is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and the schema already documents query patterns, type filtering, package filtering, maxResults, and includeTechnical. The description reiterates some query semantics but adds no meaningful parameter guidance beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Find repository objects of any type by name...' and enumerates the object types covered. This makes the tool's scope clear and distinct from the debugging and source-code siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It provides concrete usage examples, such as finding the service binding and definition behind a Fiori app or the unit-test class to use as triggerName. It does not explicitly state when to use this instead of abap_source or another sibling, but the discovery context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
abap_sourceRead active ABAP source with line numbersARead-onlyIdempotent
The ACTIVE source with its line numbers: of a class (main source or a local-class include), a program or a function module — numbered as abap_debug breakpoints use them — and of interfaces, includes, CDS views, behavior and service definitions. A service binding (SRVB) shows its service definitions: from a Fiori app's binding, follow SRVD → CDS views → BDEF → behavior pool to the code to debug. Narrow a source with method, lineStart/lineEnd or grep.
| Name | Required | Description | Default |
|---|---|---|---|
| grep | No | Case-insensitive regular expression: only matching lines (and one line around each) are returned. | |
| name | Yes | Object name. | |
| type | Yes | CLAS, PROG or FUNC (where breakpoints go); INTF, INCL, DDLS (CDS view), DCLS, DDLX, BDEF (behavior definition), SRVD (service definition) or SRVB (service binding: its service definitions) to follow a Fiori app to its code. | |
| method | No | CLAS only: just this method (get_total, zif_order~process, lhc_travel~validate_dates), numbered as in the whole source. | |
| include | No | CLAS only: a local-class include instead of the main source — implementations (local classes, e.g. RAP handlers lhc_*), testclasses (ABAP Unit), definitions (local types). Detected for lhc_/lcl_/ltc_ methods. | |
| lineEnd | No | Last line to return. | |
| lineStart | No | First line to return (1-based). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare read-only, idempotent and non-destructive behavior, and the description adds meaningful context beyond them: only ACTIVE source is returned, line numbers match abap_debug breakpoints, and SRVB returns its service definitions. It does not discuss error behavior for inactive or missing objects, but the active-only and line-number semantics are valuable.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is appropriately sized and front-loads the core resource. The first sentence is somewhat convoluted due to the colon-and-dash construction, but the later sentences add useful usage and parameter context without excess.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a seven-parameter read tool with full schema coverage and annotations, the description supplies the critical behavioral context: active-only source, supported object types, line-number alignment, and the SRVB/Fiori follow chain. It could say more about return shape or missing/inactive object handling, but is largely complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so parameter meanings are already well documented in the input schema. The description reinforces that method, lineStart/lineEnd and grep narrow the source and mentions the abap_debug line-number convention, but adds little beyond the structured parameter definitions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies the resource: ACTIVE ABAP source for classes, programs, function modules, interfaces, includes, CDS views, behavior definitions, service definitions and bindings. It adds a useful qualifier, line numbers aligned with abap_debug breakpoints, but does not explicitly distinguish itself from siblings such as abap_search.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied through the Fiori debugging flow and the suggestion to narrow source with method, lineStart/lineEnd or grep. However, it does not explicitly say when to use abap_source instead of abap_search or abap_debug, so an agent must infer the boundary.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
5 tool updates
v0.1.0- First observed
abap_breakpoints - First observed
abap_debug - First observed
abap_debug_session - First observed
abap_search - First observed
abap_source
TDQS
Scored across 5 tools
Each tool has a clearly distinct role: one-shot capture debugging, interactive session control, breakpoint/listener management, source inspection, and repository search. Although debugging and breakpoints both appear, abap_debug arms breakpoints as part of a capture while abap_breakpoints only lists/deletes leftovers and listeners, so the boundary is clear.
All names use the same abap_ prefix and snake_case style, which makes the set predictable. There is minor semantic mixing between verb-like names (abap_debug, abap_search) and noun-like names (abap_source, abap_breakpoints), but it remains readable and coherent.
Five tools is well-scoped for an ABAP debugging server, with each tool covering a distinct part of the workflow. No tool feels redundant or missing from the core set.
The surface covers the full debugging lifecycle: discovering repository objects, reading active source, performing one-shot or interactive debugging, managing breakpoints/listeners, and cleaning up sessions. No obvious operational gap remains for the stated purpose.
Maintenance
Related MCP Connectors
Live browser debugging for AI assistants — DOM, console, network via MCP.
Debug, build, and manage Power Automate cloud flows with AI agents
- FlowstepOAuthai.flowstep
Generate, inspect, and manage Flowstep UI designs directly from your AI assistant.
The bug mediator for AI-built apps: plain-English diagnosis + a ready fix, in your editor.
Related MCP Servers
- AlicenseNot gradedqualityAmaintenanceEnables AI assistants to access SAP ADT APIs for reading, writing, debugging, deploying, and testing ABAP code through natural language or DSL automation.512MIT
- AlicenseNot gradedqualityBmaintenanceEnables AI agents to debug code inside VS Code by setting breakpoints, stepping through execution, inspecting variables, and evaluating expressions across multiple languages.575MIT
- AlicenseNot gradedqualityBmaintenanceEnables AI agents to perform ABAP Development Tools operations on SAP ERP (ECC and S/4HANA) systems, including source code editing, object activation, syntax checks, and ABAP unit tests.8 npmMIT
- AlicenseNot gradedqualityCmaintenanceEnables AI assistants to work with SAP ABAP systems through the ADT REST API, supporting repository search, source code read/write, activation, syntax checks, and transport request management.1Apache 2.0