Skip to main content
Glama

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
SAP_USERYesSAP logon user.
RFC_GROUPNoLogon group for load-balanced RFC.PUBLIC
RFC_SYSNRNoTwo-digit system number for direct RFC, e.g. 00.
RFC_ASHOSTNoApplication server host for direct RFC (sap_rfc_* tools only).
RFC_MSHOSTNoMessage server host for load-balanced RFC.
RFC_R3NAMENoSystem ID for load-balanced RFC, e.g. A4H.
SAP_CLIENTYesSAP client, e.g. 100.
SAP_BASE_URLYesThe base URL of the SAP system, e.g. https://sap.example.com:44300 (no trailing slash).
SAP_LANGUAGENoSAP logon language.EN
SAP_PASSWORDYesSAP logon password.
SAP_TIMEOUT_MSNoPer-request timeout in milliseconds.60000
SAP_VERIFY_SSLNoSet to 'false' to accept self-signed certificates.true
SAP_DEBUG_STEP_TIMEOUT_MSNoPer-request timeout for debugger steps.600000

Instructions

Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.

This server publishes no instructions, or was last inspected before Glama recorded them.

Capabilities

Features and capabilities supported by this server

Protocol revision2025-11-25

CapabilityDetails
tools
{
  "listChanged": true
}

Tools

Functions exposed to the LLM to take actions

NameDescription
sap_connection_testA

Verify connectivity and authentication to the configured SAP S/4HANA system via ADT.

Performs a CSRF/session handshake and reads the ADT discovery document. Use this first to confirm SAP_BASE_URL, SAP_CLIENT, SAP_USER, and SAP_PASSWORD are correct and that the /sap/bc/adt ICF service is active.

Args:

  • response_format ('markdown' | 'json'): Output format (default: 'markdown').

Returns (json): { baseUrl, client, user, language, authenticated: boolean, workspaces: string[] }.

Examples:

  • Use when: "Can you connect to SAP?" / first call in a session. Error Handling:

  • 401 -> bad user/password. 404 -> ADT service not active (SICF). TLS errors -> set SAP_VERIFY_SSL=false.

sap_search_objectsA

Quick-search the ABAP repository for objects (programs, classes, interfaces, function modules, tables, CDS, packages, etc.) by name pattern.

Args:

  • query (string): Name pattern; '' is a wildcard (e.g. 'ZFI', 'CL_POST').

  • max_results (number): 1-200 (default 50).

  • response_format ('markdown' | 'json').

Returns (json): { query, count, objects: [{ uri, type, name, packageName?, description? }] }. 'type' is the ADT type code, e.g. PROG/P (program), CLAS/OC (class), INTF/OI (interface), FUGR/FF (function module), TABL/DT (table), DDLS/DF (CDS).

Examples:

  • "Find custom FI programs" -> query 'ZFI*'.

  • "Locate the T001 table" -> query 'T001'.

  • Don't use to read source (use sap_get_source) or table data (use sap_read_table). Error Handling:

  • Empty list -> no objects match the pattern; broaden the wildcard.

sap_get_sourceA

Read the ABAP source code of a program, include, class, interface, or function module.

Args:

  • object_type ('program'|'include'|'class'|'interface'|'function').

  • object_name (string): e.g. 'ZFI_POST', 'CL_FOO'.

  • function_group (string): required only for object_type='function'.

  • response_format ('markdown' | 'json').

Returns (json): { objectType, objectName, sourceUri, etag?, source, lineCount }. 'etag' identifies the version and enables concurrency-safe writes.

Examples:

  • "Show me class CL_FOO" -> object_type='class', object_name='CL_FOO'.

  • "Read function module Z_CALC in group ZFG1" -> object_type='function', object_name='Z_CALC', function_group='ZFG1'. Error Handling:

  • 404 -> wrong name/type, or missing function_group for a function module.

sap_get_ddicA

Inspect a Data Dictionary object's definition.

Behavior by type (read-only, release-independent via the DDIC repository tables):

  • 'table' / 'structure': returns the field list (fieldname, position, keyflag, rollname, datatype, leng, decimals, checktable).

  • 'dataelement': returns attributes (domain, datatype, length, decimals).

  • 'domain': returns the domain attributes plus fixed values.

  • 'cds': returns the CDS view DDL source text.

Args:

  • object_type ('table'|'structure'|'dataelement'|'domain'|'cds').

  • object_name (string).

  • response_format ('markdown' | 'json').

Returns (json): { objectType, objectName, detail, rawSource? }.

Examples:

  • "What fields are in TKEDRS?" -> object_type='table', object_name='TKEDRS'.

  • "Fixed values of domain BOOLE_D" -> object_type='domain', object_name='BOOLE_D'. Error Handling:

  • Empty fields -> object may not exist or is not active (as4local='A').

sap_read_tableA

Read the CONTENTS of any table or view the user is authorized for, via the ADT SQL Data Preview. This is the primary tool for reading customizing (T*) tables and business data.

Args:

  • table (string): table/view name.

  • fields (string[]): optional columns; omit for all.

  • where (string): optional WHERE clause without the 'WHERE' keyword. Use single quotes for literals.

  • max_rows (number): 1-1000 (default 100).

  • response_format ('markdown' | 'json').

Returns (json): { query, columns: [{name,type,length,description,key}], rows: [{col: value}], rowCount, totalRows, truncated }.

Examples:

  • "Show company codes" -> table='T001', fields=['BUKRS','BUTXT'].

  • "CO-PA derivation rules for strategy 1" -> table='TKEDRS', where="kalsm = '...'".

  • "FI documents for company 1000 in 2026" -> table='BKPF', where="bukrs = '1000' AND gjahr = '2026'", max_rows=50. Notes & Error Handling:

  • Read-only (SELECT only). Authorization is enforced by SAP (S_TABU_*).

  • 403 -> the user lacks display authorization for this table.

  • Large tables: always pass 'where' and/or 'fields' and a small 'max_rows'.

sap_sql_queryA

Run a freestyle, read-only ABAP-SQL SELECT (including joins) via the ADT Data Preview. Use this when sap_read_table is not expressive enough.

Args:

  • sql (string): a SELECT statement. Only SELECT is permitted.

  • max_rows (number): 1-1000 (default 100).

  • response_format ('markdown' | 'json').

Returns (json): same shape as sap_read_table.

Examples:

  • "Join BKPF and BSEG for company 1000" -> sql="SELECT kbelnr, kgjahr, bhkont, bdmbtr FROM bkpf AS k INNER JOIN bseg AS b ON kbukrs = bbukrs AND kbelnr = bbelnr AND kgjahr = bgjahr WHERE k~bukrs = '1000'". Error Handling:

  • Rejects anything that is not a SELECT.

  • SAP syntax errors are returned with the server message.

sap_syntax_checkA

Run an ABAP syntax check (check run) against an object and return errors, warnings, and info messages.

Args:

  • object_type ('program'|'include'|'class'|'interface'|'function').

  • object_name (string).

  • function_group (string): required for functions.

  • version ('active'|'inactive', default 'active').

  • response_format ('markdown' | 'json').

Returns (json): { objectType, objectName, version, errorCount, warningCount, messages: [{type, text, uri?}] }.

Examples:

  • After editing inactive source -> version='inactive' to validate before activation. Error Handling:

  • 404 -> object/version not found.

sap_list_transportsA

List workbench/customizing transport requests (and their tasks) owned by a user, via the CTS ADT service.

Args:

  • user (string): defaults to the logon user (SAP_USER).

  • response_format ('markdown' | 'json').

Returns (json): { user, count, transports: [{ number, description, status, owner, tasks: [...] }], raw? }. Status codes: 'D'/'L' = modifiable, 'O'/'R' = released.

Examples:

  • "What transports do I have open?" -> (no args).

  • Use the returned request number as 'transport' for sap_write_source. Error Handling:

  • The CTS response shape varies by release; when structured parsing yields nothing, 'raw' XML is returned.

sap_write_sourceA

Replace the source code of an EXISTING program, include, class, interface, or function module. This MODIFIES the SAP system.

The tool runs the full stateful flow: lock -> write source -> (optionally activate) -> unlock. It captures the current ETag to avoid overwriting concurrent changes.

Args:

  • object_type ('program'|'include'|'class'|'interface'|'function').

  • object_name (string): must already exist (this tool does not create objects).

  • function_group (string): required for functions.

  • source (string): the complete replacement source.

  • transport (string): required for non-local objects; get one from sap_list_transports.

  • activate (boolean, default false): activate after writing.

  • response_format ('markdown' | 'json').

Returns (json): { objectType, objectName, sourceUri, bytesWritten, transport?, activated, activationMessages: [{type,text}], message }.

Examples:

  • "Update class CL_FOO and activate" -> object_type='class', object_name='CL_FOO', source='...', transport='DEVK900123', activate=true. Error Handling:

  • 423 -> object locked by someone else. 412 -> ETag changed (re-read first).

  • Missing transport on a transportable object -> returns an actionable error; the lock is released automatically.

  • Activation errors are returned in activationMessages (the source is still written but inactive).

sap_activateA

Activate one or more inactive ABAP objects. This MODIFIES the SAP system (makes the working version live).

Args:

  • objects (array): each { object_type, object_name, function_group? }. Activating related objects together resolves cross-dependencies.

  • response_format ('markdown' | 'json').

Returns (json): { activated: boolean, objects: [{type,name}], messages: [{type,text,line?}] }. 'activated' is true only when there are no error (E) messages.

Examples:

  • "Activate CL_FOO and its interface" -> objects=[{class,CL_FOO},{interface,IF_FOO}]. Error Handling:

  • Activation errors (syntax, unresolved deps) are returned as messages with type 'E'.

sap_list_breakpointsA

List the external (ADT) breakpoints set through this MCP server.

IMPORTANT — this is a client-side list. SAP offers no enumeration for external breakpoints: GET /sap/bc/adt/debugger/breakpoints answers HTTP 200 with an empty body even while breakpoints exist, and Eclipse works the same way (client-side truth, full-set sync on write). So this returns what this server has set since it started; breakpoints set from Eclipse, or by this server before a restart, are not listed. To cross-check the server side, run sap_sql_query on ABDBG_EXTDBPS (key RQ_USER).

Returns (json): { user, client, count, breakpoints: [{id, clientId, uri, line, objectName, condition, enabled}], note }. 'id' is the structured id SAP assigned (KIND=…LINE_NR=…), used by sap_delete_breakpoints.

Examples:

  • "Show my current breakpoints" -> (no args).

sap_set_breakpointA

Set an external (ADT) breakpoint at a line in an ABAP object, for the user the debug session listens for (default SAP_USER).

Args:

  • object_type, object_name, line (required).

  • condition (optional): ABAP expression; break only when true. Best-effort — the condition attribute is not verified on this system.

  • function_group: required for object_type='function'.

  • response_format.

Returns (json): { success, breakpoints: [{id, clientId, uri, line, objectName, condition}], failed, message }. SAP resolves the source line to the line of the generated include, so the id may name a different LINE_NR than you asked for. That is normal.

Examples:

  • "Break on ZTEST line 42" -> object_type='program', object_name='ZTEST', line=42.

  • "Break on ZCL_FOO line 15 when SY-SUBRC <> 0" -> add condition="SY-SUBRC <> 0". Notes:

  • Works standalone: external breakpoints persist in SAP (table ABDBG_EXTDBPS) whether or not a debug session exists. They only TRAP execution while a listener is armed — call sap_debug_attach, then sap_debug_wait.

  • The ADT write is a FULL-SET SYNC: every call re-sends this server's whole breakpoint registry as the complete set for its identity. A consequence worth knowing: the first sap_set_breakpoint after a server restart drops breakpoints an earlier run left behind.

  • The breakpoint is keyed to the debug session's user. To trap another user's execution, pass that user to sap_debug_attach BEFORE setting breakpoints.

sap_delete_breakpointsA

Delete specific external breakpoints, or clear the whole external breakpoint set.

Args:

  • ids (string[]): structured ids from sap_list_breakpoints / sap_set_breakpoint. Omit to clear everything.

  • response_format.

Returns (json): { deleted, message }.

Examples:

  • "Clear all my breakpoints" -> (no ids). Sends an empty full-set sync, which clears the server side even for breakpoints this server no longer remembers (e.g. after a restart) — this is the reliable way to be sure nothing is left.

  • "Delete that breakpoint" -> ids=["KIND=0.SOURCETYPE=ABAP.MAIN_PROGRAM=…LINE_NR=12"]. Notes:

  • 'deleted' counts what this server knew about; the no-ids path may remove more on the server.

sap_create_objectA

Create a new ABAP repository object (program, include, class, interface, or function group). The object must not already exist. After creation, use sap_write_source to add source code and sap_activate to make it live.

Args:

  • object_type ('program'|'include'|'class'|'interface'|'function_group').

  • object_name (string): new object name.

  • description (string): short description (≤70 chars).

  • package (string): default '$TMP' (local, no transport). Use a Z-package for real development.

  • transport (string): required when package ≠ '$TMP'.

  • response_format.

Returns (json): { objectType, objectName, uri, transport?, message }.

Examples:

  • "Create program ZTEST in $TMP" -> object_type='program', object_name='ZTEST', description='Test', package='$TMP'.

  • "Create class ZCL_HANDLER in ZDEV package" -> object_type='class', object_name='ZCL_HANDLER', package='ZDEV', transport='DEVK900123'. Notes:

  • After creation the object is empty and inactive. Write source with sap_write_source then activate.

  • Function modules cannot be created directly — create the function_group first, then use SE37 or sap_write_source on the group.

sap_run_consoleA

Execute an ABAP snippet server-side via the ADT class-run endpoint — no RFC SDK required. The snippet becomes the body of IF_OO_ADT_CLASSRUN~MAIN in a reusable local ($TMP) runner class, so it can CALL FUNCTION any function module / BAPI and print results with out->write( ). This is the SDK-free substitute for the sap_rfc_* tools.

Args:

  • abap_code (string): ABAP for the method body. 'out->write( v )' returns data; 'out' is ref to if_oo_adt_classrun_out.

  • class_name (string): runner class (default 'ZMCP_CONSOLE', $TMP local).

  • response_format.

Returns (json): { className, activated, output, message }.

Examples:

  • Call a function module: CALL FUNCTION 'RFC_SYSTEM_INFO' IMPORTING rfcsi_export = DATA(ls). out->write( ls-rfcsaprl ).

  • Quick value: out->write( |Client { sy-mandt }, user { sy-uname }| ). Notes:

  • Requires S_DEVELOP (creates/activates a temp class). Dev/sandbox only — not production.

  • For data-changing BAPIs, add CALL FUNCTION 'BAPI_TRANSACTION_COMMIT' in the same snippet.

  • Prefer sap_read_table / sap_sql_query for plain data reads.

sap_where_usedA

Find all repository objects that reference a given object (where-used list). Essential before changing or deleting anything.

Supply either:

  • object_uri: the full ADT URI (from sap_search_objects), OR

  • object_type + object_name (and function_group if needed).

Args:

  • object_uri / object_type + object_name.

  • max_results (default 100).

  • response_format.

Returns (json): { objectUri, count, refs: [{uri, type, name, packageName?, description?}], truncated }.

Examples:

  • "What uses CL_FOO?" -> object_type='class', object_name='CL_FOO'.

  • "Where is this function group called?" -> object_uri='/sap/bc/adt/functions/groups/zfg1'.

sap_run_unit_testsA

Execute ABAP Unit tests for an object and return pass/fail results per test method.

Runs all test classes (FOR TESTING) contained in or associated with the object. Useful for verifying changes before activating or releasing.

Args:

  • object_type, object_name (and function_group for functions).

  • response_format.

Returns (json): { objectName, total, passed, failed, errors, skipped, testClasses: [{name, methods: [{name, outcome, alerts: [{kind, title, details?}]}]}] }.

Examples:

  • "Run tests for ZCL_FOO" -> object_type='class', object_name='ZCL_FOO'.

  • "Did my last edit break anything?" -> run tests for the changed class. Notes:

  • Object must have test classes defined. No tests = total=0.

  • Requires S_DEVELOP authorization.

sap_create_transportA

Create a new workbench or customizing transport request. Returns the transport number to use in sap_write_source, sap_create_object, or sap_delete_object.

Args:

  • description (string): shown in SE09/SE10.

  • category ('Workbench' | 'Customizing', default 'Workbench').

  • response_format.

Returns (json): { number, description, category, message }.

Examples:

  • "Create a transport for my changes" -> description='My feature XYZ'.

  • Use the returned number as the 'transport' param for write/create/delete operations.

sap_release_transportA

Release (export) a transport request. This starts the transport release job.

WARNING: Releasing a transport is IRREVERSIBLE. The request becomes read-only. Ensure all objects in it are correct and activated before releasing.

Args:

  • number (string): transport number from sap_list_transports or sap_create_transport.

  • response_format.

Returns (json): { number, released, jobId?, message }.

Examples:

  • "Release transport DEVK900123" -> number='DEVK900123'.

sap_delete_objectA

Delete an ABAP repository object. This PERMANENTLY REMOVES the object from SAP.

The tool locks the object, deletes it, and records the change in the transport if provided. This cannot be undone (except by restoring from a transport or backup).

Args:

  • object_type, object_name (and function_group for functions).

  • transport: required for non-local objects.

  • response_format.

Returns (json): { objectType, objectName, message }.

Examples:

  • "Delete program ZOLD_PROG from $TMP" -> object_type='program', object_name='ZOLD_PROG'.

  • "Delete class ZCL_OLD from transport DEVK900123" -> object_type='class', object_name='ZCL_OLD', transport='DEVK900123'. Notes:

  • Run sap_where_used first to verify nothing depends on this object.

  • Deleting a function group removes all its function modules too.

sap_browse_packageA

List the repository objects and sub-packages inside an ABAP package. Useful for exploring what's in a package before making changes or doing an audit.

Args:

  • package_name (string).

  • response_format.

Returns (json): { packageName, count, nodes: [{uri, type, name, description?, expandable?}] }. type: DEVC/K (sub-package), PROG/P (program), CLAS/OC (class), INTF/OI (interface), FUGR (function group), etc.

Examples:

  • "What's in package ZDEV?" -> package_name='ZDEV'.

  • Browse $TMP to see local objects.

sap_get_screen_sourceA

Read the flow logic (PBO/PAI) source code of a dynpro/screen. Screens are separate from program source — this is the screen ABAP (not the element list).

Args:

  • program (string): the program owning the screen.

  • screen_number (int or string): e.g. 100, '0100'.

  • response_format.

Returns (json): { program, screenNumber, sourceUri, source, lineCount }.

Examples:

  • "Read screen 100 of ZPROG" -> program='ZPROG', screen_number=100. Notes:

  • Returns only the flow logic (PBO/PAI). The screen layout (element list) is not available via ADT.

  • 404 means the screen doesn't exist on this program.

sap_get_message_classA

Read all messages in an ABAP message class (T100 content + metadata).

Args:

  • name (string): message class name.

  • response_format.

Returns (json): { name, description?, language?, count, messages: [{id, text, selfExplanatory?}] }.

Examples:

  • "What messages are in ZFI_MSGS?" -> name='ZFI_MSGS'.

  • "Find the text for message 001 in class VR" -> name='VR' then look for id='001'.

sap_get_badiA

Read the definition of a BAdI (Business Add-In) from the Enhancement Framework, including its interface and active implementations.

Args:

  • name (string): BAdI definition name.

  • response_format.

Returns (json): { name, description?, interfaceName?, implCount, implementations: [{name, active, description?}], raw? }. raw is set when structured parsing yields nothing (ADT response varies by release).

Examples:

  • "What implementations exist for MB_DOCUMENT_BADI?" -> name='MB_DOCUMENT_BADI'.

  • "Is there a BAdI for FI document posting?" -> name='BADI_FBAS_RFDT'. Notes:

  • This reads definition metadata only. Use sap_get_source to read the actual implementation class source.

  • Enhancement spot browsing follows the same pattern; try the spot name if the BAdI name isn't found.

sap_debug_attachA

Open a debug session handle and confirm this server may listen for a user's execution.

BEHAVIOUR CHANGED (the old 'attach to a terminal/session id' had no counterpart in the ADT protocol — there is no debug-session resource). ADT debugging is listener-based: you arm a listener for a USER, and the first line that user executes under a breakpoint traps and freezes their work process. This call validates the scope and creates the handle; sap_debug_wait is what actually registers the listener and blocks.

Workflow:

  1. sap_debug_attach (this call — validates, returns session_id)

  2. sap_set_breakpoint (one or more)

  3. run the ABAP code AS THAT USER (SAP GUI, a transaction, an RFC…)

  4. sap_debug_wait (registers the listener, blocks until the code traps)

  5. sap_debug_variables / sap_debug_eval / sap_debug_step

  6. sap_debug_detach (ALWAYS — clears breakpoints, releases the debuggee, deletes the listener)

Args:

  • user (string): user to trap. Default SAP_USER. The old 'terminal_id' argument is gone; it named a target the protocol does not have.

  • mode ('user' | 'terminal'): debugging scope (default 'user').

  • take_over (boolean): take the scope over from another IDE (default false).

  • response_format.

Returns (json): { sessionId, state: 'LISTENING', user, mode, message }. sessionId (e.g. 'dbg-1') is a handle in THIS server, not a SAP object. It does not survive a server restart.

Error Handling:

  • Conflict (HTTP 409): another session holds the debugging scope — the message carries SAP's conflictText and the holding user. Re-run with take_over=true to seize it. A listener this server itself left behind (crashed run) is detected and cleared automatically.

  • One debug session at a time: detach the current one first.

sap_debug_waitA

Register the debug listener and block until the watched user's code traps on a breakpoint — then attach to it and return the stop position and call stack.

BEHAVIOUR CHANGED: this is now a real server-side long-poll (POST /sap/bc/adt/debugger/listeners), not a state-polling loop, and it performs the attach itself. Registration is a side effect of this call: once made, the listener stays armed on SAP across timeouts until sap_debug_detach deletes it.

Args:

  • session_id (string): from sap_debug_attach.

  • timeout_ms (int): client-side cap (default 60000, max 300000).

  • poll_interval_ms (int): ignored, kept for compatibility.

  • response_format.

Returns (json): { sessionId, state, program?, include?, line?, stack, debuggee?, reachedBreakpoints?, message }.

  • state='STOPPED': a debuggee is attached and FROZEN. Inspect with sap_debug_variables, move with sap_debug_step, and release promptly — this is a real user session halted mid-execution, and SAP kills an abandoned debuggee after its own timeout.

  • state='TIMEOUT': nothing trapped in time; the listener is still armed, so call again (after making sure the code actually runs as that user).

  • state='CANCELLED': the listener was deleted elsewhere — call sap_debug_attach again.

Error Handling:

  • Conflict: another IDE took the scope over mid-wait; the message carries SAP's conflictText.

sap_debug_stateA

Report the state of a debug session, plus a fresh call stack when a debuggee is stopped.

Args:

  • session_id (string).

  • response_format.

Returns (json): { sessionId, state, program?, include?, line?, stack: [{index, program, include?, line?, name?}], debuggee?, reachedBreakpoints? }. States: LISTENING (armed, nothing trapped yet) · STOPPED (debuggee frozen) · RUNNING (a step has not come back yet) · TIMEOUT / CANCELLED / ENDED / DETACHED. Only STOPPED calls SAP; the other states are answered from this server.

sap_debug_variablesA

Read ABAP variable values at the current stop point.

Requires state='STOPPED' (a debuggee attached by sap_debug_wait).

Args:

  • session_id (string).

  • names (string[]): specific variables; omit for all locals (the '@ROOT' hierarchy).

  • response_format.

Returns (json): { sessionId, count, variables: [{name, id?, type?, value?, kind?, tableLines?}] }. kind: 'elementary' | 'structure' | 'table' | 'reference'. Values SAP truncated are marked as truncated; tables report tableLines.

Error Handling:

  • 'No debuggee attached' -> the session is not STOPPED; run the code and call sap_debug_wait first.

sap_debug_stepA

Move the stopped debuggee: stepOver, stepInto, stepOut, stepReturn, continue, or stop.

Requires state='STOPPED'. The call returns when the debuggee stops again — 'continue' therefore BLOCKS for as long as the program runs to its next breakpoint, which can be minutes. Steps run on their own timeout (SAP_DEBUG_STEP_TIMEOUT_MS, default 600000 ms), not the 60s global one.

Args:

  • session_id (string).

  • command ('stepOver'|'stepInto'|'stepOut'|'stepReturn'|'continue'|'stop').

  • response_format.

Returns (json): { sessionId, command, state, program?, include?, line?, reachedBreakpoints?, message }.

  • state='STOPPED': stopped again; program/line say where, reachedBreakpoints says on which breakpoint.

  • state='ENDED': the debuggee ran to completion (a NORMAL outcome of 'continue', and the only outcome of 'stop'). The listener stays armed — call sap_debug_wait to catch the next trap, or sap_debug_detach to finish.

  • state='RUNNING': the step did not come back inside the timeout; the debuggee is probably still running. Check with sap_debug_state or release it with sap_debug_detach.

sap_debug_evalA

Read one variable at the current stop point, without listing all locals.

Note: the ABAP debugger resolves variable IDs, not computed expressions. 'LV_AMOUNT', 'SY-SUBRC' and 'GT_RESULT' work; 'strlen( lv_text )' does not — there is no evaluate-expression service in this API.

Args:

  • session_id (string).

  • expression (string): variable name.

  • response_format.

Returns (json): { sessionId, expression, value, type? }. Error Handling:

  • Not in scope at the current stop point -> use sap_debug_variables to see what is visible here.

sap_debug_detachA

End a debug session and leave nothing behind on SAP. ALWAYS call this when done — a frozen debuggee is a real user session that cannot continue, and an armed listener keeps trapping that user's execution.

Cleanup, in order, each step best-effort and reported individually:

  1. clear the breakpoints this server set (empty full-set sync);

  2. release the frozen debuggee ('continue'; if that fails for any reason other than the program having ended, drop its ABAP session to force the release);

  3. log the stateful debug connection off;

  4. delete the listener registration;

  5. verify — re-check the scope and confirm nothing remains.

Args:

  • session_id (string).

  • response_format.

Returns (json): { sessionId, breakpointsCleared, debuggeeReleased, listenerDeleted, verified, message }. verified=false means the check could not confirm the listener is gone: call again.

Idempotent — safe to call twice, and safe to call on a session that already ended.

sap_rfc_pingA

Test the RFC connection to SAP using STFC_CONNECTION. Requires node-rfc and the SAP NW RFC SDK.

Configure via RFC_ASHOST + RFC_SYSNR (direct) or RFC_MSHOST + RFC_R3NAME (load-balanced) in .env.

Returns (json): { connected, systemId?, message }.

Notes:

  • If the SDK is not installed this tool returns a clear error with setup instructions.

  • Credentials are reused from SAP_CLIENT, SAP_USER, SAP_PASSWORD.

sap_rfc_system_infoA

Call RFC_SYSTEM_INFO to retrieve SAP system metadata (SID, host, release).

Returns (json): { sysId, client, host, programId?, releaseVersion?, language? }.

sap_rfc_describeA

Get the parameter list (import, export, changing, table) of any RFC-enabled function module.

Args:

  • function_name (string): name of the function module.

  • response_format.

Returns (json): { name, parameters: [{ name, direction, type, length?, description?, optional? }] }. direction: I=import, E=export, C=changing, T=table.

Examples:

  • "What parameters does BAPI_SALESORDER_CREATEFROMDAT2 take?" -> function_name='BAPI_SALESORDER_CREATEFROMDAT2'.

sap_rfc_callA

Call any RFC-enabled function module and return all exported parameters. Use sap_rfc_describe first to discover parameters.

WARNING: This can execute arbitrary function modules including write operations. Confirm authorization before calling write FMs in production.

Args:

  • function_name (string): RFC FM name.

  • params (object): import/changing parameters (default: {}).

  • response_format.

Returns (json): { functionName, result: { ...exported parameters } }.

Examples:

  • Read material: function_name='BAPI_MATERIAL_GET_DETAIL', params={"MATERIAL":"ROH-001"}.

  • RFC_READ_TABLE: function_name='RFC_READ_TABLE', params={"QUERY_TABLE":"T001","DELIMITER":"|"}.

sap_bapi_callA

Call a BAPI function module. Automatically calls BAPI_TRANSACTION_COMMIT on success or BAPI_TRANSACTION_ROLLBACK on ABAP error (type E/A in the RETURN table).

WARNING: BAPI calls can create, change, or delete business objects. Use only in development/sandbox unless you are certain of the effect.

Args:

  • bapi_name (string): BAPI name (must be RFC-enabled).

  • params (object): BAPI parameters (default: {}).

  • response_format.

Returns (json): { functionName, result, return?: [{type, id, number, message}], committed }. committed=true means BAPI_TRANSACTION_COMMIT was called. committed=false means an error occurred and it was rolled back.

Examples:

  • "Create a purchase order" -> bapi_name='BAPI_PO_CREATE1', params={...header/item tables...}.

sap_user_getA

Read SAP user details (address, logon data, lock status, roles, profiles) via BAPI_USER_GET_DETAIL.

Args:

  • username (string): SAP user name (max 12 chars).

  • response_format.

Returns (json): { username, firstName?, lastName?, email?, validFrom?, validTo?, locked?, roles: string[], profiles: string[] }.

Examples:

  • "What roles does user JSMITH have?" -> username='JSMITH'.

  • "Is user VENNELAKA locked?" -> username='VENNELAKA'.

sap_job_scheduleA

Create and schedule an ABAP background job via JOB_OPEN + JOB_SUBMIT + JOB_CLOSE.

WARNING: This immediately starts an ABAP program in background if immediate=true. Only use in development/sandbox or when you are certain of the effect.

Args:

  • job_name (string): job name visible in SM37.

  • program (string): ABAP program to execute.

  • variant (string): program variant (optional).

  • immediate (boolean): start immediately (default true).

  • response_format.

Returns (json): { jobName, jobCount, message }. Use jobCount + jobName to monitor in SM37.

Examples:

  • "Schedule ZMONTHLY_CLOSE now" -> job_name='ZMONTHLY_CLOSE', program='ZMONTHLY_CLOSE'.

  • "Schedule with variant PROD" -> ..., variant='PROD'.

sap_atc_runA

Run an ATC (ABAP Test Cockpit) check on an ABAP object and return the findings (priority, check, message, line). Use before releasing a transport.

Supply either:

  • object_uri: the full ADT URI (from sap_search_objects), OR

  • object_type + object_name (and function_group if needed).

Args:

  • object_uri / object_type + object_name.

  • check_variant (string): ATC variant; omit for the system default.

  • max_results (number): 1-1000 (default 100).

  • response_format.

Returns (json): { objectUri, checkVariant, worklistId, timestamp?, stats: {prio1, prio2, prio3}, findingCount, objects: [{uri, type, name, packageName?, findings: [{uri, location?, line?, priority, checkId?, checkTitle?, messageId?, messageTitle}]}] }. Priority 1 = error, 2 = warning, 3 = information.

Examples:

  • "ATC-check ZCL_FOO before I release the transport" -> object_type='class', object_name='ZCL_FOO'.

  • "Run the Z_STRICT variant on ZFI_POST" -> object_type='program', object_name='ZFI_POST', check_variant='Z_STRICT'. Notes:

  • Each run records a server-side ATC worklist (visible in ATC administration). It is harmless and reused per check variant.

  • Large objects can exceed SAP_TIMEOUT_MS — check one object at a time.

sap_list_dumpsA

List recent ABAP runtime errors (ST22 short dumps): error ID, terminated program, user, time, and the dump URI for sap_get_dump.

Args:

  • max_items (number): 1-100 (default 20).

  • from_date / to_date (string): YYYYMMDDHHMMSS window.

  • user (string): only dumps caused by this user.

  • response_format.

Returns (json): { count, dumps: [{ errorId, program?, user, published, shortText?, uri }], filteredBy? }. Pass 'uri' verbatim to sap_get_dump — it contains encoded characters.

Examples:

  • "Did anything dump today?" -> from_date='20260727000000'.

  • "Show my last 5 dumps" -> max_items=5, user='DEVELOPER'. Notes:

  • from_date/to_date are the only server-side filters. The server returns a fixed page of the most recent dumps regardless of max_items, so user filtering and max_items are applied to that page here — use from_date/to_date when hunting older dumps.

  • Dumps are reorganised by housekeeping jobs, so old entries eventually disappear.

sap_get_dumpA

Read one ABAP runtime error (short dump) in full: metadata plus the formatted ST22 analysis text. Get the dump_uri from sap_list_dumps.

Args:

  • dump_uri (string): the 'uri' from a sap_list_dumps entry, passed through unchanged.

  • response_format.

Returns (json): { uri, errorId, title?, author?, exception?, terminatedProgram?, serverInstance?, datetime?, text, lineCount }. 'text' is the full ST22 report (error analysis, source extract, call stack).

Examples:

  • "Why did that dump happen?" -> sap_list_dumps first, then sap_get_dump with its uri. Error Handling:

  • 404 -> the dump was reorganised (housekeeping) or the URI is wrong; re-run sap_list_dumps.

sap_list_inactiveA

List all inactive ABAP objects for the system (objects edited but not yet activated), with owner and transport. Use to find leftovers before activating or transporting.

Args:

  • user (string): optional filter on the owning user.

  • response_format.

Returns (json): { count, objects: [{ uri, type, name, parentUri?, user?, deleted?, transport? }] }.

Examples:

  • "What did I forget to activate?" -> user='DEVELOPER'.

  • "Is anything inactive before I release DEVK900123?" -> no args. Notes:

  • The user filter is applied client-side on the returned list.

  • Activate what you find with sap_activate.

sap_get_revisionsA

List the version history (revisions) of an ABAP object, or fetch the source of a specific old version.

Args:

  • object_type, object_name (and function_group for functions).

  • version (string): omit to list revisions; supply to read that revision's source.

  • response_format.

Returns (json): { objectType, objectName, versionsUri, count, revisions: [{ version, author?, updated?, contentUri }], version?, source?, lineCount? }.

Examples:

  • "What versions exist of ZFI_POST?" -> object_type='program', object_name='ZFI_POST'.

  • "Show version 00002 of ZFI_POST" -> ..., version='00002'.

  • "What changed since the last transport?" -> read an old version, then compare with sap_get_source. Notes:

  • Version records exist only where SAP created them (transport release, SE38/ADT version generation). A freshly created $TMP object may legitimately have none.

  • Requesting an unknown version returns the list of available version numbers.

sap_get_transactionA

Read a transaction code's SE93 definition: started program/screen, transaction type (decoded from the CINFO bit field), short text, package, parameter/OO target, SM01 lock, and the SE93 authorization checks (TSTCA). Core tool for authorization audits.

Args:

  • tcode (string): the transaction code.

  • response_format.

Returns (json): { tcode, exists, cinfo?, transactionType?, flags?, hasCheckObject?, lockedViaSM01?, reportWithVariant?, program?, screen?, description?, packageName?, author?, parameter?, targetClass?, targetMethod?, authChecks: [{TCODE, OBJCT, FIELD, VALUE}], authCheckCount }. transactionType is one of dialog | menu | parameter | report | object.

Examples:

  • "What does SE38 actually start?" -> tcode='SE38'.

  • "Which authorizations does VA01 check at start?" -> tcode='VA01', read authChecks. Notes:

  • The type is decoded from CINFO, which is a BIT FIELD: a transaction commonly carries several flags at once (SE38 = 84 = report transaction + has check object), so 'flags' can list more than the headline type.

  • 'program' is legitimately empty for parameter and OO transactions — look at 'parameter' / targetClass+targetMethod instead.

  • authChecks are the SE93-maintained TSTCA rows (the checks performed at transaction START), not the full set of authority checks a program performs. Code-level AUTHORITY-CHECK statements live in the source — use sap_get_source or sap_where_used for those.

  • Short text is read in English (TSTCT SPRSL='E'); a transaction with no English text returns no description.

sap_get_api_releaseA

Check whether an ABAP object is a released API and under which compatibility contract (C1 = cloud development / key-user apps). Reads the ADT apireleases resource. Objects of non-releasable types (e.g. programs) get a normal 'not releasable' answer.

Supply either:

  • object_uri: the full ADT URI (from sap_search_objects), OR

  • object_type + object_name (and function_group if needed).

Args:

  • object_uri / object_type + object_name.

  • response_format.

Returns (json): { objectUri, releasable, isAnyContractReleased?, contracts: [{contract, state, useInSAPCloudPlatform?, useInKeyUserApps?, changedBy?, changedAt?}], message? }. state is one of RELEASED, DEPRECATED, NOT_RELEASED, NOT_TO_BE_RELEASED, NOT_TO_BE_RELEASED_STABLE.

Examples:

  • "Is IF_OO_ADT_CLASSRUN a released API?" -> object_type='interface', object_name='IF_OO_ADT_CLASSRUN'.

  • "Can I use CL_GUI_ALV_GRID in cloud development?" -> object_type='class', object_name='CL_GUI_ALV_GRID'.

  • "Is the CDS view I_PRODUCT released?" -> object_uri='/sap/bc/adt/ddic/ddl/sources/i_product'. Notes:

  • On an on-premise system 'released' is SAP's upgrade-stability contract: C1 means the object is usable in cloud development and key-user extensibility. NOT_RELEASED on a Z object is the expected state, not a problem.

  • releasable=false ("No entry found for object type ...") is the normal answer for programs, includes and other non-API object types — not an error.

  • The table ARS_W_API_STATE holds the same data and is readable via sap_read_table, but this endpoint resolves object URIs and non-releasable types itself.

sap_get_auth_objectA

Read an authorization object's definition (SU21) via ADT: description, object class, and fields. Use with sap_get_transaction (TSTCA rows) and sap_sql_query (USR12/AGR_1251) for authorization audits.

Args:

  • name (string): the authorization object.

  • include_activities (boolean): append the system-wide ACTVT catalog (large — several hundred entries).

  • response_format.

Returns (json): { name, type, description?, objectClass?, objectClassDescription?, fields: [{name, description, ...}], activities?, activitiesError?, raw? }.

Examples:

  • "What does S_TCODE check?" -> name='S_TCODE'.

  • "Which fields does S_DEVELOP have, and what do the ACTVT values mean?" -> name='S_DEVELOP', include_activities=true. Notes:

  • This reads the object DEFINITION. For where it is actually checked, combine with sap_get_transaction (SE93 start checks), sap_sql_query over USOBT_C/USOBX_C (SU24 defaults), AGR_1251 (role values) and USR12 (user values).

  • The activity catalog is global, not per-object, and is fetched separately; if that call fails the main result is still returned with activitiesError set.

  • 'raw' appears only when this release structures the fields differently than expected — report it if you see it.

sap_get_text_elementsA

Read a program's / class's / function group's text elements: text symbols (TEXT-nnn), selection texts (parameter/select-option labels), and list headings.

Args:

  • object_type: 'program' | 'class' | 'function_group'.

  • object_name (string).

  • kind (string): one of 'symbols', 'selections', 'headings'; omit for all three.

  • response_format.

Returns (json): { objectType, objectName, kinds: [{ kind, entries: [{id, text, maxLength?, ddicReference?}], raw, note? }] }. Symbol ids are the 3-character numbers behind TEXT-nnn; selection ids are parameter / select-option names; heading ids are listHeader and columnHeader_1..4.

Examples:

  • "Why is my selection screen blank?" -> object_type='program', object_name='ZFI_POST', kind='selections'.

  • "What are ZCL_FOO's text symbols?" -> object_type='class', object_name='ZCL_FOO', kind='symbols'. Notes:

  • A kind the object does not use returns an empty list, not an error (a class typically has symbols only).

  • Texts come from the object's ORIGINAL (master) language pool, which is not necessarily English — SAP standard objects often return German.

  • ddicReference marks a selection text inherited from the DDIC data element rather than maintained locally.

  • Write them back with sap_set_text_elements.

sap_read_feedA

List the ADT feeds available on this system (system messages, gateway error log, ATC verdicts, ...), or read one feed's entries. For short dumps prefer sap_list_dumps, which is purpose-built.

Args:

  • feed_path (string): omit to list feeds; pass a href to read that feed.

  • max_items (number): 1-100 (default 20), applied when reading.

  • response_format.

Returns (json), listing: { count, feeds: [{ title, href, description? }] }. Returns (json), reading: { feedPath, count, entries: [{ title?, author?, published?, updated?, summary?, categories, uri? }] }.

Examples:

  • "What monitoring feeds does this system publish?" -> no arguments.

  • "Any gateway errors?" -> feed_path='/sap/bc/adt/gw/errorlog'. Notes:

  • Entry shape varies by feed; 'summary' is a best-effort plain-text rendering of what is often an escaped HTML document, capped at 500 characters per entry. Use response_format='json' for the full structure.

  • feed_path must start with /sap/bc/adt/ — this tool is not a general HTTP proxy.

  • Not every feed honours the server-side item limit, so max_items is also enforced here.

  • For ABAP runtime errors use sap_list_dumps / sap_get_dump instead; they parse the dump-specific fields.

sap_abap_docsA

Look up the system's own ABAP keyword documentation (F1 help, release-correct for this system) by keyword, reduced to readable text. Follow links from a previous result via the uri argument to navigate to sub-topics.

Args:

  • query (string): keyword or phrase to look up, OR

  • uri (string): a topic key from a previous result's links.

  • max_chars (number): 1000-20000 (default 8000).

  • response_format.

Returns (json): { query?, uri?, title?, text, truncatedAtMaxChars, links: [{title, uri}] }.

Examples:

  • "What does LOOP AT ... GROUP BY do on this release?" -> query='LOOP AT GROUP BY'.

  • "Show me the SELECT statement documentation" -> query='SELECT', then uri='ABAPSELECT' from the links to open the statement itself. Notes:

  • This is the documentation installed on THIS system, so it matches its ABAP release rather than the newest online version.

  • Language is fixed to EN this round.

  • The source is HTML reduced to text, so formatting (tables, syntax diagrams) is approximate — follow a link for depth rather than raising max_chars far.

  • A broad keyword returns a hit list: mostly links with little body text. Pick a link's uri and call again.

sap_set_text_elementsA

Write a program's / class's / function group's text elements: text symbols (TEXT-nnn), selection texts (parameter/select-option labels), or list headings. Entries are MERGED over the existing ones by id — ids you omit are preserved.

Args:

  • object_type, object_name, kind (one kind per call).

  • entries: [{ id, text, max_length? }].

  • transport (string): required for transportable packages.

  • activate (boolean): activate the owning object afterwards (default false).

  • response_format.

Returns (json): { objectType, objectName, kind, written, merged, transport?, activated, verified, notPersisted, message }. Every write is read back and compared: verified=true means the values are actually stored. notPersisted lists ids the server accepted but did not store.

Examples:

  • "Set text symbol 001" -> kind='symbols', entries=[{id:'001', text:'Processing complete', max_length:30}].

  • "Title the list output" -> kind='headings', entries=[{id:'listHeader', text:'Posting log'}]. Validation (checked before any call to SAP):

  • Symbol ids are exactly 3 characters; selection texts are at most 30 characters; heading ids must be listHeader (<= 71 chars) or columnHeader_1..4 (<= 255 chars). Notes:

  • The underlying PUT replaces the whole pool section for that kind, so this tool reads the current entries and merges yours over them. Editing one symbol therefore does not delete the others.

  • KNOWN LIMITATION on this release: kind='selections' is accepted with HTTP 200 but the values are NOT stored — the read-back still shows '?...'. The tool reports this honestly (verified=false, notPersisted listing the ids) instead of claiming success. Maintain selection texts in SE38 (Goto > Text elements > Selection texts) until this is resolved. 'symbols' and 'headings' write correctly.

  • Texts are stored in the object's ORIGINAL (master) language. On an object whose master language is not English, entries land in that language's pool.

  • Activation is not required for the texts to become visible; 'activate' is offered for the owning object's sake.

  • Read the result back with sap_get_text_elements.

sap_run_reportA

EXECUTES an ABAP report (program) on the SAP system and returns its list output as text. This runs real code with real side effects — the report may post documents, change configuration, lock objects or run for minutes. It is not a preview and there is no dry run.

The report runs synchronously (SUBMIT ... EXPORTING LIST TO MEMORY AND RETURN) inside the HTTP work process, so the output comes back in the same call, typically in under a second for a small report.

Args:

  • program_name (string): the report to run.

  • confirm_non_custom (boolean): must be true for any program not starting with Z or Y. Namespaced programs (/ABC/...) count as non-custom and need it too.

  • strip_list_header (boolean, default true): remove the ABAP list header lines.

  • max_chars (number): cap on returned characters (default 20000, max 60000).

  • response_format.

Returns (json): { programName, exists, authorized, ok, output, rawOutput, lineCount, bytes, durationMs, truncated, message }. ok=false means the run did not happen or produced no usable result — ALWAYS read ok, never assume success.

Examples:

  • "Run my report ZFI_CHECK and show the output" -> program_name='ZFI_CHECK'.

  • "Run the standard report RSUSR002" -> program_name='RSUSR002', confirm_non_custom=true (and be sure that is wanted). SELECTION-SCREEN PARAMETERS CANNOT BE PASSED:

  • The SAP endpoint's SUBMIT has no WITH clause, so a report with a selection screen runs on its DEFAULT values, silently. No client can work around this. If a report needs input, give its parameters DEFAULT values, generate a variant-free wrapper report, or use sap_job_schedule. Clean output via RESULT_TEXT (the reason to prefer this over scraping a list):

  • The handler ends with IMPORT result_text FROM MEMORY ID 'RESULT_TEXT'. A report that does EXPORT result_text = lv_string TO MEMORY ID 'RESULT_TEXT'. gets that exact string back — no list header, no 255-byte padding, no CRLF records. For a report you generate, emit JSON that way and read it back verbatim.

  • Use one channel or the other. A report that both WRITEs and exports gets the result string appended after the list, and the handler never clears RESULT_TEXT — a value left by an earlier run can reappear, so do not treat its presence as proof this run produced it. Notes:

  • HTTP 200 does not mean success: SAP answers "program does not exist" and authorization refusals with 200 and a plain sentence. This tool classifies the body and reports exists/authorized/ok accordingly, keeping the untouched body in rawOutput.

  • Empty output is a legitimate result for a report that WRITEs nothing, and is also what a report that terminates early looks like — the endpoint cannot tell them apart.

  • Only classic list output (WRITE) is captured. ALV grids and screens have no GUI to render into and are not tested on this system.

  • The only server-side gate is S_DEVELOP (OBJTYPE=PROG, ACTVT=16), which a developer passes for EVERY program including SAP standard. The Z/Y namespace rule enforced here is the real safety boundary.

  • A timeout does not cancel the report — it keeps running server-side. For long-running work use sap_job_schedule, which runs in the background and returns a job id.

Prompts

Interactive templates invoked by user choice

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription

No resources

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/appmaster3000/sap-abap-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server