Setup in three steps.
Three steps, all of them in a chat. You need Node.js 22.12 or newer and a Chromium browser (Chrome or Edge) for the SAP login. The long version, with Windows paths and the host logs, is in the README.
Install the plugin
One plugin brings the server and a setup guide the agent follows, in the Code tab or in Cowork of the Claude desktop app (the terminal works too). The easy way is to paste the sentence on the right into a chat; the agent runs the commands and asks before each one.
Install the abap-adt-mcp plugin from the marketplace williansaez/abap-adt-mcp, using plugin marketplace add and then plugin install, and tell me when I need to reload.
Or do it by hand:
- Code tab (or the terminal): type the three commands below in the chat box, one at a time.
- Cowork: Customize, Plugins, Add, Add marketplace, type
williansaez/abap-adt-mcp, then Add on the plugin.
/plugin marketplace add williansaez/abap-adt-mcp
/plugin install abap-adt-mcp@abap-adt-mcp
/reload-pluginsTell it which SAP system
In the same chat, give the address and the client. The setup guide writes ~/.abap-adt-mcp/systems.json, read-only to start, and asks you to run /reload-plugins. Until that file exists the server answers only listSystems and healthcheck, both saying what is missing. On S/4HANA Cloud your user needs the developer business role it already has for Eclipse ADT; on-prem, /sap/bc/adt must be active in SICF.
Set up abap-adt-mcp for my SAP system DEV at https://myXXXXXX.s4hana.cloud.sap, client 080, with browser login, read-only to start.
Or write the file yourself. Drop the policy line when you are ready to let the model create, edit and activate within your SAP authorizations:
{
"DEV": {
"url": "https://myXXXXXX.s4hana.cloud.sap",
"client": "080",
"authType": "sso",
"default": true,
"policy": { "readOnly": true }
}
}Say hello
After the reload, open a new chat. The model calls listSystems, login (a browser window appears once for SSO), searchObject and getObjectSource. When the source comes back, you are done.
List my SAP systems, log in to DEV and show me the source of class CL_ABAP_CHAR_UTILITIES.
If the SAP tools do not appear, run npx -y abap-adt-mcp --check in a terminal: one line per check, Node, the systems file, every system over HTTPS and the browser. Then read the host's MCP log: spawn npx ENOENT means Node.js is missing; no browser window means no Chromium found (SAP_BROWSER_PATH names one); on-prem, /sap/bc/adt must be active in SICF. The troubleshooting list has the rest.
What to ask the model.
The server is a toolbox the model picks from: ask in plain language and it chooses the sequence. Write tools lock and unlock by themselves, activate=true activates in the same call, and every error is JSON with a kind, a hint and the next tools to try.
| Ask | Tools the model reaches for |
|---|---|
| "Explain what method GET_DATA of ZCL_ORDER_SERVICE does." | searchObject, getMethodSource |
| "Where is table ZTABLE still used, and by which programs?" | whereUsed, sourceTextSearch, grepPackage |
| "Add a null check at the top of GET_DATA, activate and run the unit tests." | resolveTransport, syntaxCheckCode, editObjectSource, unitTestRun, objectDiff |
| "Create class ZCL_HELLO in package ZDEMO that prints Hello World, with a unit test." | validateNewObject, resolveTransport, createObject, setObjectSource, createTestInclude, unitTestRun |
| "Run ATC on package ZFIN and apply every quickfix that is safe." | createAtcRun, atcWorklists, atcQuickfixProposals, atcApplyQuickfix, atcSummary |
| "What changed in transport DEVK900123? Is it safe to release?" | transportDetails, transportUnifiedDiff |
| "Why did the last short dump of user DEVELOPER happen? Propose a fix." | dumps, dumpDetails, getObjectSource |
| "Is ZCL_ORDER_SERVICE ready for ABAP Cloud? Which SAP objects block it?" | apiReleaseState, createAtcRun |
| "Select the ten newest rows of ZTABLE where STATUS = 'X'." | runQuery (once the destination allows data) |
Six ready-made workflows also travel as MCP prompts: create-object, safe-edit, review-transport, fix-atc, clean-core-check, debug-dump. Each names the tools in order and says where it stops and asks.
Guard rails live in the server, not in the host.
A destination's policy block is evaluated in the server before the tool's own SAP call, whatever the host approves. Refusals come back as kind: "policyDenied" naming the gate. A destination without a policy is fully writable within your SAP authorizations and reads no table data until you allow it.
Also: secrets stay in ${env:VAR}, TLS stays on per destination, every call lands in an audit log with tool, destination, outcome and gate, and error messages pass through redaction. Content from SAP is untrusted input; use a host that asks before destructive calls.
| Policy key | Effect |
|---|---|
| readOnly | Only read-only tools run. Every source write, runSnippet, unitTestRun and ATC runs are refused. |
| allowedPackages | Writes only inside these package globs (["Z*", "$*"]); reads are never gated. |
| deniedTables | Globs refused in tableContents, in every FROM/JOIN of runQuery, and scanned in written ABAP. |
| allowDataPreview | Off unless stated. Opens table rows by name. |
| allowFreeSql | Off unless stated. Opens runQuery; implies data preview. |
| deniedTools | Names, globs or toolset:git refused on this destination; the tools stay listed. |
| allowedTransports | Every transport argument must match; creating transports is refused. |
Watch it work on the jobs you actually have.*
A short dump at three in the morning, twenty-seven ATC findings on a Friday, a transport nobody wants to sign off, a class that still needs its test, code that has to survive S/4HANA Cloud. Pick the one that looks like your week.
dumps, dumpDetails, the line, the fix, activated and tested.apiReleaseState grades every SAP object, names the successor, then the rewrite.173 tools, 16 toolsets.
Tool schemas cost context. MCP_TOOLSETS=focused publishes the 114 everyday development tools; all adds the debugger, traces, abapGit, RAP, services, refactoring and discovery. The per-tool reference with parameters and read-only/destructive annotations is docs/TOOLS.md.
- core6 · destinations, health, session
- source16 · read, write, lock, diff
- objects27 · search, navigate, create, activate
- transports18 · transports
- analysis16 · syntax, completion, apiReleaseState, runSnippet
- tests4 · ABAP Unit
- atc14 · runs, quickfixes, exemptions
- data10 · DDIC, tableContents, runQuery
- runtime3 · feeds, dumps
- discovery7 · ADT discovery, feature details
- refactoring8 · rename, extract method, change package
- rap8 · RAP generation
- services4 · business services
- git10 · abapGit
- debugger13 · breakpoints, stack, variables
- traces9 · SQL and runtime traces
● in the focused preset (114 tools). The other 59 come with MCP_TOOLSETS=all.
This server
- Many destinations from one process, stdio or HTTP
- Policies enforced server-side, audit log, redaction
- Reads and searches source, writes source, locks, dumps, data, where-used, debugger, abapGit
- Compositions such as
resolveTransport,editObjectSource,grepPackage,apiReleaseState,runSnippet,objectDiff
SAP's official ADT MCP Server
- Ships with ADT for VS Code and Eclipse under the key
abap-adt - Creates, activates, tests, checks and transports
- Does not read or search source, write source, lock, or show dumps
- Both can be registered side by side: keys and tool names do not collide. docs/ROUTING.md maps the names.
The ADT REST services are the ones Eclipse uses and are not published on the SAP Business Accelerator Hub; SAP's API Policy calls them internal. Whether SAP accepts your use is a question for your SAP contact. docs/API-POLICY.md has the policy section by section and a conservative configuration.
Other ways to install.
Without the plugin
For Claude Desktop chat, Cursor, Cline, VS Code with Copilot, or Claude Code without plugins. Claude Code takes the one line; the others take the JSON (Claude Desktop under Settings, Developer, Edit Config, then a restart; VS Code names the map servers). Write systems.json as in step 2.
claude mcp add abap-adt-mcp \
-e SAP_SYSTEMS_FILE=$HOME/.abap-adt-mcp/systems.json \
-- npx -y abap-adt-mcp{
"mcpServers": {
"abap-adt-mcp": {
"command": "npx",
"args": ["-y", "abap-adt-mcp"],
"env": {
"SAP_SYSTEMS_FILE": "/Users/me/.abap-adt-mcp/systems.json",
"MCP_TOOLSETS": "focused"
}
}
}
}Container
Built from node:22-alpine, runs as the unprivileged node user, published to GHCR on every release. Browser SSO needs a local browser; basic and oauth destinations work inside.
docker run -i --rm \
-v "$PWD/systems.json:/config/systems.json:ro" \
-e SAP_SYSTEMS_FILE=/config/systems.json \
ghcr.io/williansaez/abap-adt-mcp:latestPinned version
npx -y abap-adt-mcp fetches the newest release at every start. For a controlled rollout pin it and verify the provenance attestation trusted publishing attaches.
npx -y abap-adt-mcp@2.8.2
npm audit signaturesFrom source
A systems.json next to the checkout is picked up automatically. Point the host at dist/index.js.
git clone https://github.com/williansaez/abap-adt-mcp.git
cd abap-adt-mcp && npm ci && npm run buildAuthentication modes: sso (S/4HANA Cloud named users, a browser window once), sso2 (headless on-prem through a trusted local ticket provider), basic (on-prem users and Communication Users), oauth (unattended clients). Details in docs/AUTH.md.
One prompt away from your first activation.
Install the plugin, name your system, say hello. The first chat can read a class; the guard rails decide what it may write.