
@arc-mcp/xsuaa-auth
by arc-mcp
@arc-mcp/xsuaa-auth
XSUAA / OAuth authentication + SAP BTP principal propagation for Model Context Protocol servers built on Express and @modelcontextprotocol/sdk.
It gives an MCP server the SAP-native client→server auth stack: an XSUAA OAuth proxy provider, a stateless RFC 7591 Dynamic Client Registration store (HMAC-signed client_ids, restart-resilient), the OAuth-state callback codec that works around XSUAA's un-encoded + in state, a chained bearer verifier (XSUAA → OIDC → API-key, each optional), and a thin setupHttpAuth facade. A separate ./btp entrypoint adds per-user principal propagation via the BTP Destination Service + Cloud Connector.
Two API layers, same package: a plug-and-play facade for the common flow, and the building blocks it composes for full control.
Extracted from arc-1's production auth stack and designed so arc-1, calmcp, and LISA can adopt it with a minimal diff. The full design rationale is frozen in
docs/SPEC.mdanddocs/RESEARCH.md.
Install
npm install @arc-mcp/xsuaa-auth
ESM-only, Node >= 22. You also need these peer dependencies (the package shares the host's Express + MCP SDK instances rather than bundling its own):
| Peer | Range | Required? |
|---|---|---|
@modelcontextprotocol/sdk | >=1.18.2 <2 | yes — 1.18.2 is the first version exposing mcpAuthRouter({ resourceServerUrl }) |
express | ^5.0.1 | yes — the SDK hard-depends on Express 5; v4 cannot coexist with its router |
jose | >=5 <7 | optional — only for the OIDC verifier; lazy-imported, so non-OIDC consumers can skip it |
npm install @modelcontextprotocol/sdk express
npm install jose # only if you use createOidcVerifier / AuthOptions.oidc
@sap/xssec and @sap-cloud-sdk/connectivity are regular dependencies and install automatically.
Quickstart
Layer 1 — the setupHttpAuth facade (plug-and-play)
The facade composes the standard XSUAA + DCR + callback + bearer flow and returns the bearer middleware for your /mcp route. On Cloud Foundry, loadXsuaaCredentials() and resolveAppUrl() read the bound XSUAA service and the public route straight from the environment — no hand-parsed binding.
import express from 'express';
import { setupHttpAuth, loadXsuaaCredentials, resolveAppUrl } from '@arc-mcp/xsuaa-auth';
const app = express();
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
const bearer = setupHttpAuth(
app,
{
apiKeys: process.env.API_KEYS, // string | ApiKeyEntry[]
xsuaa: {
credentials: loadXsuaaCredentials(), // from VCAP_SERVICES
appUrl: resolveAppUrl(process.env, { publicUrlEnvVar: 'PUBLIC_URL', port: 8080 }),
clientIdPrefix: 'myapp-',
resourceName: 'My MCP Server',
// requiredScopes: ['Viewer'], // enforced via requireBearerAuth
},
oidc: { issuer: pr
Related servers

n8n
by n8n-io
Fair-code workflow automation platform with native AI capabilities. Combine visual building with custom code, self-host or cloud, 400+ integrations.

@modelcontextprotocol/server-everything
OfficialMCP server that exercises all the features of the MCP protocol

@modelcontextprotocol/server-filesystem
OfficialMCP server for filesystem access