Skip to content

Releases: consetto/calmcp

0.9.2

Choose a tag to compare

@github-actions github-actions released this 29 Sep 21:18

Clearer errors about Cloud ALM scopes, stricter tool input, a CORS fix for the local endpoint, and current dependencies including zod 4.

Breaking for deployments

  • CALM_CORS_ORIGINS no longer accepts a wildcard. *, alone or in a list, and any entry that is not scheme://host[:port] stop calmcp at startup with a message naming the fix. List each browser-based client instead, e.g. CALM_CORS_ORIGINS=http://localhost:6274 for the MCP Inspector. On the local unauthenticated endpoint a wildcard let any website call calmcp through the developer's browser and read Cloud ALM data (#23, code scanning alert #1). Deployments that leave the variable empty, the default, are not affected.
  • Unknown tool parameters are rejected. A parameter outside a tool's schema, such as projectId instead of project_id, now fails the call and is named in the error (Unrecognized key: "projectId") instead of being silently dropped. Every tool schema again advertises additionalProperties: false (#22).

Errors

  • A FORBIDDEN error names the scope the Cloud ALM API service instance is missing, e.g. calm-api.tasks.read, or the write scope for calm_create. For projects and analytics it also mentions calm-api.projects.private.read and calm-api.projects.protected.read (#3).
  • A RATE_LIMITED error without a Retry-After states Cloud ALM's limit of 500 requests per 5 seconds (#4).
  • The Tasks, Defects, Requirements and Features analytics providers note which *.personal.read scope their personal-data field needs, and Tasks notes the scopes for private and protected projects (#3).

Documentation

  • The README has a new "Cloud ALM API scopes" section: which scope each part of calmcp needs, and the private-project and personal-data scopes that are easy to leave out (#3).

Dependencies

  • zod 3 → 4, MCP SDK 1.30, pino 10, dotenv 18, helmet and express-rate-limit updates (#12, #18, #20, #22).
  • Development: TypeScript 7, Vitest 5, Biome 2.5 (#13, #15, #21).
  • calm_create keeps accepting any 8-4-4-4-12 id: zod 4's stricter UUID check is not applied (#22).

Internal

  • Every pull request gets a comment showing what changes in the tool surface: instructions, descriptions and schemas as a model sees them, with sizes (#5, #22).
  • CI adds the e2e tests, a type-check of the tests, mbt validate and an xs-security.json check, a Docker build with a /health check, and dependency review. CodeQL scans every pull request (#6, #7).
  • Dependabot opens weekly updates: minor and patch grouped, majors one per package, Vitest packages together (#6, #11, #17). GitHub Actions are on v7 (#8).

0.9.1

Choose a tag to compare

@github-actions github-actions released this 26 Sep 15:25

Security hardening, machine-readable errors and a restructured tool registry. This is the first release whose Claude Desktop bundle is built and attached by CI.

Breaking for deployments

  • The HTTP transport fails closed. With neither XSUAA nor CALM_HTTP_API_KEY configured it refuses to start instead of serving an open /mcp. For local development, CALM_HTTP_ALLOW_UNAUTHENTICATED=true serves an open endpoint bound to 127.0.0.1 that accepts only loopback Host headers. The switch is ignored on Cloud Foundry, and a bound but unreadable XSUAA service is a startup error.
  • calm_create needs the Writer scope on HTTP. xs-security.json adds the Writer scope, the Editor role template and the CALMCP_Editor role collection. Update the XSUAA service on redeploy and assign CALMCP_Editor to users who may create. Viewers and API-key callers no longer see calm_create, even with CALM_WRITE_ENABLED=true.
  • CORS is off unless configured. Without CALM_CORS_ORIGINS no CORS headers are sent.

Security

  • CALM_TENANT must be a plain subdomain, so it cannot point the OAuth client secret at another host.
  • OData string literals are escaped, a caller's analytics filter is parenthesised before the server's controls are added, path-segment ids are validated, and URLs in calm_create payloads must be http(s).
  • Request bodies are capped at 1 MB. On Cloud Foundry the gorouter hop is trusted, so rate limiting is per client instead of shared.
  • Upstream error bodies are stripped of HTML and length-capped before they reach the model.

Errors and resilience

  • A failed call returns a JSON object with a stable error code (NOT_FOUND, FORBIDDEN, RATE_LIMITED, TIMEOUT, ...), retryable, status, message and a hint. The README lists the codes.
  • A read answered with 429 or 503 is retried once when Cloud ALM asks for a wait of at most 5 seconds. A create is never retried.
  • A call the client cancels stops issuing requests.

Usability

  • Tools carry MCP annotations (read-only, non-destructive).
  • Unknown field names get a suggestion for the real name. calm_get accepts fields to project a single entity.
  • A full calm_list page names the next page, and an empty relation list says what was queried.
  • OData paging follows server-capped pages that announce @odata.nextLink instead of stopping at the first short page.
  • Grouping by an array field (such as tags) counts each value on its own.

Internal

  • The tool registry and constants are split into smaller modules, and duplicate code is removed.
  • New tests keep recipes and tool descriptions in sync with the analytics catalog and keep tool schemas within a size budget and widely supported JSON Schema.
  • Integration tests run only with live credentials. CALM_TEST_PROJECT_ID adds the project-scoped checks.
  • The release workflow tests, builds and smoke-tests calmcp-<version>.mcpb and attaches it to the release.

v0.9.0

Choose a tag to compare

@michaelconsetto michaelconsetto released this 21 Sep 17:38

Adds opt-in create-only write access. calmcp stays read-only by default: nothing changes for existing deployments unless an operator turns the switch on.

Added

  • calm_create tool, registered only when CALM_WRITE_ENABLED=true (or Write Access in the Claude Desktop extension settings). It creates a new document or a new cross-library entry (document, xlib_application, xlib_configuration, xlib_configuration_activity, xlib_development, xlib_interface). It never updates or deletes; calling it twice makes two entries.
  • Payload validation from the OpenAPI specs. Every field is checked before a request is sent. An unknown field is an error, not something silently dropped. Nested assignments (toURLReferences, toProcessHierarchyAssignments, toTaskAssignments, ...) are created together with the entity.
  • calm_resources discovery for write payloads. With write access on, calm_resources({ topic: "document" }) returns the field list of each calm_create resource.
  • CALM_WRITE_ENABLED config, the calm-api.doc.write and calm-api.lib.write XSUAA scopes, and a Write Access toggle in the MCPB manifest.

Changed

  • README documents the write-access opt-in, its scopes and the recommendation to run a separate app for writers rather than enabling it on a shared viewer deployment.
  • Version jumps from 0.2.7 to 0.9.0 to mark the first release that is no longer strictly read-only.

Spec refresh of 2025-09-21

The SAP Business Accelerator Hub republished the Cloud ALM APIs on 21 September 2025. All 19 specs under YAML/ were re-downloaded and compared byte for byte; nine changed (Tasks 1.0.31, Projects 1.0.12, Test Cases 1.0.6, Test Plans 1.0.2, Cross-Library Applications 1.0.4, Configurations 1.0.2, Developments 1.0.4, Interfaces 1.0.3, and Landscape, which changed content while staying at 1.0.0). docs/API_VERSIONS.md carries the new table.

  • us20 region is accepted by CALM_REGION and the extension settings; every service spec now lists it.
  • Cross-library classification. Applications, developments and interfaces now carry priority, readiness, usage status, usage number, clean core level and upgrade impact codes; configurations carry priority and readiness. Seventeen new calm_list code-list resources (xlib_application_priorities, xlib_development_clean_core_levels, xlib_interface_upgrade_impacts, ...) resolve the codes to labels, and calm_create accepts the codes on all four library entries, validated against the spec enums (applicationSuccessor and packageName included).
  • Landscape access control lists. calm_list resource:landscape_access_control_lists reads the new SCIM 2.0 groups endpoint (members and grant levels, filterable by displayName or id). The SCIM Resources envelope is unwrapped like the OData value one. Reading it needs the calm-api.landscape.access-control.admin scope on the technical user; the SCIM PATCH stays out, since calmcp is create-only.

v0.2.0

Choose a tag to compare

@michaelconsetto michaelconsetto released this 15 Aug 17:58

Refreshes the SAP Cloud ALM OpenAPI specs (2 months stale: 8 of 16 outdated, 10 upstream APIs absent) and extends coverage with what they revealed. All services remain on API version v1.

Fixed

  • 5 missing task status codes. The Tasks API accepts 28; calmcp advertised 23. CIPUSREV, CIPTKREV, CIPRIOPEN, CIPRIINP, CIPRIDONE are now returned by calm_resources. CIPUSREV occurs on real projects, so it was unexplainable to clients before.
  • Sub-status code list. sub_status was an accepted filter with its 19 valid values undocumented.
  • $top/$skip/$orderby stay literal in REST query strings; the process services expect the option name rather than %24top.

Added

  • Task filters lastChangedDate, lastChangedTimestamp and id, making incremental "what changed since X" queries possible.
  • Three services: Process Scopes (CALM_PM 1.1.0), Custom Processes (CALM_PMGE 1.0.0) and Test Plans (CALM_TM_PLAN 1.0.0, BETA). Process Scopes resolves the scopeId/scopeName carried on every task, which no tool could do before.
  • What the refreshed specs added: program teams and roles (Projects 1.0.11), URL references on all four cross-library services, configuration activities and assignments (Cross Library Configurations 1.0.1), and task solution-process assignments.

The spec provenance table in the README records the artifact version behind each service so the next drift check is a comparison rather than an investigation.

v0.1.1

Choose a tag to compare

@michaelconsetto michaelconsetto released this 15 Aug 16:13

First tagged release. Deployed to SAP BTP Cloud Foundry and verified against a live Cloud ALM tenant.

Added

Timebox filter and field projection for calm_list — the Tasks REST endpoint returns all 67 attributes of every record and offers no sprint filter, so a query like "open user stories in Sprint 5" meant fetching hundreds of KB and filtering client-side. That overflows smaller agent hosts such as Microsoft Copilot Studio.

  • fields — comma-separated projection of the returned records, on REST resources as well as OData ones.
  • timebox_id / timebox_name — select the tasks of one sprint or phase. calmcp pages through the project so the filter is complete, and resolves a name such as Sprint 5 against the project's timeboxes.

Both reject unknown field and timebox names rather than silently ignoring them, since a dropped filter makes an LLM's answer look authoritative and be wrong. On a real project this takes the Sprint 5 query from 263 KB to 3.2 KB.

CI — npm ci, version check, lint, tests and build on Node 22 and 24, for pushes to main and every pull request.

Single-source versioning — the version lived in five hand-maintained places, so cf deploy kept reporting the same number for different builds. scripts/sync-version.mjs propagates package.json to the rest and is wired to the npm version lifecycle, with a --check mode enforced in CI.

Fixed

keep-existing: env on the calmcp-srv MTA module. Without it every redeploy reset the app environment to the descriptor and dropped CALM_HTTP_API_KEY, breaking API-key clients.