Install
$ agentstack add skill-shrek-abaper-sap-engineering-skill-sap-adt-cli ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ● Environment & secrets Used
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
SAP ADT CLI Skill
Read ABAP source code and metadata from SAP via scripts/sap_adt_cli.py.
CLI Location
The CLI is scripts/sap_adt_cli.py inside this skill's directory. Resolve the skill directory at runtime using the skill tool's path, then build the CLI path:
SKILL_DIR="$(dirname "$(realpath "${BASH_SOURCE[0]:-$0}")")"
SAP_CLI="$SKILL_DIR/scripts/sap_adt_cli.py"
python3 "$SAP_CLI" [args]
If you already know the absolute path to the skill directory (e.g. from the skill loader), use it directly:
# Linux / macOS — skill installed via clone + symlink
SAP_CLI="$HOME/.agents/skills/sap-adt-cli/scripts/sap_adt_cli.py"
python3 "$SAP_CLI" [args]
# Windows — skill installed via setup-opencode-abap-cli.bat (Junction)
$SAP_CLI = "$env:USERPROFILE\.agents\skills\sap-adt-cli\scripts\sap_adt_cli.py"
python "$SAP_CLI" [args]
First run auto-installs click, requests, and urllib3. All source code output goes to stdout. Errors go to stderr with exit code 1.
CRITICAL: Credential Check Before First Command
Always run this before the first ABAP query in a session:
python3 "$SAP_CLI" status
Credentials configured → proceed
Output example:
URL: https://my-sap.example.com:8000
Username: DEVELOPER
Client: 100
Language: EN
SSL: verify
Write mode: DISABLED
Transport write: DISABLED
Config source: /home/user/.sap-adt-cli/config.json
Credentials NOT configured → collect and save non-interactively
You will see:
Not configured. Run: python3 sap_adt_cli.py configure
Or any ABAP command will print to stderr:
SAP credentials not configured.
...
Collect all credentials in a SINGLE question tool call — pass all fields as one array. Do NOT ask one field at a time; multiple sequential calls create separate UI tabs that can cause earlier answers to be overwritten before all values are saved.
Fields to ask (all at once):
1. SAP System URL — e.g. https://my-sap.example.com:8000 (include port)
2. SAP Username — dialog user, e.g. DEVELOPER
3. SAP Password — SAP logon password
4. SAP Client — 3-digit number, e.g. 100
5. Skip SSL check? — yes/no (yes = self-signed / internal systems, no = production with valid cert)
After receiving all answers from the single question call, save with one configure command:
python3 "$SAP_CLI" configure \
--url "https://my-sap.example.com:8000" \
--username "DEVELOPER" \
--client "100" \
--language "EN"
# add --no-verify-ssl if user said yes to skipping SSL
Pass the password via environment variable to avoid shell history exposure:
SAP_PASSWORD="mysecret" python3 "$SAP_CLI" configure \
--url "https://my-sap.example.com:8000" \
--username "DEVELOPER" \
--client "100"
Then verify:
python3 "$SAP_CLI" status
Credentials are saved to ~/.sap-adt-cli/config.json (permissions 0600) and reused in all future sessions.
To enable write or transport capabilities:
# Interactive — answer prompts for write/transport flags
python3 "$SAP_CLI" configure
# Non-interactive — pass flags explicitly
SAP_PASSWORD="mysecret" python3 "$SAP_CLI" configure \
--url "https://sap-dev.example.com:44300" \
--username "DEVELOPER" \
--client "400" \
--allow-write \
--no-allow-transport
| Flag | Default | Controls | |------|---------|---------| | --allow-write / --no-allow-write | disabled | write-source, activate | | --allow-transport / --no-allow-transport | disabled | create-transport, release-transport |
> One-time confirmation rule (CRITICAL for agent workflows): > Even when capability flags are enabled, every write/create/release operation > requires an interactive change preview and explicit [y/N] confirmation. > This confirmation applies to the current operation only and is immediately > discarded after use — it is NEVER stored, cached, or reused. > In the same conversation, if the user asks for another write/create/release > operation, confirmation must be obtained again from scratch. > Use --yes only when the caller has explicit out-of-band authorization > (e.g. a trusted CI pipeline). Never pass --yes on behalf of the user > based on a previous confirmation in the same conversation.
> Security note: inform the user that credentials stored in SKILL-local .env > or ~/.sap-adt-cli/config.json are plain text. The JSON config file is > protected with 0600 permissions but is not encrypted.
Alternative A — SKILL-local .env (recommended for per-skill isolation):
cp "$(dirname "$SAP_CLI")/../.env.example" "$(dirname "$SAP_CLI")/../.env"
# edit .env and fill SAP_URL, SAP_USERNAME, SAP_PASSWORD, SAP_CLIENT
python3 "$SAP_CLI" status
Alternative B — env vars per invocation (no file written, useful for one-off sessions):
SAP_URL="https://..." SAP_USERNAME="USER" SAP_PASSWORD="pass" SAP_CLIENT="100" python3 "$SAP_CLI" status
Credential precedence is: process env vars > SKILL-local .env > ~/.sap-adt-cli/config.json. Capability flags map to SAP_ALLOW_WRITE and SAP_ALLOW_TRANSPORT; keep both 0 unless the user explicitly authorizes write or transport operations.
Commands Quick Reference
| Command | Usage | Description | |---------|-------|-------------| | configure | configure | Interactive credential setup wizard | | status | status | Show current connection config | | get-program | get-program | ABAP program (report) source code | | get-class | get-class | ABAP class source code | | get-function-group | get-function-group | Function group top-include source | | get-function | get-function --group | Function module source code | | get-include | get-include | ABAP include source code | | get-interface | get-interface | ABAP interface source code | | get-table | get-table | DDIC table field definitions | | get-structure | get-structure | DDIC structure definition | | get-type-info | get-type-info | Domain or data element (tries domain first) | | get-package | get-package | Package object list → JSON array | | get-transaction | get-transaction | Transaction properties/package info | | search-object | search-object [--max-results N] | Quick object search (* wildcard) | | syntax-check | syntax-check [--group ] | ABAP syntax check — no system change | | get-cds-view | get-cds-view | CDS View DDL source code | | get-type-group | get-type-group | ABAP type group (TYPE POOL) source | | write-source | write-source --file | Write source code (allowwrite + confirm each time) | | activate | activate | Activate ABAP object (allowwrite + confirm each time) | | where-used | where-used [--max-results N] | Where-used list → JSON array | | run-sql | run-sql "" [--max-rows N] | Open SQL SELECT → JSON; DML statements are blocked | | list-transports | list-transports [--user U] [--status D\|R] | List transport requests → JSON | | create-transport | create-transport --description "" | Create transport request (allowtransport + confirm each time) | | release-transport | release-transport [--yes] | Release transport — irreversible (allowtransport + confirm each time) |
Usage Examples
SAP_CLI="/scripts/sap_adt_cli.py"
# Source code
python3 "$SAP_CLI" get-program SAPMV45A
python3 "$SAP_CLI" get-class ZCL_MY_CLASS
python3 "$SAP_CLI" get-function BAPI_SALESORDER_CREATEFROMDAT2 --group BAPI_SD_SALESORDER
python3 "$SAP_CLI" get-include MV45AFZZ
python3 "$SAP_CLI" get-interface ZIF_MY_INTERFACE
# Dictionary
python3 "$SAP_CLI" get-table VBAK
python3 "$SAP_CLI" get-structure VBAKKOM
python3 "$SAP_CLI" get-type-info MATNR
# Discovery
python3 "$SAP_CLI" search-object "ZCL_*" --max-results 20
python3 "$SAP_CLI" get-package ZMYPACKAGE
python3 "$SAP_CLI" get-transaction VA01
# CDS View & Type Group (read-only)
python3 "$SAP_CLI" get-cds-view ZI_INVENTORY_POSITION
python3 "$SAP_CLI" get-type-group ICON
# Write & activate (requires allow_write + confirmation each time)
python3 "$SAP_CLI" write-source class ZCL_MY_CLASS --file /tmp/zcl.abap
python3 "$SAP_CLI" write-source class ZCL_MY_CLASS --file /tmp/zcl.abap --activate
cat updated.abap | python3 "$SAP_CLI" write-source class ZCL_MY_CLASS --file -
python3 "$SAP_CLI" write-source class ZCL_MY_CLASS --file /tmp/zcl.abap --yes # skip confirm (trusted automation only)
python3 "$SAP_CLI" activate class ZCL_MY_CLASS
# Where-used (read-only)
python3 "$SAP_CLI" where-used class ZCL_PAYMENT_PROCESSOR --max-results 50
python3 "$SAP_CLI" where-used interface ZIF_MY_INTERFACE
# Open SQL via Data Preview (read-only)
python3 "$SAP_CLI" run-sql "SELECT * FROM t001 UP TO 10 ROWS"
python3 "$SAP_CLI" run-sql "SELECT bukrs, butxt FROM t001 WHERE spras = 'EN'" --max-rows 200
# Transport management
python3 "$SAP_CLI" list-transports # read-only — no flag needed
python3 "$SAP_CLI" list-transports --user SHREK --status D
python3 "$SAP_CLI" create-transport --description "Fix rounding issue" # allow_transport + confirm
python3 "$SAP_CLI" release-transport DEVK900001 # allow_transport + confirm (irreversible warning)
python3 "$SAP_CLI" release-transport DEVK900001 --yes # skip confirm (trusted automation only)
Key Behaviors & Gotchas
- Object names: SAP names are case-insensitive but always use UPPERCASE for reliability (e.g.
VBAK,ZCL_MY_CLASS, notvbak) - Source output:
get-program,get-class,get-function, etc. return raw ABAP source text - XML output:
get-table,get-structure,get-type-info,get-transaction,search-objectreturn raw XML from ADT — parse it or read it as-is - JSON output:
get-packageis the only command that returns a parsed JSON array get-type-infofallback: tries domain first; if not found, falls back to data element- SSL: for internal SAP systems with self-signed certs, configure with SSL disabled (
SAP_VERIFY_SSL=0or answer "n" in wizard) - Session reuse: the HTTP session is reused within a single script invocation; each
python3 "$SAP_CLI" ...call starts fresh - Credentials precedence: process env vars > SKILL-local
.env>~/.sap-adt-cli/config.json - Capability flags — config layer:
write-sourceandactivaterequireallow_write: true;
create-transport and release-transport require allow_transport: true. Run configure to enable. list-transports is read-only and has no flag requirement.
- One-time confirmation — execution layer: every write/create/release operation
shows a change preview and requires [y/N] confirmation before executing. This confirmation is scoped to the current operation only — it is immediately discarded after use and never cached or reused within the same session. The next write/create/release in the same session requires a fresh confirmation.
- Agent rule — never reuse confirmation: when operating as an AI agent,
do not infer that a previous confirmation covers subsequent operations. Every invocation of a write-capable command is independent. Pass --yes only with explicit user instruction for that specific call.
write-sourcelock protocol: flow is lock → PUT → unlock; unlock runs in
finally so objects are never left locked after an error.
release-transportis irreversible: once released, a transport cannot be
recalled. The confirmation preview explicitly calls this out.
run-sqlOpen SQL only: uses ADT Data Preview; accepts SAP Open SQL syntax
(e.g. UP TO N ROWS), not Native SQL or JDBC-style syntax.
run-sqlDML blocked: statements starting withINSERT,UPDATE,DELETE,
MODIFY, or TRUNCATE are unconditionally rejected in this version. Only SELECT statements are permitted. Detection is by first keyword, case-insensitive — SELECT containing write keywords in values is safe.
where-usedempty result: returns[]— not an error (exit 0).get-cds-viewname: use the CDS entity name (e.g.ZI_INVENTORY_POSITION),
not the underlying database table name.
syntax-checkwith function: requires--group(same asget-function).
Output Format
| Command | Output Format | |---------|---------------| | Source code commands (get-program, get-class, get-function, get-include, get-interface, get-cds-view, get-type-group) | Plain text ABAP source | | get-table, get-structure, get-type-info, get-transaction, search-object | Raw XML | | get-package, where-used, list-transports, run-sql | JSON array | | syntax-check | Plain text messages ([ERROR], [WARNING], [INFO] prefixed); "Syntax OK" if clean | | status | Plain text key-value pairs |
Error Handling
| Error Output | Cause | Action | |--------------|-------|--------| | Not configured | No saved credentials | Guide user through configure | | HTTP 401 | Wrong username/password | Ask user to re-run configure | | HTTP 403 | Missing ADT authorization | User needs SAP_ADT_BASE role or equivalent | | HTTP 404 | Object name not found | Try search-object to find the correct name | | HTTP 503 | ADT service not active | SAP Basis must activate /sap/bc/adt in transaction SICF | | SSL error | Certificate issue | Re-configure with SAP_VERIFY_SSL=0 |
Workflows
Read an unknown class:
python3 "$SAP_CLI" search-object "ZCL_ORDER*"
python3 "$SAP_CLI" get-class ZCL_ORDER_HANDLER
Explore a package:
python3 "$SAP_CLI" get-package ZMYPACKAGE
# → JSON list of all objects; pick the ones you need
python3 "$SAP_CLI" get-program ZMYREPORT
python3 "$SAP_CLI" get-class ZCL_MYCLASS
Look up a BAPI signature:
python3 "$SAP_CLI" get-function BAPI_SALESORDER_CREATEFROMDAT2 --group BAPI_SD_SALESORDER
Understand a table structure:
python3 "$SAP_CLI" get-table VBAK
python3 "$SAP_CLI" get-type-info VBELN # look up field type
Find a transaction's package/application:
python3 "$SAP_CLI" get-transaction VA01
Safe write workflow — syntax-check before writing:
python3 "$SAP_CLI" syntax-check class ZCL_MY_CLASS
# → fix any errors locally, then:
python3 "$SAP_CLI" write-source class ZCL_MY_CLASS --file ./zcl_my_class.abap --activate
# → preview shown, confirmation required; confirmation discarded after use
Find all usages of an interface:
python3 "$SAP_CLI" where-used interface ZIF_MY_INTERFACE --max-results 100
# → JSON list of all implementing/using objects
Quick data check without SE16N:
python3 "$SAP_CLI" run-sql "SELECT COUNT(*) AS CNT FROM ekko WHERE bstyp = 'F'"
Create and release a transport (two separate confirmations):
python3 "$SAP_CLI" create-transport --description "Sprint 12 — invoice fix"
# → preview shown, confirmation #1 required → Created transport: DEVK900042
python3 "$SAP_CLI" list-transports --status D
# → JSON list (read-only, no confirmation)
python3 "$SAP_CLI" release-transport DEVK900042
# → irreversible-warning preview shown, confirmation #2 required (fresh, not reused)
SAP Prerequisites
- ADT services active: transaction
SICF→ path/sap/bc/adt→ Activate - User authorization: role
SAP_ADT_BASEor objectsS_ADT_RES,S_RFC - Write & activate (
write-source,activate): requiresallow_write: truein config.
SAP user additionally needs S_DEVELOP with ACTVT=02 on relevant object types.
- Transport management (
create/release-transport): requiresallow_transport: truein config.
SAP user needs S_CTS_ADMI or equivalent transport authorization. list-transports is read-only and needs no additional flag.
- Data Preview (
run-sql): requires `/sap/bc/a
…
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: shrek-abaper
- Source: shrek-abaper/sap-engineering-skill
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.