guniweb-sap-mcp 0.2.2 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +110 -17
- package/dist/index.js +82 -29
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# GuniWeb SAP S/4HANA & ECC MCP Server
|
|
2
2
|
|
|
3
|
-
Designed for n8n, usable from any MCP host
|
|
3
|
+
Designed for n8n, usable from any MCP host. Free to use — built and maintained by [GuniWeb](https://guniweb.de).
|
|
4
4
|
|
|
5
|
-
Connect n8n workflows to SAP S/4HANA and ECC via OData V2, V4, IDocs, and RFC/BAPI using the Model Context Protocol (MCP).
|
|
5
|
+
Connect n8n workflows to SAP S/4HANA and ECC via OData V2, V4, IDocs, and RFC/BAPI using the Model Context Protocol (MCP). Made for **AI-assisted, human-governed workflows**: the workflow author decides which SAP APIs are called and in what order; the LLM extracts, maps and fills in parameters. Writes are off by default and switched on explicitly, per server and per token.
|
|
6
6
|
|
|
7
7
|
```mermaid
|
|
8
8
|
graph LR
|
|
9
|
-
n8n["n8n
|
|
9
|
+
n8n["n8n workflow<br/>AI-assisted, human-governed"] -->|MCP Protocol| MCP["guniweb-sap-mcp<br/>22 Tools • 7 Auth Types"]
|
|
10
10
|
MCP -->|"OData V2/V4<br/>IDoc XML<br/>RFC/BAPI"| SAP["SAP S/4HANA & ECC"]
|
|
11
11
|
MCP -->|"OAuth2 / JWT"| BTP["SAP BTP"]
|
|
12
12
|
BTP --> SAP
|
|
@@ -33,12 +33,13 @@ graph LR
|
|
|
33
33
|
- **Smart Query Routing** -- Domain-based routing resources for LLM tool selection
|
|
34
34
|
- **Decision-Tree Tool Descriptions** -- "When to use / When NOT to use" blocks guide LLMs
|
|
35
35
|
|
|
36
|
-
###
|
|
37
|
-
- **
|
|
38
|
-
- **`sap_enable_tools`** -- LLMs activate additional tool tiers at runtime
|
|
36
|
+
### Governed tool visibility
|
|
37
|
+
- **4-Tier Tool Registry** -- Core / OData / IDoc / RFC tiers with on-demand activation
|
|
38
|
+
- **`sap_enable_tools`** -- LLMs activate additional tool tiers at runtime, within the limits you set
|
|
39
39
|
- **Read-only by default (since 0.2.2)** -- write tools require `--allow-write`
|
|
40
|
-
- **
|
|
41
|
-
- **
|
|
40
|
+
- **Per-token policy (0.3.0)** -- `readOnly` and tool-tier ceilings per Bearer token, only ever more restrictive
|
|
41
|
+
- **IDoc / RFC auto-disable** -- tools hidden when the corresponding configuration is missing
|
|
42
|
+
- **MCP Annotations** -- readOnlyHint, destructiveHint, idempotentHint on all 22 tools
|
|
42
43
|
|
|
43
44
|
### Authentication (7 Types)
|
|
44
45
|
|
|
@@ -65,9 +66,10 @@ graph TB
|
|
|
65
66
|
|
|
66
67
|
### Infrastructure
|
|
67
68
|
- **Three Transport Modes** -- stdio, Streamable HTTP, SSE
|
|
68
|
-
- **
|
|
69
|
+
- **Named destinations (0.3.0)** -- one server, several SAP systems; a Bearer token per n8n credential selects the system and its permissions. Static API key still supported
|
|
69
70
|
- **Docker Ready** -- Docker Compose for n8n + SAP MCP sidecar
|
|
70
|
-
- **
|
|
71
|
+
- **Zero telemetry** -- the server talks to the SAP/BTP endpoints you configure and to nothing else. No usage statistics, no update checks, no crash reports
|
|
72
|
+
- **1267 Tests** -- Unit, integration, E2E with CI/CD via GitHub Actions
|
|
71
73
|
|
|
72
74
|
## Quick Start
|
|
73
75
|
|
|
@@ -159,11 +161,84 @@ Clients that *require* a session id — they read `mcp-session-id` from the init
|
|
|
159
161
|
|
|
160
162
|
The legacy `--transport sse` mode is different: it keeps a per-connection session and expects a `?sessionId=` query parameter on `/messages`. Prefer `http` for new setups.
|
|
161
163
|
|
|
164
|
+
#### Several SAP systems: `destinations.json`
|
|
165
|
+
|
|
166
|
+
The `SAP_*` variables describe **one** SAP system. To run one server against several — a production system next to a test client, or several customers' systems behind one n8n — put the connections into a `destinations.json` and point the server at it:
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
guniweb-sap-mcp --transport http --port 8808 --destinations /config/destinations.json
|
|
170
|
+
# or: SAP_MCP_DESTINATIONS=/config/destinations.json
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
```json
|
|
174
|
+
{
|
|
175
|
+
"version": 1,
|
|
176
|
+
"destinations": {
|
|
177
|
+
"default": {
|
|
178
|
+
"baseUrl": "https://s4prod.example.com",
|
|
179
|
+
"authType": "basic",
|
|
180
|
+
"username": "MCP_USER",
|
|
181
|
+
"password": "${S4PROD_PASSWORD}",
|
|
182
|
+
"sapClient": "100"
|
|
183
|
+
},
|
|
184
|
+
"s4test": {
|
|
185
|
+
"baseUrl": "https://s4test.example.com",
|
|
186
|
+
"authType": "basic",
|
|
187
|
+
"username": "MCP_USER",
|
|
188
|
+
"password": "${S4TEST_PASSWORD}",
|
|
189
|
+
"sapClient": "200"
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
- **One entry = one connection.** Every entry accepts exactly the fields the `SAP_*` variables accept (`authType` and its credentials, `sapClient`, `baseUrl`) — all seven authentication types work per destination.
|
|
196
|
+
- **Secrets stay out of the file.** Any string may contain `${VARIABLE}`; it is resolved from the environment at load time (Docker secrets, `.env`). A placeholder that cannot be resolved makes the file invalid — an empty password would otherwise surface as a misleading `401` from SAP.
|
|
197
|
+
- **Hot reload.** The file is watched; a change is picked up on the next request, no restart. `kill -HUP <pid>` forces a reload. An invalid file **never** replaces the running configuration — the error is logged and the last valid one stays in force.
|
|
198
|
+
- **Backwards compatible.** Without `--destinations` nothing changes: the `SAP_*` variables are the single destination `default`. With the file, `SAP_*` (if set) is added as `default` unless the file defines one — so an installation can migrate without a gap.
|
|
199
|
+
- **Which destination answers?** Without a token: the one named `default` (or the only one). With a token: the token's destination — see below.
|
|
200
|
+
|
|
201
|
+
**Tokens: one Bearer value per n8n credential selects the system.** The n8n MCP Client sends exactly one `Authorization` header, so a token does two jobs at once — it authenticates the request and picks the destination. SAP passwords never leave the server; n8n only holds the token.
|
|
202
|
+
|
|
203
|
+
```json
|
|
204
|
+
{
|
|
205
|
+
"version": 1,
|
|
206
|
+
"destinations": { "s4prod": { "...": "..." }, "s4test": { "...": "..." } },
|
|
207
|
+
"tokens": [
|
|
208
|
+
{ "hash": "sha256:9f2c…", "destination": "s4prod", "label": "n8n prod workflows" },
|
|
209
|
+
{ "hash": "sha256:1a7e…", "destination": "s4test", "label": "n8n dev", "revoked": false }
|
|
210
|
+
]
|
|
211
|
+
}
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
- The file holds only the **SHA-256 hash**; the plain token (`gsm_<destination>_<random>`) is printed **once** by `tokens issue` and cannot be recovered afterwards. Put it into an n8n **Bearer Auth** credential on the MCP Client node. As soon as at least one token exists, requests without a valid token get `401` — `--api-key` keeps working alongside and serves the `default` destination.
|
|
215
|
+
- Lookup is constant-time over all entries; `"revoked": true` disables a token on the next request (hot reload, no restart). After 10 failed attempts within a minute the client address gets `429` with `Retry-After` — also for a valid token — as a brake on guessing (a reverse proxy with a real rate limit is still the right place for that). Tokens are never written to the log; rejections are logged with address and reason.
|
|
216
|
+
**Managing the file — no hand-editing needed.** The same binary carries the admin commands; every command validates the result exactly like the server does before writing (never leaves an unloadable file), writes atomically, and a running server picks the change up on the next request:
|
|
217
|
+
|
|
218
|
+
```bash
|
|
219
|
+
export SAP_MCP_DESTINATIONS=/config/destinations.json # or --destinations <path> on each call
|
|
220
|
+
|
|
221
|
+
guniweb-sap-mcp destinations add s4prod --base-url https://s4prod.example.com --auth-type basic \
|
|
222
|
+
--username MCP_USER --password '${S4PROD_PASSWORD}' --sap-client 100
|
|
223
|
+
guniweb-sap-mcp destinations add legacy --from-env # copy the current SAP_* environment (migration)
|
|
224
|
+
guniweb-sap-mcp destinations list # names, URLs, auth type, client, token count — never secrets
|
|
225
|
+
|
|
226
|
+
guniweb-sap-mcp tokens issue s4prod --label "n8n prod" --read-only --tiers core,odata
|
|
227
|
+
# → prints the plain token ONCE on stdout (everything else goes to stderr, so TOKEN=$(…) works)
|
|
228
|
+
guniweb-sap-mcp tokens list # label, destination, hash prefix, policy, status
|
|
229
|
+
guniweb-sap-mcp tokens revoke "n8n prod" # by label or ≥ 8 hex chars of the hash
|
|
230
|
+
guniweb-sap-mcp destinations remove s4test [--force] # refuses while tokens point at it, unless --force
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
`--set field=value` covers any auth type (`--auth-type oauth2 --set clientId=… --set clientSecret='${BTP_SECRET}' --set tokenServiceUrl=…`); `${ENV_VAR}` values are checked against the current environment (`--allow-missing-env` to skip, e.g. when the variable only exists inside the container). In Docker, run the commands inside the container so they see the same file and environment: `docker compose exec sap-mcp guniweb-sap-mcp tokens issue s4prod`.
|
|
234
|
+
|
|
235
|
+
- **Per-token permissions** — `"policy": { "readOnly": true, "tiers": ["core", "odata"] }`. A policy only ever *restricts*: `readOnly: true` hides the write tools for that token even when the server runs with `--allow-write` (`readOnly: false` cannot open a read-only server), and `tiers` is a ceiling — tiers outside it are invisible for that token and `sap_enable_tools` cannot switch them on. `tools/list` is filtered per request, so an agent on a read-only token never sees `sap_create` in the first place.
|
|
236
|
+
|
|
162
237
|
### 4. Use with n8n
|
|
163
238
|
|
|
164
239
|
1. Add an **AI Agent** node with an **MCP Client Tool** sub-node
|
|
165
|
-
2. Set the MCP Client URL to `http://sap-mcp:8808/mcp` (Docker) or `http://localhost:8808/mcp
|
|
166
|
-
3. The AI
|
|
240
|
+
2. Set the MCP Client URL to `http://sap-mcp:8808/mcp` (Docker) or `http://localhost:8808/mcp`, with a Bearer Auth credential holding your API key or destination token
|
|
241
|
+
3. The AI Agent node discovers the SAP tools automatically. **Which** tools it sees is your decision, not the model's: read-only by default, write tools only with `--allow-write`, and per-token policies narrow it further. Design the workflow as a deterministic, human-authored sequence — the LLM fills in the parameters
|
|
167
242
|
|
|
168
243
|
## Setup for SAP ECC
|
|
169
244
|
|
|
@@ -173,7 +248,7 @@ ECC NetWeaver backends require additional setup beyond the [Quick Start](#quick-
|
|
|
173
248
|
|
|
174
249
|
In transaction `SICF`, activate the standard ICF services under `/sap/opu/odata/`. Then use transaction `/IWFND/MAINT_SERVICE` to register the OData services you want to expose.
|
|
175
250
|
|
|
176
|
-
The MCP server's catalog auto-discovery
|
|
251
|
+
The MCP server's catalog auto-discovery probes three paths in sequence and caches the first 200 hit:
|
|
177
252
|
|
|
178
253
|
- `/sap/opu/odata/IWFND/CATALOGSERVICE;v=2/ServiceCollection` (S/4HANA default)
|
|
179
254
|
- `/sap/opu/odata/iwfnd/CATALOGSERVICE;v=2/ServiceCollection` (lower-case ECC)
|
|
@@ -400,10 +475,28 @@ Additionally validated against:
|
|
|
400
475
|
|
|
401
476
|
## Documentation
|
|
402
477
|
|
|
403
|
-
- [Setup Guide](docs/setup-guide.md) -- Installation, all 7 auth types, CLI flags, Docker deployment
|
|
404
|
-
- [Architecture](docs/architecture.md) -- Technical architecture, request flows, design decisions
|
|
405
|
-
- [API Reference](docs/api-reference.md) -- All
|
|
406
|
-
- [Examples](docs/examples.md) -- SAP workflow examples with step-by-step instructions
|
|
478
|
+
- [Setup Guide](https://github.com/guniweb/guniweb-sap-mcp/blob/main/docs/setup-guide.md) -- Installation, all 7 auth types, CLI flags, named destinations and tokens, Docker deployment
|
|
479
|
+
- [Architecture](https://github.com/guniweb/guniweb-sap-mcp/blob/main/docs/architecture.md) -- Technical architecture, request flows, design decisions
|
|
480
|
+
- [API Reference](https://github.com/guniweb/guniweb-sap-mcp/blob/main/docs/api-reference.md) -- All 22 tools, resources, and prompts with parameters
|
|
481
|
+
- [Examples](https://github.com/guniweb/guniweb-sap-mcp/blob/main/docs/examples.md) -- SAP workflow examples with step-by-step instructions
|
|
482
|
+
- [SAP interfaces, tool by tool](https://github.com/guniweb/guniweb-sap-mcp/blob/main/docs/sap-interfaces.md) -- which SAP endpoint each of the 22 tools calls, what is bounded, what leaves your network — for Basis teams, license managers and auditors
|
|
483
|
+
- [Changelog](https://github.com/guniweb/guniweb-sap-mcp/blob/main/CHANGELOG.md) · [Releases](https://github.com/guniweb/guniweb-sap-mcp/releases) · [Issues](https://github.com/guniweb/guniweb-sap-mcp/issues) · [Discussions](https://github.com/guniweb/guniweb-sap-mcp/discussions)
|
|
484
|
+
|
|
485
|
+
## Governance: how this fits SAP's rules
|
|
486
|
+
|
|
487
|
+
- **Standard integration interfaces only.** The server speaks OData V2/V4 through NetWeaver Gateway, IDoc over HTTP/XML and RFC/BAPI — the documented, supported ways into an SAP system ([tool-by-tool list](https://github.com/guniweb/guniweb-sap-mcp/blob/main/docs/sap-interfaces.md)). No UI automation, no undocumented interfaces, no bulk replication of SAP data. Paging limits and time budgets are built in so a single tool call cannot turn into a load test of your Gateway.
|
|
488
|
+
- **The write path is governed and auditable.** Read-only by default; write tools exist only with an explicit `--allow-write`; per-token policies can only restrict, never widen; every tool call leaves one log line with a correlation id that also appears on each SAP request it triggered. That is what makes "human-governed" verifiable: the workflow author, not the model, decides where writes are possible.
|
|
489
|
+
- **Two things to settle before you automate document creation.** SAP's API usage policy contains terms on autonomous, generative use of its APIs — build workflows as deterministic, human-authored sequences with LLM assistance rather than open-ended autonomous agents (this server is designed for exactly that). And business documents created automatically (a sales order, for instance) may fall under SAP Digital Access licensing for your tenant — clarify that with your SAP account team before you go live. Neither sentence is legal advice; both are the questions your auditor will ask.
|
|
490
|
+
|
|
491
|
+
## Who is behind this — and how to get help
|
|
492
|
+
|
|
493
|
+
guniweb-sap-mcp is built and maintained by [GuniWeb](https://guniweb.de) — a consultancy with its own solutions: *processes that work, systems that grow with you*. GuniWeb optimises business processes for mid-sized companies, with more than 20 years of practice, strategic consulting and hands-on implementation, so that a company does not just become more digital but runs better. This server is one of those solutions: it runs in production at customers and is used in teaching and research. The compiled package on npm is **free to use** under the ISC license; the source code is not public.
|
|
494
|
+
|
|
495
|
+
- **Community** — questions, bug reports and ideas via [Issues](https://github.com/guniweb/guniweb-sap-mcp/issues) and [Discussions](https://github.com/guniweb/guniweb-sap-mcp/discussions), best effort. See [SUPPORT.md](https://github.com/guniweb/guniweb-sap-mcp/blob/main/SUPPORT.md).
|
|
496
|
+
- **Production support** — maintenance subscription with prioritised fixes, compatibility with SAP release changes and a direct channel; optionally with a response-time SLA for the write path: **[guniweb.de/sap-mcp](https://guniweb.de/sap-mcp#support)**
|
|
497
|
+
- **SAP MCP Checkup** — we review your n8n/SAP setup (auth, governance, tool visibility, performance) before it goes live: **[guniweb.de/sap-mcp](https://guniweb.de/sap-mcp#checkup)**
|
|
498
|
+
|
|
499
|
+
Contact: [support@guniweb.de](mailto:support@guniweb.de). Security issues: see [SECURITY.md](https://github.com/guniweb/guniweb-sap-mcp/blob/main/SECURITY.md) — and note the zero-telemetry commitment there.
|
|
407
500
|
|
|
408
501
|
## Technology
|
|
409
502
|
|