@mcp-abap-adt/calm-server

@mcp-abap-adt/calm-server

MCP server for SAP Cloud ALM, providing 54 tools across 9 services to manage features, tasks, test cases, documents, projects, and more via natural language.

Category
Visit Server

README

@mcp-abap-adt/calm-server

Stand With Ukraine

MCP server for SAP Cloud ALM, built on @mcp-abap-adt/calm-client. Ships 54 MCP tools covering all 9 Cloud ALM services — full CRUD where the service supports it, plus a wide read surface — with rich JSON Schema descriptions that let an LLM plan multi-step workflows.

This package is dual-purpose:

  • Runnable stdio servernpx @mcp-abap-adt/calm-server. Plug directly into Claude Desktop, Claude Code, or any MCP-compatible host.
  • Reusable library of tool primitives — import individual tools (FEATURES_GROUP, TASKS_GROUP, …) and embed them in a larger composed MCP server without reimplementing anything.

Status

0.2.0 — 54 tools, 232 tests (224 unit + integration, 7 env-gated skips, 1 todo), full build green. Integration suite runs live against the SAP sandbox (api.sap.com) or any OAuth2 Cloud ALM tenant with a single .env switch; gates skip cleanly when no backend is wired.

Installation

As a standalone MCP server

npm install -g @mcp-abap-adt/calm-server
# or per-project:
npm install @mcp-abap-adt/calm-server

As a library (compose into your own MCP server)

npm install @mcp-abap-adt/calm-server
# peers:
npm install @mcp-abap-adt/calm-client @mcp-abap-adt/interfaces @modelcontextprotocol/sdk

Standalone: running the server

1. Configure credentials

Copy the template and fill in:

cp .env.example .env

OAuth2 mode (real tenant) — paste values from an XSUAA service key:

CALM_MODE=oauth2
CALM_BASE_URL=https://<tenant>.<region>.alm.cloud.sap
CALM_UAA_URL=https://<tenant>.authentication.<region>.hana.ondemand.com
CALM_UAA_CLIENT_ID=sb-…!b…|calm!b…
CALM_UAA_CLIENT_SECRET=…

Sandbox mode (SAP API Business Hub):

CALM_MODE=sandbox
CALM_API_KEY=<your-key-from-api.sap.com>
# CALM_BASE_URL defaults to https://sandbox.api.sap.com/SAPCALM

2. Launch

# Global install:
calm-mcp
# Or via npx without install:
npx @mcp-abap-adt/calm-server
# Or from a clone:
npm run build && node dist/bin/stdio.js

The server speaks MCP over stdio. Misconfiguration is reported to stderr with a non-zero exit code.

Authentication setup

calm-mcp supports two OAuth2 flows for live tenants, selectable via CALM_AUTH_FLOW:

Flow Use case Browser? Refresh token?
client_credentials (default) technical service-binding (sb-* client) no no
authorization_code end-user dev workflow, full user scope once yes

Option A — quick CC setup (technical user)

Plain .env with inline CALM_UAA_URL / CALM_UAA_CLIENT_ID / CALM_UAA_CLIENT_SECRET works as before — no extra steps. The broker uses an in-memory session shim for these inline creds.

Option B — broker-backed setup (CC or AC)

Use the bundled mcp-auth CLI to convert a BTP service key into a token-bearing .env:

# CC (no browser)
npx mcp-auth --service-key ./sk.json --output ./DEFAULT.env \
             --type xsuaa --credential

# AC (browser pops once; refresh_token persists)
npx mcp-auth --service-key ./sk.json --output ./DEFAULT.env \
             --type xsuaa --browser auto

Then in your .env:

CALM_MODE=oauth2
CALM_BASE_URL=https://<tenant>.<region>.alm.cloud.sap
CALM_AUTH_FLOW=authorization_code   # or client_credentials
CALM_DESTINATION=DEFAULT

The server's runtime auth pipeline is @mcp-abap-adt/auth-broker.

Note: buildCalmClient is async since v0.4.0 (was sync in v0.3.x). Library consumers must await it.

3. Wire into Claude Desktop

Add to your Claude Desktop config (~/Library/Application Support/Claude/claude_desktop_config.json on macOS, %APPDATA%\Claude\claude_desktop_config.json on Windows):

{
  "mcpServers": {
    "calm": {
      "command": "npx",
      "args": ["-y", "@mcp-abap-adt/calm-server"],
      "env": {
        "CALM_MODE": "sandbox",
        "CALM_API_KEY": "<your-sandbox-key>"
      }
    }
  }
}

Restart Claude Desktop; the 54 calm_* tools become available to the model.

Library: composing into another MCP server

Useful when you want to expose Cloud ALM tools alongside ADT tools, Reports tools, or your own domain tools in a single MCP process.

import { CalmClient, CalmConnection } from '@mcp-abap-adt/calm-client';
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import {
  ALL_GROUPS,
  BaseCalmMcpServer,
  CalmToolRegistry,
  FEATURES_GROUP,
  TASKS_GROUP,
} from '@mcp-abap-adt/calm-server';

// Option A — BaseCalmMcpServer with a curated subset
const calm = new CalmClient(
  new CalmConnection({ baseUrl, apiKey }),
);
const server = new BaseCalmMcpServer({
  name: 'my-mcp',
  version: '1.0.0',
  calm,
  groups: [FEATURES_GROUP, TASKS_GROUP], // only these land as tools
});

// Option B — embed into your existing McpServer
const existing = new McpServer({ name: 'combined', version: '1.0.0' });
const registry = new CalmToolRegistry([...ALL_GROUPS]);
registry.registerAll(existing, () => ({ calm }));
// Now `existing` serves Cloud ALM tools + whatever else you registered.

Subpath exports:

import { ALL_GROUPS } from '@mcp-abap-adt/calm-server/tools';
import { CalmToolRegistry } from '@mcp-abap-adt/calm-server/registry';

Tool surface (54 tools across 9 services)

Service Tools
Features (11) list, get, get_by_display_id, create, update, delete, create_external_reference, delete_external_reference, list_external_references, list_statuses, list_priorities
Tasks (10) list, get, create, update, delete, list_comments, create_comment, list_references, list_deliverables, list_workstreams
TestCases (9) list, get, create, update, delete, create_activity, create_action, list_activities, list_actions
Documents (7) list, get, create, update, delete, list_statuses, list_types
Projects (7) list, get, create, list_programs, get_program, list_team_members, list_timeboxes
Hierarchy (5) list, get_with_children, create_node, update_node, delete_node
Analytics (2, read-only) query (17 endpoints), list_providers (static catalog)
Logs (2, domain-specific REST) get (provider + serviceId + time window), post (inbound log records)
ProcessMonitoring (1, read-only) list_processes

Every MCP tool:

  • Has a full JSON Schema with descriptions — the LLM reads these to plan.
  • Wraps arguments into OData $filter / $select / $top / $skip internally — the LLM never sees raw OData syntax.
  • Returns compact records by default (limit=20, fields default ≈ 6 columns per entity); callers opt into more via fields, limit, withCount, offset.
  • Maps CalmApiError → a typed MCP error the LLM can branch on (NOT_FOUND, NETWORK, ODATA_ERROR with serviceCode, …).

See src/tools/<service>/*.ts for per-tool argument schemas.

Destructive tools (write operations)

Every Cloud ALM service that supports writes is now exposed:

  • Features: create, update, delete, plus external-reference create / delete
  • Tasks: create, update, delete, create_comment
  • TestCases: create, update, delete, plus nested create_activity / create_action
  • Documents: create, update, delete
  • Hierarchy: create_node, update_node, delete_node
  • Projects: create
  • Logs: post (inbound OpenTelemetry-style record ingestion)

The shared SAP sandbox at api.sap.com is read-friendly only — mutation integration tests are opt-in (see Live-tenant integration below).

Debug logging

CALM_LOG_LEVEL=debug         # error | warn | info | debug
DEBUG_CALM_CONNECTORS=true   # CalmConnection retries, 401 refresh, URLs
DEBUG_CALM_LIBS=true         # resource-client internals
DEBUG_CALM_TESTS=true        # test execution progress

Logging goes to stderr (stdout is reserved for the MCP protocol stream).

Development

git clone git@github.com:fr0ster/mcp-calm-server.git
cd mcp-calm-server
npm install

npm run test           # 224 unit + integration tests
npm run build          # emits dist/, includes executable bin
npm run lint:check     # biome

Live-tenant integration

src/__tests__/integration/ runs against a real backend when env is present, and skips cleanly when it isn't (so npm test without secrets is always green). Five gates, drop them into .env:

Gate Env trigger What it unlocks
describeSandbox CALM_MODE=sandbox + CALM_API_KEY The api.sap.com sandbox
describeOAuth2 CALM_MODE=oauth2 + CALM_BASE_URL + 3× UAA env Live tenant (incl. endpoints absent from the sandbox catalog, e.g. Business Processes)
describeWhenLive either of the above Read-side tests that work in either mode
describeWithProject live backend + CALM_PROJECT_ID Project-scoped chains (features list→get, tasks list→get→comments, …)
describeMutating live + CALM_PROJECT_ID + CALM_ALLOW_MUTATIONS=1 Write tests (every mutation finalises via try/finally { delete })

A quick smoke script lives at scripts/smoke-sandbox.mjs — spawns the stdio bin, lists tools, calls a handful of read endpoints, and exits 1 on any non-skip failure.

License

MIT — see LICENSE.

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured