PageSourceSearch

https://erpl.io/assets/js/4742c6c6.9a962d28.js

js erpl.io collected 2026-10-03 23:22:20 UTC 23,083 bytes, 1 lines download raw bytes

1"use strict";(self.webpackChunkerpl_docusaurus=self.webpackChunkerpl_docusaurus||[]).push([[3350],{28453:(e,n,r)=>{r.d(n,{R:()=>i,x:()=>a});var s=r(96540);const t={},o=s.createContext(t);function i(e){const n=s.useContext(o);return s.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:i(e.components),s.createElement(o.Provider,{value:n},e.children)}},49308:e=>{e.exports=JSON.parse('{"permalink":"/blog/introducing-erpl-adt","editUrl":"https://github.com/datazoode/erpl-landingpage/tree/main/blog/2026-02-13-introducing-erpl-adt/index.md","source":"@site/blog/2026-02-13-introducing-erpl-adt/index.md","title":"Your AI Coding Agent Just Learned ABAP","description":"erpl-adt is a single binary that speaks the SAP ADT REST API \u2014 the same protocol Eclipse uses. As a CLI or MCP server, it lets AI coding agents like Claude Code and Gemini search ABAP objects, read source code, run unit tests, and write fixes against any SAP system.","date":"2026-02-13T00:00:00.000Z","tags":[{"inline":false,"label":"ERPL","permalink":"/blog/tags/erpl","description":"ERPL extension tutorials"},{"inline":false,"label":"SAP","permalink":"/blog/tags/sap","description":"SAP system integration"},{"inline":false,"label":"ABAP","permalink":"/blog/tags/abap","description":"ABAP development and tooling"},{"inline":false,"label":"AI","permalink":"/blog/tags/ai","description":"AI-powered development and automation"},{"inline":false,"label":"MCP","permalink":"/blog/tags/mcp","description":"Model Context Protocol integrations"},{"inline":false,"label":"CLI","permalink":"/blog/tags/cli","description":"Command-line tools and interfaces"}],"readingTime":6.4,"hasTruncateMarker":true,"authors":[{"name":"Joachim Rosskopf","title":"Co-Founder & CEO","url":"https://data-zoo.de","socials":{"linkedin":"https://www.linkedin.com/in/joachim-rosskopf/","github":"https://github.com/jrosskopf"},"imageURL":"/images/profiles/profile_jr.png","key":"joachim-rosskopf","page":null}],"frontMatter":{"slug":"introducing-erpl-adt","title":"Your AI Coding Agent Just Learned ABAP","authors":["joachim-rosskopf"],"tags":["erpl","sap","abap","ai","mcp","cli"],"date":"2026-02-13T00:00:00.000Z","description":"erpl-adt is a single binary that speaks the SAP ADT REST API \u2014 the same protocol Eclipse uses. As a CLI or MCP server, it lets AI coding agents like Claude Code and Gemini search ABAP objects, read source code, run unit tests, and write fixes against any SAP system."},"unlisted":false,"prevItem":{"title":"ERPL Speaks More Than SAP Now","permalink":"/blog/erpl-enterprise-data-hub"},"nextItem":{"title":"ERPL vs Traditional SAP Integration: A Performance Comparison","permalink":"/blog/erpl-vs-traditional-sap-integration"}}')},60912:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>i,metadata:()=>s,toc:()=>d});var s=r(49308),t=r(74848),o=r(28453);const i={slug:"introducing-erpl-adt",title:"Your AI Coding Agent Just Learned ABAP",authors:["joachim-rosskopf"],tags:["erpl","sap","abap","ai","mcp","cli"],date:new Date("2026-02-13T00:00:00.000Z"),description:"erpl-adt is a single binary that speaks the SAP ADT REST API \u2014 the same protocol Eclipse uses. As a CLI or MCP server, it lets AI coding agents like Claude Code and Gemini search ABAP objects, read source code, run unit tests, and write fixes against any SAP system."},a=void 0,l={authorsImageUrls:[void 0]},d=[{value:"Why This Exists",id:"why-this-exists",level:2},{value:"What erpl-adt Does",id:"what-erpl-adt-does",level:2},{value:"Demo: Claude Code Explores an ABAP System",id:"demo-claude-code-explores-an-abap-system",level:2},{value:"Same System, Different Agent: Gemini CLI",id:"same-system-different-agent-gemini-cli",level:2},{value:"What erpl-adt Handles for You",id:"what-erpl-adt-handles-for-you",level:2},{value:"The Full Command Set",id:"the-full-command-set",level:2},{value:"Get Started",id:"get-started",level:2}];function c(e){const n={a:"a",blockquote:"blockquote",code:"code",em:"em",h2:"h2",hr:"hr",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,o.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.p,{children:"We built erpl-
1adt 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 \u2014 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."}),"\n",(0,t.jsx)(n.p,{children:"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."}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"erpl-adt CLI demo: search, read, test, fix, verify",src:r(62065).A+"",width:"1200",height:"750"})}),"\n",(0,t.jsx)(n.h2,{id:"why-this-exists",children:"Why This Exists"}),"\n",(0,t.jsx)(n.p,{children:"Eclipse ADT communicates with SAP over a well-structured REST API. The protocol itself is actually quite good \u2014 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."}),"\n",(0,t.jsx)(n.p,{children:"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 \u2014 ABAP developers were locked out."}),"\n",(0,t.jsx)(n.h2,{id:"what-erpl-adt-does",children:"What erpl-adt Does"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"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:"]}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"CLI"})," \u2014 21 commands across 10 groups. Search objects, read and write source, activate, run unit tests, manage transports, browse data dictionaries."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"MCP Server"})," \u2014 the same operations exposed as ",(0,t.jsx)(n.a,{href:"https://modelcontextprotocol.io/",children:"Model Context Protocol"})," tools. You can plug it into Claude Code, Gemini CLI, Cursor, or any MCP-compatible agent."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"The MCP mode is the interesting part. It means any AI coding agent can talk to your SAP system \u2014 search code, read source, run tests, write fixes \u2014 through a standardized protocol. The agent decides which tools to call and in what order."}),"\n",(0,t.jsx)(n.h2,{id:"demo-claude-code-explores-an-abap-system",children:"Demo: Claude Code Explores an ABAP System"}),"\n",(0,t.jsx)(n.p,{children:"Here's what a session looks like. Claude Code is connected to a SAP system via erpl-adt's MCP server \u2014 no scripting, just a normal conversation."}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Setup"})," \u2014 three lines in your Claude Code MCP config:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\r\n  "mcpServers": {\r\n    "sap": {\r\n      "command": "erpl-adt",\r\n      "args": ["mcp", "--host", "sap.example.com", "--port", "44300", "--https"],\r\n      "env": { "SAP_PASSWORD": "..." }\r\n    }\r\n  }\r\n}\n'})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"The conversation"}),":"]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"You:"})," What flight-related classes exist in this SAP system?"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Claude calls ",(0,t.jsx)(n.code,{children:"adt_search"})," with pattern ",(0,t.jsx)(n.code,{children:"ZCL_FLIGHT*"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"Found 4 matching objects:\r\n\r\n  Name              Type      Package       Description\r\n  \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500  \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500  \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500  \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n  ZCL_FLIGHT_CTRL   CLAS/OC   ZFLIGHT_APP   Flight booking controller\r\n  ZCL_FLIGHT_MODEL  CLAS/OC   ZFLIGHT_APP   Flight data model\r\n  ZCL_FLIGHT_TEST   CLAS/OC   ZFLIGHT_APP   Flight module unit tests\r\n  ZCL_FLIGHT_API    CLAS/OC   ZFLIGHT_APP   REST API wrapper\n"})}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"You:"})," Show me the source of the booking controller."]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Claude calls ",(0,t.jsx)(n.code,{children:"adt_read_object"})," to get the structure, then ",(0,t.jsx)(n.code,{children:"adt_read_source"})," on the main include:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-abap",children:"CLASS zcl_flight_ctrl DEFINITION PUBLIC FINAL CREATE PUBLIC.\r\n  PUBLIC SECTION.\r\n    METHODS book_flight\r\n      IMPORTING iv_carrid TYPE s_carr_id\r\n                iv_connid TYPE s_conn_id\r\n                iv_fldate TYPE s_date\r\n      RETURNING VALUE(rv_booking_id) TYPE s_book_id\r\n      RAISING   zcx_flight_error.\r\n\r\n    METHODS cancel_booking\r\n      IMPORTING iv_booking_id TYPE s_book_id\r\n      RAISING   zcx_flight_error.\r\n  ...\r\nENDCLASS.\n"})}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"You:"})," Run the unit tests for this class."]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Claude calls ",(0,t.jsx)(n.code,{children:"adt_run_tests"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"ABAP Unit Results \u2014 ZCL_FLIGHT_CTRL\r\n\r\n  Method                      Time      Result\r\n  \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500  \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500  \u2500\u2500\u2500\u2500\u2500\u2500\r\n  test_book_valid_flight      12ms      PASS\r\n  test_book_invali
1d_carrier   8ms       PASS\r\n  test_book_past_date         5ms       PASS\r\n  test_cancel_existing        15ms      PASS\r\n  test_cancel_nonexistent     6ms       PASS\r\n  test_double_booking         9ms       PASS\r\n\r\n  6/6 passed (55ms total)\n"})}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"You:"})," What does the underlying SFLIGHT table look like?"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Claude calls ",(0,t.jsx)(n.code,{children:"adt_read_table"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"Table: SFLIGHT \u2014 Flight schedule\r\n\r\n  Field     Type    Key   Description\r\n  \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500  \u2500\u2500\u2500\u2500\u2500\u2500  \u2500\u2500\u2500\u2500  \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n  MANDT     CLNT    *     Client\r\n  CARRID    CHAR    *     Airline code\r\n  CONNID    NUMC    *     Connection number\r\n  FLDATE    DATS    *     Flight date\r\n  PRICE     CURR          Airfare\r\n  CURRENCY  CUKY          Currency key\r\n  PLANETYPE CHAR          Aircraft type\r\n  SEATSMAX  INT4          Max. capacity\n"})}),"\n",(0,t.jsx)(n.p,{children:"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."}),"\n",(0,t.jsx)(n.h2,{id:"same-system-different-agent-gemini-cli",children:"Same System, Different Agent: Gemini CLI"}),"\n",(0,t.jsx)(n.p,{children:"Here's the same SAP system, this time accessed through Google's Gemini CLI. Same erpl-adt binary, same MCP config:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\r\n  "mcpServers": {\r\n    "sap": {\r\n      "command": "erpl-adt",\r\n      "args": ["mcp", "--host", "sap.example.com", "--port", "44300", "--https"]\r\n    }\r\n  }\r\n}\n'})}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"You:"})," I need to understand the ZFLIGHT_APP package. What's in it?"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Gemini calls ",(0,t.jsx)(n.code,{children:"adt_package_tree"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"Package tree: ZFLIGHT_APP (12 objects)\r\n\r\n  Type      Name                  Package          Description\r\n  \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500  \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500  \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500  \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n  CLAS/OC   ZCL_FLIGHT_CTRL       ZFLIGHT_APP      Flight booking controller\r\n  CLAS/OC   ZCL_FLIGHT_MODEL      ZFLIGHT_APP      Flight data model\r\n  CLAS/OC   ZCL_FLIGHT_TEST       ZFLIGHT_APP      Flight module unit tests\r\n  CLAS/OC   ZCL_FLIGHT_API        ZFLIGHT_APP      REST API wrapper\r\n  PROG/P    ZFLIGHT_REPORT        ZFLIGHT_APP      Flight status report\r\n  TABL/DT   ZFLIGHT_LOG           ZFLIGHT_APP      Booking log table\r\n  DEVC/K    ZFLIGHT_SUB           ZFLIGHT_APP      Sub-package\r\n  CLAS/OC   ZCL_FLIGHT_CLEANUP    ZFLIGHT_SUB      Data cleanup utility\r\n  PROG/P    ZFLIGHT_MIGRATION     ZFLIGHT_SUB      Migration program\n"})}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"You:"})," Run ATC checks on the whole package. Are there quality issues?"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Gemini calls ",(0,t.jsx)(n.code,{children:"adt_run_atc"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"ATC Results \u2014 ZFLIGHT_APP (variant: DEFAULT)\r\n\r\n  2 warnings, 0 errors\r\n\r\n  Priority  Object              Message\r\n  \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500  \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500  \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n  Warning   ZCL_FLIGHT_MODEL    Method GET_FLIGHTS has cyclomatic complexity > 10\r\n  Warning   ZFLIGHT_REPORT      Program contains unused variable LV_TEMP\n"})}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"You:"})," Fix the unused variable in ZFLIGHT_REPORT."]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Gemini calls ",(0,t.jsx)(n.code,{children:"adt_read_source"}),", removes the unused ",(0,t.jsx)(n.code,{children:"lv_temp"})," declaration, then calls ",(0,t.jsx)(n.code,{children:"adt_write_source"})," with activation \u2014 which handles the lock/write/unlock/activate cycle automatically:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"Source updated: /sap/bc/adt/programs/programs/zflight_report/source/main\r\nLock acquired, source written, lock released.\r\nActivated: /sap/bc/adt/programs/programs/zflight_report\n"})}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"You:"})," Verify \u2014 run syntax check and ATC again."]}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"Syntax check: 0 errors, 0 warnings\r\nATC check:    1 warning (cyclomatic complexity), 0 errors\r\n\r\nUnused variable warning resolved.\n"})}),"\n",(0,t.jsx)(n.p,{children:"Two different AI agents, same SAP system, same MCP protocol, same results. That's the whole point \u2014 erpl-adt doesn't tie you to a specific AI vendor. It speaks a standard protocol, so any MCP-compatible agent works."}),"\n",(0,t.jsx)(n.h2,{id:"what-erpl-adt-handles-for-you",children:"What erpl-adt Handles for You"}),"\n",(0,t.jsx)(n.p,{children:"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:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"CSRF token management"}
1)," \u2014 automatic fetch, cache, and refresh on 403"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Stateful sessions"})," \u2014 context IDs and cookies for lock/write/unlock workflows"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Lock guards"})," \u2014 automatic unlock on scope exit, even if the agent crashes mid-edit"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Async polling"})," \u2014 operations that return ",(0,t.jsx)(n.code,{children:"202 Accepted"})," (like activation) are polled to completion"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Error categorization"})," \u2014 structured error codes so the agent can decide whether to retry (auth failure vs. lock conflict vs. not found)"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"the-full-command-set",children:"The Full Command Set"}),"\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Group"}),(0,t.jsx)(n.th,{children:"Commands"}),(0,t.jsx)(n.th,{children:"What it does"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"search"})}),(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"query"})}),(0,t.jsx)(n.td,{children:"Find ABAP objects with wildcards and type filters"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"object"})}),(0,t.jsxs)(n.td,{children:[(0,t.jsx)(n.code,{children:"read"})," ",(0,t.jsx)(n.code,{children:"create"})," ",(0,t.jsx)(n.code,{children:"delete"})," ",(0,t.jsx)(n.code,{children:"lock"})," ",(0,t.jsx)(n.code,{children:"unlock"})]}),(0,t.jsx)(n.td,{children:"Full object lifecycle"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"source"})}),(0,t.jsxs)(n.td,{children:[(0,t.jsx)(n.code,{children:"read"})," ",(0,t.jsx)(n.code,{children:"write"})," ",(0,t.jsx)(n.code,{children:"check"})]}),(0,t.jsxs)(n.td,{children:["Source code with lock-safe writes (",(0,t.jsx)(n.code,{children:"--activate"})," flag)"]})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"activate"})}),(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"run"})}),(0,t.jsx)(n.td,{children:"Activate inactive objects (by name or URI)"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"test"})}),(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"run"})}),(0,t.jsx)(n.td,{children:"ABAP Unit test execution (by name or URI)"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"check"})}),(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"run"})}),(0,t.jsx)(n.td,{children:"ATC quality checks (by name or URI)"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"transport"})}),(0,t.jsxs)(n.td,{children:[(0,t.jsx)(n.code,{children:"list"})," ",(0,t.jsx)(n.code,{children:"create"})," ",(0,t.jsx)(n.code,{children:"release"})]}),(0,t.jsx)(n.td,{children:"Transport request management"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"ddic"})}),(0,t.jsxs)(n.td,{children:[(0,t.jsx)(n.code,{children:"table"})," ",(0,t.jsx)(n.code,{children:"cds"})]}),(0,t.jsx)(n.td,{children:"Table definitions and CDS view source"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"package"})}),(0,t.jsxs)(n.td,{children:[(0,t.jsx)(n.code,{children:"list"})," ",(0,t.jsx)(n.code,{children:"tree"})," ",(0,t.jsx)(n.code,{children:"exists"})]}),(0,t.jsx)(n.td,{children:"Package contents and tree traversal"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"discover"})}),(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"services"})}),(0,t.jsx)(n.td,{children:"SAP system capability discovery"})]})]})]}),"\n",(0,t.jsxs)(n.p,{children:["Every command works both as a CLI invocation (",(0,t.jsx)(n.code,{children:'erpl-adt search query "ZCL_*"'}),") and as an MCP tool call. Same binary, same behavior."]}),"\n",(0,t.jsx)(n.h2,{id:"get-started",children:"Get Started"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Download"})," the latest release for your platform:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"# Linux\r\ncurl -LO https://github.com/DataZooDE/erpl-adt/releases/latest/download/erpl-adt-linux-x86_64.tar.gz\r\ntar xzf erpl-adt-linux-x86_64.tar.gz\r\n\r\n# macOS (Apple Silicon)\r\ncurl -LO https://github.com/DataZooDE/erpl-adt/releases/latest/download/erpl-adt-macos-arm64.tar.gz\r\ntar xzf erpl-adt-macos-arm64.tar.gz\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Try the CLI"})," \u2014 connect to your SAP system:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'erpl-adt search query "Z*" --host sap.example.com --port 44300 --https --json\n'})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Configure as MCP server"})," \u2014 add to your Claude Code or Gemini CLI config:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\r\n  "mcpServers": {\r\n    "sap": {\r\n      "command": "/path/to/erpl-adt",\r\n      "args": ["mcp", "--host", "sap.example.com", "--port", "44300", "--https"],\r\n      "env": { "
1SAP_PASSWORD": "your_password" }\r\n    }\r\n  }\r\n}\n'})}),"\n",(0,t.jsx)(n.p,{children:"Then ask your AI agent anything about your SAP system. It will figure out which tools to call."}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Star the repo"}),": ",(0,t.jsx)(n.a,{href:"https://github.com/DataZooDE/erpl-adt",children:"github.com/DataZooDE/erpl-adt"})]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsxs)(n.em,{children:["erpl-adt is part of the ",(0,t.jsx)(n.a,{href:"https://erpl.io",children:"ERPL"})," family of SAP integration tools by ",(0,t.jsx)(n.a,{href:"https://data-zoo.de",children:"DataZoo"}),". We build bridges between SAP and modern data & AI tooling."]})})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(c,{...e})}):c(e)}},62065:(e,n,r)=>{r.d(n,{A:()=>s});const s=r.p+"assets/images/demo-952a6d007cf717e66a9a89e1b64dfde3.gif"}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.