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.
Files changed (3) hide show
  1. package/README.md +74 -19
  2. package/dist/index.js +127 -55
  3. 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 AI Agent<br/>+ LLM"] -->|MCP Protocol| MCP["guniweb-sap-mcp<br/>22 Tools &bull; 7 Auth Types"]
9
+ n8n["n8n workflow<br/>AI-assisted, human-governed"] -->|MCP Protocol| MCP["guniweb-sap-mcp<br/>22 Tools &bull; 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
- ### Tool Visibility (v1.5)
37
- - **3-Tier Tool Registry** -- Core / OData / IDoc tiers with on-demand activation
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
- - **IDoc Auto-Disable** -- IDoc tools hidden when no IDoc config present
41
- - **MCP Annotations** -- readOnlyHint, destructiveHint, idempotentHint on all 17 tools
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 (7 Types)
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
- - **API Key Protection** -- Secure HTTP transport with Bearer token
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 seven authentication types work per destination.
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 agent discovers SAP tools automatically and can query, create, update SAP data
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 (Phase 23) probes three paths in sequence and caches the first 200 hit:
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 &bull; Redirect &bull; Auth"]
357
- Auth["Auth Layer<br/>7 Auth Types"]
394
+ Auth["Auth Layer<br/>8 Auth Types"]
358
395
  Cache["Per-User Token Cache<br/>LRU &bull; 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 7 auth types, CLI flags, Docker deployment
477
- - [Architecture](docs/architecture.md) -- Technical architecture, request flows, design decisions
478
- - [API Reference](docs/api-reference.md) -- All 17 tools, resources, and prompts with parameters
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