# EPOD ADT MCP Server An Eclipse ADT plugin that exposes your SAP ABAP systems to AI coding assistants via the [Model Context Protocol (MCP)](https://modelcontextprotocol.io). It runs an embedded HTTP server inside Eclipse, so any MCP-compatible client — Claude Code, Cursor, and others — can search, read, edit, test, and analyze ABAP code through your existing ADT SNC/SSO session. Connect multiple ABAP projects simultaneously and route each tool call to the right system via a `systemId` parameter. No credentials are stored or transmitted by the plugin. Authentication is handled transparently by the Eclipse ADT communication framework. ``` AI Client --(HTTP/JSON-RPC)--> Eclipse Plugin --(ADT REST API / SNC)--> SAP System(s) ``` ## What's new in 2.4.0 - `sap_create_object` creates a class with a test classes include. - `sap_pull_source`, `sap_push_source`, and `sap_push_source_from_file` accept `includeType`. A write to `testclasses` creates the include if it is missing. See [CHANGELOG.md](CHANGELOG.md) for earlier versions. ## Token-efficient by design AI assistants are billed by tokens, and most of the bill is not the prompt. Measured on a real ABAP task, 63% of the cost was cache write — everything a tool returns enters the model context — and 29% was cache read, the context re-read on every tool call. The prompt was 3%. The server therefore keeps tool responses small and call counts low: - **Member lists without source.** `sap_object_members` returns the members of a 2,000-line class in about 300 tokens. - **Element-level read and write.** Pull one `METHOD` block instead of the class. Push one method back — the server merges it into the full source and sends it to ADT. The model never holds the class. - **One-call edit.** `sap_push_source` runs the full lock → write → unlock → activate pipeline in a single call. - **Compact checks.** `sap_check_object` runs syntax check, ATC, and ABAP Unit in one call and returns findings only — no long text. - **No silent fallbacks.** A tool never falls back to the full source in silence. It states the fallback in the response, or it returns an error. ## Installation ### Via Eclipse Update Site The same site is served from two locations. Both carry byte-identical artifacts and the same version. Pick the one for you. #### Users outside SAP — external site (no sign-in) Install straight from the update-site URL `https://git.epod.dev/erhan/epod-adt-mcp-updatesite/raw/branch/main/`. 1. In Eclipse ADT, go to **Help > Install New Software...** 2. Click **Add...** and enter: - Name: `EPOD ADT MCP Server` - Location: `https://git.epod.dev/erhan/epod-adt-mcp-updatesite/raw/branch/main/` 3. Select **EPOD ADT MCP Server** from the list. 4. Click **Next**, accept the license, and complete the wizard. 5. Restart Eclipse when prompted. #### SAP developers — internal site (git clone, then local install) The internal repo is `https://github.tools.sap/GLOFINDEFICA/epod-adt-mcp-updatesite`. The GitHub Enterprise host serves files only to a signed-in browser session. Eclipse cannot supply that session, so a direct update-site URL does not work. Install from a local clone instead. 1. Clone the update-site repo: ``` git clone https://github.tools.sap/GLOFINDEFICA/epod-adt-mcp-updatesite.git ``` 2. In Eclipse ADT, go to **Help > Install New Software...** 3. Click **Add... > Local...** and select the cloned folder. The folder holds `compositeContent.xml`. 4. Select **EPOD ADT MCP Server** from the list. 5. Click **Next**, accept the license, and complete the wizard. 6. Restart Eclipse when prompted. To get a later release, run `git pull` in the clone. Then repeat the install. ### Via dropins (quick install) Download the plugin JAR from the latest release and drop it into your Eclipse `dropins/` folder, then restart Eclipse. ## Requirements - Eclipse 2024-03 or later with **SAP ADT** (ABAP Development Tools) installed - Java 21 or later to run the plugin in ADT 3.63.0. The ADT bundles `com.sap.adt.communication` and `com.sap.adt.tools.core` require JavaSE 21 (`Require-Capability: osgi.ee`, `version=21`), and the ADT launcher sets `-Dosgi.requiredJavaVersion=21` - One or more ABAP projects in your Eclipse workspace with active SNC/SSO connections to SAP ## Setup ### 1. Open the MCP Server view **Window > Show View > Other... > ABAP MCP Server** ### 2. Connect to your ABAP projects The view shows all ABAP projects in your workspace. Click **Connect All** to connect to every project at once, or select a project and click **Connect** to connect individually. The plugin reuses each project's existing ADT session — no password prompt. ### 3. Start the server Click **Start Server**. The embedded MCP server starts on `http://127.0.0.1:3000/mcp` (port is configurable). It binds to localhost only and is not accessible from the network. The server prints the client configuration block, with a bearer token, to the view console. The **Copy client config** button copies that block to the clipboard. ### 4. Configure your MCP client Add the following to your client's MCP configuration. Replace `` with the token from the view: ```json { "mcpServers": { "abap-adt": { "type": "streamable-http", "url": "http://127.0.0.1:3000/mcp", "headers": { "Authorization": "Bearer " } } } } ``` **Claude Code** — add to `.claude/settings.json` or `~/.claude/settings.json`: ```json { "mcpServers": { "abap-adt": { "type": "streamable-http", "url": "http://127.0.0.1:3000/mcp", "headers": { "Authorization": "Bearer " } } } } ``` #### Why the token and the Origin rejection The server binds to `127.0.0.1`, so the network cannot reach it. A local browser can still reach `127.0.0.1`. Any open web page can post JSON-RPC to the `/mcp` endpoint and drive the tools through your ADT session. The server rejects any request that carries an `Origin` header with HTTP 403, because a browser always sends one and an MCP client sends none. The server also requires the bearer token, which a web page cannot read. The server stores the token and reuses it on every later start. The token survives an Eclipse restart. The **Regenerate token** button creates a new token when the token leaks. The old token stops working at once. The token stays in the view and in the clipboard. The token never goes to a log or a tool response. ### 5. Verify Check the health endpoint in your browser or with curl: ``` GET http://127.0.0.1:3000/health ``` ### Preferences **Window > Preferences > ABAP MCP Server** — change the server port, enable auto-start when you connect to a project, or set the full-source line threshold for element reads (default: 200 lines). The token buttons sit in the **ABAP MCP Server** view, not on the preference page. The **Copy client config** button copies the configuration block, with the bearer token, to the clipboard. The **Regenerate token** button creates a new token when the token leaks. The server stores the token and reuses it on every later start. The token survives an Eclipse restart, so the client configuration stays valid. ## Multi-System Support When multiple ABAP projects are connected, pass `systemId` (the Eclipse project name) to route a tool call to the right system: ```json { "query": "ZCL*", "systemId": "ER1_001" } ``` - **Single system connected** — `systemId` is optional; the call is routed automatically. - **Multiple systems connected** — `systemId` is required. Omitting it returns an error listing the available systems. - **`sap_list_systems`** — call this tool at any time to see which systems are currently connected. The `systemId` description in every tool's schema is dynamically populated from the live registry, so the AI always knows which systems are available. ## Access Mode Each connected system has an access mode: write or read-only. A new connection starts in write. The mode lives in the third column of the **ABAP MCP Server** view table, next to Project and Status. The **Toggle Read-Only** button flips the mode of the selected system. A read-only system refuses the 10 write tools and makes no ADT call against SAP. Every other tool works on a read-only system. The 10 write tools are `sap_push_source`, `sap_push_source_from_file`, `sap_push_element`, `sap_push_message`, `sap_create_object`, `sap_activate`, `sap_lock`, `sap_unlock`, `sap_transport_create`, and `sap_transport_release`. The mode survives an Eclipse restart and a reconnect. The plugin stores the mode per project name. `sap_list_systems` shows the mode of each connected system. ## MCP Tools The plugin exposes 31 tools covering the full ABAP development workflow: ### Search & Navigation | Tool | Description | |------|-------------| | `sap_search_object` | Search for ABAP objects by name pattern and/or type | | `sap_object_structure` | Get the structure and metadata of an object (includes, links, source URLs) | | `sap_object_members` | List the members of a class, interface, program, or function group — name, kind, visibility, include — without source. `includeLocal=true` also lists local and test classes | | `sap_usage_references` | Find all where-used references for an object (parsed JSON) | | `sap_element_info` | Resolve an element to its signature, type, and documentation | | `sap_object_versions` | List the version history of an object (compact): number, date, author, transport, request text. A class splits the feed per include — set `includeType` | | `sap_object_diff` | Diff two versions of an object. The plugin computes a git-style unified diff and never returns two full sources. With no version numbers the tool compares the active version with the newest transported version. Set `element` to diff one member | | `sap_compare_systems` | Compare the same object in two connected systems. Set `systemId` and `compareTo`. The plugin reads the active source from both systems and computes a git-style unified diff. It never returns two full sources. An object present in one system only is reported, not an error. Set `element` to compare one member | | `sap_inactive_objects` | List objects that are currently inactive (not yet activated) | ### Read & Write Source | Tool | Description | |------|-------------| | `sap_pull_source` | Read source code of an ABAP object into the AI context. `element=` returns one `METHOD` block (`part=definition` for the declaration); `includeType` selects a class include — `main` (Global Class, default), `definitions`, `implementations`, `macros`, `testclasses`, `all` | | `sap_pull_source_to_file` | Fetch source from SAP and write it to a local file (preferred for large objects). Same `element` and `includeType` parameters | | `sap_push_source` | Write source code from context to an ABAP object in SAP — runs the full lock → write → unlock → activate pipeline in one call. `includeType` selects a class include; a write to `testclasses` creates the include if it is missing | | `sap_push_source_from_file` | Save a local file back to SAP through the same one-call pipeline. Same `includeType` parameter as `sap_push_source` | | `sap_push_element` | Write one member block. The server merges the block into the current full source and pushes it — the model never holds the class. CLAS, INTF, PROG, FUGR | | `sap_push_message` | Write one message or several messages into an existing message class (MSAG). The server reads the class, merges the messages, and writes the class back in one call. A new number is appended. An existing number is updated | | `sap_pretty_print` | Format (pretty-print) ABAP source through the ADT pretty-printer service. The tool takes only the source and uses the server's stored settings | ### Lifecycle | Tool | Description | |------|-------------| | `sap_lock` | Lock an object for editing (returns a lock handle) | | `sap_unlock` | Release a previously acquired lock | | `sap_activate` | Activate an ABAP object | | `sap_create_object` | Create a new ABAP object: class, interface, program, function group, function module (FUNC), data element, domain, table, structure, table type (TTYP), message class (MSAG), or CDS-family source (DDLS, DDLX, SRVD, DCLS, DDLA) | ### Transport Management | Tool | Description | |------|-------------| | `sap_transport_of_object` | Find which transport request an object is assigned to | | `sap_transport_list` | List transport requests (filter by status / owner) | | `sap_transport_create` | Create a new transport request | | `sap_transport_release` | Release a transport request | ### Quality, Testing & Runtime | Tool | Description | |------|-------------| | `sap_syntax_check` | Run a syntax check and return errors and warnings with line numbers | | `sap_run_unit_test` | Execute ABAP Unit tests and return pass/fail results | | `sap_atc_run` | Run ATC (ABAP Test Cockpit) checks and return quality findings | | `sap_check_object` | Syntax check, ATC, and ABAP Unit in one call. One line per step, findings only — severity, object, method, line, short message. Set `coverage=true` to add ABAP Unit statement coverage for the global class | | `sap_run_class` | Run a class implementing IF_OO_ADT_CLASSRUN (ABAP console / F9) | | `sap_short_dumps` | List recent ABAP runtime errors / short dumps (ST22) | ### Systems | Tool | Description | |------|-------------| | `sap_list_systems` | List all SAP systems currently connected and available for tool calls | ## Supported Object Types `CLAS` · `INTF` · `PROG` · `FUGR` · `FUNC` · `TABL` · `STRU` · `DDLS` · `DTEL` · `DOMA` · `SRVD` · `DDLX` · `DCLS` · `DDLA` · `SRVB` · `TTYP` · `ENQU` · `MSAG` · `BDEF` ## Protocol - MCP protocol version: `2024-11-05` - Transport: Streamable HTTP - Messaging: JSON-RPC 2.0 - Session management: `Mcp-Session-Id` header | Endpoint | Method | Description | |----------|--------|-------------| | `/mcp` | POST | JSON-RPC (initialize, tools/list, tools/call) | | `/mcp` | GET | SSE stream for server-sent events | | `/mcp` | DELETE | Close an MCP session | | `/health` | GET | Server status | ## License Copyright 2025-2026 Erhan Keseli. Licensed under the [Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0).