From abap-adt-skill
Interact with SAP ABAP systems to search, read, modify, create, debug, and test ABAP workbench objects via ADT (ABAP Developer Tools). Use this skill when the user mentions SAP, ABAP, ADT, transports, ABAP classes, ABAP programs, function modules, or wants to work with ABAP objects on a remote SAP system.
How this skill is triggered — by the user, by Claude, or both
Slash command
/abap-adt-skill:abap-adtThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
You can interact with SAP ABAP systems through the `abap-adt` CLI tool.
You can interact with SAP ABAP systems through the abap-adt CLI tool.
NEVER print, echo, eval, or log passwords or encrypted credential blobs. You must:
echo $ADT_PASS, printenv ADT_PASS, or any command that would expose the password--password with an actual password value to any commandencryptedPassword field from ~/.sap/adt-connection.jsonabap-adt systems connect — do not attempt to read or display credentials yourselfUse the systems commands to browse and connect to SAP systems from SAPUILandscape.xml:
abap-adt systems list
abap-adt systems search SE1
abap-adt systems connect SE1 600
The connect command stores the connection (encrypted) to ~/.sap/adt-connection.json. Multiple systems can be stored and switched between. No env vars needed after connecting (Windows).
Use --no-https to force HTTP.
abap-adt systems status # show all stored connections + active details
abap-adt systems switch SE1 # switch active connection (partial match supported)
abap-adt systems switch SS2/100 # switch with exact key
abap-adt systems remove SS2/100 # remove a stored connection
After systems connect, credentials are stored encrypted. No env vars needed for subsequent commands (Windows).
ADT_PASS — only needed for the initial systems connect call, or as an overrideADT_USER — optional override; defaults to stored user or OS username (uppercased)ADT_PASS must be set for every sessionEnv vars override the connection file when set:
ADT_URL, ADT_CLIENT, ADT_LANGUAGE, ADT_ALLOW_SELF_SIGNED, ADT_USER, ADT_PASSAfter abap-adt systems connect ..., subsequent commands pick up the connection automatically:
abap-adt search "Z*"
abap-adt sql "SELECT * FROM T000"
abap-adt command not found)npm install -g @st-gr/abap-adt-skill
All commands support --json for machine-readable output.
abap-adt search "Z*" --type CLAS/OC --max 20
abap-adt search "Z*" --type DEVC/K # search packages
abap-adt search "CL_ADT*" --type CLAS/OC # search standard classes
Returns: Name, Type, Package, Description, URI for each match.
abap-adt structure /sap/bc/adt/oo/classes/zcl_my_class
Returns: Object name, type, description, source URI, class includes (for classes), links.
abap-adt read /sap/bc/adt/oo/classes/zcl_my_class
abap-adt read /sap/bc/adt/oo/classes/zcl_my_class --include definitions
abap-adt read /sap/bc/adt/programs/programs/zmy_report
If given an object URL (not a source URL), automatically resolves the source URI.
For classes, use --include to read: main, definitions, implementations, testclasses.
abap-adt write /sap/bc/adt/oo/classes/zcl_my_class --source-file /tmp/source.abap --transport NPLK900042
Handles the full lock-edit-save-unlock cycle automatically.
Writing class includes (testclasses, definitions, implementations):
abap-adt write /sap/bc/adt/oo/classes/zcl_my_class/includes/testclasses -s /tmp/tests.abap
For testclasses: automatically creates the include if it doesn't exist yet. The class must be activated before writing tests.
Important workflow: To modify ABAP source:
readwrite to push it to SAPactivate to activate the objectsyntax-check to verifyabap-adt create class ZCL_NEW_CLASS --package ZPACKAGE --description "My new class" --transport NPLK900042
abap-adt create program ZNEW_REPORT --package $TMP --description "Test report"
Type aliases: program, class, interface, function-group, function-module, include, table, structure, cds, data-element, domain, package, message-class, service-definition, service-binding
After creation, write source code and activate.
abap-adt delete /sap/bc/adt/programs/programs/zmy_report
abap-adt delete /sap/bc/adt/oo/classes/zcl_my_class --transport NPLK900042
Handles the lock-delete-unlock cycle. Auto-selects transport if required and available.
abap-adt activate ZCL_MY_CLASS /sap/bc/adt/oo/classes/zcl_my_class
abap-adt inactive-objects
abap-adt transport info /sap/bc/adt/oo/classes/zcl_my_class
abap-adt transport create /sap/bc/adt/oo/classes/zcl_my_class --description "My changes" --devclass ZPACKAGE
abap-adt transport release NPLK900042
abap-adt transport list --user DEVELOPER
abap-adt transport delete NPLK900042
abap-adt test /sap/bc/adt/oo/classes/zcl_my_class
abap-adt test /sap/bc/adt/oo/classes/zcl_my_class --risk critical --duration long
Risk levels cascade up: --risk critical includes harmless+dangerous+critical.
Duration cascades similarly.
abap-adt syntax-check /sap/bc/adt/programs/programs/zmy_report --source-file /tmp/source.abap
Write the source to a temp file first, then pass the file path.
abap-adt atc /sap/bc/adt/oo/classes/zcl_my_class --variant DEFAULT
abap-adt pretty-print --source-file /tmp/source.abap
abap-adt pretty-print --source-file /tmp/source.abap --output /tmp/formatted.abap
abap-adt table SFLIGHT --rows 10
abap-adt table HTTPURLLOC --rows 10
abap-adt table T000 --rows 50
The table command uses the ADT tableContents API. It returns columns and rows as structured data.
Response format: { columns: [{name}], values: [{COL1: val, COL2: val, ...}] }
Column names are always UPPERCASE. String values may have trailing spaces — always .trim() when comparing.
abap-adt sql "SELECT * FROM sflight WHERE carrid = 'LH'" --rows 50
abap-adt sql "SELECT * FROM T000" --rows 10
The sql command uses the ADT runQuery API. Same response format as table.
Note: Some older systems may return HTTP 400 for SQL queries — use table as a fallback.
abap-adt whereused /sap/bc/adt/oo/classes/zcl_my_class
abap-adt whereused /sap/bc/adt/oo/classes/zcl_my_class --line 10 --column 5
Returns all objects that reference the given object (callers, includes, type usages).
abap-adt classrun ZCL_MY_RUNNER
Runs a class that implements IF_OO_ADT_CLASSRUN and returns its console output. Does not work with reports — only classes with IF_OO_ADT_CLASSRUN~MAIN.
abap-adt users
abap-adt package $TMP
abap-adt package ZDEV
Lists all objects in a development package with type and name.
abap-adt exec --code "out->write( 'hello world' )."
abap-adt exec --source-file /tmp/my_code.abap
Creates a temporary class implementing IF_OO_ADT_CLASSRUN in $TMP, writes the provided ABAP code into the MAIN method, activates, runs, prints output, and deletes the temp class. The code you provide is placed inside the method body — use out->write() for output.
abap-adt definition /sap/bc/adt/oo/classes/zcl_my_class/source/main --line 10 --start-col 5 --end-col 15
abap-adt definition /sap/bc/adt/oo/classes/zcl_my_class/source/main --line 10 --start-col 5 --end-col 15 --implementation
Finds the definition (or implementation with --implementation) of a symbol at the given source position. Returns URI, line, and column of the target. Source is fetched from server automatically unless --source-file is provided.
abap-adt classinfo /sap/bc/adt/oo/classes/zcl_my_class
Lists all class components (methods, attributes, types, events) with their visibility. Useful for understanding a class before reading its source.
abap-adt completion /sap/bc/adt/oo/classes/zcl_my_class/source/main -s /tmp/source.abap --line 10 --column 5
Returns code completion proposals at the given position. Requires a source file and the source URL.
abap-adt quickfix /sap/bc/adt/oo/classes/zcl_my_class/source/main -s /tmp/source.abap --line 10 --column 5
abap-adt quickfix /sap/bc/adt/oo/classes/zcl_my_class/source/main -s /tmp/source.abap --line 10 --column 5 --apply 0
Lists available quick fixes at a position. Use --apply <index> to retrieve the actual edits for a fix.
abap-adt rename /sap/bc/adt/oo/classes/zcl_my_class/source/main --line 8 --start-col 14 --end-col 22 --new-name evaluate_number
abap-adt rename /sap/bc/adt/oo/classes/zcl_my_class/source/main --line 8 --start-col 14 --end-col 22 --new-name evaluate_number --transport NPLK900042
Renames a symbol across all usages. Evaluates the rename, previews affected objects, then executes. Requires a transport for non-$TMP objects.
| Table | Description | Key Fields |
|---|---|---|
HTTPURLLOC | HTTP/HTTPS URL configuration | PROTOCOL, HOST, PORT |
T000 | SAP clients | MANDT, MTEXT |
TDEVC | Development packages | DEVCLASS, DLVUNIT, PARENTCL |
DD02L | Table directory (all tables) | TABNAME, TABCLASS, AS4LOCAL |
TADIR | Object directory (all objects) | PGMID, OBJECT, OBJ_NAME, DEVCLASS |
USR02 | User master (logon data) | BNAME, USTYP |
SFLIGHT | Flight demo data | CARRID, CONNID, FLDATE |
# Start listening for a debuggee (blocks until breakpoint is hit)
abap-adt debug listen --mode user
# Attach to the debuggee
abap-adt debug attach <debuggeeId> --mode user
# Set breakpoints (URI with line: /sap/bc/adt/.../source/main#start=42)
abap-adt debug breakpoints "/sap/bc/adt/programs/programs/zmy_report/source/main#start=10"
# Step through code
abap-adt debug step stepOver
abap-adt debug step stepInto
abap-adt debug step stepReturn
abap-adt debug step stepContinue
# Inspect call stack
abap-adt debug stack
# Inspect variables
abap-adt debug variables SY-SUBRC LV_RESULT
abap-adt debug children @ROOT
# List all SAPGUI systems from landscape file
abap-adt systems list
abap-adt systems list --urls # include HTTP URLs in output
abap-adt systems list --landscape /path/to/file.xml
# Search systems by SID or name (case-insensitive)
abap-adt systems search S4
abap-adt systems search "solution manager"
# Connect to a system — saves connection to ~/.sap/adt-connection.json
abap-adt systems connect SE1 600
abap-adt systems connect SE1 600 --no-https --user DEVELOPER
# Show all stored connections and active connection details
abap-adt systems status
# Switch active connection (partial key match supported)
abap-adt systems switch SE1
abap-adt systems switch SS2/100
# Remove a stored connection
abap-adt systems remove SS2/100
The connect command auto-discovers HTTPS, stores credentials encrypted, and sets the connection as active. Use --no-https to force HTTP. If multiple landscape entries share the same SID, picks the first in non-interactive mode.
abap-adt search "ZCL_MY*" --type CLAS/OCabap-adt structure /sap/bc/adt/oo/classes/zcl_my_class (from search URI)abap-adt read /sap/bc/adt/oo/classes/zcl_my_classabap-adt read /sap/bc/adt/oo/classes/zcl_my_class — get current source/tmp/abap_source.abap)abap-adt write /sap/bc/adt/oo/classes/zcl_my_class -s /tmp/abap_source.abap -r NPLK900042abap-adt activate ZCL_MY_CLASS /sap/bc/adt/oo/classes/zcl_my_classabap-adt syntax-check and abap-adt testabap-adt create class ZCL_NEW --package ZDEV --description "Description" --transport NPLK900042abap-adt write /sap/bc/adt/oo/classes/zcl_new -s /tmp/source.abap -r NPLK900042abap-adt activate ZCL_NEW /sap/bc/adt/oo/classes/zcl_newFOR TESTING)abap-adt write /sap/bc/adt/oo/classes/zcl_new/includes/testclasses -s /tmp/tests.abap
(auto-creates the testclasses include if it doesn't exist)abap-adt activate ZCL_NEW /sap/bc/adt/oo/classes/zcl_newabap-adt test /sap/bc/adt/oo/classes/zcl_newUse table for simple full-table reads (more reliable), sql for filtered queries:
# Read all rows from a table
abap-adt table T000 --rows 50
# SQL with WHERE clause
abap-adt sql "SELECT DEVCLASS, DLVUNIT FROM TDEVC WHERE DEVCLASS LIKE 'Z%'" --rows 100
Tips:
.trim() when comparing--rows limits the result set (default varies by command)sql returns HTTP 400, fall back to table and filter client-side# Inline code (placed inside IF_OO_ADT_CLASSRUN~MAIN)
abap-adt exec --code "out->write( sy-datum )."
# From a file
abap-adt exec --source-file /tmp/my_logic.abap
The temp class is auto-cleaned up. Use out->write() for output.
abap-adt debug listen --mode user (runs in background — blocks until breakpoint hit)abap-adt debug attach <debuggeeId>abap-adt debug stack to see where you areabap-adt debug children @ROOT to see local variablesabap-adt debug step stepOver / abap-adt debug step stepInto to navigateabap-adt debug step stepContinue or abap-adt debug step terminateDebuggee to end| Type | ID | Example URI pattern |
|---|---|---|
| Program | PROG/P | /sap/bc/adt/programs/programs/<name> |
| Class | CLAS/OC | /sap/bc/adt/oo/classes/<name> |
| Interface | INTF/OI | /sap/bc/adt/oo/interfaces/<name> |
| Function Group | FUGR/F | /sap/bc/adt/functions/groups/<name> |
| Function Module | FUGR/FF | /sap/bc/adt/functions/groups/<group>/fmodules/<name> |
| Table | TABL/DT | /sap/bc/adt/ddic/tables/<name> |
| CDS View | DDLS/DF | /sap/bc/adt/ddic/ddl/sources/<name> |
| Data Element | DTEL/DE | /sap/bc/adt/ddic/dataelements/<name> |
| Domain | DOMA/DD | /sap/bc/adt/ddic/domains/<name> |
| Package | DEVC/K | /sap/bc/adt/packages/<name> |
| Message Class | MSAG/N | /sap/bc/adt/messageclass/<name> |
The --code inline flag silently fails or errors if any single shell argument
exceeds ~255 characters. For anything beyond a trivial one-liner, write the code
to a file and use --source-file:
abap-adt exec --source-file /tmp/my_logic.abap
The exec context is an OO method body (IF_OO_ADT_CLASSRUN~MAIN). This means:
out->write() for output, not WRITE statementsFORM/ENDFORM, REPORT, or START-OF-SELECTIONIMPORT ... FROM DATABASE must use the OO form: IMPORT name TO var FROM DATABASE ...
(the short form IMPORT var FROM DATABASE ... is not allowed in OO context)Always write the combined DEFINITION + IMPLEMENTATION as a single file to
/source/main. Writing to /includes/definitions and /includes/implementations
separately creates duplicate CLASS ... IMPLEMENTATION blocks and breaks activation.
# Correct — single combined file
abap-adt write /sap/bc/adt/oo/classes/zcl_my_class -s /tmp/combined.abap
# Wrong — causes activation error
abap-adt write /sap/bc/adt/oo/classes/zcl_my_class/includes/implementations -s /tmp/impl.abap
To call an RFC-enabled function module on a remote system from exec, use the
DESTINATION addition. Parse the output by writing delimited lines with
out->write():
DATA lv_msg TYPE c LENGTH 200.
CALL FUNCTION 'SOME_RFC_FM'
DESTINATION 'RFC_DEST_NAME'
EXPORTING query_table = 'SOME_TABLE'
TABLES ...
EXCEPTIONS
system_failure = 1 MESSAGE lv_msg
communication_failure = 2 MESSAGE lv_msg
OTHERS = 7.
out->write( |RC={ sy-subrc } MSG={ lv_msg }| ).
The MESSAGE addition on system_failure/communication_failure must use a
fixed-length TYPE c field — TYPE string causes an activation error.
This generic table-read FM is common on SAP systems with Data Services:
=), not ABAP keywords (EQ)REQUEST = '0000011333'tblout128, ≤512 → tblout512, ≤2048 → tblout2048, ≤8192 → tblout8192, >8192 → tblout30000rowcount EXPORTING parameter — passing it causes RC=7 (OTHERS)ABAP cluster tables (like /RSC/T_BD_2S) store compressed internal tables that
cannot be read directly via RFC_READ_TABLE. The round-trip approach:
IMPORT var TO var FROM DATABASE table(ZZ) ID key to deserializeUse string template formatting to respect the logged-in user's date/time format
(SY-DATFM):
" Locale-aware (respects user settings, e.g. MM/DD/YYYY)
DATA(lv_date_str) = |{ sy-datum DATE = USER }|.
DATA(lv_time_str) = |{ sy-uzeit TIME = USER }|.
" Hardcoded ISO (ignores locale — avoid unless specifically needed)
DATA(lv_iso) = |{ sy-datum+0(4) }-{ sy-datum+4(2) }-{ sy-datum+6(2) }|.
Some SAP systems restrict DDIC object creation (structures, table types, data
elements, domains) via ADT. If abap-adt create structure or similar fails,
the user may need to create DDIC objects manually via transaction SE11. The
abap-adt sql command can query DDIC metadata (DD03L, DD02L, DD40L) to inspect
existing structures:
abap-adt sql "SELECT FIELDNAME, DATATYPE, LENG FROM DD03L WHERE TABNAME = 'MY_STRUCT' AND AS4LOCAL = 'A' ORDER BY POSITION"
ADT_USER and ADT_PASS$TMP — a transport number must be providedADT_URL and ensure the SAP system is reachableProvides a checklist for code reviews covering functionality, security, performance, maintainability, tests, and quality. Use for pull requests, audits, team standards, and developer training.
npx claudepluginhub st-gr/abap-adt-skill --plugin abap-adt-skill