SAP AI Stack

What is Model Context Protocol?

The Model Context Protocol (MCP) is an open standard (created by Anthropic, now adopted widely) that lets LLMs and AI assistants interact with external tools and data sources through a standardised interface.

Instead of prompting the AI to generate API calls and hoping it gets the URL right, MCP tools are structured, typed, and server-side. The AI calls a tool by name with typed parameters, your MCP server executes the actual logic, and returns structured results.

For SAP developers, this means: you can give Claude or GPT-4 access to your BTP tenant β€” query integration flows, check message monitor status, read HANA tables β€” and it will use real APIs correctly.

Architecture overview

The setup I built:

Claude Desktop
    ↓ MCP tool call: { name: "get_failed_messages", params: { hours: 24 } }
MCP Server (Node.js, running locally)
    ↓ OAuth2 client credentials flow
XSUAA β†’ access token
    ↓ Bearer token
CPI OData API β†’ message processing logs
    ↑ JSON results
Claude Desktop renders the results

The MCP server runs locally on your machine (or on a server). It holds the service key credentials from your Integration Suite instance and handles all token management.

XSUAA token exchange

The tricky part is authentication. Your MCP server needs a valid XSUAA token to call CPI APIs. Here's the token exchange logic:

interface XsuaaConfig {
  url: string;
  clientid: string;
  clientsecret: string;
}

let tokenCache: { token: string; expires: number } | null = null;

async function getToken(config: XsuaaConfig): Promise<string> {
  // Return cached token if still valid (with 60s buffer)
  if (tokenCache && Date.now() < tokenCache.expires - 60_000) {
    return tokenCache.token;
  }

  const response = await fetch(`${config.url}/oauth/token`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded',
      Authorization: `Basic ${Buffer.from(
        `${config.clientid}:${config.clientsecret}`
      ).toString('base64')}`,
    },
    body: 'grant_type=client_credentials',
  });

  const data = await response.json();
  tokenCache = {
    token: data.access_token,
    expires: Date.now() + data.expires_in * 1000,
  };
  return tokenCache.token;
}

Load credentials from environment variables β€” never hardcode them:

# .env (never commit this)
XSUAA_URL=https://yoursubaccount.authentication.eu10.hana.ondemand.com
XSUAA_CLIENT_ID=sb-your-client-id
XSUAA_CLIENT_SECRET=your-client-secret
CPI_BASE_URL=https://yoursubaccount.it-cpi.cfapps.eu10.hana.ondemand.com

Handling scope mismatches

The most common error when building MCP tools for CPI: your token is valid but every API call returns 403 Forbidden. The cause is almost always a scope mismatch.

CPI APIs require specific scopes like it!b12345.IntegrationOperationServer.read. These scopes are defined in your Integration Suite service instance's security configuration. When you create a service key, the key's scopes depend on the role collections assigned in XSUAA.

Debug this by decoding your token at jwt.io. Look for the scope claim. If IntegrationOperationServer.read is missing, go to your XSUAA service instance β†’ Role Collections β†’ assign the Integration Suite operator role to your service key's user.

Pitfall

Creating a new service key doesn't automatically give it all scopes. You must explicitly assign role collections in XSUAA to the service key's technical user. This is a BTP security feature β€” minimal permissions by default.

What works in production

After three months running this in a real project, the most useful MCP tools I built for SAP BTP:

  • get_failed_messages(hours) β€” fetch all failed CPI messages in the last N hours
  • get_iflow_status(packageId, iflowId) β€” check if an iFlow is deployed and its version
  • query_hana(sql) β€” run read-only SQL against HANA Cloud (with a read-only DB user)
  • get_api_analytics(apiProxyName, days) β€” API Management traffic summary
  • list_event_queues() β€” SAP Event Mesh queue depths and consumer status

The AI becomes a genuinely useful operations assistant. You describe the problem in plain English, it calls the right tools, correlates the results, and gives you a diagnosis β€” often faster than clicking through BTP Cockpit manually.

← All articles