MCP Server Template — SAP BTP
Provides tools for interacting with SAP OData backends (such as S/4HANA or BTP services), enabling AI agents to discover entity metadata, query entity sets, and fetch records by key via a configured SAP Destination.
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., "@MCP Server Template — SAP BTPShow the first 5 sales orders from the OData service"
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.
MCP Server Template — SAP BTP
A Node.js MCP (Model Context Protocol) server template for SAP BTP Cloud Foundry. It exposes OData backend APIs to AI agents (e.g. Claude) via HTTP with XSUAA authentication and principal propagation.
Architecture
MCP Client (Claude / AI agent)
│ HTTP POST /mcp (Bearer JWT from XSUAA)
▼
MCP Server (this app, running on BTP CF)
│ validates JWT via @sap/xssec
│ exchanges JWT for backend token via Destination Service (OAuth2UserTokenExchange)
▼
OData Backend (S/4HANA, BTP, etc.)Each deployed instance wraps one OData backend via a single named SAP Destination.
Related MCP server: BTP MCP Server
Prerequisites
Node.js 20+
SAP BTP subaccount with:
XSUAA service instance (
xsuaaplan:application)Destination service instance
A configured Destination pointing to your OData backend
Cloud Foundry CLI (
cf) logged in to your target space
Project Structure
src/
index.js ← Entrypoint — loads env, starts HTTP server
constants.js ← ⭐ Configure DESTINATION_NAME and SERVICE_PATH here
core/
server.js ← Express app, /mcp and /health endpoints
lib/
mcp.js ← Registers tools with the MCP SDK
xsuaa.js ← XSUAA JWT validation middleware
logger.js ← Pino logger
lib/
odata.js ← Generic OData HTTP client (uses SAP Cloud SDK)
tools/
index.js ← ⭐ Register tools here
discover-metadata/ ← Built-in: fetches $metadata and formats it for LLMs
query-entity/ ← Built-in: queries an entity set with OData options
get-entity-by-key/ ← Built-in: fetches a single record by primary key
scripts/
bind-services.sh ← Fetches CF service keys and writes default-env.json
build-srv.sh ← Copies src/ to gen/ for MTA deployment
mta.yaml ← MTA deployment descriptor
xs-security.json ← XSUAA app security descriptor
default-env.json.example ← Template for local credentials fileGetting Started
1. Configure destination and service path
Edit src/constants.js — this is the primary configuration file:
const DESTINATION_NAME = 'MY_ODATA_DESTINATION'; // name of your SAP Destination
const SERVICE_PATH = '/sap/opu/odata/sap/MY_SRV'; // OData service root pathDESTINATION_NAME must match the name of an existing SAP Destination in your BTP subaccount. SERVICE_PATH is the base path that all tool requests are prefixed with.
2. Install dependencies
npm install3. Set up local credentials
The app reads BTP service credentials from default-env.json (loaded by @sap/xsenv). This file is git-ignored and must never be committed.
Option A — automated (recommended): pull credentials directly from CF service keys:
npm run bind-servicesThis script (scripts/bind-services.sh) creates service keys for mcp-xsuaa and mcp-destination in your logged-in CF space and writes default-env.json automatically. Requires cf CLI to be logged in and the service instances to exist.
Option B — manual: copy the example and fill in the values:
cp default-env.json.example default-env.json
# Edit default-env.json and fill in clientid, clientsecret, url, etc.4. Run locally
npm run dev # starts with --watch (auto-restarts on file changes)
npm start # plain node
npm run inspect # launches MCP Inspector UI for interactive testingThe server listens on http://localhost:4004 by default. Override with the PORT environment variable.
5. Add custom tools
Open src/tools/index.js and add an entry to the tools array:
const tools = [
require('./discover-metadata'),
require('./query-entity'),
require('./get-entity-by-key'),
require('./my-custom-tool'), // ← add your tool here
];Create the tool as a directory under src/tools/:
src/tools/my-custom-tool/
index.js ← exports { tool, handler }
handler.js ← implements the handler functionindex.js defines the tool name, description, and input schema:
'use strict';
const { handleMyTool } = require('./handler');
module.exports = {
tool: {
name: 'my_custom_tool',
description: 'What this tool does — shown to the AI agent.',
inputSchema: {
type: 'object',
properties: {
orderId: { type: 'string', description: 'The sales order ID.' },
top: { type: 'number', description: 'Max results to return.' },
},
required: ['orderId'],
},
},
handler: handleMyTool,
};handler.js receives the validated args and the user's JWT for principal propagation:
'use strict';
const { odataGet } = require('../../lib/odata');
const { SERVICE_PATH } = require('../../constants');
async function handleMyTool({ orderId, top }, userJwt) {
const data = await odataGet(`${SERVICE_PATH}/A_SalesOrder`, userJwt, {
$filter: `SalesOrder eq '${orderId}'`,
$top: String(top ?? 10),
});
return JSON.stringify(data, null, 2);
}
module.exports = { handleMyTool };6. Add an MCP server to Claude Desktop
To use this server from the Claude Desktop app, add it to claude_desktop_config.json:
{
"mcpServers": {
"my-btp-mcp": {
"command": "node",
"args": ["/absolute/path/to/mcp-template/src/index.js"],
"env": {}
}
}
}For a deployed instance on BTP CF, use the url transport instead:
{
"mcpServers": {
"my-btp-mcp": {
"type": "http",
"url": "https://<app-url>.cfapps.<region>.hana.ondemand.com/mcp"
}
}
}Built-in Tools
discover_metadata
Fetches the OData $metadata document from SERVICE_PATH/$metadata and returns a structured summary of entity types, properties, and navigation properties. Call this first to understand what entities are available.
query_entity
Queries an entity set collection. Supports $filter, $expand, $select, $top, $skip, and $orderby.
query_entity({ entity: "A_SalesOrder", $filter: "SalesOrderType eq 'OR'", $top: 5 })get_entity_by_key
Fetches a single record by primary key. For composite keys, use comma-separated Field=Value pairs.
get_entity_by_key({ entity: "A_SalesOrder", key: "0000000001" })
get_entity_by_key({ entity: "A_SalesOrderItem", key: "SalesOrder=0000000001,SalesOrderItem=10" })Endpoints
Endpoint | Auth | Description |
| XSUAA JWT (Bearer) | MCP JSON-RPC endpoint |
| XSUAA JWT (Bearer) | MCP SSE stream endpoint |
| None | Returns |
Deploy to BTP Cloud Foundry
# First time: create service instances
cf create-service xsuaa application mcp-xsuaa -c xs-security.json
cf create-service destination lite mcp-destination
# Build and deploy via MTA
npm run build
cf deploy mta_archives/mcp-server-template_1.0.0.mtarOr without MTA:
npm run build
cf pushAvailable npm Scripts
Script | Description |
| Start with file-watch (auto-restart) |
| Start production server |
| Open MCP Inspector for interactive testing |
| Pull CF service keys → write |
| Copy |
| Run tests with Vitest |
| ESLint |
| Prettier |
This server cannot be deployed
Maintenance
Related MCP Connectors
Let AI agents query data and act across all your business apps via MCP.
Connect any AI agent to 1,000+ apps and 27,000+ actions through one remote MCP server (OAuth).
Give AI agents identity, scoped access, trusted context, and verifiable actions through MCP.
Zero-setup MCP gateway securely connecting AI to your tools with authentication and workflows
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceTransforms SAP S/4HANA or ECC systems into conversational AI interfaces by exposing OData services as dynamic MCP tools. Enables natural language interactions with ERP data for querying, creating, updating, and deleting business entities.22 npm1MIT
- AlicenseAqualityCmaintenanceConnects AI agents to SAP BTP platform APIs for service discovery, instance management, and destination queries via natural language.532 PyPI1MIT
- AlicenseNot gradedqualityAmaintenanceEnables AI assistants to securely connect with SAP ABAP and BTP services, allowing execution of function modules, BAPIs, table reads, and various BTP operations through MCP.1Apache 2.0
- 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.111 npm31MIT