@aspirio/sap-adt-mcp
v1.2.1
Published
MCP server for SAP ADT (ABAP Development Tools)
Maintainers
Readme
abap-adt-mcp
⚠️ Known Issue: Generating the lock file with npm 11 (bundled with Node 24) produces a
package-lock.jsonthat is incompatible with npm 10 (Node 22). This causesnpm cito fail in CI/CD pipelines with "Missing: @emnapi/core from lock file". Always regenerate the lock file using the same npm version used in CI, or upgrade CI to Node 24+.
A standalone Node.js MCP (Model Context Protocol) server for SAP ADT (ABAP Development Tools). Interact directly with your SAP system — search objects, read/write source code, run tests, and more.
This is a TypeScript port of the Eclipse-based SAP ADT MCP Server plugin.
Features
19 tools covering the full ABAP development lifecycle:
| Tool | Description |
| ------------------------- | ------------------------------------------------------------- |
| sap_search_object | Search ABAP objects by name pattern with wildcards |
| sap_get_source | Read source code (active, inactive, or working area) |
| sap_set_source | Write source code with automatic lock/unlock/activate |
| sap_object_structure | Get object metadata, includes, and function modules |
| sap_usage_references | Where-used analysis across the system |
| sap_syntax_check | Syntax check with errors/warnings and line numbers |
| sap_activate | Activate objects after editing |
| sap_lock / sap_unlock | Manual object locking/unlocking (lock includes transport info)|
| sap_create_object | Create programs, includes, classes, interfaces, function groups, data elements, domains, tables, structures |
| sap_inactive_objects | List all inactive objects for the current user |
| sap_run_unit_test | Run ABAP Unit tests with pass/fail per method |
| sap_atc_run | Run ATC code quality checks |
| sap_sql_query | Execute SQL SELECT queries with data preview |
| sap_abap_docu | Look up ABAP documentation (keywords, classes, etc.) |
| sap_list_package_objects | List all objects in a package with optional type filtering |
| sap_transport_check | Validate transport requirements before creation/modification |
| sap_get_main_programs | Get main programs that use a given include |
| sap_object_properties | Get object properties (package, owner, version, dates, etc.) |
Flexible Input Resolution
Most tools accept two input styles:
- By type + name (primary):
objectType: "CLAS", objectName: "ZCL_MY_CLASS" - By direct ADT URL (advanced):
objectSourceUrlorobjectUrlorurl
When both are provided, objectType + objectName takes priority. This matches the Java reference implementation's AbstractMcpTool resolution pattern.
Notable Output Formats
sap_usage_referencesreturns{ statusCode: number, response: string }— theresponsefield contains the raw ADT XML body. This matches the JavaUsageReferencesTooloutput contract.sap_abap_docuuses ADT type codesCLAS,FUNC, andTYPEfor class, function module, and type documentation lookups respectively.
Requirements
- Node.js 18+
- SAP system with ADT services enabled (HTTP/HTTPS)
- SAP user with appropriate ADT authorizations
Installation
npm install
npm run buildConfiguration
Set these environment variables:
| Variable | Required | Description |
| ------------------ | -------- | ------------------------------------------------ |
| SAP_URL | ✅ | SAP system URL (e.g. https://myserver:44300) |
| SAP_USER | ✅ | SAP username |
| SAP_PASSWORD | ✅ | SAP password |
| SAP_CLIENT | | SAP client number (default: 100) |
| SAP_LANGUAGE | | Logon language (default: EN) |
| SAP_INSECURE_SSL | | Set to true to skip SSL certificate validation |
Usage
With an MCP client
Add to your MCP client configuration (e.g. ~/.claude.json or equivalent):
{
"mcpServers": {
"abap-adt-mcp": {
"command": "node",
"args": ["/path/to/abap-adt-mcp/dist/index.js"],
"env": {
"SAP_URL": "https://your-sap-server:44300",
"SAP_USER": "YOUR_USER",
"SAP_PASSWORD": "YOUR_PASSWORD",
"SAP_CLIENT": "100"
}
}
}
}Standalone
SAP_URL=https://myserver:44300 SAP_USER=admin SAP_PASSWORD=secret node dist/index.jsThe server communicates via stdio using the MCP protocol.
Local Testing
The server uses stdio (JSON-RPC over stdin/stdout), so you can't just run it and see output. Here's how to test it locally:
Quick smoke test
Create a test script (e.g. test-local.mjs):
import { spawn } from "child_process";
const proc = spawn("node", ["dist/index.js"], {
env: {
...process.env,
SAP_URL: "https://your-sap-server:8443",
SAP_USER: "YOUR_USER",
SAP_PASSWORD: "YOUR_PASSWORD",
SAP_CLIENT: "800",
SAP_INSECURE_SSL: "true", // set to "true" for self-signed certs
},
stdio: ["pipe", "pipe", "pipe"],
});
proc.stderr.on("data", (d) => console.error("[server]", d.toString().trim()));
proc.stdout.on("data", (d) => console.log("[response]", d.toString().trim()));
function send(msg) {
proc.stdin.write(JSON.stringify(msg) + "\n");
}
// 1. Initialize handshake
send({
jsonrpc: "2.0",
id: 1,
method: "initialize",
params: {
protocolVersion: "2024-11-05",
capabilities: {},
clientInfo: { name: "test", version: "1.0" },
},
});
setTimeout(() => {
send({ jsonrpc: "2.0", method: "notifications/initialized" });
// 2. List all available tools
send({ jsonrpc: "2.0", id: 2, method: "tools/list", params: {} });
}, 500);
setTimeout(() => {
// 3. Call a tool — search for classes starting with ZCL_
send({
jsonrpc: "2.0",
id: 3,
method: "tools/call",
params: {
name: "sap_search_object",
arguments: { query: "ZCL_*", max: 5 },
},
});
}, 1500);
setTimeout(() => {
proc.kill();
process.exit(0);
}, 8000);Run it:
node test-local.mjsExpected output:
[server] abap-adt-mcp server running (SAP: https://your-sap-server:8443, user: YOUR_USER)
[response] {"result":{"protocolVersion":"2024-11-05","capabilities":{...},"serverInfo":{"name":"abap-adt-mcp","version":"1.0.0"}},"jsonrpc":"2.0","id":1}
[response] {"result":{"tools":[...19 tools...]},"jsonrpc":"2.0","id":2}
[response] {"result":{"content":[{"type":"text","text":"{\"totalResults\":5,\"results\":[...]}"}]},"jsonrpc":"2.0","id":3}Finding your SAP ADT port
If you don't know which port ADT runs on, try common SAP HTTPS ports:
for port in 443 8443 44300 44301 50001; do
echo -n "Port $port: "
curl -sk --connect-timeout 3 -o /dev/null -w "%{http_code}\n" \
"https://your-sap-server:$port/sap/bc/adt/core/discovery"
doneA response of 401 (Unauthorized) means ADT is running on that port.
Development
npm run build # Compile TypeScript
npm run dev # Build and runDebugging ADT API calls with Eclipse Communication Log
To see exactly which HTTP requests Eclipse ADT makes to the SAP backend (useful for implementing new tools):
- Enable the log: Window → Preferences → ABAP Development → Communication Log → Enable
- Open the view: Window → Show View → ABAP Communication Log
This dumps every HTTP request/response ADT makes. Trigger an action in Eclipse (e.g. open a class, run ATC, activate an object) and the corresponding /sap/bc/adt/ calls will appear in the log with full URLs, headers, and XML bodies.
Architecture
src/
├── index.ts # MCP server with all 19 tool registrations
├── adt-client.ts # HTTP REST client (CSRF tokens, cookies, auth, connection retry)
├── resolve-helpers.ts # Tool input resolution with direct URL fallback
├── abap-docu-utils.ts # Documentation type detection and keyword list
├── url-resolver.ts # Object type → ADT URL mapping
└── xml-parser.ts # XML response parsers for all ADT endpoints