Skip to main content

Your AI Coding Agent Just Learned ABAP

· 7 min read
Joachim Rosskopf
Co-Founder & CEO

We built erpl-adt because we got tired of Eclipse being the only way to interact with ABAP systems programmatically. If you wanted to search objects, read source code, or run unit tests against SAP — you had to use Eclipse ADT. No CLI, no scriptable API client, nothing you could plug into a CI pipeline or hand to an AI agent.

So we built one. A single binary that speaks the ADT REST API, works from the command line, and doubles as an MCP server for AI coding agents.

erpl-adt CLI demo: search, read, test, fix, verify

Why This Exists

Eclipse ADT communicates with SAP over a well-structured REST API. The protocol itself is actually quite good — proper resource URIs, XML payloads, stateful sessions for locking. The problem was never the protocol. It was that Eclipse was the only client for it.

That means no VS Code extension that actually works against the real API. No way to script searches or automate source reads. And when the rest of the development world started using AI coding agents like Claude Code, Cursor, and Gemini — ABAP developers were locked out.

What erpl-adt Does

erpl-adt is a single, statically-linked C++ binary. No JVM, no SAP RFC SDK, no Eclipse. It runs on Linux, macOS, and Windows and works in two modes:

  1. CLI — 20 commands across 9 groups. Search objects, read and write source, run unit tests, manage transports, browse data dictionaries.
  2. MCP Server — the same operations exposed as Model Context Protocol tools. You can plug it into Claude Code, Gemini CLI, Cursor, or any MCP-compatible agent.

The MCP mode is the interesting part. It means any AI coding agent can talk to your SAP system — search code, read source, run tests, write fixes — through a standardized protocol. The agent decides which tools to call and in what order.

Demo: Claude Code Explores an ABAP System

Here's what a session looks like. Claude Code is connected to a SAP system via erpl-adt's MCP server — no scripting, just a normal conversation.

Setup — three lines in your Claude Code MCP config:

{
"mcpServers": {
"sap": {
"command": "erpl-adt",
"args": ["mcp", "--host", "sap.example.com", "--port", "44300", "--https"],
"env": { "SAP_PASSWORD": "..." }
}
}
}

The conversation:

You: What flight-related classes exist in this SAP system?

Claude calls adt_search with pattern ZCL_FLIGHT*:

Found 4 matching objects:

Name Type Package Description
──────────────── ──────── ──────────── ──────────────────────────
ZCL_FLIGHT_CTRL CLAS/OC ZFLIGHT_APP Flight booking controller
ZCL_FLIGHT_MODEL CLAS/OC ZFLIGHT_APP Flight data model
ZCL_FLIGHT_TEST CLAS/OC ZFLIGHT_APP Flight module unit tests
ZCL_FLIGHT_API CLAS/OC ZFLIGHT_APP REST API wrapper

You: Show me the source of the booking controller.

Claude calls adt_read_object to get the structure, then adt_read_source on the main include:

CLASS zcl_flight_ctrl DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
METHODS book_flight
IMPORTING iv_carrid TYPE s_carr_id
iv_connid TYPE s_conn_id
iv_fldate TYPE s_date
RETURNING VALUE(rv_booking_id) TYPE s_book_id
RAISING zcx_flight_error.

METHODS cancel_booking
IMPORTING iv_booking_id TYPE s_book_id
RAISING zcx_flight_error.
...
ENDCLASS.

You: Run the unit tests for this class.

Claude calls adt_run_tests:

ABAP Unit Results — ZCL_FLIGHT_CTRL

Method Time Result
────────────────────────── ──────── ──────
test_book_valid_flight 12ms PASS
test_book_invalid_carrier 8ms PASS
test_book_past_date 5ms PASS
test_cancel_existing 15ms PASS
test_cancel_nonexistent 6ms PASS
test_double_booking 9ms PASS

6/6 passed (55ms total)

You: What does the underlying SFLIGHT table look like?

Claude calls adt_read_table:

Table: SFLIGHT — Flight schedule

Field Type Key Description
──────── ────── ──── ─────────────────
MANDT CLNT * Client
CARRID CHAR * Airline code
CONNID NUMC * Connection number
FLDATE DATS * Flight date
PRICE CURR Airfare
CURRENCY CUKY Currency key
PLANETYPE CHAR Aircraft type
SEATSMAX INT4 Max. capacity

Claude figured out which tools to call, in what order, and how to present the results. The agent has full access to the SAP system through erpl-adt's MCP tools.

Same System, Different Agent: Gemini CLI

Here's the same SAP system, this time accessed through Google's Gemini CLI. Same erpl-adt binary, same MCP config:

{
"mcpServers": {
"sap": {
"command": "erpl-adt",
"args": ["mcp", "--host", "sap.example.com", "--port", "44300", "--https"]
}
}
}

You: I need to understand the ZFLIGHT_APP package. What's in it?

Gemini calls adt_package_tree:

Package tree: ZFLIGHT_APP (12 objects)

Type Name Package Description
──────── ──────────────────── ─────────────── ──────────────────────
CLAS/OC ZCL_FLIGHT_CTRL ZFLIGHT_APP Flight booking controller
CLAS/OC ZCL_FLIGHT_MODEL ZFLIGHT_APP Flight data model
CLAS/OC ZCL_FLIGHT_TEST ZFLIGHT_APP Flight module unit tests
CLAS/OC ZCL_FLIGHT_API ZFLIGHT_APP REST API wrapper
PROG/P ZFLIGHT_REPORT ZFLIGHT_APP Flight status report
TABL/DT ZFLIGHT_LOG ZFLIGHT_APP Booking log table
DEVC/K ZFLIGHT_SUB ZFLIGHT_APP Sub-package
CLAS/OC ZCL_FLIGHT_CLEANUP ZFLIGHT_SUB Data cleanup utility
PROG/P ZFLIGHT_MIGRATION ZFLIGHT_SUB Migration program

You: Run ATC checks on the whole package. Are there quality issues?

Gemini calls adt_run_atc:

ATC Results — ZFLIGHT_APP (variant: DEFAULT)

2 warnings, 0 errors

Priority Object Message
──────── ────────────────── ──────────────────────────────────────
Warning ZCL_FLIGHT_MODEL Method GET_FLIGHTS has cyclomatic complexity > 10
Warning ZFLIGHT_REPORT Program contains unused variable LV_TEMP

You: Fix the unused variable in ZFLIGHT_REPORT.

Gemini calls adt_read_source, removes the unused lv_temp declaration, then calls adt_write_source — which handles the lock/write/unlock cycle automatically:

Source updated: /sap/bc/adt/programs/programs/zflight_report/source/main
Lock acquired, source written, lock released.

You: Verify — run syntax check and ATC again.

Syntax check: 0 errors, 0 warnings
ATC check: 1 warning (cyclomatic complexity), 0 errors

Unused variable warning resolved.

Two different AI agents, same SAP system, same MCP protocol, same results. That's the whole point — erpl-adt doesn't tie you to a specific AI vendor. It speaks a standard protocol, so any MCP-compatible agent works.

What erpl-adt Handles for You

The SAP ADT protocol has a few tricky parts that erpl-adt takes care of so your agent (or your script) doesn't have to:

  • CSRF token management — automatic fetch, cache, and refresh on 403
  • Stateful sessions — context IDs and cookies for lock/write/unlock workflows
  • Lock guards — automatic unlock on scope exit, even if the agent crashes mid-edit
  • Async polling — operations that return 202 Accepted (like activation) are polled to completion
  • Error categorization — structured error codes so the agent can decide whether to retry (auth failure vs. lock conflict vs. not found)

The Full Command Set

GroupCommandsWhat it does
searchqueryFind ABAP objects with wildcards and type filters
objectread create delete lock unlockFull object lifecycle
sourceread write checkSource code with lock-safe writes
testrunABAP Unit test execution
checkrunATC quality checks
transportlist create releaseTransport request management
ddictable cdsTable definitions and CDS view source
packagelist tree existsPackage contents and tree traversal
discoverservicesSAP system capability discovery

Every command works both as a CLI invocation (erpl-adt search query "ZCL_*") and as an MCP tool call. Same binary, same behavior.

Get Started

Download the latest release for your platform:

# Linux
curl -LO https://github.com/DataZooDE/erpl-adt/releases/latest/download/erpl-adt-linux-x86_64.tar.gz
tar xzf erpl-adt-linux-x86_64.tar.gz

# macOS (Apple Silicon)
curl -LO https://github.com/DataZooDE/erpl-adt/releases/latest/download/erpl-adt-macos-arm64.tar.gz
tar xzf erpl-adt-macos-arm64.tar.gz

Try the CLI — connect to your SAP system:

erpl-adt search query "Z*" --host sap.example.com --port 44300 --https --json

Configure as MCP server — add to your Claude Code or Gemini CLI config:

{
"mcpServers": {
"sap": {
"command": "/path/to/erpl-adt",
"args": ["mcp", "--host", "sap.example.com", "--port", "44300", "--https"],
"env": { "SAP_PASSWORD": "your_password" }
}
}
}

Then ask your AI agent anything about your SAP system. It will figure out which tools to call.

Star the repo: github.com/DataZooDE/erpl-adt


erpl-adt is part of the ERPL family of SAP integration tools by DataZoo. We build bridges between SAP and modern data & AI tooling.