248 lines
13 KiB
Markdown
248 lines
13 KiB
Markdown
# 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, Windsurf, 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)
|
|
```
|
|
|
|
|
|
## 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/I301710/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/I301710/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 17 or later
|
|
- 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 `<token>` with the token from the view:
|
|
|
|
```json
|
|
{
|
|
"mcpServers": {
|
|
"abap-adt": {
|
|
"type": "streamable-http",
|
|
"url": "http://127.0.0.1:3000/mcp",
|
|
"headers": { "Authorization": "Bearer <token>" }
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
**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 <token>" }
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
#### 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 9 write tools and makes no ADT call against SAP. Every other tool works on a read-only system. The 9 write tools are `sap_push_source`, `sap_push_source_from_file`, `sap_push_element`, `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 30 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=<member>` 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 |
|
|
| `sap_push_source_from_file` | Save a local file back to SAP through the same one-call pipeline |
|
|
| `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_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, data element, domain, table, structure, 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).
|