Skip to content

Release Notes

What each ARC-1 release changed, why it matters, and whether you have to do anything about it.

What it is Use it for
CHANGELOG.md Machine-generated by release-please — one line per merged PR The complete, exact list of what went into a version
This page The same releases, annotated Deciding whether a release affects you, and what to do about it

See also: Updating for upgrade mechanics and migration steps, Configuration for every flag named here, Tools Reference for the tool surface.

How to read this

Each release gets a short framing paragraph and a table:

  • Change — the merged PR, linked.
  • What it means — the effect on a running ARC-1 instance, or on an LLM using the tools.
  • Action — what you have to do. none for the large majority — that is the useful signal, not filler.

From 1.0 onward ARC-1 follows semantic versioning, except for experimental default-off features (today: multi-target mode), whose surface may still change in a minor release until they are promoted.

Coverage

1.0.0 and the whole 0.9 line are annotated release by release. 0.10.8 are summarized per minor line — nobody runs them today, and the one part that still matters when jumping from an ancient version is the v0.7.0 authorization break, which is spelled out in full at the bottom of this page.

1.0.0 — semver commitment, experimental multi-target, bounded tool results (2026-07-31)

The version number is the headline: from 1.0 ARC-1 follows semantic versioning, so breaking changes to the MCP tool surface, configuration, or auth contract now require a major bump. Default-off experimental features are explicitly carved out of that guarantee — today that means only the new multi-target BTP mode. The release itself runs on three tracks: an experimental, mutation-free multi-target mode for BTP Cloud Foundry (ADR-0006 / ADR-0007), hard bounds on tool results that were previously unbounded (one where-used call could return ~968k tokens), and a wider write surface for procedural ABAP, function groups, and server-driven objects. One hard upgrade action: cache warmup is gone, and ARC-1 refuses to start if its retired settings are still present.

Change What it means Action
Experimental destination-discovered multi-target endpoints (#579) BTP CF only. Discovers subaccount destinations marked arc1.enabled=true and serves pinned /<SID>/<CLIENT>/mcp routes plus an aggregate /multi/mcp. Mutation-free — read/data/SQL scopes only. Requires bound XSUAA + Destination + Connectivity, HTTP transport, standard tools, cache none, UI/plugins off. Principal-propagation targets are strict; a shared Basic identity is a separate default-off exception requiring exactly one CF instance. opt-in: ARC1_MULTI_TARGET_ENDPOINTS=true — read Multi-System Setup and Multi-Target Administration
Bound unbounded tool results, reject unknown params, compact JSON (#583) The largest LLM-facing change. SAPNavigate(references) is capped (default 100, clamp 1–1000) and returns {total, shown, truncated, hint, references}; its objectType filter now actually filters (it was dead code — SAP ignores objectTypeFilter and nothing filtered client-side). SAPTransport(list) defaults to headers-only. SAPContext(impact) caps each bucket at 50 and names truncatedBuckets. Unknown tool parameters are rejected instead of silently stripped. All JSON results are emitted compact (15–37% fewer tokens). The server now advertises MCP instructions. none — but a client passing unknown params now gets an error instead of a wrong-but-successful result
Remove cache warmup (#573) The startup TADIR scan and repository-wide node/edge indexes are gone. SAPContext(action="usages") queries SAP's live where-used index under the calling user's identity. Request-driven memory/SQLite caching is unchanged. breaking — remove the retired settings before upgrading (see below)
Procedural unit source surgery (#571) New on-prem SAPWrite action="edit_unit" replaces a single named FORM…ENDFORM or MODULE…ENDMODULE block in a PROG or INCL without the caller re-sending the whole program. ARC-1 locates the block with abaplint's structure tree and validates that the replacement has the same kind and name before splicing. none
FUGR structural includes, NW 7.50 gates, FUNC processing read-back (#637) SAPWrite type="INCL" with group= gains create and delete of function-group structural includes (names must start with L<GROUP>, checked client-side because SAP answers with an opaque 500). SAPRead type="FUNC" includeSignature=true reports processingType/updateTaskKind. On NW 7.50, SAPRead type="FUGR" falls back to objectstructure instead of failing, and DOMA create / SAPManage create_package return a release hint instead of a raw 404 (both endpoints are absent before 7.52). none
Create Remote-Enabled and update-task function modules (#634) SAPWrite type="FUNC" gains processingType (normal/rfc/update) and updateTaskKind (startImmediate/immediateStartNoRestart/startDelayed). The create POST envelope is unchanged — a locked metadata PUT is the single writer, because the create attribute was measured inert on 758. none
DTDC (Dynamic Cache) read/write (#612) Adds SAPRead / SAPWrite create,update,delete / SAPActivate for DTDC. It is the first server-driven object that does not use the <blue:blueSource> metadata format, so the engine is now registry-driven per metadata format rather than blue-only. Live-verified create→update→activate→read→delete on 758 and 816. none
Per-type source format for server-driven objects + DSFD (#604) DTSC writes were failing with HTTP 415 because the source format was assumed uniform across server-driven types. It is now per-type (text for DTSC/DSFD/DTDC, json for the rest). Adds DSFD (Scalar Function Definition). none
Read Launchpad App Descriptor Items (UIAD), gate server-driven types on discovery (#642) SAPRead type="UIAD" reads LADIs — the successor to the deprecated tile/target-mapping model. Write is registered but SAP refuses it outside ABAP Cloud, so it is read-only in practice on-prem; that is documented, not guarded. Server-driven types are now discovery-gated at read, write, and activate. none
SAPDiagnose action=atc_variants (#611) Lists the ATC check variants available on the system plus the system default, so a caller can bind a real variant at worklist creation instead of guessing. read scope. none
Serve RFC 9728 protected-resource metadata in OIDC mode (#632) ARC-1 publishes OAuth protected-resource metadata at /.well-known/oauth-protected-resource/mcp (plus base-path and /multi variants), so MCP clients auto-discover the authorization server instead of needing a manual override. On by default. opt-out: SAP_OIDC_DISCOVERY=false for Entra ID if OAuth fails with AADSTS9010010 — see OAuth / JWT
Advertise a configurable MCP server name per deployment (#606) Each instance can advertise its own name in the MCP initialize handshake. Without it, MCP clients (VS Code) collapse several ARC-1 instances pointing at different SAP systems and assign dynamic arc-N tool suffixes. opt-in: ARC1_SERVER_NAME=<name> when running more than one instance
Propagate W3C trace context to SAP, record calling-agent identity (#641) An inbound traceparent is forwarded verbatim to SAP; ARC-1 never originates one (non-participating pass-through). Audit events record the calling agent, falling back to User-Agent because stateless HTTP makes the MCP client version unavailable. none
Publish a CycloneDX npm SBOM with releases (#633) Each release gets a best-effort, non-gating arc-1-<version>-sbom.cdx.json asset describing the production npm dependency graph only — not the Docker image, the .mcpb, or dynamically loaded extensions. none — verification recipe in the Security Guide
Allow jwt-bearer exchange against ARC-1's XSUAA client (#605) A BTP app (CAP service, Fiori app, assistant backend) can call /mcp as its own logged-in users via an OAuth2JWTBearer destination or a direct token exchange. client_credentials and password stay off the allowlist; identity propagates, authorization does not widen. needs an XSUAA update: cf update-service arc1-mcp-xsuaa -c xs-security.json (or MTA redeploy); existing bindings inherit without rebinding — XSUAA Setup
Omit adtcore:responsible when it cannot be an on-prem user name (#638) Under BTP principal propagation to an on-prem system the identity is an email, which overflows XUBNAME (CHAR12) — so every object create failed with HTTP 400. The attribute is now omitted when it is empty, over 12 chars, or contains @, and ADT assigns the correctly propagated logged-on user. DEVC is the one type that cannot omit it. none — fixes a total create outage in that configuration
Never block tools/list on startup feature discovery (#639) tools/list awaited the feature probe behind a 10s cap; Cline cancels at ~5s, so against a slow SAP system clients showed "Tools (0)" every time. It answers from cache immediately, and the unprobed surface is a strict superset of the probed one (standard mode previously dropped SAPGit and all 17 of its enum values before discovery finished). none
Propagate corrNr to the class-include init POST (#646) Creating a class's testclasses include on a transportable package failed with 500 … already locked in request <REQ>. The init POST was the only lock-scoped write that dropped the transport number. Reproduced identically on 7.50, 758 and 816 — it stayed hidden because the path was originally verified in $TMP, where the lock returns an empty CORRNR. none
Walk the AUnit result structure so alerts, program name and skips survive (#648) Run-level and class-level AUnit alerts (aborted runs, class_setup failures, "object cannot be tested") were silently dropped — the caller got an empty array and no error, so the reason was lost. They now surface as explicit failed rows. none
Reconcile recursive transport release with terminal SAP state (#613) SAP can return HTTP 200 with abortrelapifail after it has already committed a recursive parent release. ARC-1 reconciles that contradictory report against one fresh request read and reports success when the request has reached terminal status R. none
Reload a rotated cookie file before the 401 retry (#631) Re-running arc1-cli extract-cookies recovers the in-flight call instead of failing it and waiting for the next request. SAP_COOKIE_FILE only — SAP_COOKIE_STRING has no source to re-read. none
MCP 2026-07-28 forward-compatibility (#601) CORS preflight allows mcp-protocol-version and last-event-id, which every SDK client sends — browser-based MCP clients failed preflight without them. Adds era-contract regression tests and an ADR (stay on TS SDK v1 until defined triggers). Also deletes dead elicitation helpers that were never on any execution path and failed open; the opt-in plugin ctx.elicit path is unchanged. none
Improve DDLS view-extension lint and diagnostics (#627) abaplint recognizes EXTEND VIEW as a DDLS source instead of mis-detecting it, and SAP's DDLS006 "View Extend is not allowed in this system" gets a dedicated hint instead of a bare 400. none
Harden multi-target behavior (#628) Multi-target diagnostic actions fail closed rather than open, plus 1.0 contract alignment across ADR-0006/0007 and the multi-target docs. none
Don't crash startup on PP-off overrides (#582) SAP_PP_STRICT=true without SAP_PP_ENABLED=true warns instead of throwing — an mtaext cannot unset a base mta.yaml property, so the old hard throw bricked the deployment. Adds a startup warning for the mirror-image trap: strict PP plus ARC1_API_KEYS passes validation but rejects 100% of API-key traffic at runtime. none
Patch and monitor AppRouter dependencies (#625) The BTP AppRouter's own package.json is now patched and covered by Dependabot and CI, closing a gap where it sat outside the monitored dependency graph. none
Lead SAPWrite with its purpose; complete the TTYP documentation (#644) Tool-description wording only — reorders SAPWrite's description to lead with purpose and fills the TTYP gaps in the Tools Reference. none

Upgrade notes — checklist form in Updating → v1.0.

  • Cache warmup is removed. Delete ARC1_CACHE_WARMUP, ARC1_CACHE_WARMUP_PACKAGES, --cache-warmup and --cache-warmup-packages from your configuration before upgrading. ARC-1 deliberately refuses to start while any of them is present — including ARC1_CACHE_WARMUP=false — so stale deployment config is visible rather than silently ignored. The same guard covers SAP_BTP_DESTINATIONS from the removed multi-destination prototype. Existing SQLite cache files need no manual migration: the retired nodes/edges tables are dropped on first open, preserving sources, dependency graphs, released-API metadata, and function-group mappings.
  • Unknown tool parameters are now rejected. A client sending a parameter that is not in a tool's schema gets a validation error instead of a silently-stripped key and a wrong-but-successful result. Applies to the top-level tool schemas; batch_create item schemas stay lenient.
  • SAPTransport(list) returns headers-only by default. Object lists are omitted; pass summary=false to restore the previous full response.
  • XSUAA descriptor changed. For app-to-app principal propagation apply the new grant type with cf update-service arc1-mcp-xsuaa -c xs-security.json or an MTA redeploy. Existing bindings inherit it without rebinding; all existing login paths are unaffected.

New configuration

  • ARC1_SERVER_NAME / --server-name — server name advertised in the MCP handshake. Default arc-1.
  • ARC1_MULTI_TARGET_ENDPOINTS — enable experimental multi-target mode (BTP CF only). Default false.
  • ARC1_MULTI_TARGET_ALLOW_BASIC_AUTH — permit shared BasicAuthentication destinations in multi-target mode; never a PP fallback, and v1 requires exactly one CF instance. Default false.
  • SAP_OIDC_DISCOVERY — serve RFC 9728 protected-resource metadata in OIDC mode. Default true.
  • SAP_OIDC_SCOPES — IdP scope names advertised as scopes_supported (e.g. api://CLIENT_ID/access_as_user). Omitted when unset.
  • ARC1_MCP_HTTP_RATE_LIMIT — optional shared MCP HTTP per-IP override. Unset derives max(OAuth×30, 600); 0 disables.
  • Removed (now hard startup errors): ARC1_CACHE_WARMUP, ARC1_CACHE_WARMUP_PACKAGES, SAP_BTP_DESTINATIONS.

Tool-surface changes

  • SAPWrite action — new edit_unit (on-prem): replace one FORM or MODULE in a PROG/INCL.
  • SAPWrite — new unit (FORM/MODULE name), processingType (normal/rfc/update), updateTaskKind (startImmediate/immediateStartNoRestart/startDelayed).
  • SAPRead type / SAPWrite type — new DTDC (Dynamic Cache), DSFD (Scalar Function Definition), UIAD (Launchpad App Descriptor Item). UIAD writes are refused by SAP outside ABAP Cloud.
  • SAPDiagnose action — new atc_variants.
  • SAPActivate — new group parameter (parent FUGR for a FUNC or a structural INCL).
  • SAPNavigate, SAPContext, SAPTransport — new maxResults. SAPNavigate(references) also changes shape to {total, shown, truncated, hint, references}, and its existing objectType filter now actually filters.
  • SAPTransport(list)summary default flips to true (headers-only).
  • SAPRead type="FUNC" with includeSignature=true — response gains processingType and updateTaskKind, reported verbatim from SAP (may include values the create enum omits, e.g. collectiveRun).
  • SAPGit — remote-credential parameters for private repositories (user, password, token).
  • SAPTargets — new tool, aggregate route only (/multi/mcp) in multi-target mode; lists configured target IDs with role-sensitive detail.
  • All JSON tool results are emitted compact (no pretty-print indentation). Audit previews and CLI rendering are unaffected.
  • The MCP server returns instructions in the initialize response (~1 KB).

0.9 line — from ADT tool surface to deployable managed service (2026-05-08 → 2026-07-13)

The 0.9 line opened by cleaning up the object-type vocabulary (0.9.0 purged invented ADT aliases and collapsed STRU into TABL) and closed as a hardened, multi-deployment product. Three capability areas grew: write depth (FUGR/FUNC CRUD, class-section and method surgery, server-driven objects, TTYP, RAP behavior extensions, class text symbols), diagnostics (ATC variants, unit-test coverage, OData sap-statistics probes, CDS Show-SQL, ST05 trace control, authorization traces), and deployment reach (BTP ABAP Environment object and package create, S/4HANA Public Cloud, XSUAA auth extracted to @arc-mcp/xsuaa-auth, MCPB/Claude Code one-click install, a plugin framework, a read-only UI console). What stabilized was the safety perimeter: a 10-PR security batch in 0.9.21 made HTTP auth mandatory and principal propagation fail-closed, and 0.9.15/0.9.26 flipped several defaults from fail-open to fail-closed. Most releases need no operator action; the ones that do are 0.9.21 (HTTP auth), 0.9.26 (cache + error defaults) and 0.9.0 (removed type names).

0.9.27 (2026-07-13)

Release-plumbing fix only — no runtime change (#568 pinned release npm to 11.x so npm ci can build better-sqlite3).

0.9.26 (2026-07-13)

One new diagnostic plus three default changes an existing deployment will notice.

  • SAPDiagnose action=authorization_trace (#560) — reads SAP's authorization-check trace (on-prem SUAUTHVALTRC, TOBJ-decoded) so a missing S_DEVELOP/S_ADT_RES right can be diagnosed without SU53. Action: opt-in — needs SAP_ALLOW_DATA_PREVIEW=true and a data-scoped profile.
  • HTTP transport defaults to minimal client-facing errors (#552) — ARC1_MINIMAL_ERRORS defaults to true on http-streamable (stdio stays false). SAP diagnostic detail is stripped from tool errors; operators still get it via audit correlation. Action: set ARC1_MINIMAL_ERRORS=false only for trusted debugging.
  • The SQLite source cache is now explicit opt-in (#557) — ARC1_CACHE=auto previously selected SQLite on HTTP transport; it now always means memory, and SQLite logs a plaintext-source-at-rest warning. Action: set ARC1_CACHE=sqlite explicitly if your deployment relied on a cache surviving restarts.
  • Principal-propagation identity boundaries hardened (d458c66) — preserves per-user isolation and verifies API-key provenance against configured secrets. Action: none.
  • change_package object-type matching hardened (#556); SAPQuery Open SQL guidance and accurate dialect errors (#559); Windows OAuth browser launch via rundll32 (#555) so & in the authorize URL is no longer eaten by the shell. Action: none.

0.9.25 (2026-07-02)

Class text-pool editing, and a fix for recurring BTP invalid_client logouts.

  • Read and write class text symbols (#541) — SAPRead include=text_symbols and SAPWrite action=edit_text_symbols via the ADT textelements service. Writes are immediately active (no SAPActivate), on-prem only and discovery-gated, with their own policy row so SAP_DENY_ACTIONS=SAPWrite.edit_text_symbols works. Action: none beyond the usual write scope.
  • DCR client_id TTL defaults to never-expire (#540) — ARC1_OAUTH_DCR_TTL_SECONDS defaults to 0; positive values still opt into expiry (clamped 60s–90d). A finite TTL bought no security (client_ids are stateless HMAC tokens with no per-client revocation) but caused periodic invalid_client outages in VS Code/Copilot/Eclipse. Action: set a stable ARC1_DCR_SIGNING_SECRET on BTP so cf deploy stops invalidating cached client_ids.

0.9.24 (2026-06-30)

Two papercuts, both in how ARC-1 is consumed.

  • add_method auto-appends a missing terminating period (#539) — an unterminated METHODS clause used to swallow the following source lines and surface as an opaque SAP 400. Action: none.
  • The MCPB bundle ships unsigned (#537) — the self-signed signature block appended after the ZIP end-of-central-directory made strict third-party MCPB/DXT hosts reject the file. Action: re-download the .mcpb if a host refused the previous one.

0.9.23 (2026-06-29)

BTP ABAP Environment (Steampunk) becomes writable end-to-end.

  • Cloud-correct object create on BTP (#522) — in cloud mode the create XML drops adtcore:masterSystem/responsible (the JWT owns them) and adds abapLanguageVersion="cloudDevelopment". On-prem bodies are byte-for-byte unchanged. Live-verified create→activate→read→delete on SAP_BASIS 919. Action: none; note $TMP and the ZLOCAL structure package cannot host objects — target a regular cloud sub-package.
  • SAPManage create_package works on BTP (#534) — nests under a structure superPackage, defaults software component ZLOCAL, and passes the internal ABAP user as responsible (SAP rejects the IAS email). The internal user is auto-resolved from the createdBy of a prior cloud create. Action: none.
  • Labels on source diffs (#528) — SAPRead action=diff gains optional fromLabel/toLabel. Action: none.
  • Just-activated source served on the next read (#530) — on BTP/919 a read right after SAPActivate re-cached the still-lagging pre-activation source plus a sticky "unactivated draft" note until force_refresh. Backend eventual consistency, not a cache-invalidation miss; on-prem never reproduced it. Action: none.

0.9.22 (2026-06-26)

S/4HANA Public Cloud lands; one schema default reverts to the portable form.

  • S/4HANA Public Cloud support (#524, external contribution) — a per-user samlAuthorization path sends a SAMLAssertion from the BTP Destination Service verbatim as Authorization plus x-sap-security-session: create (mirrors the SAP Cloud SDK). Set only per-user, never from shared credentials. Action: none — see S/4HANA Public Cloud.
  • Nullable SAPWrite schemas are now opt-in (#526) — new ARC1_SCHEMA_NULLABLE_OPTIONALS (auto|off|on, default auto). auto/off emit portable plain JSON Schemas; on emits null unions for OpenAI/Azure strict mode. Action: set on only for a tested OpenAI/Azure strict-mode client.
  • DDIC structure context (#515) — new SAPContext.structure action (read scope) walking a structure hierarchy. Action: none.
  • odata_perf reports client wait (#521) — adds clientWaitMs (wall clock − Gateway total) so network/proxy/queue overhead is no longer misread as SAP server time. Action: none.

0.9.21 (2026-06-25)

The largest release of the line: a 10-PR security-hardening batch alongside a wave of diagnostics and DDIC features. Read the HTTP-auth note.

  • HTTP transport refuses to boot without ARC-1 auth (#487) — breaking for unauthenticated HTTP deployments. http-streamable now requires ARC1_API_KEYS, OIDC issuer/audience, or SAP_XSUAA_AUTH=true. New ARC1_ALLOW_HTTP_NO_AUTH (default false) is the explicit local/dev-only escape hatch. Action: configure auth, or set ARC1_ALLOW_HTTP_NO_AUTH=true for local dev.
  • Principal propagation fails closed (#488) — a PP resolution error no longer silently degrades to shared credentials. Action: none, but verify PP deployments still start.
  • Quickfix application gated as a write (#489) — SAPDiagnose.apply_quickfix was mapped to read. Action: read-only profiles lose it; grant write if they need it.
  • Package allowlist enforced on gCTS mutations (#490); audit events redacted before sink writes (#493); audit and cache files created with private permissions (#496); insecure-TLS warning + trace-path encoding (#494); deployment descriptors default to verified SAP TLS (#491). Action: none.
  • Minimal client-facing SAP errors (#495) — ARC1_MINIMAL_ERRORS introduced here (default false; the HTTP default flips to true in 0.9.26). Action: opt-in for untrusted clients.
  • TTYP (table type) read and create (#504); SAPManage set_api_state (#506) writing an object's API release contract (C0–C4, default C1) for clean-core work; RAP behavior extensions (#507) — create detects extend behavior for X and the base BDEF must be extensible; write FUGR structural include source (#505). Action: none.
  • Diagnostics wave — ABAP Unit coverage on SAPDiagnose unittest (#503); odata_perf + cds_sql Show-SQL + an ICF-inactive guard (#509); ST05 sql_trace_state / set_sql_trace_state / sql_trace_directory (#510) — set_sql_trace_state is a write and flips all instances; ABAP profiler trace_start / trace_requests / trace_cancel (#508); odata_perf verdict wording (#513). Action: odata_perf needs data scope + SAP_ALLOW_DATA_PREVIEW.
  • Transport release pre-check (#501) — release/release_recursive fail fast when the request still holds inactive objects, which otherwise hang SAP's release pipeline as an opaque timeout; the release-check report is now surfaced (#514). Action: activate before releasing.
  • Self-correcting "unknown column" hint (#502); CLI sql/search shortcuts send correct arg shapes (#512); UI5 BSP filestore probed via /objects (#498). Action: none.

0.9.20 (2026-06-22)

Extensibility and observability, both default-off.

  • Read-only UI console (#485) — experimental, admin-auth-protected. New ARC1_UI (off|local|web, default off), ARC1_UI_ADDR, ARC1_UI_OPEN. Action: opt-in ARC1_UI=local.
  • Gated non-ADT writes from plugins (#474) — new SAP_ALLOW_PLUGIN_RAW_WRITES (default false) lets plugin tools POST/PUT/DELETE to OData/ICF paths. Also needs SAP_ALLOW_WRITES and a write-scoped tool; ADT writes are always refused, and SAP_ALLOWED_PACKAGES does not constrain raw writes. Action: opt-in only for audited plugins.
  • Context-first KTD workflow (#486) — Knowledge Transfer Documents readable/writable with guarded writes; KTD is an alias normalized to canonical SKTD. Action: none.
  • Regex backtracking removed from ADT error parsing (#476) — ReDoS hardening. Action: none.

0.9.19 (2026-06-18)

Auth code moves out of the repo; plugins arrive.

  • XSUAA/OAuth and BTP principal propagation via @arc-mcp/xsuaa-auth (#456, hardened in #468) — new runtime dependency; OIDC validation hardened and API-key comparison made constant-time. Action: none; DCR revocation is still "rotate ARC1_DCR_SIGNING_SECRET".
  • Extension framework for Custom_* plugin tools (#454) — new ARC1_PLUGINS (CSV of absolute local .js/.json paths, not npm names) and SAP_ALLOW_PLUGIN_EXECUTE (default false). Follow-up #467 closed two policy-boundary gaps found in post-merge review. Action: opt-in — see Extensions.
  • Non-3-digit SAP_CLIENT rejected at startup (#471) — breaking for misconfigured deployments: SAP_CLIENT=10 used to authenticate against the wrong client and surface as an unexplained 401. Empty stays valid. Action: pad to three digits (010, not 10).
  • Repo moved to the arc-mcp org, docs to docs.arc-1-mcp.com (#459). Action: none.

0.9.18 (2026-06-16)

Two read-side conveniences for review workflows.

  • SAPRead action="diff" (#445) — server-side version diff within one system. Action: none.
  • SAPTransport list summary=true (#448) — headers-only mode, much cheaper for transport-backlog sweeps (it becomes the default in 1.0.0). Action: none.
  • Quieter startup (#444) — expected feature-probe failures no longer log as noise. Action: none.

0.9.17 (2026-06-15)

  • SAPTransport remove_object (#432) — removes one object from a request; transports scope, feature-gated. Action: none.
  • Null-body statuses on the Cloud Connector proxy path (#440) — 304/204/205 are handled instead of erroring, so conditional GETs work through the proxy. Action: none.
  • Cross-subaccount OAuth2UserTokenExchange guidance (#436) — the failure is a signing-key mismatch, not an ARC-1 bug; deploy in the same subaccount as the BTP ABAP environment. Action: none.

0.9.16 (2026-06-12)

Single fix — class test-include surgery initializes the include before splicing (#429), completing the 0.9.15 work. Action: none.

0.9.15 (2026-06-12)

Install experience, a fail-closed config change, and the handler refactor.

  • One-step "Install in Claude" (#425) — the repo root is a Claude Code plugin marketplace (server + skills), the .mcpb Claude Desktop bundle is built and attached to each GitHub Release, and tools carry MCP annotations. Action: none — see Install in Claude.
  • Empty env values fall back to defaults (#427) — security-relevant fail-open fix. SAP_ALLOWED_PACKAGES="" previously parsed to [], which the safety layer read as all packages allowed; SAP_CLIENT=""/SAP_LANGUAGE="" silently overrode the 100/EN defaults. Empty now means "not provided"; unrestricted packages stays an explicit *. Exposed by the new install dialogs, where a user can clear a pre-filled field. Action: re-check any deployment that intentionally passed empty strings.
  • maxResults accepted then clamped at the sinks (#423); SRVB publish/unpublish content negotiation 758-proof (#403); SAPContext dependency convoy avoided (#411); Docker OpenSSL CVE patched, release CVE gate hardened (#400). Action: none.
  • Internal: intent.ts split into per-tool handler modules (#402, #405) with the LLM-visible tool-definition fixtures held byte-identical. Action: none.

0.9.14 (2026-06-11)

Four safety fixes, no new surface.

  • SRVB package gate enforced (#394) — service-binding writes honour SAP_ALLOWED_PACKAGES. Action: none.
  • PP cache state isolated (#393) — including inactive-list cache keys, so one user's drafts can't leak into another's reads. Action: none.
  • SAPRead grep regex handling hardened (#392) — ReDoS class. Action: none.
  • MSAG payloads emit adtcore:language + masterLanguage (#397). Action: none.

0.9.13 (2026-06-09)

Four hardening fixes from the June security audit.

  • Unbounded result limits clamped (#388) — maxRows, maxResults and maxDeps were used without an upper bound, so one call could buffer a huge result set and amplify SAP load. Clamped gracefully at the sinks, never errors. Action: none.
  • Package allowlist enforced on abapGit pull/push (#389). Action: none.
  • OAuth redirect-uri allowlist matched on parsed URL components (#387) — string-prefix matching was bypassable. Action: none.
  • Transport delete works when the request holds locked objects (#386). Action: none.

0.9.12 (2026-06-09)

Server-driven objects arrive; three security fixes ship with them.

  • Server-driven object read and write (#356, #362) — DESD, EVTB, DTSC, CSNM, EVTO, COTA via a generic AFF-backed engine, with create/update/delete plus activation. Action: none.
  • SAPDiagnose action=cds_testcases (#351) — CDS test-case scaffolding, read-only, discovery-gated (8.16+). Action: none.
  • Scope-router privilege escalation closed (#352) — the SAPRead scope key came from the raw args.type, so type: ["TABLE_CONTENTS"] or type: "table_contents" fell through to the base read scope and was then normalized into the data-scoped handler. The key now comes from the same normalized object the handler dispatches on, which also aligns SAP_DENY_ACTIONS matching. Action: calls that relied on the lowercase/array form bypassing a scope check now correctly require data.
  • allowedPackages ceiling enforced on activation and change_package (#357); XSUAA redirect-uri allowlist for the shared default client (#358). Action: none.
  • Tool-arg validation hardened against LLM schema pollution (#363) — z.coerce.boolean() mapped "false"/"0"/"no" to true, live-proven to corrupt DDIC (a domain created with signExists="false" persisted as true). Every optional boolean moved to a tolerant parser. Action: none — this silently fixes data corruption for OpenAI-family clients.
  • XSUAA refresh-token validity raised to 30 days (#383) — the shipped descriptor used 12h, so sessions died overnight and clients that don't aggressively re-auth hit invalid_token the next morning. Action: re-apply the descriptor: cf update-service <xsuaa-instance> -c xs-security.json && cf restage <app>.
  • Transportable package creation on SAP_BASIS 816 (#375); logon user threaded into adtcore:responsible (#380). Action: none.

0.9.11 (2026-06-05)

ABAP Platform 2025 (SAP_BASIS 816) compatibility.

  • Parse errors beyond abaplint's grammar no longer block writes (#350) — on 8xx releases, syntax abaplint cannot yet parse is demoted from blocking error to warning. Action: none.
  • Probe CLI repaired and validated against 816 (#347). Action: none.

0.9.10 (2026-06-05)

Single fix — the withSafety() clone copies the TABL write-URL cache (#335), so a safety-scoped client doesn't lose resolved write URLs. Action: none.

0.9.9 (2026-06-04)

Function groups and transports get real.

  • Recursive FUGR include expansion (#341) — SAPRead(type=FUGR, expand_includes) finally captures function-module code, which lives in nested LZ…U01 includes. Non-expanded FUGR reads return the real function-module list (#342). Action: none.
  • Explicit transport target on SAPTransport create (#339) — discovery-gated (present on 7.58, absent on 7.50). Action: none.
  • ATC check variant bound at worklist creation (#336) — SAPDiagnose(atc) previously returned no findings because the variant was bound too late. Action: none.
  • Created objects derive master language from SAP_LANGUAGE (#344) — behavior change: SAP_LANGUAGE is now both the request language and the master language of created objects. Action: none, unless you relied on objects always being created as EN while requesting another language.
  • XSUAA OAuth errors surfaced on /oauth/callback (#327); express-rate-limit 8.5.2, IPv6 keyed by /56 subnet (#330). Action: none.

0.9.8 (2026-06-01)

Single fix — a callback proxy for XSUAA OAuth state, resolving "State does not match" from VS Code (#325). Action: none.

0.9.7 (2026-05-30)

Surgical editing and targeted reads.

  • Class-section surgery for CLAS (#307) — edit a class section with a client-side refuse-diff before the PUT. Action: none.
  • SAPRead grep (#316) — regex search within one object's source instead of pulling the whole body. Cannot be combined with method. Action: none.
  • TABLE_QUERY read type (#309) — multi-column structured queries. Action: needs the data scope.
  • Class-local includes auto-initialised on write (#314). Action: none.
  • allowedPackages X/** subtree rule (#284) — ZFOO/** matches ZFOO and every transitive sub-package per the real package hierarchy, instead of forcing admins to over-allow with ZFOO*. Action: opt-in — switch SAP_ALLOWED_PACKAGES=ZFOO* to ZFOO/** for hierarchy-accurate scoping.
  • Per-user OAuth2UserTokenExchange bearer token for headless BTP→ABAP (#315); Cookie header deduped so the live session id wins over a stale file copy (#310); mixed-case object names rejected on update/edit_method/delete (#311); release-aware 423 lock-handle guidance (#312). Action: none.

0.9.6 (2026-05-27)

Rate limiting and DDIC routing corrections.

  • Layered rate limiting (#276) — new ARC1_AUTH_RATE_LIMIT (per-IP OAuth cap, default 20/min) and ARC1_RATE_LIMIT (per-user MCP tool-call cap, default 0 = off, because it is the only layer that can fail legitimate user work). The server-wide ARC1_MAX_CONCURRENT semaphore is now shared correctly across per-user clients. Action: opt-in ARC1_RATE_LIMIT for multi-user deployments — see Rate Limiting.
  • TABL/DT writes refused on NW 7.50/7.51 with an SE11 hint (#286); TABL/DS create routed to /ddic/structures (#302); pre-write hint for the canonical %admin draft include (#271). Action: none.

0.9.5 (2026-05-11)

  • SAPSearch tadir_lookup source modes and batch_create activateAtEnd (#270) — activateAtEnd batches interdependent objects into one activator pass. Action: the db/both lookup sources need the sql scope.
  • Stable DCR signing key (#267) — new ARC1_DCR_SIGNING_SECRET so a cf deploy (which rotates the XSUAA client secret) stops invalidating cached client_ids. Action: set it on BTP.
  • RAP handler skeletons written to CCIMP, not CCDEF (#263) — generated code landed in the wrong include. Action: none.

0.9.4 (2026-05-10)

Method-level editing and RAP scaffolding.

  • edit_method splices into class-local includes (CCDEF/CCIMP) (#261) and class include writes + RAP skeletons (#257). Action: none.
  • SAPWrite generate_behavior_implementation (#260) — generates the behavior pool from a BDEF. Action: none.
  • FUNC structured parameters (#259) — typed importing/exporting/changing/tables instead of raw source. Action: none.
  • TADIR lookup and batch package overrides (#256) — SAPSearch searchType="tadir_lookup" with a names array for exact cross-package resolution; prefer it over long SAPQuery IN-lists. Action: none.
  • SAPDiagnose action=object_state (#254) — compares active vs inactive source per object (ETags, byte lengths, hashes, divergence flags, all class includes) without returning full source; diagnoses activation failures. Action: none.
  • ED064 activation retry and a lint release override (#255) — new SAP_ABAP_RELEASE; a pure-ED064 batch is retried once as singles, mixed real errors are not. Action: opt-in only if the release probe is wrong for your system.

0.9.3 (2026-05-09)

  • FUGR and FUNC create/update/delete (#251) — function groups and modules become writable; SAPGUI signature comment blocks are auto-stripped. Action: none.
  • BTP CF deploy hardened, Viewer+SQL XSUAA role collection added (#246). Action: re-apply xs-security.json to pick up the new role collection.

0.9.2 (2026-05-08)

Release-plumbing only — a re-triggered release after a chore merge. No runtime change (#244).

0.9.1 (2026-05-08)

Three small corrections.

  • DEVC listing descriptions aligned with object names (#242) and XML entities decoded in search-result descriptions (#243). Action: none.
  • npm CLI dropped from the Docker runtime image (#240) — smaller attack surface. Action: none, unless you shell into the container expecting npm.

0.9.0 (2026-05-08)

Breaking. The object-type vocabulary was audited against live ADT responses and the invented entries removed.

  • Invented ADT slash aliases purged (#223) — FUNC/FM, CLAS/LI, VIEW/V and TRAN/O never appear in real ADT output and now fail validation; FUGR/FF was repointed from FUGR to FUNC (it is a function module). Action: migrate to FUGR/FF, VIEW/DV, TRAN/T, or the canonical short forms.
  • STRU collapsed into TABL (#219) — use TABL for both transparent tables and DDIC structures. The slash form STRU/DS survives as a back-compat alias. Action: replace type='STRU' with type='TABL'.
  • FTG2 renamed to FEATURE_TOGGLE, MSAG added to the read enum (#224) — FTG2 was ARC-1-invented with zero hits in SAP's own metadata; the read enum used MESSAGES while writes used canonical MSAG. Both old names still route with a deprecation warning for one minor release. Action: switch to FEATURE_TOGGLE and MSAG.
  • Cookie hot-reload on a stale 401 (#200); layered lock-conflict detection + MSAG transport guard (#202); three-file schema sync and universal write guards (#201); SAPTransport.create works on NW 7.50 (#228); HTML entity decoder tightened (#238). Action: none.

0.1 – 0.8 — early history (2026-03-31 → 2026-05-06)

ARC-1 began as a TypeScript rewrite of the Go-based oisee/vibing-steampunk (migration completed 2026-03-26), and 0.1.1 was the first npm/Docker release: 11 intent tools, on-prem ADT over Basic auth, read/write/activate, and the first safety flags. 0.2–0.3 added E2E infrastructure and direct BTP ABAP Environment connectivity via OAuth 2.0. 0.4 was the first large capability jump — DDIC completeness, object caching, method-level surgery, hyperfocused mode, runtime diagnostics, abaplint presets — and 0.5 introduced the two-dimensional authorization model (per-user scopes under a server safety ceiling) plus Zod runtime validation. 0.6 was the workhorse line (eleven releases in twelve days): BTP Cloud Foundry deployment, most DDIC/RAP write types, package and FLP management, ATC quickfixes, and finally SAPGit in 0.6.10 — completing today's 12-tool surface. 0.7 rewrote authorization around a single ACTION_POLICY matrix with positive opt-in flags (breaking — see below), and 0.8.0 hardened the HTTP/OAuth edge so DCR client registrations survive container restarts.

0.8 (2026-05-06)

  • Breaking: OAuth Dynamic Client Registration moved from an in-memory Map to a stateless, HMAC-signed client_id store, so registrations survive cf push/restart/cell moves and work across scaled-out instances (#212). Cost: no per-client revocation (TTL or secret rotation only), and the loose redirect-URI encoding match was dropped.
  • HTTP security headers via helmet + opt-in CORS (ARC1_ALLOWED_ORIGINS) for browser MCP clients (#215).
  • ARC1_PUBLIC_URL for reverse-proxy deployments, so advertised OAuth metadata URLs are correct (#216).

0.7 (2026-04-26 → 2026-04-28)

  • Breaking: authorization refactor (#181) — full details in the block at the end of this page.
  • RAP on-prem authoring gaps closed with preflight + handler scaffolding (#173); CDS CRUD dependency guidance for DDLS workflows (#176); sibling DDLS/DDLX coverage-mismatch detection in SAPContext (#177).
  • 0.7.1 was a hotfix restoring npx execution (#189) — 0.7.0 could not be run via npx.
  • 0.7.2 added the ETag-validated source cache and the active/inactive version parameter on SAPRead (#186).

0.6 (2026-04-08 → 2026-04-20)

  • Breaking (0.6.0): write safety simplified — allowedPackages now defaults to $TMP and is actually enforced (checkPackage() existed but was never called), and allowTransportableEdits was removed (#56).
  • 0.6.2 was the largest release of the line: BTP Cloud Foundry deployment with SAP Cloud SDK + MTA (#97), the safe-by-default posture — read-only, no SQL, no data preview (#89) — and write support for DOMA/DTEL, TABL, MSAG, SRVB, plus DEVC package create/delete, FLP management, and transport delete/reassign/recursive-release.
  • Robustness batch across 0.6.5–0.6.9: ATC quickfix proposals (#123), object-type auto-normalization (#122), proactive ADT discovery MIME negotiation (#127), SAP-domain error hints (#128), concurrency limiter + 503 retry (#132), SKTD documents (#134), CDS impact analysis (#143), PrettyPrint (#145), revision history (#144).
  • 0.6.10 added SAPGit (gCTS + abapGit) — the 12th tool, completing today's tool set — plus the ADT type-availability probe (#159, #163).

0.5 (2026-04-08)

  • Breaking: SAPQuery moved from read to the new data scope, and SAPTransport from admin down to write (developers need transports).
  • Two-dimensional authorization model (#48): server safety ceiling × per-user JWT scopes, implied scopes (write→read, sql→data), and six named profile presets. All of it superseded by 0.7.0.
  • Zod v4 runtime input validation for every MCP tool (#52); OAuth review per RFC 9700 (#51).

0.4 (2026-04-07)

  • The first big feature batch: DDIC completeness — structures, domains, data elements, transactions (#21); DDLX/SRVB reads + batch activation (#22); method-level surgery and hyperfocused mode (#23); runtime diagnostics — short dumps and ABAP traces — in SAPDiagnose (#24).
  • Object caching (#31), scope-based where-used for SAPNavigate (#38), system-aware abaplint presets with pre-write validation (#37), and the LLM eval harness (#33).
  • 0.4.1–0.4.4 contained no product changes — release-pipeline fixes only (npm self-upgrade bug on Node 22.22.x, then three attempts at the arm64 Docker build, ending with native arm64 runners instead of QEMU).

0.3 (2026-04-01)

  • Direct BTP ABAP Environment connectivity via OAuth 2.0 (#18) — the first non-on-prem target.

0.2 (2026-03-31)

  • E2E testing infrastructure, XML error cleanup, CI hardening (#13); tool improvements driven by real LLM feedback (#14); Docker image name corrected to arc-1.

0.1 (2026-03-31)

  • 0.1.1 is the initial release, ported from oisee/vibing-steampunk. It already shipped 11 intent tools (SAPGit arrived in 0.6.10), read-only mode, package allowlisting, transport controls, and the HTTP Streamable transport.
  • 0.1.2–0.1.4 are publishing plumbing only: npm OIDC trusted publishing, npm 11.5+ for OIDC support, and the repository field for provenance verification.

Every release in this range

Version Date Summary
0.8.0 2026-05-06 Breaking: stateless HMAC-signed OAuth DCR store; helmet security headers + opt-in CORS; ARC1_PUBLIC_URL
0.7.2 2026-04-28 ETag-validated source cache + active/inactive version on SAPRead; HANA detection via S4CORE/HDB
0.7.1 2026-04-27 Hotfix: restore npx arc-1 execution
0.7.0 2026-04-26 Breaking: authorization refactor (ACTION_POLICY, positive opt-in flags, transports/git scopes); RAP preflight + scaffolding
0.6.10 2026-04-20 SAPGit (gCTS + abapGit) — 12th tool; ADT type-availability probe; NW 7.50 suites green
0.6.9 2026-04-17 CDS impact analysis; PrettyPrint; revision history; transport history; AUTH/FTG2/ENHO reads; cookie→PP leak fix
0.6.8 2026-04-16 change_package object moves; SKTD (knowledge transfer documents); 503 + CSRF retry
0.6.7 2026-04-15 DCLS read/write; ADT discovery MIME negotiation; SAP error-intelligence hints; concurrency limiter
0.6.6 2026-04-14 CI only: wait for Docker image before MCP Registry publish
0.6.5 2026-04-14 ATC quickfix proposals; object-type auto-normalization; CDS/DDLS abaplint; CF buildpack + BTP write fixes
0.6.4 2026-04-14 CI only: MCP Registry OCI annotation in Dockerfile
0.6.3 2026-04-14 CI only: mcpName for MCP Registry publishing
0.6.2 2026-04-14 BTP Cloud Foundry deployment (Cloud SDK + MTA); safe-by-default; DOMA/DTEL/TABL/MSAG/SRVB writes; DEVC + FLP management; transport enhancements
0.6.1 2026-04-10 API release state (clean core); BSP/UI5 filestore types; class hierarchy in SAPNavigate; CTS media types + 406/415 retry
0.6.0 2026-04-08 Breaking: allowedPackages defaults to $TMP and is enforced; allowTransportableEdits removed
0.5.0 2026-04-08 Breaking: SAPQuerydata scope, SAPTransportwrite; two-dimensional authz model; Zod v4 validation
0.4.4 2026-04-07 CI only: native arm64 runners instead of QEMU
0.4.3 2026-04-07 CI only: separate deps stage to avoid QEMU arm64 crash
0.4.2 2026-04-07 CI only: avoid QEMU emulation crash in arm64 Docker build
0.4.1 2026-04-07 CI only: npm self-upgrade fix in release workflow (Node 22.22.x bug)
0.4.0 2026-04-07 DDIC completeness; DDLX/SRVB reads + batch activation; method-level surgery + hyperfocused mode; caching; runtime diagnostics; where-used; abaplint presets
0.3.0 2026-04-01 Direct BTP ABAP Environment connectivity via OAuth 2.0
0.2.0 2026-03-31 E2E test infrastructure, XML error cleanup, CI hardening; LLM-feedback tool improvements
0.1.4 2026-03-31 Publishing: repository field for npm OIDC provenance
0.1.3 2026-03-31 Publishing: npm 11.5+ for OIDC trusted publishing
0.1.2 2026-03-31 Publishing: npm OIDC trusted publishing; docs navigation reorganized
0.1.1 2026-03-31 Initial release — 11 intent tools, ported from oisee/vibing-steampunk

Breaking change: 0.7.0 authorization refactor

The authorization layer was rewritten around a single ACTION_POLICY matrix as the source of truth for (tool, action) → (scope, opType). Old configuration does not degrade gracefully — the server aborts at startup with a migration error naming each legacy variable.

Removed (startup aborts if set)

  • Env vars: SAP_READ_ONLY, SAP_BLOCK_DATA, SAP_BLOCK_FREE_SQL, SAP_ENABLE_TRANSPORTS, SAP_ENABLE_GIT, SAP_ALLOWED_OPS, SAP_DISALLOWED_OPS, ARC1_PROFILE, ARC1_API_KEY (single-key mode).
  • The matching CLI flags (--read-only, --block-data, --block-free-sql, --enable-transports, --enable-git, --allowed-ops, --disallowed-ops, --profile, --api-key) and the server-side profile system.

Added

  • Positive opt-in flags, all defaulting to restrictive: SAP_ALLOW_WRITES, SAP_ALLOW_DATA_PREVIEW, SAP_ALLOW_FREE_SQL, SAP_ALLOW_TRANSPORT_WRITES, SAP_ALLOW_GIT_WRITES, plus SAP_DENY_ACTIONS (Tool, Tool.action, Tool.glob*; fail-fast at startup on an invalid pattern).
  • Two new scopes, transports and git; admin now implies all seven scopes (previously admin alone yielded the most restrictive safety). New API-key profile admin alongside viewer/viewer-data/viewer-sql/developer/developer-data/developer-sql.
  • Observability: the effective safety: … startup line with per-field source attribution, contradiction warnings, arc1 config show, and a CI policy validator.

Behavior changes that can surprise you

  • SAP_ALLOW_WRITES=false now truly blocks every mutation, including activation, transport writes and Git writes — the old readOnly did not gate checkTransport/checkGit (a silent security gap).
  • Transport and Git reads are always available; only writes need the extra opt-in. SAPTransport.check/.history dropped from write to read, SAPManage.flp_list_* dropped to read, and SAPLint.set_formatter_settings was promoted to write (it performs an update).

Migration

Map each removed variable — SAP_READ_ONLYSAP_ALLOW_WRITES, SAP_BLOCK_DATASAP_ALLOW_DATA_PREVIEW, SAP_BLOCK_FREE_SQLSAP_ALLOW_FREE_SQL (all three inverted), SAP_ENABLE_TRANSPORTSSAP_ALLOW_TRANSPORT_WRITES, SAP_ENABLE_GITSAP_ALLOW_GIT_WRITES — replace ARC1_API_KEY with ARC1_API_KEYS="key:profile", and replace the op-code lists with SAP_DENY_ACTIONS. On BTP, cf update-service arc1-xsuaa -c xs-security.json and a full MTA deploy (the service update alone does not create role collections). Step-by-step, including the BTP role-collection checks: Updating → v0.7 Authorization Refactor.

How these notes are maintained

CHANGELOG.md stays fully machine-generated; all context lives here. New releases are annotated with the repo's /release-notes command (.claude/commands/release-notes.md), preferably while the release-please PR is still open so the notes land before the release does. tests/unit/server/release-notes.test.ts fails CI while any released version is missing from this page, and the release workflow appends a link to this page to every GitHub Release.