{"ref":"artifact:consetto-calmcp","page":"/artifacts/consetto-calmcp","json":"/artifacts/consetto-calmcp.json","generated":"2026-10-26","drafted_with_ai":true,"entity":{"id":"consetto-calmcp","name":"calmcp","artifact_type":"mcp-server","ecosystem":"btp","domain":"ai-and-agents","secondary_domains":["operations-and-runtime"],"origin_ring":"independent","description":{"one_line":"An MCP server in front of the SAP Cloud ALM APIs: four read tools over tasks, projects, features, documents, tests and analytics, run over stdio locally or Streamable HTTP on Cloud Foundry.","short":"MCP server with read tools over the SAP Cloud ALM APIs","what_it_solves":"[SAP Cloud ALM](external:sap-cloud-alm) keeps a project's tasks, requirements, user stories, defects, features, documents, test cases and landscape behind a dozen OData and REST services, each with its own scopes and its own filter rules, and in that product a requirement and a defect are both tasks distinguished by a type code. calmcp puts four tools in front of all of it, `calm_list`, `calm_get`, `calm_analytics` and `calm_resources`, and makes the last one the catalogue an agent reads first, so the valid resource names, the analytics providers and the task type codes come from the server instead of from a guess. Several of its rules are about not answering: a parameter the chosen resource does not read is rejected with the list of parameters it does read, a payload over 100 KB is withheld and replaced by a count with the fields the records carry, and a filtered analytics count is also run unfiltered, because the analytics service drops a filter on a field it does not support and then answers with every row. It reads, and never updates or deletes; an operator who sets `CALM_WRITE_ENABLED=true` registers a fifth tool that creates documents and cross-library entries, offered on the HTTP transport only to a caller whose token carries the `Writer` scope. It runs as a Claude Desktop extension bundle over stdio, and as a Cloud Foundry application over Streamable HTTP, where it reaches Cloud ALM through a bound [destination](artifact:btp-destination) and puts [XSUAA](artifact:btp-authorization-and-trust-management) in front of its own `/mcp` endpoint."},"links":{"repo":"https://github.com/consetto/calmcp","homepage":"https://www.consetto.com/calm-mcp"},"identity":{"license":"MIT"},"source_available":true,"maintainers":["actor:consetto","actor:michaelconsetto"],"contributors":["actor:marianfoo","actor:michaelconsetto"],"compat":{"runtimes":["node"],"deployment":["cf","local"]},"provides":[{"capability":"capability:agent-systems-access","what_it_does":"Puts four read tools in front of the Cloud ALM APIs, one of them the catalogue of resources, analytics providers and code lists, so an agent asks a running Cloud ALM tenant about projects, tasks and defects rather than being handed a dozen services to learn.","sources":[{"url":"https://raw.githubusercontent.com/consetto/calmcp/main/README.md","title":"consetto/calmcp — README","checked":"2026-10-11","quote":"It exposes the Cloud ALM read APIs through four consolidated, intent-based tools, runs over **stdio** locally or **Streamable HTTP** remotely, and deploys to **SAP BTP Cloud Foundry**."},{"url":"https://raw.githubusercontent.com/consetto/calmcp/main/README.md","title":"consetto/calmcp — README, Tools","checked":"2026-10-11","quote":"Discovery: the catalog of resources/providers, per-provider analytics dimensions and measures, the task type/status/priority code lists, and worked recipes."}]}],"type_properties":{"runs":{"value":["local-process","central-server"],"sources":[{"url":"https://raw.githubusercontent.com/consetto/calmcp/main/README.md","title":"consetto/calmcp — README, Run over stdio","checked":"2026-10-11","quote":"CALM_SANDBOX=true CALM_API_KEY=<key> node dist/index.js"},{"url":"https://raw.githubusercontent.com/consetto/calmcp/main/README.md","title":"consetto/calmcp — README, Using the MTA descriptor","checked":"2026-10-11","quote":"This creates and binds `calmcp-xsuaa` (XSUAA), `calmcp-destination` (Destination) and `calmcp-logs` (Application Logs), and runs the HTTP transport with a `/health` check."}]},"transports":{"value":["stdio","http"],"sources":[{"url":"https://raw.githubusercontent.com/consetto/calmcp/main/README.md","title":"consetto/calmcp — README","checked":"2026-10-11","quote":"It exposes the Cloud ALM read APIs through four consolidated, intent-based tools, runs over **stdio** locally or **Streamable HTTP** remotely, and deploys to **SAP BTP Cloud Foundry**."},{"url":"https://raw.githubusercontent.com/consetto/calmcp/main/README.md","title":"consetto/calmcp — README, Consuming the deployed server from an AI tool","checked":"2026-10-11","quote":"`/mcp` speaks the **Streamable HTTP** MCP transport, so point a remote-MCP-capable client at it"}]},"auth":{"value":["oauth","api-key","destination"],"sources":[{"url":"https://raw.githubusercontent.com/consetto/calmcp/main/README.md","title":"consetto/calmcp — README, Endpoint authentication","checked":"2026-10-11","quote":"It also exposes MCP-native OAuth (RFC 8414 discovery + RFC 7591 dynamic client registration, proxied to XSUAA), so an AI tool such as Claude Desktop, Cursor or VS Code **signs the user in interactively** with no manual token handling."},{"url":"https://raw.githubusercontent.com/consetto/calmcp/main/README.md","title":"consetto/calmcp — README, Endpoint authentication","checked":"2026-10-11","quote":"**Alternative: a static API key** for non-interactive, server-to-server callers (for example Microsoft Copilot Studio). Set `CALM_HTTP_API_KEY` and the caller sends `Authorization: Bearer <key>`."},{"url":"https://raw.githubusercontent.com/consetto/calmcp/main/README.md","title":"consetto/calmcp — README, Configuration","checked":"2026-10-11","quote":"`CALM_DESTINATION_NAME` | Name of a bound BTP Destination (BTP mode; takes precedence)."}]},"tool_count":{"value":4,"source":{"url":"https://raw.githubusercontent.com/consetto/calmcp/main/README.md","title":"consetto/calmcp — README","checked":"2026-10-11","quote":"It exposes the Cloud ALM read APIs through four consolidated, intent-based tools, runs over **stdio** locally or **Streamable HTTP** remotely, and deploys to **SAP BTP Cloud Foundry**."}},"read_only":{"value":true,"source":{"url":"https://raw.githubusercontent.com/consetto/calmcp/main/README.md","title":"consetto/calmcp — README","checked":"2026-10-11","quote":"calmcp is read-only by default: it never updates or deletes data in SAP Cloud ALM. An operator can opt in to **create-only** access for documents and library entries with `CALM_WRITE_ENABLED=true`"}},"guardrails":[{"source":{"url":"https://raw.githubusercontent.com/consetto/calmcp/main/README.md","title":"consetto/calmcp — README, Endpoint authentication","checked":"2026-10-11","quote":"**With neither configured, the HTTP transport refuses to start.**"}},{"source":{"url":"https://raw.githubusercontent.com/consetto/calmcp/main/README.md","title":"consetto/calmcp — README, Endpoint authentication","checked":"2026-10-11","quote":"The switch is ignored on Cloud Foundry, and a bound but unreadable XSUAA service is a startup error, so a broken binding never exposes Cloud ALM data publicly."}},{"source":{"url":"https://raw.githubusercontent.com/consetto/calmcp/main/README.md","title":"consetto/calmcp — README, Configuration","checked":"2026-10-11","quote":"A wildcard (`*`) is refused at startup: on the local unauthenticated endpoint it would let any website read Cloud ALM data through the developer's browser."}},{"source":{"url":"https://raw.githubusercontent.com/consetto/calmcp/main/README.md","title":"consetto/calmcp — README, Write access","checked":"2026-10-11","quote":"**Create only.** There is no update and no delete, on purpose."}},{"source":{"url":"https://raw.githubusercontent.com/consetto/calmcp/main/README.md","title":"consetto/calmcp — README, Write access","checked":"2026-10-11","quote":"On the HTTP transport the switch alone is not enough: `calm_create` is offered only to callers whose XSUAA token carries the `Writer` scope (role collection `CALMCP_Editor`). Viewers of the same deployment and API-key callers never see the tool."}},{"source":{"url":"https://raw.githubusercontent.com/consetto/calmcp/main/README.md","title":"consetto/calmcp — README, Write access","checked":"2026-10-11","quote":"**Strict payloads.** Each resource's fields are transcribed from the `*-create` schemas in the OpenAPI specs and validated before any request is sent. An unknown field is an error, not something silently dropped."}},{"source":{"url":"https://raw.githubusercontent.com/consetto/calmcp/main/README.md","title":"consetto/calmcp — README, Cloud ALM API scopes","checked":"2026-10-11","quote":"Grant only what the deployment should expose: every caller of calmcp sees what these scopes allow."}},{"source":{"url":"https://raw.githubusercontent.com/consetto/calmcp/main/README.md","title":"consetto/calmcp — README, Keeping responses small","checked":"2026-10-11","quote":"A payload over `CALM_MAX_RESPONSE_BYTES` (default 100 KB) is withheld and replaced by a summary naming how many records matched, which fields they carry, and how to ask again."}},{"source":{"url":"https://raw.githubusercontent.com/consetto/calmcp/main/README.md","title":"consetto/calmcp — README, Keeping responses small","checked":"2026-10-11","quote":"Unknown field names and unknown timebox names are rejected rather than silently ignored."}}]},"connects":[{"ref":"external:sap-cloud-alm","kind":"data","protocols":["http"],"direction":"outbound","style":"sync","for":"calls the Cloud ALM services for the records an agent asked about, appending each service's path to the tenant's API base","sources":[{"url":"https://raw.githubusercontent.com/consetto/calmcp/main/README.md","title":"consetto/calmcp — README","checked":"2026-10-11","quote":"It exposes the Cloud ALM read APIs through four consolidated, intent-based tools, runs over **stdio** locally or **Streamable HTTP** remotely, and deploys to **SAP BTP Cloud Foundry**."},{"url":"https://raw.githubusercontent.com/consetto/calmcp/main/README.md","title":"consetto/calmcp — README, Configure the destination","checked":"2026-10-11","quote":"your Cloud ALM API base **including the `/api` suffix**: `https://<tenant>.<region>.alm.cloud.sap/api`"}]},{"ref":"artifact:btp-destination","kind":"authentication","direction":"outbound","condition":"run in BTP mode, where `CALM_DESTINATION_NAME` names the destination entry the server looks up at runtime","for":"reads the OAuth2 client-credentials and the Cloud ALM API base out of a destination the deployment binds, instead of holding them in its own environment","sources":[{"url":"https://raw.githubusercontent.com/consetto/calmcp/main/README.md","title":"consetto/calmcp — README, Deploy to SAP BTP Cloud Foundry","checked":"2026-10-11","quote":"calmcp authenticates to Cloud ALM via a bound **Destination** (type OAuth2 client-credentials, URL = your Cloud ALM API base, e.g. `https://<tenant>.<region>.alm.cloud.sap/api`). Set `CALM_DESTINATION_NAME` to that destination's name."},{"url":"https://raw.githubusercontent.com/consetto/calmcp/main/README.md","title":"consetto/calmcp — README, Configure the destination","checked":"2026-10-11","quote":"**`CALM_DESTINATION_NAME`** (default `SAP_CALM`) — the name of the destination *entry* the app looks up at runtime."}]},{"ref":"artifact:btp-authorization-and-trust-management","kind":"authentication","direction":"outbound","condition":"the HTTP transport with the `calmcp-xsuaa` service bound","for":"has XSUAA sign the caller in and issue the token the `/mcp` endpoint checks for the `Viewer` scope, with OAuth discovery and client registration proxied to it","sources":[{"url":"https://raw.githubusercontent.com/consetto/calmcp/main/README.md","title":"consetto/calmcp — README, Endpoint authentication","checked":"2026-10-11","quote":"When the `calmcp-xsuaa` service is bound, `/mcp` requires a valid XSUAA token carrying the `Viewer` scope (granted via the `CALMCP_Viewer` role collection)."},{"url":"https://raw.githubusercontent.com/consetto/calmcp/main/README.md","title":"consetto/calmcp — README, Endpoint authentication","checked":"2026-10-11","quote":"The OAuth flow is delegated to XSUAA; calmcp never sees the user's password."}]}],"requires":[{"ref":"artifact:btp-destination","requirement":"conditional","condition":"run in BTP mode, which the MTA descriptor and `cf push` both set up","for":"the destination service instance the deploy creates and binds, which holds the destination entry the server resolves","sources":[{"url":"https://raw.githubusercontent.com/consetto/calmcp/main/README.md","title":"consetto/calmcp — README, Using the MTA descriptor","checked":"2026-10-11","quote":"This creates and binds `calmcp-xsuaa` (XSUAA), `calmcp-destination` (Destination) and `calmcp-logs` (Application Logs), and runs the HTTP transport with a `/health` check."}]},{"ref":"artifact:btp-authorization-and-trust-management","requirement":"conditional","condition":"the HTTP transport, which refuses to start unless XSUAA or a static API key is configured","for":"the authorization server behind the `/mcp` endpoint, whose `Viewer` and `Writer` scopes decide who may call the tools","sources":[{"url":"https://raw.githubusercontent.com/consetto/calmcp/main/README.md","title":"consetto/calmcp — README, Endpoint authentication","checked":"2026-10-11","quote":"**With neither configured, the HTTP transport refuses to start.**"},{"url":"https://raw.githubusercontent.com/consetto/calmcp/main/README.md","title":"consetto/calmcp — README, Using `cf push`","checked":"2026-10-11","quote":"cf create-service xsuaa application calmcp-xsuaa -c xs-security.json"}]},{"ref":"artifact:btp-application-logging","requirement":"conditional","condition":"deployed with the MTA descriptor or `cf push`, which create and bind `calmcp-logs`","for":"the application logs instance the deploy binds to the running server","sources":[{"url":"https://raw.githubusercontent.com/consetto/calmcp/main/README.md","title":"consetto/calmcp — README, Using the MTA descriptor","checked":"2026-10-11","quote":"This creates and binds `calmcp-xsuaa` (XSUAA), `calmcp-destination` (Destination) and `calmcp-logs` (Application Logs), and runs the HTTP transport with a `/health` check."}]}],"lineage":[{"target":"artifact:arc-mcp-arc-1","kind":"inspired-by","source":{"url":"https://raw.githubusercontent.com/consetto/calmcp/main/README.md","title":"consetto/calmcp — README","checked":"2026-10-11","quote":"The Architecture is based on [`marianfoo's`](https://github.com/marianfoo) [`arc-1`](https://github.com/marianfoo/arc-1) as reference architecutre."}}],"agent":{"source":{"url":"https://raw.githubusercontent.com/consetto/calmcp/main/README.md","title":"consetto/calmcp — README, Local development","checked":"2026-10-11"},"install":"npm install\nnpm run build","config_snippet":"{\n  \"mcpServers\": {\n    \"calmcp\": {\n      \"command\": \"node\",\n      \"args\": [\"/absolute/path/to/calmcp/dist/index.js\"],\n      \"env\": { \"CALM_SANDBOX\": \"true\", \"CALM_API_KEY\": \"<key>\" }\n    }\n  }\n}","minimal_example":"calm_analytics({ \"provider\": \"Tasks\", \"filter\": \"type eq 'User Story'\", \"count_only\": true })"},"provenance":{"discovered_via":[{"source":"source:curator"}],"first_seen":"2026-10-11"},"history":[{"date":"2026-10-11","field":"entry","from":null,"to":"created","reason":"The repository was handed over directly. Written from the README, the repository's own record and the product page at consetto.com. Filed on the BTP door because Cloud ALM has no door of its own and the server deploys to Cloud Foundry, binds XSUAA and resolves a destination there, the same strain recorded on [cloud-alm-itsm-mcp](artifact:gregorwolf-cloud-alm-itsm-mcp). origin_ring is independent because the product page states it: \"calmcp is an independent open-source project.\""}],"drafted_with_ai":true},"effective_normative_relations":[],"readings":{"liveness":[{"label":"Maintenance","tier":"unknown","evidence":"no release data"},{"label":"Continuity","tier":"good","evidence":"3 contributors, org-owned"},{"label":"Repository","tier":"good","evidence":"pushed 2026-10, not archived"}],"compatibility":[{"label":"Declared for","tier":"unknown","evidence":"no BTP release lines in the atlas"},{"label":"Survived majors","tier":"unknown","evidence":"no BTP release lines in the atlas"},{"label":"Maintainer's CI","tier":"good","evidence":"CI green, 2026-10-01"}],"practice":[{"label":"Tests","tier":"good","evidence":"25 test files"},{"label":"Docs","tier":"good","evidence":"docs/ with 4 pages, README 28 KB"},{"label":"Changelog","tier":"fair","evidence":"none in the repo"}],"reach":[{"value":null,"unit":"installs/week"},{"value":3,"unit":"watching"}]},"signals":{"crawled_at":"2026-10-24","npm":"not published under this name","stars":3,"forks":2,"open_issues":6,"archived":false,"pushed_at":"2026-10-20","license_spdx":"MIT","org_owned":true,"default_branch":"main","created_at":"2026-06-14T20:52:32Z","open_prs":6,"tree_truncated":false,"test_files":25,"workflows":4,"other_ci":false,"readme_bytes":28840,"docs_files":4,"changelog":false,"license_file":true,"dts_files":0,"first_commit":"2026-06-13","last_commit":"2026-10-01","commits":92,"contributors":3,"ci_status":"success","ci_run_at":"2026-10-01","ci_workflow":"CI","ci_event":"push","readme_path":"README.md","readme_sha":"acc657d83273b26cc610353cc11dff9d63010330","repo_read":"2026-10-24"},"release_notes":{"license":"MIT","quotable":true,"source":{"kind":"github-releases","url":"https://github.com/consetto/calmcp/releases"},"format":"github-releases","releases":[{"version":"0.9.2","date":"2026-09-29","date_source":"github","heading":"0.9.2","url":"https://github.com/consetto/calmcp/releases/tag/v0.9.2","sections":[{"kind":"breaking","heading":"Breaking for deployments","items":2}],"hash":"ae85c5b6c33fef16"},{"version":"0.9.1","date":"2026-09-26","date_source":"github","heading":"0.9.1","url":"https://github.com/consetto/calmcp/releases/tag/v0.9.1","sections":[{"kind":"breaking","heading":"Breaking for deployments","items":3},{"kind":"security","heading":"Security","items":4}],"hash":"fd6e13f16a1f0bb7"},{"version":"0.9.0","date":"2026-09-21","date_source":"github","heading":"v0.9.0","url":"https://github.com/consetto/calmcp/releases/tag/v0.9.0","sections":[{"kind":"feature","heading":"Added","items":4},{"kind":"change","heading":"Changed","items":2}],"hash":"d93e4c704535e47d"},{"version":"0.2.0","date":"2026-08-15","date_source":"github","heading":"v0.2.0","url":"https://github.com/consetto/calmcp/releases/tag/v0.2.0","sections":[{"kind":"fix","heading":"Fixed","items":3},{"kind":"feature","heading":"Added","items":3}],"hash":"9b33a4ae5c33eb10"},{"version":"0.1.1","date":"2026-08-15","date_source":"github","heading":"v0.1.1","url":"https://github.com/consetto/calmcp/releases/tag/v0.1.1","sections":[{"kind":"feature","heading":"Added","items":2},{"kind":"fix","heading":"Fixed","items":0}],"hash":"b54ef386f2d97f0c"}],"crawled_at":"2026-10-25"},"edges":{"maintainers":[{"ref":"actor:consetto","name":"Consetto","json":"/actors/consetto.json"},{"ref":"actor:michaelconsetto","name":"Michael Scharf","json":"/actors/michaelconsetto.json"}],"contributors":[{"ref":"actor:marianfoo","name":"Marian Zeis","json":"/actors/marianfoo.json"},{"ref":"actor:michaelconsetto","name":"Michael Scharf","json":"/actors/michaelconsetto.json"}],"explained_by":[],"alternative_to_this":[],"needed_by":[],"available_via":[],"parts":[],"add_ons":[],"answered_through_parts":[]}}