MCP serverMCP servertypeExposes tools to a coding agent over MCP.See every one →What this type is →independently maintainedindependently maintainedoriginPublished by one person or a small company outside SAP. Says nothing about quality; the readings say that.See every one →Starting point

btp-cf-mcp

An MCP server over an SAP BTP account and its Cloud Foundry runtime that acts as the person who logged in, so their own global-account and space roles decide what an agent can see.

An assistant asked which applications are running, or what a subaccount is entitled to, normally needs a technical user with rights nobody wants to hand it. This is its own OAuth authorization server: it proxies login to SAP Cloud Identity Services, seals the user's credential into an audience-bound JWE of its own, and on every call unseals it, does the app-to-app exchange and calls Cloud Controller v3 and the btp CLI server protocol as that user, so the audit trail names the real person. Reads and writes are separate tools, which is what lets each read tool declare readOnlyHint:true and a read-only deployment render only CFInspect and BTPInspect. CFInspect covers orgs, spaces, applications, services, routes and instance health; BTPInspect covers subaccounts, the global account, environments, entitlements and subscriptions. A shared read-only technical user is the second identity model, for headless callers with an API key, and both run on one instance. It reimplements the btp CLI server protocol over HTTPS, so no CLI binary sits in the container, and it is deployed to Cloud Foundry rather than run from npm.

Facts

Last pushLicenceMIT

Where it sits

Lives in
Provides
Serve your application over MCPBTPServe your application over MCPcapabilityExposing selected application data and business operations to an AI agent through the Model Context Protocol. An application may also integrate remote services through [service integration](capability:service-integration), connecting its exposed contract with [agent access to your systems](capability:agent-systems-access). Development assistance belongs to [agent access to your code](capability:agent-code-access).
Runs
Cloud Foundry
Requires
SAP BTP, Cloud Foundry RuntimeSAP BTP, Cloud Foundry RuntimeartifactWhere the server itself is deployed, and one of the two APIs it reads: it is pushed as a Cloud Foundry application and calls Cloud Controller v3.

Who is behind it

Marian ZeisMarian ZeisPersonMaintains this
In the atlas: maintains 35, contributes to 86, wrote 25
@marianfoo
maintainer

Before choosing this

Conditions

PolicySAP API Policy 4.2026a§ 1.1, 1.2, 2.2.2from Serve your application over MCPAn MCP server exposes an SAP API, or uses SAP APIs to supply tools, resources or data to an agent.
  • § 1.1 Published APIs. Published APIs are made available for the documented purposes identified by SAP, including integration, extensions and data exchange.
  • § 1.2 Non-Published APIs. Customer and third-party applications must not access non-published APIs except where documentation permits it or SAP otherwise authorizes it.
  • § 2.2.2 AI call sequences and data extraction. Outside SAP-endorsed architectures, data services or expressly identified pathways, the policy prohibits specified agentic API use and systematic or large-scale extraction.

MCP does not replace the API's documented-use boundary. Check that every endpoint is published for the intended use and whether the policy's AI-call or extraction provisions apply to the design.

SAP API Policy 4.2026a →

What it declares

Every artifact

Type
MCP server
Origin
Independently maintained
Runtime
Node.js
Runs on
Cloud Foundry

As an MCP server

Runs as
central server
Transport
HTTP
Authentication
OAuth / OIDCAPI key
Read-only
yesstates it is
Guardrails
4 quoted from README, Safety show all
  • Scopes (read/write/admin) prune the tool list — the LLM only sees what the caller may do.

  • Two authz layers — the server's scope gate and the user's real BTP/CF roles (defense in depth).

  • Consent gate on the OAuth proxy (confused-deputy defense); secrets never logged; sealed tokens are audience-bound so they can't be replayed at a sibling service.

  • CFApps gates on the app's server-resolved space (never a caller-supplied value).

Connections3

A central serverYour SAP BTP subaccountmarianfoo/btp-cf-mcp — README, Quick start, checked 2026-09-18: “Point an MCP client (Claude, `npx @modelcontextprotocol/inspector`) at `https://<route>/mcp`”HTTPdocumentedrequiresYour MCP client, actorYour MCP clientbtp-cf-mcp, modulebtp-cf-mcpSAP BTP, Cloud Foundry Runtime, service instanceSAP BTP, CloudFoundry Runtime
SAPnot SAP's, or the project's ownstated in the documentdocumented only

README

quoted from marianfoo/btp-cf-mcp under MIT, read
marianfoo/btp-cf-mcp/README.mdOn GitHub

btp-cf-mcp

An MCP server that lets an AI assistant inspect and manage your SAP BTP account and Cloud Foundry — as you. A user signs in once via IAS; the server then calls the BTP and Cloud Foundry APIs under that person's own identity, so their real roles are enforced and the audit trail shows the real human — no shared technical password, no second login. A shared read-only technical user mode is also available for headless/automation callers.

Status: a working proof-of-concept, read-only by default. Reads are live-verified on a free-tier BTP account; writes (app lifecycle, service create/delete) execute only when explicitly enabled and only against allowlisted targets. See Status.


What it is

An MCP server (same lineage as arc-1, which does this for ABAP) that gives Claude — or any MCP client — a small, safe set of tools over:

  • SAP BTP account — subaccounts, environments, entitlements (via the btp CLI server APIs).
  • Cloud Foundry — orgs, spaces, apps, services (via the Cloud Controller v3 API).

The point of difference is identity: the server is its own OAuth authorization server that proxies login to IAS, seals the user's credential into its own token, and then acts as that user on every call — CF enforces their org/space roles, BTP enforces their global-account roles. It reimplements the btp CLI server protocol over plain HTTPS, so there is no CLI binary in the container.

What you can do

Reads and writes are separate tools so each read tool is honestly readOnlyHint:true (hosts auto-approve, no confirm friction), and a read-only deployment renders only the two Inspect tools:

ToolActionsNotes
CFInspect (read)orgs, spaces, apps, services, routes, app_detail, app_processesCloud Controller v3; as the user or a shared CF token. app_processes = instance health/state
BTPInspect (read)subaccount, subaccounts, global_account, environments, entitlements, subscriptionsentitlements = global-account catalog, or a subaccount's plan assignments if you pass a subaccount
whoami—diagnostic: resolved scopes + token claims
CFApps / BTPServices (write)restart/stop/start an app · create/delete service instancesper-user (OAuth) only; hidden unless ALLOW_WRITES=true; targets must be allowlisted — CFApps resolves the app's real space server-side

A deliberately small surface (fewer tools select more accurately). Every action is defined once in a single-source registry (src/registry.ts); the schema, scopes, MCP annotations, and dispatch all derive from it — so growing capability is adding a row, not a tool.

Use cases

  • "Which of my apps are running, and is anything crashed?" — an AI ops helper over CFInspect.apps for a developer, scoped to exactly the spaces they have roles in.
  • "What service plans is this account entitled to, and how much quota is left?" — BTPInspect.entitlements for capacity/licensing questions, without opening the cockpit.
  • "List my subaccounts and their environments" — a quick BTP-account overview from chat.
  • Team read-only assistant — point a shared, read-only technical user (Global Account Viewer + Subaccount Viewer) at a support channel so anyone can ask about the landscape, with one auditable identity.
  • Per-developer accountability — each developer's assistant logs in as them, so it sees only what they're entitled to and every action is attributed to the real person.

How it works

 MCP client ──OAuth (this server IS the auth server, proxying to IAS)──▶ [btp-cf-mcp]
      │  or  Authorization: Bearer <api-key>                                  │ MCP token = a sealed JWE
      ▼                                                                       │ holding the user's IAS credential
   IAS login (browser, once)  ◀───────────────────────────────────────────────┤
                                  per request: unseal → IAS app-to-app exchange │
                    ┌───────────────────────────────────────────────────────────┘
                    ▼ CFInspect                            ▼ BTPInspect
        CF UAA → Cloud Controller v3 (as you)   btp CLI *server* REST (as you) — no binary
  • Inbound — the server exposes OAuth (/authorize /token /register + discovery), proxies login to IAS, and issues its own token: a sealed, audience-bound JWE of the IAS credential (never a passthrough). DCR is guarded by a consent gate so a user always sees which client they're authorizing.
  • Outbound — per request it unseals the credential, does the IAS app-to-app exchange, and calls CF (via CF UAA) and BTP (via the CLI-server protocol) as the user.

Full design + the hard-won auth details: docs/guides/per-user-ias-auth-setup.md.

Two identity models

  • Per-user ("acts as you") — best audit + least-privilege; each user logs in via IAS.
  • Shared read-only technical user — one service account (Global Account Viewer + Subaccount Viewer) for headless/API-key callers; simpler, one audited identity.

Both can run on the same instance — an OAuth caller runs per-user, an API-key caller uses the tech user. Setup + trade-offs: docs/guides/admin-deployment.md → "Identity models".

Safety

  • Read-only by default (ALLOW_WRITES=false); writes need explicit enablement + a fail-closed target allowlist (ALLOWED_SUBACCOUNTS/ORGS/SPACES) + per-action DENY_ACTIONS.
  • Scopes (read/write/admin) prune the tool list — the LLM only sees what the caller may do.
  • Two authz layers — the server's scope gate and the user's real BTP/CF roles (defense in depth).
  • Consent gate on the OAuth proxy (confused-deputy defense); secrets never logged; sealed tokens are audience-bound so they can't be replayed at a sibling service.

Quick start

Deploy to BTP Cloud Foundry (IAS-first, per-user):

npm ci && npm run build                # dist/ is not committed — build before pushing
cf push btp-cf-mcp                     # or: mbt build && cf deploy (secrets via an mtaext OUTSIDE the repo — see mta.yaml)
# then set the IAS-first config (secrets via cf set-env, never manifest.yml):
cf set-env btp-cf-mcp SEALING_SECRET "$(openssl rand -hex 32)"
cf set-env btp-cf-mcp IAS_ISSUER https://<tenant>.accounts.ondemand.com
cf set-env btp-cf-mcp IAS_CLIENT_ID <id>   # + IAS_CLIENT_SECRET, CF_PLATFORM_CLIENT_ID,
cf set-env btp-cf-mcp CF_UAA_URL ...        #   CF_UAA_URL, CF_API, BTP_GA_SUBDOMAIN, PUBLIC_URL
cf restage btp-cf-mcp

Point an MCP client (Claude, npx @modelcontextprotocol/inspector) at https://<route>/mcp → it discovers OAuth, you log in via IAS, and tool calls run as you. Full step-by-step (IAS app, the roles that make reads return data, troubleshooting, caveats): docs/guides/admin-deployment.md.

Status

Shipped + live-verified (free-tier BTP account):

  • ✅ IAS-first per-user inbound (OAuth proxy) + a signed, browser-bound consent gate.

  • ✅ Per-user Cloud Foundry (Cloud Controller, as the user) and BTP account reads (CLI-server protocol, no binary).

  • ✅ Shared read-only technical user mode (username/password login).

  • ✅ Read-only safety gate + scope-based tool pruning; sealing-key rotation; refresh-token rotation; session caching.

  • ✅ Read/write-split tool surface (CFInspect/BTPInspect + write tools) with honest MCP annotations.

  • ✅ Writes: CF app lifecycle (restart/stop/start) + Service Manager create/delete — off by default, fail-closed target allowlists, and CFApps gates on the app's server-resolved space (never a caller-supplied value).

PoC boundaries:

  • ⏳ Async job polling for service create/delete is manual (verify via BTPInspect.service_instances).
  • ⏳ Mapping IAS groups → scopes and an MTA-only deploy are future work.

Documentation

MIT, read
Serve your application over MCP
  1. API ManagementAPI proxies with security and traffic policies and Developer Hub

Details

Sources3
GitHub APIdiscovered here, marianfoochecked
github.com/marianfoo/btp-cf-mcptree, pushes, contributors, CIchecked
README.mdquoted, and what the entry declareschecked

Sources are graph entities: the same page may back several entries, and an unreachable source flags every row that rests on it.

Compatibility and provenance
runtimesnode
deploymentCloud Foundry
discovered viaGitHub API · marianfoo
first seen in the atlas
ecosystem and domainbtp, operations-and-runtime
History in the atlas2
  1. Read out of the marianfoo account listing. Entered as a starting-point, since the maintainer's own status line calls it "a working proof-of-concept", so its boundaries sit in description.to_build_on_it rather than in a warning. capability:mcp-servers already reads core-only on the BTP door because every provider there is SAP-published; this is an independent one, which is a reading the capability will have to move.
  2. First seen.
For your agent
Ref
artifact:marianfoo-btp-cf-mcp
JSON
/artifacts/marianfoo-btp-cf-mcp.json
MCP
Connecting an agent