BTP MCP Server
Provides tools for discovering and managing SAP BTP services, instances, destinations, and recommendations, allowing AI agents to interact with the SAP Business Technology Platform.
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., "@BTP MCP ServerWhat BTP services are available in my account?"
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.
SAP BTP Services Discovery — MCP Server
A production-ready MCP (Model Context Protocol) server that exposes SAP BTP platform APIs as tools for any MCP-compatible AI agent — Claude Code, Cursor, Joule Studio, LangGraph agents, or any other MCP client.
Connect any AI agent to your SAP BTP landscape via the Model Context Protocol.
What is this?
The BTP MCP Server is an open-source Model Context Protocol server that connects AI agents to the SAP Business Technology Platform (BTP) APIs.
Instead of switching to BTP Cockpit to answer common developer questions, you can ask your AI agent directly:
"What BTP services are available in my account?"
"Is HANA Cloud already running in my subaccount?"
"I need async messaging in my CAP app — what should I use?"
"What destinations are configured and what authentication do they use?"
Works with Claude Code, Cursor, Joule Studio, LangGraph agents, and any other MCP-compatible AI client.
Related MCP server: sap-mcp-server
Tools
Tool | What it answers |
| What BTP services exist in the global catalog? |
| What plans does service X have? Are any free? |
| What is running in my subaccount? Is it healthy? |
| What external connections are configured? |
| Given a use case, what service should I use? |
Installation
pip install btp-mcp-serverPrerequisites
You need a Service Manager service key from your BTP subaccount.
Steps to get one:
Go to BTP Cockpit → your subaccount → Services → Service Marketplace
Search for Service Manager → Create instance with plan
subaccount-adminCreate a Service Key on the instance
The key JSON contains your credentials — see Configuration below
Configuration
All configuration is via environment variables. Copy .env.example to .env
and fill in the values from your Service Manager service key:
# From your Service Manager service key JSON
BTP_CLIENT_ID=your-client-id # from "clientid"
BTP_CLIENT_SECRET=your-client-secret # from "clientsecret"
BTP_TOKEN_URL=https://your-subdomain.authentication.us10.hana.ondemand.com/oauth/token
BTP_SM_URL=https://service-manager.cfapps.us10.hana.ondemand.com # from "sm_url"
# From BTP Cockpit → your subaccount → Overview → "Subaccount ID"
BTP_SUBACCOUNT_ID=your-subaccount-guid
# Destination Service URL (region-specific — adjust region if needed)
BTP_DESTINATION_URL=https://destination.cfapps.us10.hana.ondemand.com
# Optional: cache TTL in seconds (default: 300)
# CACHE_TTL_SECONDS=300Note: Never commit your
.envfile to GitHub. Use.env.example(with no real values) as a reference template.
Usage
With Claude Desktop
Add to your claude_desktop_config.json:
Mac: ~/.claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"sap-btp": {
"command": "btp-mcp-server",
"env": {
"BTP_CLIENT_ID": "your-client-id",
"BTP_CLIENT_SECRET": "your-client-secret",
"BTP_TOKEN_URL": "https://your-subdomain.authentication.us10.hana.ondemand.com/oauth/token",
"BTP_SM_URL": "https://service-manager.cfapps.us10.hana.ondemand.com",
"BTP_SUBACCOUNT_ID": "your-subaccount-guid",
"BTP_DESTINATION_URL": "https://destination.cfapps.us10.hana.ondemand.com"
}
}
}
}Restart Claude Desktop. Then ask:
"What BTP services do I have available?"
"Are there any failed service instances?"
"I need to connect to an on-premise SAP system — what BTP service handles that?"
With Claude Code / Cursor
{
"mcpServers": {
"sap-btp": {
"command": "btp-mcp-server",
"env": {
"BTP_CLIENT_ID": "...",
"BTP_CLIENT_SECRET": "...",
"BTP_TOKEN_URL": "...",
"BTP_SM_URL": "...",
"BTP_SUBACCOUNT_ID": "..."
}
}
}
}With a LangGraph agent
from langchain_mcp_adapters.client import MultiServerMCPClient
from langgraph.prebuilt import create_react_agent
from langchain_anthropic import ChatAnthropic
async with MultiServerMCPClient({
"btp": {
"command": "btp-mcp-server",
"transport": "stdio",
"env": {
"BTP_CLIENT_ID": "...",
"BTP_CLIENT_SECRET": "...",
"BTP_TOKEN_URL": "...",
"BTP_SM_URL": "...",
"BTP_SUBACCOUNT_ID": "...",
}
}
}) as client:
tools = client.get_tools()
agent = create_react_agent(
ChatAnthropic(model="claude-sonnet-4-6"),
tools
)
result = await agent.ainvoke({
"messages": [{"role": "user", "content":
"What BTP services do I have? Is there anything I should use for messaging?"
}]
})With Joule Studio (BTP)
Deploy in HTTP mode and register as a BTP Destination:
MCP_TRANSPORT=http btp-mcp-server
# Server starts at http://0.0.0.0:8080/mcpThen in BTP Cockpit → Destinations → create a destination pointing to your server URL. In Joule Studio Agent Builder → Tools → Add MCP Server → select the destination.
Running locally from source
git clone https://github.com/ABRANJAN07/btp-mcp-server.git
cd btp-mcp-server
pip install -r requirements.txt
cp .env.example .env
# fill in .env with your BTP credentials
# Test BTP connectivity
python test_connection.py
# Start the MCP server
python server.pyRunning tests
Tests use mocked BTP responses — no real credentials needed.
pip install -r requirements.txt
pytest tests/ -vExpected output: 17 tests passed
Project structure
btp-mcp-server/
├── server.py ← MCP server entry point (5 tools)
├── test_connection.py ← Verify BTP connectivity
├── requirements.txt
├── .env.example ← Configuration template
├── btp_mcp/
│ ├── config.py ← Reads .env settings
│ ├── auth.py ← OAuth2 token management
│ ├── btp_client.py ← BTP API calls + caching
│ ├── cache.py ← TTL cache
│ └── models.py ← Pydantic response models
└── tests/
└── test_tools.py ← 17 tests with mocked responsesHow it works
AI Agent (Claude / Cursor / LangGraph)
│
│ MCP Protocol (stdio)
▼
BTP MCP Server (this package)
│ OAuth2 client_credentials
│ + TTL cache (5 min)
▼
SAP BTP APIs
├── Service Manager API → service catalog, instances, plans
└── Destination API → configured connectionsCaching: BTP API responses are cached for 5 minutes by default. The service catalog and instance list change rarely — caching keeps responses fast without sacrificing data freshness.
Pagination: All list endpoints fetch every page from BTP, not just the first 50 results.
Roadmap
This is Phase 2 of a 6-phase project building toward a full AI-powered BTP operations platform.
Phase | Status | Description |
Phase 1 | ✅ Done | BTP auth + 2 tools + local MCP server |
Phase 2 | ✅ Done | 5 tools + caching + pagination + tests + PyPI |
Phase 3 | 🔜 Next | LangGraph agent + FastAPI streaming + memory |
Phase 4 | 📋 Planned | Chainlit prototype → React + UI5 Web Components on BTP |
Phase 5 | 📋 Planned | Multi-agent supervisor + RAG + proactive alerts |
Phase 6 | 📋 Planned | Production hardening + CI/CD + BTP marketplace |
Coming soon (Phase 3)
LangGraph ReAct agent with multi-turn conversation memory
FastAPI SSE streaming endpoint
Code generation for recommended services (CAP binding config, CLI commands, YAML manifests)
Entitlements API (temporarily disabled)
The get_btp_entitlements tool requires a separate
Cloud Management Service (CIS Central plan) service key.
The code is fully written and commented out — see
ENTITLEMENTS_SETUP.md to enable it when ready.
Contributing
Contributions are welcome! Please open an issue first to discuss what you'd like to change.
git clone https://github.com/ABRANJAN07/btp-mcp-server.git
cd btp-mcp-server
pip install -r requirements.txt
pytest tests/ -v # make sure tests pass before submitting a PRLicense
MIT — see LICENSE for details.
Author
Built by Abhijeet Ranjan as part of a series on AI + SAP BTP integration.
Follow the journey on LinkedIn for Phase 3 updates.
Available Tools
5 toolsget_btp_destinationsA
Lists all destinations configured in your BTP subaccount.
A destination is a saved connection to an external system. Instead of hardcoding URLs in your code, you define a named destination in BTP and reference it by name.
Filter options: proxy_type: "OnPremise" (via Cloud Connector) or "Internet" (cloud) auth_type: e.g. "OAuth2ClientCredentials", "BasicAuthentication"
Examples of when to use this tool:
"What destinations are configured in BTP?"
"Is there a destination for our S/4HANA system?"
"Show me all on-premise destinations"
"What authentication does the ERP destination use?"
| Name | Required | Description | Default |
|---|---|---|---|
| auth_type | No | ||
| proxy_type | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries full burden. It implies a read operation ('Lists all destinations') but does not explicitly state readonly behavior, potential performance, or error conditions. Adequate but not detailed beyond that.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise and well-structured: a clear intro, then filter options, then usage examples. Every sentence serves a purpose, no waste.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity (2 optional params, output schema exists), the description covers purpose, parameters, and usage adequately. It could mention the return format briefly, but output schema presence mitigates that.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0% schema description coverage, the description adds meaningful value by explaining the filter options (proxy_type: 'OnPremise' or 'Internet'; auth_type: e.g., 'OAuth2ClientCredentials') with examples, compensating for the schema's lack of descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it lists all destinations in a BTP subaccount, using specific verbs and resources. It distinguishes from sibling tools like get_btp_service_plans by focusing on connections to external systems.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides example queries for when to use the tool, such as 'What destinations are configured in BTP?' but does not explicitly state when not to use it or mention alternative tools for similar tasks.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_btp_service_plansA
Returns all available plans for a specific BTP service.
Plans differ in capacity, features, and cost. Some have a free tier. Use this to understand what options exist before creating an instance.
| Name | Required | Description | Default |
|---|---|---|---|
| service_name | Yes | The service name as it appears in BTP (e.g. "hana-cloud", "destination", "aicore") |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It mentions that some plans have a free tier and implies a read-only operation (before creation), but does not explicitly state no side effects or authorization needs. It adds some behavioral context but is not comprehensive.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two concise sentences with a line break, front-loading the primary purpose. Every sentence adds value: the first states the core function, and the second adds practical usage guidance.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given a single parameter with 100% schema coverage and an output schema present, the description covers the essential purpose and usage. It could mention what the output contains, but the output schema likely handles that. The description is complete for this simple tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and the input schema already describes the parameter well, including examples. The description does not add significant new meaning beyond what the schema provides; it repeats the concept of plan options but adds no syntax or additional constraints.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb and resource: 'Returns all available plans for a specific BTP service.' It distinguishes from sibling tools like list_btp_services and get_btp_destinations, which focus on services, instances, or destinations rather than plans.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit usage context: 'Use this to understand what options exist before creating an instance.' It notes that plans differ in capacity, features, and cost, helping the agent decide when to call this tool. No explicit when-not or alternatives, but the context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_btp_instancesA
Lists all service instances currently provisioned in your BTP subaccount.
An instance is one running copy of a BTP service that you created. Shows the current state: SUCCEEDED (healthy), FAILED, or IN_PROGRESS.
Examples of when to use this tool:
"What service instances do I have running?"
"Is HANA Cloud already set up in my account?"
"Are there any failed instances?"
"What's the ID of my Destination service instance?"
| Name | Required | Description | Default |
|---|---|---|---|
| service_name | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses that the tool lists all instances shows states (SUCCEEDED, FAILED, IN_PROGRESS). It does not explicitly state it is read-only or mention limitations like pagination or rate limits. Given no annotations, this is adequate but not comprehensive.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise and front-loaded: first sentence states core purpose, then defines instance, shows states, and provides examples. No unnecessary words or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers purpose, usage examples, and state information. The output schema handles return values. However, the lack of any parameter explanation leaves a gap in completeness, as the agent may not know how to filter by service name.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has one parameter (service_name) with no description in the schema (0% coverage) and no explanation in the tool description. The agent must infer its filtering purpose from the name alone, risking misuse or underutilization.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'lists' and the resource 'service instances', with specific scope 'in your BTP subaccount'. It distinguishes from sibling tools like list_btp_services (services) and get_btp_destinations (destinations) by focusing on instances.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit example queries to guide usage, such as checking for existing instances or failed ones. However, it does not mention when not to use this tool or suggest alternative tools for different needs (e.g., listing services), leaving some ambiguity.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_btp_servicesA
Lists all SAP BTP services available in the global service catalog.
These are services that EXIST in BTP — not necessarily what your subaccount is running. Use list_btp_instances to see what is actually provisioned and running.
Optionally filter by keyword (searches name, description, and tags).
Examples of when to use this tool:
"What BTP services are available?"
"Is there an AI service in BTP?"
"Show me all messaging services"
"Does BTP have a workflow service?"
| Name | Required | Description | Default |
|---|---|---|---|
| keyword | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries full burden. It explains the tool lists existing services not necessarily running, and mentions optional keyword filtering. Additional details on pagination or order would improve transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise, with a clear header, differentiation, filter details, and usage examples. Every sentence adds value without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has an output schema, the description adequately covers the tool's purpose and filter capability. It could mention if there are limits or default ordering, but overall it is complete enough for selection.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With schema coverage at 0%, the description adds critical meaning: it explains the keyword parameter searches name, description, and tags, which the schema alone (empty description) does not provide.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool lists SAP BTP services from the global catalog and distinguishes itself from the sibling tool list_btp_instances by stating it shows services that exist, not necessarily provisioned. Examples further clarify purpose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit usage guidance is provided: use this tool for available services, and use list_btp_instances for provisioned ones. Example queries give concrete context for when to use.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
recommend_btp_serviceA
Recommends the right BTP service(s) for a described use case. Also checks whether the recommended services are already running as instances in your subaccount.
Note: Entitlement checking is temporarily disabled. The 'is_entitled' field always shows null until re-enabled.
Examples of when to use this tool:
"What BTP service should I use for async messaging?"
"I need to store files in BTP — what service do I use?"
"How do I call an LLM from my CAP app?"
"What service handles OAuth2 auth in BTP?"
"I need to connect to an on-premise SAP system"
| Name | Required | Description | Default |
|---|---|---|---|
| use_case | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses that the tool checks for running instances and that entitlement checking is temporarily disabled (is_entitled always null), providing useful behavioral context beyond no annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Concise, well-structured description with examples and a note about disabled feature; no unnecessary words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With one parameter, an output schema, and clear purpose, the description is fully adequate for an agent to use the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The single parameter 'use_case' has no schema description, but the description adds meaning by listing example queries, effectively showing valid input forms.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool recommends BTP services for a described use case and checks existing instances, distinguishing it from sibling tools like list_btp_services.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit examples of when to use the tool (e.g., 'What BTP service should I use for async messaging?'), giving clear context; does not explicitly exclude any cases.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
TDQS
Each tool targets a distinct aspect of BTP: destinations, service plans, instances, services catalog, and recommendations. No overlaps cause confusion.
All tools follow the consistent 'verb_btp_noun' pattern, using snake_case with clear verbs (get, list, recommend).
With 5 tools, the set is well-scoped for BTP subaccount management—neither sparse nor excessive.
Covers discovery and recommendations well but lacks CRUD operations for instances, destinations, or entitlements, leaving notable gaps.
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
Connect AI agents to 1000+ apps with managed authentication and tool-calling.
Let AI agents query data and act across all your business apps via MCP.
Connects AI assistants to CloudQuell multi-cloud and AI cost, savings, anomaly, and budget data.
Provides capabilities that let LLM agents perform a range of infrastructure management tasks.
Related MCP Servers
- 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
- FlicenseNot gradedqualityCmaintenanceEnables natural language querying of SAP business partner data by exposing OData APIs as MCP tools for LLM agents.
- AlicenseBqualityDmaintenanceEnables conversational management of SAP BTP cloud infrastructure, security, and entitlements through natural language via AI agents.23MIT
- FlicenseNot gradedqualityCmaintenanceConnects to SAP ABAP Development Tools (ADT) via MCP, enabling AI assistants to manage SAP systems through natural language.
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/ABRANJAN07/btp-mcp-server'
If you have feedback or need assistance with the MCP directory API, please join our Discord server