Files
epod-adt-mcp-updatesite/README.md
2026-09-08 19:37:05 +02:00

249 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 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=<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_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, 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).