Files
runtipi/apps/sap-mcp-bridge/metadata/description.md

124 lines
4.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# SAP MCP Bridge
Five SAP / UI5 / Fiori Model Context Protocol servers, packaged in a
single container and routed through an internal **nginx reverse
proxy** so the app exposes only **one external port** (Runtipi /
Traefik friendly).
## Bundled MCP servers
| Path prefix | MCP server | Use case |
| -------------- | ----------------------------------------- | ------------------------------------------ |
| `/cap/mcp` | `@iflow-mcp/cap-js-mcp-server` | SAP CAP (Cloud Application Programming) |
| `/abap/mcp` | `@iflow-mcp/mcp-abap-adt` | SAP ABAP via ADT (S/4HANA Cloud, on-prem) |
| `/odata/mcp` | `@iflow-mcp/btp-sap-odata-to-mcp-server` | SAP OData via BTP Destination service |
| `/ui5/mcp` | `@ui5/mcp-server` | SAPUI5 framework guidance + linting |
| `/fiori/mcp` | `@sap-ux/fiori-mcp-server` | SAP Fiori tools / app generation |
Each stdio MCP server is wrapped by `supergateway` and speaks
**Streamable HTTP** on its own internal port (90019005). An internal
nginx (port 8080 — the only EXPOSEd port) routes external requests by
URL path. Long timeouts and disabled buffering make MCP streaming
responses work correctly.
## Health endpoints
- `/healthz` — aggregate (probes the CAP gateway)
- `/cap/healthz`, `/abap/healthz`, `/odata/healthz`, `/ui5/healthz`, `/fiori/healthz`
## Using from Claude Code
Once the app is installed (and either exposed via a domain or
reachable on the LAN), wire the servers you want into your MCP
client. With the Claude Code CLI:
```bash
claude mcp add --transport http sap-cap https://sap-mcp.example.com/cap/mcp
claude mcp add --transport http sap-abap https://sap-mcp.example.com/abap/mcp
claude mcp add --transport http sap-odata https://sap-mcp.example.com/odata/mcp
claude mcp add --transport http ui5 https://sap-mcp.example.com/ui5/mcp
claude mcp add --transport http fiori https://sap-mcp.example.com/fiori/mcp
```
…or by adding the equivalent block to your project's `.mcp.json` /
`~/.claude.json`:
```json
{
"mcpServers": {
"sap-cap": { "type": "http", "url": "https://sap-mcp.example.com/cap/mcp" },
"sap-abap": { "type": "http", "url": "https://sap-mcp.example.com/abap/mcp" },
"sap-odata": { "type": "http", "url": "https://sap-mcp.example.com/odata/mcp" },
"ui5": { "type": "http", "url": "https://sap-mcp.example.com/ui5/mcp" },
"fiori": { "type": "http", "url": "https://sap-mcp.example.com/fiori/mcp" }
}
}
```
## ⚠️ Security warning — read before exposing externally
This app intentionally enables **wildcard CORS** (`Access-Control-Allow-Origin: *`)
inside the supergateway wrappers, because MCP clients may call the
endpoint from a variety of origins. Combined with `exposable: true`
and **no built-in authentication**, this means: if you expose the app
on a public URL via Traefik or a Cloudflare Tunnel, *anyone who knows
the URL* can drive your configured SAP credentials.
Recommended deployments:
- **Local LAN only**: leave `exposable: false` (default) and reach it
via `http://<runtipi-host>:<port>` from inside the LAN.
- **Exposed to the internet**: put it behind a Traefik
**ForwardAuth** middleware (e.g. Authentik / Authelia), a
Cloudflare Access policy, or basic-auth in nginx-proxy-manager —
i.e. authenticate at the proxy, not the app.
Do NOT expose this publicly without an auth layer in front of it.
## Configuration
All credential form fields are **optional**. Empty values are fine —
servers that don't have their required env vars simply won't be
usable, but the others (and the container as a whole) will still run.
- **`sap-abap-adt` needs:** `SAP_URL`, `SAP_USERNAME`, `SAP_PASSWORD`,
`SAP_CLIENT`
- **`sap-odata` needs:** `SAP_DESTINATION_NAME`,
`DESTINATION_SERVICE_URL`, `DESTINATION_CLIENT_ID`,
`DESTINATION_CLIENT_SECRET`, `DESTINATION_AUTH_URL`
- **`sap-cap`, `ui5-mcp-server`, `fiori-mcp-server`** require no
credentials — they read your **project workspace** at request time.
## Workspace mount
The container's `/workspace` is bound to:
```
/etc/runtipi/user-config/runtipi/sap-mcp-bridge/workspace
```
This lives under `user-config/`, which **survives Runtipi restarts
and `app update`**. Drop your CAP / UI5 / Fiori projects in there for
the `cap`, `ui5`, and `fiori` MCP servers to operate on.
The entrypoint chowns this directory to the in-container `mcp` user
(UID 10001) on every start, so a freshly auto-created mount works.
If you want `/workspace` to point at a different host path, create
`/etc/runtipi/user-config/runtipi/sap-mcp-bridge/docker-compose.yml`
with an overlay, e.g.:
```yaml
services:
sap-mcp-bridge:
volumes:
- /your/other/path:/workspace
```
## Image
Custom image:
`git.alexzaw.dev/alexz/sap-mcp-bridge:latest` — built from the
sources in `build/` (Dockerfile + entrypoint.sh + nginx.conf). See
`build/README.md` for the build & push procedure.