dsp-mcp
Exposes 19 SAP Datasphere CLI skills as MCP tools, enabling hosted assistants to drive SAP Datasphere modeling operations. Supports creating and managing Datasphere objects such as local tables, views, analytic models, models, data flows, replication flows, and transformation flows; inspecting objects and models; modifying columns; cascading column changes; and exporting models.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@dsp-mcplist all tables in my Datasphere space"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
dsp-mcp
A local MCP (Model Context Protocol) server that exposes the 19 SAP Datasphere CLI
skills from dsp-cli as MCP tools over
Streamable HTTP, so hosted assistants (like SAP Joule) can drive Datasphere modeling
by URL.
The server is a thin wrapper: each MCP tool call spawns the corresponding
node --env-file=<dsp-cli>/.env skills/<name>/<name>.js … child process and streams
its stdout back to the caller verbatim. All authentication, OAuth token caching, and
Datasphere logic stays in dsp-cli.
Disclaimer. This is a personal, unofficial project. It is not an SAP product and is in no way endorsed, supported, or maintained by SAP. There is no support and no warranty: use it entirely at your own risk, and you are responsible for anything you do with it. See LICENSE.
Attribution. The 19 bundled Datasphere CLI skills are third-party code by Frederic Wall (
dsp-cli, a fork ofyuyonggang/dsp-cli), redistributed under their ISC license. This repository adds only the MCP wrapper around them. See NOTICE for full attribution, licenses, and trademarks.
Quick start
# 1. Configure
cp .env.example .env
# edit .env: set DSP_CLI_DIR plus your Datasphere credentials
# (DATASPHERE_HOST, CLIENT_ID, CLIENT_SECRET, SPACE) — all required
# 2. Install
npm install
# 3. Run
npm run devYou'll see a banner like:
[dsp-mcp] listening on http://127.0.0.1:3333/mcp
[dsp-mcp] health: http://127.0.0.1:3333/health
[dsp-mcp] tools: 19 registered
[dsp-mcp] dsp-cli dir: /Users/…/dsp-cli [ok]
[dsp-mcp] env file: /Users/…/dsp-cli/.env [ok]
[dsp-mcp] configure Joule with URL: http://127.0.0.1:3333/mcpPoint Joule (or any MCP client that speaks Streamable HTTP) at http://127.0.0.1:3333/mcp.
Related MCP server: CI MCP Server
Desktop app (menu bar)
Prefer not to babysit a terminal? A small macOS menu bar app (Electron) can
run the server for you — Start/Stop, Copy URL, Logs, and Preferences from a
status-bar icon, installable as a .dmg. It spawns this same server as a child
process (system Node required; the server code is unchanged). The 19 skills are
bundled inside the app, so users only enter their Datasphere credentials in
Preferences — no separate dsp-cli checkout needed (though an own DSP_CLI_DIR
can override the bundled skills).
cd desktop
npm install
npm run dev # develop against the live tray app
DSP_CLI_SRC=/path/to/dsp-cli npm run dist # build desktop/dist/dsp-mcp-<version>.dmgSee desktop/README.md for details. From the repo root you
can also use npm run desktop:dev / npm run desktop:dist.
Cloud Foundry (SAP BTP)
The server also runs on Cloud Foundry so a hosted assistant can reach the MCP
endpoint over a public URL. The dsp-cli skills are bundled into this repo under
cf/dsp-cli-src/ (source, committed) and vendored to cf/vendor/dsp-cli/
(generated by heroku-postbuild, git-ignored) — no separate dsp-cli checkout is
needed in the container.
# One-time: seed the OAuth token (from a prior local browser login) so the CLI
# authenticates headless. secrets.json holds access + refresh tokens.
B64=$(base64 -i ~/.@sap/datasphere-cli/.cache/secrets.json | tr -d '\n')
cf push
cf set-env dsp-mcp DATASPHERE_HOST "https://<tenant>.hcs.cloud.sap"
cf set-env dsp-mcp CLIENT_ID '<client-id>' # single-quote: XSUAA ids contain ! and |
cf set-env dsp-mcp CLIENT_SECRET '<client-secret>'
cf set-env dsp-mcp SPACE '<space>'
cf set-env dsp-mcp DSP_SECRETS_B64 "$B64"
cf restart dsp-mcpmanifest.yml sets MCP_HOST=0.0.0.0, MCP_ALLOWED_HOSTS (the route host, for the
SDK's DNS-rebinding guard), and DSP_CLI_DIR=cf/vendor/dsp-cli. Key notes:
Headless auth: the CLI's normal login is an interactive browser flow. On CF,
DSP_SECRETS_B64is written into the CLI token cache at startup andDSP_SKIP_LOGINtells the skills to use it instead of logging in. The refresh token is valid ~180 days — re-seedDSP_SECRETS_B64when it expires.Endpoint auth: the MCP endpoint itself is currently open (sandbox). Add an auth layer before any non-sandbox use.
Secrets:
DSP_SECRETS_B64/CLIENT_SECRETare plaintext in the app env here; for production use a credential/user-provided service instead.
Smoke tests
# Health
curl -sS http://127.0.0.1:3333/health
# tools/list (JSON-RPC over Streamable HTTP)
curl -sS -X POST http://127.0.0.1:3333/mcp \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'
# initialize
curl -sS -X POST http://127.0.0.1:3333/mcp \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-d '{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"curl","version":"0"}}}'
# call a read-only tool
curl -sS -X POST http://127.0.0.1:3333/mcp \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"list-objects","arguments":{}}}'Offline registry dump:
npm run list-tools # human-readable
npm run list-tools -- --json # machine-readableConfiguration
All settings come from this project's own .env (see .env.example):
Var | Default | Purpose |
| (required) | Directory containing |
| (required) | Datasphere tenant URL, forwarded to each skill. |
| (required) | OAuth client credentials, forwarded to each skill. |
| (required) | Default space ID used when |
| (unset) | Local convenience only: if set, this file is loaded into the environment at startup (lets an existing |
|
| Bind address (localhost only for DNS-rebinding safety) |
|
| Port |
|
| Per-skill hard timeout |
|
| When |
The server reads DATASPHERE_HOST, CLIENT_ID, CLIENT_SECRET, and SPACE from its
own environment and passes them to each skill's child process (the skills read them
straight from process.env). This single source of truth works the same on a laptop
(dotenv-loaded .env) and on Cloud Foundry (platform env vars / a user-provided
service) — no on-disk credential file is required at runtime.
Adding a skill
The registry is the only file you need to edit. Add one entry to SKILLS in
src/skills.ts:
{
name: 'my-new-skill', // MCP tool name
description: 'One-line summary shown to the LLM.',
entry: entry('my-new-skill', 'my-new-skill.js'), // resolved from skillsDir
category: 'inspect',
mutates: false,
inputSchema: {
thing: z.string().describe('What to look at'),
...spaceField, // shared --space field
},
flags: {
thing: { flag: '--thing', kind: 'value' },
space: spaceFlag, // shared --space mapping
},
},No other file changes needed — src/index.ts iterates SKILLS and registers each.
Tool catalog
Nineteen tools, grouped by category (from npm run list-tools):
Create —
create-local-table,create-view,create-analytic-model,create-model,create-data-flow,create-replication-flow,create-transformation-flowInspect —
list-objects,read-object,describe-model,impact-analysisModify —
add-columns-to-table,add-columns-to-view,rename-column,remove-columnCascade —
propagate-columns,rename-column-cascade,remove-column-cascadeLifecycle —
export-model
Troubleshooting
skill env … [MISSING]on startup — one or more ofDATASPHERE_HOST,CLIENT_ID,CLIENT_SECRET,SPACEare not set. Add them to.env(see.env.example), or on Cloud Foundry set them as platform env vars. The startup warning names exactly which are missing.skill 'X' failed (exit 1): Missing required environment variables: DATASPHERE_HOST— same problem: the server had no credentials to forward. Check the four vars above.Tool call hangs then returns "timed out after …" — bump
SKILL_TIMEOUT_MS. Some cascade operations on large graphs need more than 5 minutes.Host: evil.examplereturns 4xx — that's the SDK's DNS-rebinding protection. Legitimate clients speakingHost: 127.0.0.1(orlocalhost) are accepted.
Security
Server binds to
127.0.0.1only. Nothing outside your machine can reach it.SDK-provided Host-header validation blocks DNS-rebinding attacks against localhost.
No auth on the MCP endpoint itself: anyone with a shell on this machine can call mutating tools. Acceptable for a single-user dev laptop; do not run this on a shared host.
⚠️ Do not expose this publicly without adding authentication. The Cloud Foundry path above binds
0.0.0.0behind a public router with no auth on the MCP endpoint. Anyone who finds the URL can call mutating tools against your Datasphere tenant. The deployment steps are a sandbox example only. Before any real use, put an auth layer in front of the endpoint and store credentials in a user-provided service, not plaintext env vars.
Concurrency
Each tool call spawns a Node child. Concurrent modeling operations targeting the same Datasphere object are a Datasphere-side race — the MCP server does not serialize them. Rely on your caller (e.g. Joule) to sequence dependent operations.
This server cannot be deployed
Maintenance
Related MCP Connectors
Query, browse, and automate OmegaAI workspaces from any MCP client. Streamable HTTP with OAuth 2.0.
Any REST/SOAP/GraphQL/OData/SQL API as MCP tools for Claude & ChatGPT. 325 connectors: SAP, ERP.
Governed MCP gateway: one endpoint for your tools, with credential custody and audit log.
Unified gateway exposing 150+ tools across all NexGenData MCP servers via one endpoint.
Related MCP Servers
- AlicenseAqualityAmaintenanceProduction-ready MCP server that enables AI assistants to seamlessly interact with SAP Datasphere environments for real tenant data discovery, metadata exploration, analytics operations, ETL data extraction, database user management, data lineage analysis, and column-level data profiling.3949 npm124 PyPI48MIT
- AlicenseNot gradedqualityFmaintenanceEnables AI assistants to manage SAP Cloud Integration (CPI) landscapes through natural language by exposing CPI OData APIs as MCP tools.12MIT
- AlicenseNot gradedqualityDmaintenanceExposes SAP AI Core APIs as MCP tools, enabling AI assistants to manage AI Core lifecycle and administration through natural language.7MIT
- AlicenseNot gradedqualityBmaintenanceA config-driven MCP server that exposes OData and REST APIs as MCP tools, enabling AI assistants to query, manage, and monitor SAP backends through natural language.112 npm32MIT