guniweb-sap-mcp 0.3.0 → 0.4.0
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 +74 -19
- package/dist/index.js +127 -55
- 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 • 8 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,19 +33,21 @@ 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
|
-
### Authentication (
|
|
44
|
+
### Authentication (8 Types)
|
|
44
45
|
|
|
45
46
|
```mermaid
|
|
46
47
|
graph TB
|
|
47
48
|
subgraph Technical["Technical User Auth"]
|
|
48
49
|
basic["basic<br/><i>Direct S/4HANA</i>"]
|
|
50
|
+
userbasic["user-basic<br/><i>Personal SAP login per request</i>"]
|
|
49
51
|
oauth2["oauth2<br/><i>BTP Client Credentials</i>"]
|
|
50
52
|
apikey["apikey<br/><i>Sandbox / Testing</i>"]
|
|
51
53
|
end
|
|
@@ -65,12 +67,25 @@ graph TB
|
|
|
65
67
|
|
|
66
68
|
### Infrastructure
|
|
67
69
|
- **Three Transport Modes** -- stdio, Streamable HTTP, SSE
|
|
68
|
-
- **
|
|
70
|
+
- **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
71
|
- **Docker Ready** -- Docker Compose for n8n + SAP MCP sidecar
|
|
72
|
+
- **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
|
|
70
73
|
- **1267 Tests** -- Unit, integration, E2E with CI/CD via GitHub Actions
|
|
71
74
|
|
|
72
75
|
## Quick Start
|
|
73
76
|
|
|
77
|
+
### Try it without an SAP system: `--demo`
|
|
78
|
+
|
|
79
|
+
No SAP system at hand? Start the server against a built-in mock S/4HANA and try every tool from n8n or any MCP client:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
npx guniweb-sap-mcp --demo # stdio — n8n MCP Client in command mode
|
|
83
|
+
npx guniweb-sap-mcp --demo --transport http --port 8808 # HTTP — n8n MCP Client with URL http://localhost:8808/mcp
|
|
84
|
+
npx guniweb-sap-mcp --demo --allow-write # also try sap_create / sap_update / sap_delete / sap_batch
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
The demo starts an in-memory OData V2 gateway on localhost (three services with real SAP field names — `API_BUSINESS_PARTNER`, `API_SALES_ORDER_SRV`, `API_PRODUCT_SRV`; ~20 business partners, 15 sales orders with items, 10 products) and points the server at it. It behaves like a Gateway where it matters: catalog discovery, `$metadata`, `$filter`/`$expand`/paging, CSRF tokens, ETags, deep insert, function imports, `$batch` with changesets, SAP-style error payloads. Sample data only — nothing is real, nothing leaves your machine, and changes are gone when the process ends. Also `SAP_MCP_DEMO=true` (e.g. in Docker). A workflow you build against the demo runs against a real system after you replace `--demo` with your `SAP_*` configuration.
|
|
88
|
+
|
|
74
89
|
### 1. Install
|
|
75
90
|
|
|
76
91
|
```bash
|
|
@@ -190,7 +205,8 @@ guniweb-sap-mcp --transport http --port 8808 --destinations /config/destinations
|
|
|
190
205
|
}
|
|
191
206
|
```
|
|
192
207
|
|
|
193
|
-
- **One entry = one connection.** Every entry accepts exactly the fields the `SAP_*` variables accept (`authType` and its credentials, `sapClient`, `baseUrl`) — all
|
|
208
|
+
- **One entry = one connection.** Every entry accepts exactly the fields the `SAP_*` variables accept (`authType` and its credentials, `sapClient`, `baseUrl`) — all authentication types work per destination.
|
|
209
|
+
- **Personal SAP login per request** — `"authType": "user-basic"`: the destination knows system and client only; SAP user and password come with each request (`X-SAP-Username`/`X-SAP-Password`, in n8n the credential of the [GuniWeb SAP node](https://github.com/guniweb/n8n-nodes-guniweb-sap)). Everyone acts in SAP as themselves — authorizations, change documents and audit trail on the real user, no shared technical account. No fallback to a technical user (`401` without a login), caches per user, passwords never logged. HTTP transport only. Details in the [setup guide](https://github.com/guniweb/guniweb-sap-mcp/blob/main/docs/setup-guide.md#personal-sap-login-per-request-user-basic).
|
|
194
210
|
- **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.
|
|
195
211
|
- **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.
|
|
196
212
|
- **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.
|
|
@@ -232,11 +248,32 @@ guniweb-sap-mcp destinations remove s4test [--force] # refuses while token
|
|
|
232
248
|
|
|
233
249
|
- **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.
|
|
234
250
|
|
|
251
|
+
**Admin API — the same operations over HTTP (self-service).** With `--admin-token <secret>` (or `SAP_MCP_ADMIN_TOKEN`, at least 16 characters, e.g. `openssl rand -base64 32`) the server exposes the CLI's operations under `/admin` — for an n8n workflow that provisions a new customer's access, a script, or a person with `curl`, without a shell on the host:
|
|
252
|
+
|
|
253
|
+
```bash
|
|
254
|
+
guniweb-sap-mcp --transport http --port 8808 --destinations /config/destinations.json --admin-token "$ADMIN"
|
|
255
|
+
|
|
256
|
+
A="Authorization: Bearer $ADMIN"; J="Content-Type: application/json"; U=http://localhost:8808/admin
|
|
257
|
+
curl -H "$A" $U/destinations # list — never secrets
|
|
258
|
+
curl -H "$A" -H "$J" -X PUT $U/destinations/s4prod \ # create (201) or replace (200)
|
|
259
|
+
-d '{"baseUrl":"https://s4prod.example.com","authType":"basic","username":"MCP_USER","password":"${S4PROD_PASSWORD}","sapClient":"100"}'
|
|
260
|
+
curl -H "$A" -H "$J" -X POST $U/tokens \ # → { "token": "gsm_s4prod_…", … } — shown ONCE
|
|
261
|
+
-d '{"destination":"s4prod","label":"n8n prod","readOnly":true,"tiers":["core","odata"]}'
|
|
262
|
+
curl -H "$A" $U/tokens # label, destination, hash prefix, policy, status
|
|
263
|
+
curl -H "$A" -X DELETE "$U/tokens/n8n%20prod" # revoke by label or hash prefix
|
|
264
|
+
curl -H "$A" -X DELETE "$U/destinations/s4test?force=true" # remove; without force it refuses while tokens exist
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
- **Separate keys, separate doors.** The admin secret opens *only* `/admin`; the n8n tokens and `--api-key` open *only* `/mcp`. A leaked n8n token cannot mint further access, an admin secret cannot read SAP data. Wrong secrets are counted per client address (`429` after 10 failures per minute); every change is logged with action, target and client address — never the token, never the secret. Without `--admin-token`, `/admin/*` answers `404`.
|
|
268
|
+
- **Effective immediately.** Every write validates like the CLI, writes atomically and reloads the running configuration before answering (`"reloaded": true`). If the server cannot load what was written — typically a `${VAR}` that only your shell knows, written with `?allowMissingEnv=true` — the answer says `"reloaded": false` with the errors, and the last valid configuration stays in force.
|
|
269
|
+
- **Bootstrap without any SAP configuration.** With `--admin-token` the server starts even if `destinations.json` does not exist yet and no `SAP_*` is set: `/mcp` answers `503` until the first destination (and a token, or a destination named `default`) has been created through the API. `docker run … -e SAP_MCP_ADMIN_TOKEN=… -e SAP_MCP_DESTINATIONS=/config/destinations.json` is a complete first start.
|
|
270
|
+
- Put the API behind the same reverse proxy/TLS as `/mcp`; the admin secret travels as a Bearer header like any other credential.
|
|
271
|
+
|
|
235
272
|
### 4. Use with n8n
|
|
236
273
|
|
|
237
274
|
1. Add an **AI Agent** node with an **MCP Client Tool** sub-node
|
|
238
|
-
2. Set the MCP Client URL to `http://sap-mcp:8808/mcp` (Docker) or `http://localhost:8808/mcp
|
|
239
|
-
3. The AI
|
|
275
|
+
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
|
|
276
|
+
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
|
|
240
277
|
|
|
241
278
|
## Setup for SAP ECC
|
|
242
279
|
|
|
@@ -246,7 +283,7 @@ ECC NetWeaver backends require additional setup beyond the [Quick Start](#quick-
|
|
|
246
283
|
|
|
247
284
|
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.
|
|
248
285
|
|
|
249
|
-
The MCP server's catalog auto-discovery
|
|
286
|
+
The MCP server's catalog auto-discovery probes three paths in sequence and caches the first 200 hit:
|
|
250
287
|
|
|
251
288
|
- `/sap/opu/odata/IWFND/CATALOGSERVICE;v=2/ServiceCollection` (S/4HANA default)
|
|
252
289
|
- `/sap/opu/odata/iwfnd/CATALOGSERVICE;v=2/ServiceCollection` (lower-case ECC)
|
|
@@ -354,7 +391,7 @@ graph TB
|
|
|
354
391
|
Discovery["Service Discovery<br/>16 Domain Categories"]
|
|
355
392
|
NLQuery["NL-to-OData<br/>Filter Builder"]
|
|
356
393
|
HTTP["SapHttpClient<br/>CSRF • Redirect • Auth"]
|
|
357
|
-
Auth["Auth Layer<br/>
|
|
394
|
+
Auth["Auth Layer<br/>8 Auth Types"]
|
|
358
395
|
Cache["Per-User Token Cache<br/>LRU • SHA-256"]
|
|
359
396
|
|
|
360
397
|
Transport --> UserCtx
|
|
@@ -473,10 +510,28 @@ Additionally validated against:
|
|
|
473
510
|
|
|
474
511
|
## Documentation
|
|
475
512
|
|
|
476
|
-
- [Setup Guide](docs/setup-guide.md) -- Installation, all
|
|
477
|
-
- [Architecture](docs/architecture.md) -- Technical architecture, request flows, design decisions
|
|
478
|
-
- [API Reference](docs/api-reference.md) -- All
|
|
479
|
-
- [Examples](docs/examples.md) -- SAP workflow examples with step-by-step instructions
|
|
513
|
+
- [Setup Guide](https://github.com/guniweb/guniweb-sap-mcp/blob/main/docs/setup-guide.md) -- Installation, all 8 auth types, CLI flags, named destinations and tokens, Docker deployment
|
|
514
|
+
- [Architecture](https://github.com/guniweb/guniweb-sap-mcp/blob/main/docs/architecture.md) -- Technical architecture, request flows, design decisions
|
|
515
|
+
- [API Reference](https://github.com/guniweb/guniweb-sap-mcp/blob/main/docs/api-reference.md) -- All 22 tools, resources, and prompts with parameters
|
|
516
|
+
- [Examples](https://github.com/guniweb/guniweb-sap-mcp/blob/main/docs/examples.md) -- SAP workflow examples with step-by-step instructions
|
|
517
|
+
- [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
|
|
518
|
+
- [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)
|
|
519
|
+
|
|
520
|
+
## Governance: how this fits SAP's rules
|
|
521
|
+
|
|
522
|
+
- **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.
|
|
523
|
+
- **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.
|
|
524
|
+
- **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.
|
|
525
|
+
|
|
526
|
+
## Who is behind this — and how to get help
|
|
527
|
+
|
|
528
|
+
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.
|
|
529
|
+
|
|
530
|
+
- **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).
|
|
531
|
+
- **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)**
|
|
532
|
+
- **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)**
|
|
533
|
+
|
|
534
|
+
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.
|
|
480
535
|
|
|
481
536
|
## Technology
|
|
482
537
|
|