MCP Quickstart ​
The SAP Developers site exposes a hosted Model Context Protocol (MCP) server so your AI client — Claude Desktop, Claude Code, or any MCP-compatible tool — can search tutorials, read missions, and query the knowledge graph directly. No SDK, no scraping.
Phase 1 is anonymous and read-only. There's no sign-in and no API key. The approuter's per-IP throttle still applies, so treat it as a shared resource.
Available services ​
Three CDS services are mounted under /mcp/* using @cap-js/mcp@1.1.1 over the Streamable HTTP transport (MCP protocol version 2025-06). Each service exposes two auto-generated tools (describe, query) plus one tool per CDS action.
| Service | Mount | Curated tools |
|---|---|---|
| SearchService | /mcp/search | search_tutorials, list_missions, get_mission, get_tutorial, search_events, search_channels |
| HomepageService | /mcp/homepage | get_recent_news, get_recent_videos, get_news_detail |
| KnowledgeGraphService | /mcp/graph | kg_prerequisites, kg_what_to_learn_next |
One-liners:
search_tutorials— full-text search across published tutorials.list_missions— enumerate curated learning missions.get_mission— fetch a mission's ordered tutorial list by slug.get_tutorial— fetch a single tutorial's metadata and rendered steps.search_events— search the public SAP community events catalog (CodeJams, Devtoberfest, TechEd, user groups) by text, type, and region.search_channels— search the public external-channels catalog (SAP and community YouTube channels, blogs, podcasts, feeds) by text, category, platform, and owner scope.get_recent_news— recent SAP Developer News episodes shown on the homepage.get_recent_videos— recent SAP Developers YouTube videos shown on the homepage.get_news_detail— full article body for one news item, fetched by its URL (complementsget_recent_news).kg_prerequisites— concepts you should already know before this tutorial.kg_what_to_learn_next— recommended follow-on tutorials from the knowledge graph.
Full parameter reference: docs/developers/reference/mcp-server.md.
Base URLs ​
- Production:
https://developers.sap.com(cutover end of July 2026) - Dev: ask your admin for the current dev route
Replace <base> in the examples below with the appropriate URL.
Claude Desktop ​
Edit claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/, Windows: %APPDATA%\Claude\):
{
"mcpServers": {
"sap-developers-search": {
"url": "<base>/mcp/search"
},
"sap-developers-homepage": {
"url": "<base>/mcp/homepage"
},
"sap-developers-graph": {
"url": "<base>/mcp/graph"
}
}
}Restart Claude Desktop. The tools appear in the tools picker.
Claude Code ​
Add a .mcp.json at the root of your project:
{
"mcpServers": {
"sap-developers-search": {
"type": "http",
"url": "<base>/mcp/search"
},
"sap-developers-homepage": {
"type": "http",
"url": "<base>/mcp/homepage"
},
"sap-developers-graph": {
"type": "http",
"url": "<base>/mcp/graph"
}
}
}Joule Work Desktop ​
Naming: SAP ships no product literally called "Joule Studio Desktop." The desktop client that connects to a remote MCP server by pasting a URL is Joule Work Desktop (GA expected Q3–Q4 2026). If you meant the cloud low-code agent builder Joule Studio, classic edition, see Joule Studio (classic edition) below — it connects via a BTP destination, not a URL.
Joule Work Desktop connects to an MCP server by registering the server's URL. For our anonymous, read-only Phase 1 services this is all you need — no sign-in, no destination:
- In Joule Work Desktop, add / register an MCP server.
- Paste the service URL, e.g.
<base>/mcp/search(the server speaks Streamable HTTP, which Joule Work Desktop expects). - Repeat for
<base>/mcp/homepageand<base>/mcp/graphas needed.
The curated tools then appear to Joule.
Authenticated tools (
/mcp-auth/*) work from Joule Work Desktop's native flow. Pasting an authenticated URL triggers Joule Work Desktop's OAuth 2.0 handshake, which uses Dynamic Client Registration (RFC 7591) — itPOSTs to theregistration_endpointto self-register. The server implements DCR (facade over the environment's IAS public client), so Joule Work Desktop self-registers, shows the Application Access Request consent, and the personalized tools (get_my_tutorials,complete_step, …) become available after sign-in.
Joule Studio (classic edition) ​
If instead you are building a Joule agent in the cloud low-code Joule Studio, classic edition, MCP servers are added via an SAP BTP destination, not a raw URL. Only the anonymous Phase 1 /mcp/* services fit cleanly (the authenticated namespaces need a pre-registered OAuth client, and interactive/authorization-code OAuth is not supported here).
- In SAP BTP Cockpit, create a streamable HTTPS destination whose URL points at
<base>(the destination URL must not end in/mcp), with the additional propertysap-joule-studio-mcp-server = true. Create it with the same name in both the Joule Studio classic subaccount and the Joule subaccount, and register it in the control tower. - In your Joule agent, open the MCP Servers tab → Add MCP Server.
- Give it a Name and Description, set Path to the service you want (e.g.
/mcp/search), pick the destination, review the listed Tools, and choose Add Server.
SSE-type destinations are not supported. For servers that do require auth, SAP recommends Client Credentials; OAuth2 Authorization Code and Principal Propagation are not supported. Full reference: Add MCP Servers to Your Joule Agent.
Older stdio-only clients ​
Clients that only speak stdio (older Claude Desktop builds, custom scripts) can bridge through mcp-remote:
npm install -g mcp-remoteThen in your client config:
{
"mcpServers": {
"sap-developers-search": {
"command": "npx",
"args": ["-y", "mcp-remote", "<base>/mcp/search"]
}
}
}Repeat the block for /mcp/homepage and /mcp/graph as needed.
Transport notes ​
The server speaks Streamable HTTP. Clients may send Accept: application/json or Accept: text/event-stream. JSON-only clients get JSON responses; SSE-capable clients get streaming responses when appropriate. You don't need to configure this — MCP clients negotiate it.
Troubleshooting ​
initializereturns 401. You hit/mcp-auth/*, the authenticated surface — it needs an OAuth bearer (IAS/XSUAA). For the anonymous tools use/mcp/*(/mcp/search,/mcp/homepage,/mcp/graph).tools/listreturns an empty array. Wrong service path. Each service is mounted separately —/mcp/search,/mcp/homepage,/mcp/graph. There is no aggregate/mcproot.- First response is slow (5–15s). Cold start. The CAP backend spins down when idle. Subsequent requests are fast.
- Nothing returns and no error. Anonymous IP throttle. Back off and retry.
Sign in with Claude Desktop (OAuth) ​
Phase 2 adds authenticated tools under /mcp-auth/* — your tutorial progress, events, and personalized recommendations. To use them, sign in with your SAP universal ID via OAuth.
Native-HTTP OAuth clients (incl. Claude Desktop) connect with NO client_id. The server supports RFC 7591 Dynamic Client Registration: a client that does its own OAuth discovers the
registration_endpointfrom<base>/.well-known/oauth-authorization-server, self-registers, and is handed the correct client_id for that environment automatically — just point it at<base>/mcp-auth/apiand approve the browser sign-in. No--static-oauth-client-info, no per-environment id to look up. Use themcp-remotebridge below only for clients that cannot do native HTTP OAuth; it needs the explicit, environment-specificclient_idfrom the table.
For clients that need the mcp-remote bridge (no native OAuth), supply the environment's client_id:
{
"mcpServers": {
"sap-developers-auth": {
"command": "npx",
"args": [
"-y", "mcp-remote", "<base>/mcp-auth/api",
"--static-oauth-client-info", "{\"client_id\":\"5a7cb5fd-a0f0-4678-8f51-f8c471e0ab34\"}",
"--host", "localhost"
]
}
}
}The
client_idis ENVIRONMENT-SPECIFIC — match it to your<base>:
Environment <base>client_idProduction https://developers.sap.com5a7cb5fd-a0f0-4678-8f51-f8c471e0ab34Dev your dev route 0b1e8b56-5f5d-4ebf-a9e9-28aae2964236Both environments authenticate against IAS (a public OIDC client — authorization_code + PKCE S256, no secret) in the shared tenant
atxgsg7zi. But DEV and PROD each have their owntutorials-identityservice instance, and each instance has a distinct clientid — so the ids differ per environment. The interactive id_token'saudequals the client_id you supply, and the resource (/mcp-auth) validates it against the clientid bound to that env'stutorials-srv-mcp— using the wrong env's id fails with aWrongAudience/invalid_token401 after a successful browser login ("server rejected a token it just issued"). The old XSUAA ids (sb-tutorials-prod!…,sb-tutorials!…) are retired: sinceMCP_ISSUER_KIND: iaslanded in both mtaexts (#2593), discovery advertises IAS and an XSUAAsb-…id is rejected at the authorize endpoint. If atutorials-identityinstance is recreated its clientid changes — read the current value from the IAS admin console (tenantatxgsg7zi→ apptutorials-identityfor that space → Client Authentication → Client ID), or fromVCAP_SERVICES.identity[].credentials.clientidon that env'stutorials-srv-mcp, and update the matching row.
On first connection mcp-remote opens a browser tab for consent (PKCE, no client secret required). The endpoints are discovered automatically from <base>/.well-known/oauth-authorization-server; you supply only the client_id. After approval, the token is cached and refreshed silently.
Available authenticated tools (DeveloperService + HomepageService):
| Tool | What it does |
|---|---|
get_my_tutorials | Your in-progress and completed tutorials |
get_my_missions | Your mission progress |
get_my_events | Your registered upcoming events |
get_my_completed_steps | Completed step numbers for a specific tutorial |
get_tutorial_step | Full HTML content of a tutorial step |
complete_step | Mark a step done |
reset_tutorial_progress | Reset all progress on a tutorial |
get_my_recommended_tutorials | Persona-ranked tutorial recommendations |
get_my_recommended_missions | Persona-ranked mission recommendations |
Mint a PAT: open
/me/tokens/(self-service — any signed-in user with the Tutorials MCP Users role collection) and use Create token. The token is shown once at mint time — copy it immediately.
Sign in with Claude Code (OAuth via mcp-remote) ​
Claude Code's native
type: httpOAuth now works against this server. Its built-in OAuth client uses Dynamic Client Registration (RFC 7591) — itPOSTs to theregistration_endpointto self-register. The server implements DCR, so native HTTP OAuth succeeds with noclient_id:"sap-developers-auth": { "type": "http", "url": "<base>/mcp-auth/api" }, then approve the browser sign-in. Themcp-remotebridge below remains available for older clients or headless use; a PAT is still simplest for CI (no browser flow).
For older clients without native OAuth, bridge through mcp-remote, which performs the OAuth 2.1 authorization-code + PKCE handshake and forwards the bearer to /mcp-auth/api (supply the environment's client_id from the table above):
npm install -g mcp-remote{
"mcpServers": {
"sap-developers-auth": {
"command": "npx",
"args": [
"-y", "mcp-remote", "<base>/mcp-auth/api",
"--static-oauth-client-info", "{\"client_id\":\"5a7cb5fd-a0f0-4678-8f51-f8c471e0ab34\"}",
"--host", "localhost"
]
}
}
}5a7cb5fd-a0f0-4678-8f51-f8c471e0ab34 (PROD) / 0b1e8b56-5f5d-4ebf-a9e9-28aae2964236 (DEV) is the IAS public OIDC client (tutorials-identity app) for each environment — a public PKCE client with no secret, in the shared IAS tenant atxgsg7zi. DEV and PROD each have their own tutorials-identity service instance with a distinct clientid, so you must use the id matching your <base> (see the table above) — the resource validates the token's aud against its own env's bound clientid. The retired XSUAA ids (sb-tutorials-prod!…, sb-tutorials!…) no longer work — IAS rejects them at the authorize endpoint. To confirm the current id for an env, read it from the IAS admin console (tenant atxgsg7zi, the tutorials-identity app for that space → Client Authentication → Client ID) or from VCAP_SERVICES.identity[].credentials.clientid on that env's tutorials-srv-mcp. The flow uses PKCE with no client secret. On first run, mcp-remote opens your browser for the SAP universal-ID consent flow; after approval the token is cached in ~/.mcp-auth/ and refreshed silently. The server advertises its endpoints at <base>/.well-known/oauth-authorization-server, so mcp-remote discovers the authorize/token URLs automatically — you only supply the client_id.
Flag note: use
--static-oauth-client-info '{"client_id":"…"}', not--static-oauth-client-id. The latter is not a realmcp-remoteflag — it is silently ignored, somcp-remotefalls back to Dynamic Client Registration and fails withdoes not support dynamic client registration. Only--static-oauth-client-info(a JSON blob carryingclient_id) short-circuits registration.
Callback-host note (
--host localhost): XSUAA matches the OAuthredirect_uriliterally against the client's registered list, which whitelistshttp://localhost:*/oauth/callback. Somemcp-remotebuilds bind the callback to the loopback IP127.0.0.1instead (RFC 8252's preferred default), producinghttp://127.0.0.1:<port>/oauth/callback— which does not matchlocalhostand fails at/oauth/authorizewith "redirect_uri does not match the configuration." Passing--host localhostforces the registered hostname to match. If you still hit this, delete the cached tokens in~/.mcp-auth/and reconnect.
Simplest path for Claude Code: skip OAuth entirely and use a Personal Access Token. The PAT path needs no browser handshake and no pre-registered client.
Headless / CI with a Personal Access Token ​
For CI pipelines, scripts, and headless agents that cannot complete an interactive OAuth flow, use a Personal Access Token (PAT).
Mint a PAT:
- Sign in to
<base>/me/tokens/as a user with theTutorials MCP Usersrole collection. - Click New token, give it a name, select scopes (
readfor read-only tools;read writeto allowcomplete_stepandreset_tutorial_progress), set a TTL. - Copy the displayed token — it is shown once only. The server stores only a SHA-256 hash.
Configure your MCP client:
{
"mcpServers": {
"sap-developers-auth": {
"url": "<base>/mcp-pat/api",
"headers": {
"Authorization": "Bearer pat_..."
}
}
}
}PATs are validated by the mcp-pat-middleware in the CAP backend. An expired or revoked PAT returns 401.
Reading tutorial content as resources (Phase 3) ​
MCP clients can read tutorials, missions, and concepts as first-class resources:
tutorial://<slug>— a tutorial's metadata, step titles, and rendered HTML.mission://<slug>— a mission and its ordered tutorials.concept://<id>— a knowledge-graph concept and the tutorials that teach it.
List them with resources/list; read one with resources/read and the URI. Example (Claude Desktop): just ask "read tutorial://hcp-create-trial-account and summarize step 2".
Prompt templates (Phase 3) ​
The server ships reusable prompt templates, discoverable via prompts/list:
| Prompt | Arguments | What it does |
|---|---|---|
summarize_mission_for_beginner | mission_slug | Beginner-friendly mission summary |
generate_lab_exercise | tutorial_slug, step? | A hands-on lab from a tutorial |
explain_concept | concept_id | Explains a KG concept and its tutorials |
suggest_learning_path | from_slug, to_slug | Ordered path between two tutorials |
Invoke with prompts/get; the client fills the arguments.
What's next ​
Phase 3 is shipping. The /mcp/*, /mcp-auth/*, and /mcp-pat/* namespaces are stable — client configs will not need to change.