PluginWorld
Ib

ibp-mcp-server

MCP

Enables AI assistants such as Claude to read SAP IBP master data and key figures through IBP's standard OData APIs on SAP BTP, with read-only access enforced.

@BinnyRD · v1.0.0 · MIT License · updated today

SECURITY

B

SCORE

68

STARS

▲ 0

PLUG IN

git clone https://github.com/BinnyRD/ibp-mcp-server.git

See the README to configure this MCP server

README

IBP MCP Server (read-only) for SAP BTP

CI License: MIT

An MCP server that lets Claude (or any MCP client) read SAP IBP master data and key figures through IBP's standard OData APIs. It runs on SAP BTP Cloud Foundry, reaches IBP through a BTP Destination, and is protected by XSUAA.

It never writes to IBP: the only HTTP method it sends is GET, and every tool is marked read-only.

What Claude gets

Tool Purpose
ibp_list_entities Planning areas or master data types that IBP exposes and this server allows
ibp_describe_entity Fields of a planning area / master data type (attributes, key figures, PERIODID*_TSTAMP), searchable by name or label
ibp_read_key_figures Key figure values at a chosen planning level, with time range, filters and paging
ibp_read_master_data Master data records with filters and paging

Example prompt once connected: "Compare consensus demand vs statistical forecast for coffee products at the Auckland DC for Q1 2026."

Architecture

Claude ──HTTPS + Bearer JWT──▶ ibp-mcp-server (CF app)
                                 │  XSUAA: validates token, requires $XSAPPNAME.Read
                                 │  Allow-lists, input validation, row & size caps
                                 ▼
                         BTP Destination "IBP" (Basic auth, communication user)
                                 ▼
             IBP  /IBP/PLANNING_DATA_API_SRV   (key figures)
                  /IBP/MASTER_DATA_API_SRV     (master data)     ← SAP_COM_0720

Why these services: SAP positions PLANNING_DATA_API_SRV and MASTER_DATA_API_SRV (scenario SAP_COM_0720) for external systems; EXTRACT_ODATA_SRV is aimed at SAP Analytics Cloud. Service paths are configurable if your landscape differs.

Security model (why it is safe to put in front of a client tenant)

  • Read-only by construction: GET only; the IBP communication user should also hold read-only authorisation.
  • Two allow-lists, fail closed: IBP's Global Configuration decides what the API exposes; this server's ALLOWED_PLANNING_AREAS / ALLOWED_MASTER_DATA_TYPES narrow it further. Empty list = nothing allowed.
  • No raw OData from the model: filters are structured (field, op, value); field names must match ^[A-Za-z_][A-Za-z0-9_]{0,59}$, string values are quote-escaped, control characters rejected. Injection attempts are covered by tests.
  • Bounded results: MAX_ROWS (default 1000, hard max 5000) and MAX_RESPONSE_CHARS cap every response; paging via nextSkip.
  • Auth required: in xsuaa mode the app refuses to start without an XSUAA binding; AUTH_MODE=none is rejected when NODE_ENV=production.
  • No credential leakage: IBP credentials live only in the BTP Destination; error messages return IBP's message text, never raw responses or headers.
  • Rate limiting per client IP (RATE_LIMIT_PER_MINUTE).

Get written IT/security sign-off from the client before connecting to a production tenant, and agree which planning areas and master data types may be exposed. Planning data is commercially sensitive.

1. Try it locally in 2 minutes (no IBP needed)

Requires Node.js 22+.

npm ci
npm test        # 10 unit tests
npm run smoke   # mock IBP + real MCP client, calls every tool

Run the demo stack for Claude Code / Claude Desktop:

npm run build
npm run mock:ibp &       # fictional NZ data on :4004, user demo / demo

AUTH_MODE=none \
ALLOWED_PLANNING_AREAS=SAPIBP1 \
ALLOWED_MASTER_DATA_TYPES=SAP1PRODUCT,SAP1LOCATION \
destinations='[{"name":"IBP","url":"http://localhost:4004","authentication":"BasicAuthentication","username":"demo","password":"demo"}]' \
npm start

claude mcp add --transport http ibp-demo http://localhost:8080/mcp

This is the safe portfolio demo: realistic IBP shapes, zero client data.

2. IBP setup (client tenant)

  1. Maintain Communication Users → create a user, generate a strong password.
  2. Communication Systems → new system, tick Inbound Only, assign the user.
  3. Communication Arrangements → new arrangement for SAP_COM_0720, select the system. Note the service URLs shown.
  4. Global Configuration → expose only what is needed:
    • FLEXQUERY / PLANNINGAREA → e.g. SAPIBP1
    • FLEXQUERY / RELEVANT_MDT_FOR_MD_API → the master data types (avoid * on client systems)
  5. Ensure the business user behind the arrangement has read access to those planning areas.

3. BTP setup (Cloud Foundry)

cf login -a https://api.cf.<region>.hana.ondemand.com

cf create-service xsuaa application ibp-mcp-xsuaa -c xs-security.json
cf create-service destination lite ibp-mcp-destination

In the BTP cockpit → Connectivity → Destinations → New Destination:

Field Value
Name IBP
Type HTTP
URL your IBP API host, e.g. https://myXXXXXX-api.scmibp.ondemand.com
Proxy Type Internet
Authentication BasicAuthentication
User / Password communication user from step 2

Edit manifest.yml → set ALLOWED_PLANNING_AREAS and ALLOWED_MASTER_DATA_TYPES. Then:

npm ci && npm run build      # dist/ is pushed; CF installs production deps only
cf push

Assign the IBP_MCP_Reader role collection to users who should use it (for user-based tokens).

4. Connect Claude

Get a token (client credentials, valid 1 hour):

TOKEN=$(./scripts/get-token.sh)

Claude Code

claude mcp add --transport http ibp https://<app-route>/mcp --header "Authorization: Bearer $TOKEN"

Claude Desktop (claude_desktop_config.json, uses the mcp-remote bridge):

{
  "mcpServers": {
    "ibp": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://<app-route>/mcp", "--header", "Authorization: Bearer ${IBP_TOKEN}"],
      "env": { "IBP_TOKEN": "<paste token>" }
    }
  }
}

Tokens expire after token-validity (3600 s in xs-security.json). Refresh with the script; raise the validity only if the client's security policy allows it.

Configuration

Variable Default Notes
IBP_DESTINATION IBP BTP Destination name
IBP_PLANNING_SERVICE_PATH /sap/opu/odata/IBP/PLANNING_DATA_API_SRV
IBP_MASTER_DATA_SERVICE_PATH /sap/opu/odata/IBP/MASTER_DATA_API_SRV
ALLOWED_PLANNING_AREAS (empty = none) comma-separated, * = all exposed
ALLOWED_MASTER_DATA_TYPES (empty = none) comma-separated, * = all exposed
MAX_ROWS 1000 1–5000
MAX_RESPONSE_CHARS 200000 keeps tool output within model context
REQUEST_TIMEOUT_MS 30000
AUTH_MODE xsuaa none for local only
REQUIRED_SCOPE Read local scope checked on every call
RATE_LIMIT_PER_MINUTE 120 per client IP

Troubleshooting

Symptom Likely cause / fix
HTTP 401 from IBP Wrong communication user/password in the Destination
HTTP 403 from IBP Arrangement inactive, or planning area / MDT missing from Global Configuration
HTTP 404 from IBP Name not exposed by the API; run ibp_list_entities
not on this server's allow-list Add it to ALLOWED_* in manifest.yml and cf push (or cf set-env + cf restage)
App crashes: No XSUAA service bound cf bind-service ibp-mcp-server ibp-mcp-xsuaa then cf restage
401 from the MCP server Token missing/expired; rerun get-token.sh
Timeouts Narrow timeRange, add filters, lower top

Known limits / next steps

  • Your tenant's exact field names (e.g. which PERIODID*_TSTAMP matches the planning level) vary by configuration; the model discovers them with ibp_describe_entity. Verify the first queries against a planning view in Excel.
  • Version/scenario: add a filter on the version attribute (e.g. VERSIONID) if you need a non-baseline version.
  • claude.ai custom connectors need OAuth with discovery; XSUAA does not offer dynamic client registration. Supporting that is a v2 item (OAuth protected-resource metadata + pre-registered client). Claude Code and Claude Desktop work today via bearer token.
  • npm audit reports a node-forge advisory inside SAP Cloud SDK's JKS keystore support. This server uses Basic-auth destinations, so that code path is not used; upgrade @sap-cloud-sdk/* when SAP ships a fix.
  • Delta reads and write-back are deliberately out of scope.

Disclaimer

Independent open-source project, not affiliated with or endorsed by SAP. SAP, SAP IBP and SAP BTP are trademarks of SAP SE. Demo data is fictional. Provided as-is under the MIT licence; you are responsible for security review before connecting to any IBP tenant.

Author

Rakesh Binny Dasari, SAP IBP delivery lead, Auckland. LinkedIn

SIMILAR PLUGINS