Content
# SAP S/4HANA MCP Server
Connect AI assistants (Claude, Cursor, Cline, and any MCP-compatible client) directly to SAP S/4HANA via OData. Ask business questions in plain language — the server handles service discovery, metadata inspection, query execution, and analysis autonomously.
```
"Show me all Azure cloud invoices this year grouped by cost center"
→ Claude calls analyze_cloud_spend, queries SAP, returns structured spend breakdown
```
---
## Quickstart
### 1. Clone and install
```bash
git clone https://github.com/Elhamkhorasani/sap-s4-mcp-server.git
cd sap-s4-mcp-server
npm install
npm run build
```
### 2. Configure your SAP connection
```bash
cp .env.example .env
```
Edit `.env`:
```env
# Required
S4_ODATA_HOST=https://your-s4-system:44300
S4_ODATA_CLIENT=100
AUTH_METHOD=basic
S4_ODATA_USER=your_username
S4_ODATA_PASSWORD=your_password
# Optional
LOG_LEVEL=info
DRY_RUN=false
```
> **Self-signed certificate?** Add `NODE_TLS_REJECT_UNAUTHORIZED=0` to `.env` for on-premise systems with internal CAs.
### 3. Add to your MCP client
**Claude Desktop** — edit `~/.claude/claude_desktop_config.json` (Mac/Linux) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows):
```json
{
"mcpServers": {
"sap-s4": {
"command": "node",
"args": ["/absolute/path/to/sap-s4-mcp-server/dist/src/index.js"],
"env": {
"S4_ODATA_HOST": "https://your-s4-system:44300",
"S4_ODATA_CLIENT": "100",
"AUTH_METHOD": "basic",
"S4_ODATA_USER": "your_username",
"S4_ODATA_PASSWORD": "your_password"
}
}
}
}
```
**Claude Code / Cursor / Cline** — copy `.mcp.json.example` to `.mcp.json` in the project root and fill in your values:
```bash
cp .mcp.json.example .mcp.json
# Edit .mcp.json — never commit this file (it's gitignored)
```
Restart your MCP client after any config change.
### 4. Verify the connection
Ask Claude:
> *"Test my SAP connection"*
You should see a response confirming the system is reachable, the auth method, and response latency. If it fails, the response includes an exact hint for what to fix.
---
## Example Prompts
**Service exploration**
```
What SAP OData services are available related to supplier invoices?
```
**Data inspection**
```
Show me the entity structure of API_BUSINESS_PARTNER
```
**Cloud spend analysis**
```
Find all Microsoft Azure invoices in company code 1000 from 2025 and group them by supplier and month
```
**Data quality**
```
Run a quality analysis on payment statistics data
```
**Anomaly detection**
```
Check the purchase order data for anomalies and duplicates
```
**Service diagnosis**
```
Why is API_SUPPLIERINVOICE_PROCESS_SRV returning errors?
```
**Direct query**
```
Get the last 20 open purchase orders for supplier 1000008 in company code 1000
```
---
## For colleagues: getting started in 10 minutes
> **What you need:** Node.js 18+, your SAP username and password, and Claude Desktop or another MCP client.
> You do not need to understand OData, SAP transactions, or how the tools work internally.
### Step 1 — Clone and build (2 minutes)
```bash
git clone https://github.com/Elhamkhorasani/sap-s4-mcp-server.git
cd sap-s4-mcp-server
npm install
npm run build
```
### Step 2 — Set up your credentials (2 minutes)
```bash
cp .mcp.json.example .mcp.json
```
Open `.mcp.json` and replace the placeholder values:
- `args`: the full absolute path to `dist/src/index.js` on your machine
- `S4_ODATA_HOST`: your SAP system URL (ask your SAP admin if unsure)
- `S4_ODATA_USER` / `S4_ODATA_PASSWORD`: your own SAP login
- Keep `DRY_RUN` as `true` until you are comfortable — this prevents any accidental writes
> **Important:** Never share `.mcp.json` or commit it to git. It contains your personal SAP credentials.
### Step 3 — Connect to Claude (2 minutes)
In Claude Desktop, go to Settings → Developer → Edit Config and paste the content of your `.mcp.json`.
Restart Claude Desktop.
For Claude Code or Cursor, the `.mcp.json` in the project root is picked up automatically.
### Step 4 — Test it works (1 minute)
In a new Claude conversation, type:
> *"Test my SAP connection"*
You should see a green status with latency. If something is wrong, the response tells you exactly what to fix.
### What to try first
Once connected, start with these — they are safe read-only operations:
```
What SAP services are available on this system?
```
```
Run a summary analysis on purchase order data
```
```
Find all invoices from the last 6 months and show me the top 10 by amount
```
### Security notes for colleagues
- `DRY_RUN=true` (the default in the example) blocks all write operations — safe for exploring
- Every write attempt is logged to the server console even if blocked
- Each person uses their own SAP credentials — no shared accounts
- Your `.mcp.json` stays on your machine and is never committed to git
---
## Tools
### Connection
| Tool | What it does |
|---|---|
| `ping_sap_connection` | Tests the SAP connection and reports status, auth method, client, and latency. Run this first. |
### Foundation Layer
| Tool | What it does |
|---|---|
| `discover_sap_services` | Search the SAP Gateway catalog for available OData services. Always use the returned `oDataName` in downstream calls. |
| `get_entity_metadata` | Inspect entity sets, key fields, and all properties of a service. Use before querying to know the correct field names. |
| `get_field_values` | Look up valid dropdown/value-list options for a field. Use before writing to avoid invalid input errors. |
| `execute_odata_query` | Execute OData operations — GET (returns CSV), POST, PATCH, DELETE. |
### Service Inspection Layer
| Tool | What it does |
|---|---|
| `check_service_status` | Check whether a specific OData service is reachable and active. |
| `analyze_service_activation` | Diagnose why a service is not activating and get step-by-step fix instructions. |
| `list_active_vs_inactive_services` | Overview of all services and their current activation state. |
| `get_service_entity_relationships` | Map entity relationships and navigation properties — shows which entities are connected and how. |
| `get_ddic_table_metadata` | Retrieve SAP DDIC table and field definitions via ADT REST API or OData fallback. |
### Agentic Layer
| Tool | What it does |
|---|---|
| `run_analysis` | Autonomous multi-step agent: auto-discovers the right service and entity for a plain-language topic, fetches a data sample, and runs a focused analysis. Modes: `anomalies`, `duplicates`, `summary`, `quality`, `trends`. |
| `analyze_cloud_spend` | End-to-end cloud spend workflow: searches invoice text for keywords (Azure, Microsoft, AWS), aggregates by supplier / month / GL account / cost center, returns open purchase orders. |
---
## Recommended Workflow
When working with an unfamiliar SAP service, follow this order:
```
1. discover_sap_services → find the right service name (use oDataName)
2. get_entity_metadata → understand available fields and key properties
3. get_field_values → look up valid values before filtering or writing
4. execute_odata_query → read or write the actual data
```
For analysis without knowing the service in advance, use `run_analysis` directly with a plain-language topic.
---
## Configuration Reference
| Variable | Required | Default | Description |
|---|---|---|---|
| `S4_ODATA_HOST` | ✅ | — | Full URL of your SAP system, e.g. `https://my-s4.example.com:44300` |
| `S4_ODATA_CLIENT` | — | `100` | SAP client number |
| `AUTH_METHOD` | — | `basic` | `basic` (username/password) or `token` (bearer token) |
| `S4_ODATA_USER` | if basic | — | SAP username |
| `S4_ODATA_PASSWORD` | if basic | — | SAP password |
| `S4_ODATA_TOKEN` | if token | — | Bearer token |
| `LOG_LEVEL` | — | `info` | `debug` / `info` / `warn` / `error` |
| `DRY_RUN` | — | `false` | Set `true` to block all write operations |
| `NODE_TLS_REJECT_UNAUTHORIZED` | — | `1` | Set `0` for self-signed certificates (on-premise only) |
See [docs/authentication.md](docs/authentication.md) for details on CSRF token handling and token-based auth.
---
## SAP Requirements
This server calls standard SAP S/4HANA OData services. The following need to be active in your system:
| Service | Used by | Activate in |
|---|---|---|
| `CATALOGSERVICE;v=2` | `discover_sap_services` | `/IWFND/MAINT_SERVICE` |
| `API_SUPPLIERINVOICE_PROCESS_SRV` | `analyze_cloud_spend` (invoices) | `/IWFND/MAINT_SERVICE` |
| `API_PURCHASEORDER_PROCESS_SRV` | `analyze_cloud_spend` (POs) | `/IWFND/MAINT_SERVICE` |
| Any OData service | `run_analysis`, `execute_odata_query` | `/IWFND/MAINT_SERVICE` |
| `/sap/bc/adt` (ICF node) | `get_ddic_table_metadata` | `SICF` |
> The catalog service is almost always active by default. If `API_*` services are not available on your system, pass `invoiceService` / `poService` override parameters to `analyze_cloud_spend` with whatever service names your system exposes.
**Minimum SAP user authorizations:** `S_SERVICE` for each OData service, plus `SAP_ADT_DEVELOPER_BASIC_READONLY` if using DDIC metadata.
---
## Governance
Write operations are controlled via `DRY_RUN=true` (blocks all writes and returns a clear error). All write attempts are logged to stderr in the format:
```
[audit] SUCCESS tool=execute_odata_query detail="POST API_SUPPLIERINVOICE_PROCESS_SRV/A_SupplierInvoice"
```
See [docs/governance.md](docs/governance.md) for the full policy model.
---
## Development
```bash
npm run dev # run with tsx watch (hot reload)
npm run build # compile TypeScript
npm run typecheck # type-check without emitting
```
**Adding a new tool:**
1. Create `tools/your-tool.tool.ts` — follow an existing tool as the pattern
2. Import and register in `src/server.ts`
3. Add a row to the tool table above
4. Run `npm run build`
---
## Roadmap
### Phase 1 — Safety and Governance
- [ ] Service allowlist support
- [ ] Entity blocklist support
- [ ] Role-based tool access
- [ ] Stronger dry-run enforcement
### Phase 2 — Query Improvements
- [ ] Structured OData query builder with field validation
- [ ] JSON output mode alongside CSV
- [ ] Metadata caching
### Phase 3 — Business Tools
- [ ] `find_supplier_invoices` — search and filter invoices by vendor, amount, date
- [ ] `find_purchase_orders` — open commitments by supplier and category
- [ ] `trace_invoice_to_po` — full document chain from invoice to PO to contract
- [ ] `analyze_vendor_spend` — spend concentration and trend analysis
### Phase 4 — Enterprise Features
- [ ] SAP BTP Destination Service auth
- [ ] OAuth2 client credentials
- [ ] Docker support
### Phase 5 — Testing and DX
- [ ] Mock SAP OData server for local testing
- [ ] Unit tests for all tools
- [ ] GitHub Actions CI
---
## License
MIT
MCP Config
Below is the configuration for this MCP Server. You can copy it directly to Cursor or other MCP clients.
mcp.json
Connection Info
You Might Also Like
No recommendations available