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 "Install 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 |
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
No tool schema history has been recorded yet.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Let AI agents query data and act across all your business apps via MCP.
Zero-setup MCP gateway securely connecting AI to your tools with authentication and workflows
MCP server connecting AI agents to 100+ apps (Gmail, Slack, Notion, GitHub) via one-click OAuth.
Unified MCP Server is a remote MCP connector for AI agents and vertical AI products that provides access to 22,000+ authorized SaaS tools across 400+ integrations and 24 categories directly inside LLMs (Claude, GPT, Gemini, Cohere). Tools operate only on explicitly authorized customer connections, enabling agents to safely read and write against live third-party systems.
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.341MIT
- AlicenseAqualityCmaintenanceConnects AI agents to SAP BTP platform APIs for service discovery, instance management, and destination queries via natural language.51MIT
- 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 gradedqualityDmaintenanceA 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.5929MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/Timo-Maier/mcp-template'
If you have feedback or need assistance with the MCP directory API, please join our Discord server