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.
nonefor 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.1–0.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-warmupand--cache-warmup-packagesfrom your configuration before upgrading. ARC-1 deliberately refuses to start while any of them is present — includingARC1_CACHE_WARMUP=false— so stale deployment config is visible rather than silently ignored. The same guard coversSAP_BTP_DESTINATIONSfrom the removed multi-destination prototype. Existing SQLite cache files need no manual migration: the retirednodes/edgestables 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_createitem schemas stay lenient. SAPTransport(list)returns headers-only by default. Object lists are omitted; passsummary=falseto 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.jsonor 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. Defaultarc-1.ARC1_MULTI_TARGET_ENDPOINTS— enable experimental multi-target mode (BTP CF only). Defaultfalse.ARC1_MULTI_TARGET_ALLOW_BASIC_AUTH— permit sharedBasicAuthenticationdestinations in multi-target mode; never a PP fallback, and v1 requires exactly one CF instance. Defaultfalse.SAP_OIDC_DISCOVERY— serve RFC 9728 protected-resource metadata in OIDC mode. Defaulttrue.SAP_OIDC_SCOPES— IdP scope names advertised asscopes_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 derivesmax(OAuth×30, 600);0disables.- Removed (now hard startup errors):
ARC1_CACHE_WARMUP,ARC1_CACHE_WARMUP_PACKAGES,SAP_BTP_DESTINATIONS.
Tool-surface changes
SAPWrite action— newedit_unit(on-prem): replace oneFORMorMODULEin aPROG/INCL.SAPWrite— newunit(FORM/MODULE name),processingType(normal/rfc/update),updateTaskKind(startImmediate/immediateStartNoRestart/startDelayed).SAPRead type/SAPWrite type— newDTDC(Dynamic Cache),DSFD(Scalar Function Definition),UIAD(Launchpad App Descriptor Item).UIADwrites are refused by SAP outside ABAP Cloud.SAPDiagnose action— newatc_variants.SAPActivate— newgroupparameter (parent FUGR for aFUNCor a structuralINCL).SAPNavigate,SAPContext,SAPTransport— newmaxResults.SAPNavigate(references)also changes shape to{total, shown, truncated, hint, references}, and its existingobjectTypefilter now actually filters.SAPTransport(list)—summarydefault flips totrue(headers-only).SAPRead type="FUNC"withincludeSignature=true— response gainsprocessingTypeandupdateTaskKind, 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
instructionsin 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-premSUAUTHVALTRC, TOBJ-decoded) so a missingS_DEVELOP/S_ADT_RESright can be diagnosed without SU53. Action: opt-in — needsSAP_ALLOW_DATA_PREVIEW=trueand adata-scoped profile.- HTTP transport defaults to minimal client-facing errors (#552) —
ARC1_MINIMAL_ERRORSdefaults to true onhttp-streamable(stdio stays false). SAP diagnostic detail is stripped from tool errors; operators still get it via audit correlation. Action: setARC1_MINIMAL_ERRORS=falseonly for trusted debugging. - The SQLite source cache is now explicit opt-in (#557) —
ARC1_CACHE=autopreviously selected SQLite on HTTP transport; it now always means memory, and SQLite logs a plaintext-source-at-rest warning. Action: setARC1_CACHE=sqliteexplicitly 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_packageobject-type matching hardened (#556); SAPQuery Open SQL guidance and accurate dialect errors (#559); Windows OAuth browser launch viarundll32(#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_symbolsandSAPWrite action=edit_text_symbolsvia the ADTtextelementsservice. Writes are immediately active (noSAPActivate), on-prem only and discovery-gated, with their own policy row soSAP_DENY_ACTIONS=SAPWrite.edit_text_symbolsworks. Action: none beyond the usualwritescope. - DCR client_id TTL defaults to never-expire (#540) —
ARC1_OAUTH_DCR_TTL_SECONDSdefaults to0; 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 periodicinvalid_clientoutages in VS Code/Copilot/Eclipse. Action: set a stableARC1_DCR_SIGNING_SECRETon BTP socf deploystops invalidating cached client_ids.
0.9.24 (2026-06-30)¶
Two papercuts, both in how ARC-1 is consumed.
add_methodauto-appends a missing terminating period (#539) — an unterminatedMETHODSclause 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
.mcpbif 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 addsabapLanguageVersion="cloudDevelopment". On-prem bodies are byte-for-byte unchanged. Live-verified create→activate→read→delete on SAP_BASIS 919. Action: none; note$TMPand theZLOCALstructure package cannot host objects — target a regular cloud sub-package. SAPManage create_packageworks on BTP (#534) — nests under a structuresuperPackage, defaults software componentZLOCAL, and passes the internal ABAP user as responsible (SAP rejects the IAS email). The internal user is auto-resolved from thecreatedByof a prior cloud create. Action: none.- Labels on source diffs (#528) —
SAPRead action=diffgains optionalfromLabel/toLabel. Action: none. - Just-activated source served on the next read (#530) — on BTP/919 a read right after
SAPActivatere-cached the still-lagging pre-activation source plus a sticky "unactivated draft" note untilforce_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
samlAuthorizationpath sends aSAMLAssertionfrom the BTP Destination Service verbatim asAuthorizationplusx-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
SAPWriteschemas are now opt-in (#526) — newARC1_SCHEMA_NULLABLE_OPTIONALS(auto|off|on, defaultauto).auto/offemit portable plain JSON Schemas;onemits null unions for OpenAI/Azure strict mode. Action: setononly for a tested OpenAI/Azure strict-mode client. - DDIC structure context (#515) — new
SAPContext.structureaction (readscope) walking a structure hierarchy. Action: none. odata_perfreports client wait (#521) — addsclientWaitMs(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-streamablenow requiresARC1_API_KEYS, OIDC issuer/audience, orSAP_XSUAA_AUTH=true. NewARC1_ALLOW_HTTP_NO_AUTH(default false) is the explicit local/dev-only escape hatch. Action: configure auth, or setARC1_ALLOW_HTTP_NO_AUTH=truefor 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_quickfixwas mapped toread. Action: read-only profiles lose it; grantwriteif 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_ERRORSintroduced 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 detectsextend behavior for Xand the base BDEF must beextensible; write FUGR structural include source (#505). Action: none. - Diagnostics wave — ABAP Unit coverage on
SAPDiagnose unittest(#503);odata_perf+cds_sqlShow-SQL + an ICF-inactive guard (#509); ST05sql_trace_state/set_sql_trace_state/sql_trace_directory(#510) —set_sql_trace_stateis awriteand flips all instances; ABAP profilertrace_start/trace_requests/trace_cancel(#508);odata_perfverdict wording (#513). Action:odata_perfneedsdatascope +SAP_ALLOW_DATA_PREVIEW. - Transport release pre-check (#501) —
release/release_recursivefail 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/searchshortcuts 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-inARC1_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 needsSAP_ALLOW_WRITESand a write-scoped tool; ADT writes are always refused, andSAP_ALLOWED_PACKAGESdoes not constrain raw writes. Action: opt-in only for audited plugins. - Context-first KTD workflow (#486) — Knowledge Transfer Documents readable/writable with guarded writes;
KTDis an alias normalized to canonicalSKTD. 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 "rotateARC1_DCR_SIGNING_SECRET". - Extension framework for
Custom_*plugin tools (#454) — newARC1_PLUGINS(CSV of absolute local.js/.jsonpaths, not npm names) andSAP_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_CLIENTrejected at startup (#471) — breaking for misconfigured deployments:SAP_CLIENT=10used to authenticate against the wrong client and surface as an unexplained 401. Empty stays valid. Action: pad to three digits (010, not10). - Repo moved to the
arc-mcporg, docs todocs.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;transportsscope, 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
OAuth2UserTokenExchangeguidance (#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
.mcpbClaude 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. maxResultsaccepted 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.tssplit 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 grepregex 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,maxResultsandmaxDepswere 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
SAPReadscope key came from the rawargs.type, sotype: ["TABLE_CONTENTS"]ortype: "table_contents"fell through to the basereadscope and was then normalized into thedata-scoped handler. The key now comes from the same normalized object the handler dispatches on, which also alignsSAP_DENY_ACTIONSmatching. Action: calls that relied on the lowercase/array form bypassing a scope check now correctly requiredata. allowedPackagesceiling enforced on activation andchange_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 withsignExists="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_tokenthe 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 nestedLZ…U01includes. 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_LANGUAGEis 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 withmethod. Action: none.TABLE_QUERYread type (#309) — multi-column structured queries. Action: needs thedatascope.- Class-local includes auto-initialised on write (#314). Action: none.
allowedPackagesX/**subtree rule (#284) —ZFOO/**matchesZFOOand every transitive sub-package per the real package hierarchy, instead of forcing admins to over-allow withZFOO*. Action: opt-in — switchSAP_ALLOWED_PACKAGES=ZFOO*toZFOO/**for hierarchy-accurate scoping.- Per-user
OAuth2UserTokenExchangebearer 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) andARC1_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-wideARC1_MAX_CONCURRENTsemaphore is now shared correctly across per-user clients. Action: opt-inARC1_RATE_LIMITfor 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%admindraft include (#271). Action: none.
0.9.5 (2026-05-11)¶
SAPSearch tadir_lookupsource modes andbatch_create activateAtEnd(#270) —activateAtEndbatches interdependent objects into one activator pass. Action: thedb/bothlookup sources need thesqlscope.- Stable DCR signing key (#267) — new
ARC1_DCR_SIGNING_SECRETso acf 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_methodsplices 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 anamesarray for exact cross-package resolution; prefer it over longSAPQueryIN-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.jsonto 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/VandTRAN/Onever appear in real ADT output and now fail validation;FUGR/FFwas repointed from FUGR to FUNC (it is a function module). Action: migrate toFUGR/FF,VIEW/DV,TRAN/T, or the canonical short forms. STRUcollapsed intoTABL(#219) — useTABLfor both transparent tables and DDIC structures. The slash formSTRU/DSsurvives as a back-compat alias. Action: replacetype='STRU'withtype='TABL'.FTG2renamed toFEATURE_TOGGLE,MSAGadded to the read enum (#224) —FTG2was ARC-1-invented with zero hits in SAP's own metadata; the read enum usedMESSAGESwhile writes used canonicalMSAG. Both old names still route with a deprecation warning for one minor release. Action: switch toFEATURE_TOGGLEandMSAG.- 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.createworks 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
Mapto a stateless, HMAC-signedclient_idstore, so registrations survivecf 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_URLfor 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
npxexecution (#189) — 0.7.0 could not be run vianpx. - 0.7.2 added the ETag-validated source cache and the active/inactive
versionparameter onSAPRead(#186).
0.6 (2026-04-08 → 2026-04-20)¶
- Breaking (0.6.0): write safety simplified —
allowedPackagesnow defaults to$TMPand is actually enforced (checkPackage()existed but was never called), andallowTransportableEditswas 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:
SAPQuerymoved fromreadto the newdatascope, andSAPTransportfromadmindown towrite(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 (SAPGitarrived 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
repositoryfield 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: SAPQuery→data scope, SAPTransport→write; 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, plusSAP_DENY_ACTIONS(Tool,Tool.action,Tool.glob*; fail-fast at startup on an invalid pattern). - Two new scopes,
transportsandgit;adminnow implies all seven scopes (previouslyadminalone yielded the most restrictive safety). New API-key profileadminalongsideviewer/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=falsenow truly blocks every mutation, including activation, transport writes and Git writes — the oldreadOnlydid not gatecheckTransport/checkGit(a silent security gap).- Transport and Git reads are always available; only writes need the extra opt-in.
SAPTransport.check/.historydropped fromwritetoread,SAPManage.flp_list_*dropped toread, andSAPLint.set_formatter_settingswas promoted towrite(it performs an update).
Migration
Map each removed variable — SAP_READ_ONLY→SAP_ALLOW_WRITES, SAP_BLOCK_DATA→SAP_ALLOW_DATA_PREVIEW, SAP_BLOCK_FREE_SQL→SAP_ALLOW_FREE_SQL (all three inverted), SAP_ENABLE_TRANSPORTS→SAP_ALLOW_TRANSPORT_WRITES, SAP_ENABLE_GIT→SAP_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.