sap-ai-dev-toolkit 0.9.9911 → 0.9.9913

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -24,7 +24,7 @@ You are an ABAP development agent for SAP Business Application Studio (BAS). Fol
24
24
  - **Clean Core:** `PlanABAPCloudMigration` to batch-check release-state evidence for relevant ADT object URIs. Treat unknown states as unverified and validate any replacement against the target release.
25
25
  Tool modes and system capabilities vary. Do not infer tool availability from this map or static documentation.
26
26
 
27
- For a requested transparent DDIC persistence table, use the live `CreateTable` tool (`create_table` on a single-destination proxy). It creates the table, writes generated DDL, and activates in one call; require explicit SAP-change approval and a known package/transport. It does not create authorization objects.
27
+ Use `GetStructure`, `GetTypeInfo`, and `GetMessages` for read-only DDIC shape, ABAP type, and SE91 message-text inspection. Use `CreatePackage` only when a new package is required and explicitly approved; transportable packages need a known software component and explicit transport. For transparent DDIC persistence, use `CreateTable`; it creates, writes generated DDL, and activates in one call. For existing Z/Y tables, use `UpdateTable` with reviewed current DDL and exact confirmation. Use `DeleteEmptyDDLS` only for a blank Z/Y DDLS shell after verifying it is empty; generic `DeleteObject` remains hidden. Neither creator creates authorization objects.
28
28
 
29
29
  4. **Use test-driven development.** ABAP code changes require a real test plan. Add or refine ABAP Unit assertions before changing production code, covering success, boundary, and relevant error behavior. Run the test and observe the failing behavior, make the smallest production change, then rerun it and observe the pass. If the object type is hard to unit test, introduce a test seam, injectable collaborator, local test double, or small executable test harness rather than relying only on syntax/lint. If an executable red test truly cannot be created or run, explain the specific constraint and report the strongest real check performed; never describe a substitute as a passing test.
30
30
  5. **Author locally first; check and lint before sending to SAP.** Create or change sources in the workspace as plain source files named `object.type.extension` (for example `zcl_report.clas.abap`), together with their ABAP Unit tests, instead of writing directly into SAP. Author only the plain source files; do not generate XML or other object-metadata sidecar files. Run the live `LintABAP` MCP tool on those caller-supplied local files plus every required dependency source, and consume BAS editor LSP diagnostics when that LSP is configured; `LintABAP` analyzes only the submitted in-memory files and does not read workspace files or resolve dependencies. Fix findings locally and re-lint until clean or the residual findings are explicitly accepted. Only then send the reviewed sources to SAP with `EditSource`, `WriteSource`, or staged change sets, reviewing every diff before apply; prefer the source-hash guard (`include_hash` on reads, `expected_source_hash` on writes) when the live schemas offer it. Do not send to SAP source that was not linted locally unless the tool is unavailable; then report that deviation.
@@ -19,7 +19,7 @@ You are a specialized ABAP runtime debugging and performance diagnosis agent for
19
19
  - **Logs/runtime evidence:** `GetApplicationLog` for bounded SLG1 evidence; `GetSystemInfo`, `GetFeatures`, `GetInstalledComponents`, and `GetConnectionInfo` for environment context. Short-dump, SQL-trace, and general SAP-router tools are intentionally not exposed by this addon.
20
20
  - **Debugger/breakpoints:** `SetBreakpoint`, `GetBreakpoints`, `DebuggerAttach`, `DebuggerGetStack`, `DebuggerGetVariables`, `DebuggerStep`, and `DebuggerDetach` when the session is authorized. Delete/listen helper tools are not part of the curated proxy surface.
21
21
  - **Call-flow and static analysis:** `FindDefinition`, `FindReferences`, `CompareSource`, `GetContext`, `ListDependencies`, `GetCDSDependencies`, `GetCDSImpactAnalysis`, and `GetCDSElementInfo`.
22
- - **Source/object inspection:** `SearchObject`, `GrepObjects`, `GrepPackages`, `GetSource`, `GetClass`, `GetClassInfo`, `GetClassComponents`, `GetClassInclude`, `GetFunction`, `GetFunctionGroup`, `GetProgram`, `GetInclude`, `GetInterface`, `GetPackage`, and `GetTable`.
22
+ - **Source/object inspection:** `SearchObject`, `GrepObjects`, `GrepPackages`, `GetSource`, `GetClass`, `GetClassInfo`, `GetClassComponents`, `GetClassInclude`, `GetFunction`, `GetFunctionGroup`, `GetProgram`, `GetInclude`, `GetInterface`, `GetPackage`, `GetStructure`, `GetTypeInfo`, `GetMessages`, and `GetTable`.
23
23
  - **Safe validation/data inspection:** `RunQuery` and `GetTableContents` only for safe read-only evidence on the target.
24
24
  - **Fix validation when code changes are authorized:** `EditSource`, `WriteSource`, `PrepareABAPChangeSet`, `ApplyABAPChangeSet`, `LintABAP`, `SyntaxCheck`, `RunUnitTests`, `RunATCCheck`, `PrettyPrint`, `GetInactiveObjects`, `Activate`, and `ActivateMultiple`.
25
25
  Tool modes and target systems vary; never infer availability from this static list.
@@ -23,7 +23,7 @@ You are a specialized SAP RAP service development agent for SAP Business Applica
23
23
  - **Validation:** `LintABAP`, `SyntaxCheck`, `RunUnitTests`, `RunATCCheck`, `PrettyPrint`, `RunQuery`, `GetTableContents`, `GenerateRAPRegressionSuite`, and `RunRAPRegressionSuite` when safely applicable.
24
24
  - **Activation/service operations:** `GetInactiveObjects` to review pending inactive objects, then `Activate` and `ActivateMultiple` only when explicitly authorized by the task. Create a service binding with `CreateObject` (`SRVB/SVB`, with an explicit `binding_version`) and publish or withdraw it with `PublishServiceBinding` / `UnpublishServiceBinding` only when the task authorizes publication.
25
25
  - **Runtime diagnosis:** `GetApplicationLog`, `GetSystemInfo`, `GetFeatures`, `FindReferences`, `GetContext`, and read-only data queries.
26
- Tool modes and target systems vary; never infer availability from this static list.
26
+ Tool modes and target systems vary; never infer availability from this static list. Use `GetStructure`, `GetTypeInfo`, and `GetMessages` for read-only DDIC/type/message metadata. If the target package must be created, use `CreatePackage` only after explicit approval; a transportable package requires its software component and transport. `CreateTable` does not create authorization objects.
27
27
 
28
28
  When a RAP business object requires a new transparent persistence table, include `CreateTable` before dependent CDS/behavior artifacts. It creates the table, writes generated DDL, and activates in one call; require explicit SAP-change approval and a known package/transport. It does not create authorization objects.
29
29
  4. **Model RAP dependencies deliberately.** Inspect existing package conventions before editing. Work through dependencies in order: interface/root CDS, compositions/associations, behavior definition, behavior pool/local classes, projection CDS, projection behavior, service definition, and service binding. Preserve naming, annotations, authorization patterns, locking, draft, numbering, validations, determinations, actions, messages, and ETags used by the target codebase.
@@ -20,7 +20,7 @@ Follow this workflow in order and use only capabilities actually exposed by the
20
20
  - **CDS/RAP/API analysis:** `GetCDSDependencies`, `GetCDSImpactAnalysis`, `GetCDSElementInfo`, `RunQuery`, `GetTableContents`, `GenerateRAPRegressionSuite`, `RunRAPRegressionSuite`, `GetAPIReleaseState`, and `PlanABAPCloudMigration` for relevant dependencies and candidate APIs.
21
21
  - **Quality and risk signals:** `LintABAP`, `SyntaxCheck`, `RunUnitTests`, `RunATCCheck`, `PrettyPrint`, and `GetApplicationLog` when assessing existing behavior.
22
22
  - **Transport context:** `GetUserTransports`, `GetTransport`, `GetTransportInfo`, `ListTransports`, `CreateTransport`, `CheckTransportReadiness`, and `ListDependencies` only for planning or explicitly authorized preparation. Never claim transport release/deletion support; transport release is unavailable through this addon.
23
- Tool modes and target systems vary. Do not infer availability from this map or static documentation.
23
+ Tool modes and target systems vary. Do not infer availability from this map or static documentation. Use `GetStructure`, `GetTypeInfo`, and `GetMessages` for read-only DDIC/type/message evidence. Include `CreatePackage` only when package provisioning is required, with explicit approval and a known software component/transport for transportable packages.
24
24
 
25
25
  For an approved design requiring new transparent DDIC persistence, include `CreateTable` as a state-changing work-package step. It creates the table, writes generated DDL, and activates in one call; require explicit approval and a known package/transport. It does not create authorization objects.
26
26
  3. **Evaluate SAP standard and recommend APIs first.** Look for standard business processes, configuration, released BAPIs/RFCs, OData services, CDS views/entities, RAP BOs, events, BADIs, enhancement spots, workflow/rules, communication scenarios, and documented integration APIs before proposing custom code. Recommend the best API/extension point for each integration or data operation, including read/write semantics, release state, authorization model, payload/data contract, error behavior, and known limitations. State whether each candidate is standard, released, extensible, deprecated/unsupported, or unavailable in the target system. Use `GetAPIReleaseState` where available; otherwise mark release status as unverified.
@@ -11,6 +11,8 @@ description: Diagnose ABAP runtime failures using application logs, source/refer
11
11
 
12
12
  Query the active MCP server's live `tools/list` once; use the exact live tool name and schema for the target. Start with `GetApplicationLog`, source/object inspection (`SearchObject`, `GetSource`, `GetContext`, `FindDefinition`, `FindReferences`, `ListDependencies`), and safe data inspection (`RunQuery`, `GetTableContents`). For an authorized debugger session, use `SetBreakpoint`, review registered breakpoints with `GetBreakpoints`, attach with `DebuggerAttach`, inspect with `DebuggerGetStack` / `DebuggerGetVariables`, step with `DebuggerStep`, and finish with `DebuggerDetach`. Avoid attaching to another user's session. Dump, trace, debugger-listen, delete-breakpoint, and arbitrary execution/RFC tools are not exposed by this addon. Tool names shown in PascalCase (such as `GetSource` or `LintABAP`) are logical names; the live MCP surface exposes them as lowercase snake_case. A server scoped to a single destination (the normal case for generated `mcp.json` entries) exposes them unprefixed, so `GetSource` appears as `get_source` and `LintABAP` as `lint_abap`; when several destinations share one server, each name is destination-prefixed with its slug for disambiguation (for example `cfd_run_query`). Always call the exact names returned by `tools/list`.
13
13
 
14
+ Use `GetStructure`, `GetTypeInfo`, and `GetMessages` as read-only aids when a failure depends on DDIC layout, ABAP type metadata, or SE91 text.
15
+
14
16
  1. Reproduce the reported failure when safe and within the requested target. Establish the observed input, outcome, and execution context before changing code.
15
17
  2. Inspect relevant application logs, source, dependency/reference context, safe runtime data, and debugger state using only the current live MCP tool listing and schemas. Correlate evidence to the failing path before proposing a cause; when dumps or traces are needed, hand off to SAP tools outside this addon.
16
18
  3. Keep debugger sessions and execution bounded. Set breakpoints sparingly; breakpoints registered with `SetBreakpoint` cannot be deleted through this surface (`DeleteBreakpoint` is not exposed), and `DebuggerDetach` releases the session. Do not change business data or attach to, interrupt, or alter another user's session. Prefer read-only diagnostics unless a change is specifically authorized.
@@ -11,7 +11,7 @@ description: Implement or change ABAP programs, classes, interfaces, function gr
11
11
 
12
12
  Query the active MCP server's live `tools/list` once; use task-relevant tools with their returned schemas. Locate objects and usages with `SearchObject`, `GrepObjects`, and `GrepPackages`; read with `GetSource` and `GetContext`; trace callers or dependencies with `FindDefinition` and `FindReferences`; compare workspace and SAP versions with `CompareSource`. Use `EditSource` for a localized change and `WriteSource` for a larger rewrite. Format with `PrettyPrint`; lint caller-supplied source with `LintABAP`; validate with `SyntaxCheck` and `RunUnitTests`, plus `RunATCCheck` when exposed and relevant. For Clean Core requirements, use `GetAPIReleaseState` on each relevant dependency. Tool names shown in PascalCase (such as `GetSource` or `LintABAP`) are logical names; the live MCP surface exposes them as lowercase snake_case. A server scoped to a single destination (the normal case for generated `mcp.json` entries) exposes them unprefixed, so `GetSource` appears as `get_source` and `LintABAP` as `lint_abap`; when several destinations share one server, each name is destination-prefixed with its slug for disambiguation (for example `cfd_run_query`). Always call the exact names returned by `tools/list`.
13
13
 
14
- For a requested transparent DDIC persistence table, use live `CreateTable` (`create_table` on a single-destination proxy), not `CreateObject`. It creates the table, writes generated DDL, and activates in one SAP call; require explicit approval and a known package/transport. It does not create authorization objects; transport release/deletion is unavailable through this addon.
14
+ Use `GetStructure`, `GetTypeInfo`, and `GetMessages` for read-only DDIC shape, ABAP type, and SE91 text inspection. If a new package is required, use live `CreatePackage` only with explicit approval; a transportable package requires its software component and transport. For transparent DDIC persistence, use `CreateTable`, not `CreateObject`; it creates the table, writes generated DDL, and activates in one SAP call. For an existing Z/Y table, `UpdateTable` compares the reviewed DDL and uses a hash-guarded locked update; it requires exact confirmation. `DeleteEmptyDDLS` only deletes blank Z/Y DDLS shells after checking source and exact confirmation; generic `DeleteObject` remains hidden. Neither creator supports authorization objects; transport release/deletion is unavailable through this addon.
15
15
 
16
16
  ## Release compatibility and Clean ABAP naming
17
17
 
@@ -11,6 +11,8 @@ description: Analyze ABAP runtime incidents, debugger state, and performance sym
11
11
 
12
12
  Query the active MCP server's live `tools/list` once and use the exact live names and schemas. Prefer these curated addon tools when available: `GetSystemInfo`, `GetFeatures`, `GetConnectionInfo`, `GetInstalledComponents`, `GetContext`, `GetApplicationLog`, `DebuggerAttach`, `DebuggerGetStack`, `DebuggerGetVariables`, `DebuggerStep`, `DebuggerDetach`, `SetBreakpoint`, `GetBreakpoints`, `FindDefinition`, `FindReferences`, `CompareSource`, `ListDependencies`, `SearchObject`, `GrepObjects`, `GrepPackages`, `GetSource`, `GetClass`, `GetClassInfo`, `GetClassComponents`, `GetClassInclude`, `GetFunction`, `GetFunctionGroup`, `GetProgram`, `GetInclude`, `GetInterface`, `GetPackage`, `GetTable`, `GetCDSDependencies`, `GetCDSImpactAnalysis`, `GetCDSElementInfo`, `RunQuery`, and `GetTableContents`. For authorized fixes, also use `EditSource`, `WriteSource`, `PrepareABAPChangeSet`, `ApplyABAPChangeSet`, `LintABAP`, `SyntaxCheck`, `RunUnitTests`, `RunATCCheck`, `PrettyPrint`, `Activate`, and `ActivateMultiple`. Dump, trace, arbitrary execution/RFC, and delete-breakpoint helpers are not exposed by this addon. Tool names shown in PascalCase (such as `GetSource` or `LintABAP`) are logical names; the live MCP surface exposes them as lowercase snake_case. A server scoped to a single destination (the normal case for generated `mcp.json` entries) exposes them unprefixed, so `GetSource` appears as `get_source` and `LintABAP` as `lint_abap`; when several destinations share one server, each name is destination-prefixed with its slug for disambiguation (for example `cfd_run_query`). Always call the exact names returned by `tools/list`.
13
13
 
14
+ Use `GetStructure`, `GetTypeInfo`, and `GetMessages` for read-only DDIC, ABAP type, and message-class context during runtime analysis.
15
+
14
16
  1. Establish incident boundaries: symptom, expected result, object/service, destination, user/session, input, time window, frequency, and whether reproduction/debugging is authorized.
15
17
  2. Gather read-only evidence first. Correlate logs, source/reference context, dependencies, debugger state, and data conditions by timestamp and object path. Do not start with source edits.
16
18
  3. For debugger sessions, set breakpoints sparingly — breakpoints registered with `SetBreakpoint` cannot be deleted through this surface because `DeleteBreakpoint` is not exposed — and attach only to the authorized session. Inspect stack and variables, step minimally, then detach; `DebuggerDetach` releases the session. Never attach to another user's unrelated session.
@@ -11,7 +11,7 @@ description: Implement, change, or analyze ABAP CDS data definitions and their d
11
11
 
12
12
  Query the active MCP server's live `tools/list` once; use task-relevant tools with their returned schemas. Locate views and usages with `SearchObject` and `GrepObjects`; read DDLS with `GetSource`; compare workspace and SAP versions with `CompareSource`; use `GetCDSDependencies` for upstream dependencies, `GetCDSImpactAnalysis` for consumers, and `GetCDSElementInfo` for element metadata. Trace references with `FindReferences`; edit via `EditSource` / `WriteSource`. Validate with `SyntaxCheck`, `RunATCCheck`, activation via `Activate` / `ActivateMultiple`, and read-only runtime queries via `RunQuery` or `GetTableContents` when exposed. Tool names shown in PascalCase (such as `GetSource` or `LintABAP`) are logical names; the live MCP surface exposes them as lowercase snake_case. A server scoped to a single destination (the normal case for generated `mcp.json` entries) exposes them unprefixed, so `GetSource` appears as `get_source` and `LintABAP` as `lint_abap`; when several destinations share one server, each name is destination-prefixed with its slug for disambiguation (for example `cfd_run_query`). Always call the exact names returned by `tools/list`.
13
13
 
14
- For a new transparent DDIC table backing a CDS entity, use live `CreateTable`; it is not for CDS views. It writes generated DDL and activates in one SAP call, so require explicit approval and a known package/transport. It does not create authorization objects; transport release/deletion is unavailable through this addon.
14
+ Use `GetStructure` and `GetTypeInfo` to inspect DDIC-backed structure and type metadata when resolving CDS field dependencies. If a new package is needed, `CreatePackage` is state-changing: require explicit approval, and provide a software component plus transport for a transportable package. For a new transparent DDIC table backing a CDS entity, use `CreateTable`; it is not for CDS views, writes generated DDL, and activates in one SAP call. `UpdateTable` is limited to existing Z/Y DDIC tables; it is not a CDS-view editor. `DeleteEmptyDDLS` only removes a blank Z/Y DDLS shell after exact confirmation. Authorization-object creation and transport release/deletion are unavailable through this addon.
15
15
 
16
16
  ## Language level and naming
17
17
 
@@ -11,7 +11,7 @@ description: Develop SAP RAP business objects, behavior, projections, and OData
11
11
 
12
12
  Query the active MCP server's live `tools/list` once; use task-relevant tools with their returned schemas. Check support and the connected destination with `GetSystemInfo`, `GetFeatures`, and `GetConnectionInfo`; locate objects with `SearchObject` and `GrepObjects`; inspect sources and structure with `GetSource`, `GetContext`, `ListDependencies`, `GetCDSDependencies`, `GetCDSImpactAnalysis`, `GetCDSElementInfo`, `GetClassInfo`, `GetClassComponents`, `GetClassInclude`, `GetInterface`, `GetProgram`, and `GetInclude`. Edit with `EditSource` / `WriteSource` or reviewed `PrepareABAPChangeSet` / `ApplyABAPChangeSet`; validate with `LintABAP`, `SyntaxCheck`, `RunUnitTests`, `RunATCCheck`, `RunQuery`, `GetTableContents`, and `GenerateRAPRegressionSuite` / `RunRAPRegressionSuite` for GET-only OData smoke checks when exposed. Activate with `Activate` / `ActivateMultiple` only when requested. Create service bindings with `CreateObject` (`SRVB/SVB`; set `binding_version` explicitly because V2 is the default) and publish or withdraw them with `PublishServiceBinding` / `UnpublishServiceBinding` only when publication is requested. Tool names shown in PascalCase (such as `GetSource` or `LintABAP`) are logical names; the live MCP surface exposes them as lowercase snake_case. A server scoped to a single destination (the normal case for generated `mcp.json` entries) exposes them unprefixed, so `GetSource` appears as `get_source` and `LintABAP` as `lint_abap`; when several destinations share one server, each name is destination-prefixed with its slug for disambiguation (for example `cfd_run_query`). Always call the exact names returned by `tools/list`.
13
13
 
14
- When a RAP business object needs a new transparent persistence table, use live `CreateTable` before dependent CDS/behavior artifacts. It writes generated DDL and activates in one SAP call; require explicit approval and a known package/transport. It does not create authorization objects; transport release/deletion is unavailable through this addon.
14
+ Use `GetStructure`, `GetTypeInfo`, and `GetMessages` for read-only DDIC/type/message metadata. If a new package is required, use `CreatePackage` only with explicit approval; transportable packages need a software component and transport. When a RAP business object needs a new transparent persistence table, use `CreateTable` before dependent CDS/behavior artifacts; it writes generated DDL and activates in one SAP call. Authorization-object creation and transport release/deletion are unavailable through this addon.
15
15
 
16
16
  ## Release compatibility and naming
17
17
 
@@ -11,7 +11,7 @@ description: Validate and deliver SAP RAP OData services, behavior implementatio
11
11
 
12
12
  Query the active MCP server's live `tools/list` once and use the exact live names and schemas. Prefer these curated addon tools when available: `GetSystemInfo`, `GetFeatures`, `GetConnectionInfo`, `SearchObject`, `GrepObjects`, `GrepPackages`, `GetSource`, `GetContext`, `ListDependencies`, `GetCDSDependencies`, `GetCDSImpactAnalysis`, `GetCDSElementInfo`, `GetClass`, `GetClassInfo`, `GetClassComponents`, `GetClassInclude`, `GetInterface`, `EditSource`, `WriteSource`, `PrepareABAPChangeSet`, `ApplyABAPChangeSet`, `LintABAP`, `SyntaxCheck`, `RunUnitTests`, `RunATCCheck`, `PrettyPrint`, `RunQuery`, `GetTableContents`, `GenerateRAPRegressionSuite`, `RunRAPRegressionSuite`, `GetApplicationLog`, `GetInactiveObjects`, `Activate`, `ActivateMultiple`, `CreateTable`, `CreateObject` (service bindings), `PublishServiceBinding`, and `UnpublishServiceBinding`. Read UI5 apps already deployed to the ABAP repository with `UI5ListApps`, `UI5GetApp`, and `UI5GetFileContent`. UI5 deployment, dump, trace, arbitrary execution/RFC, and code-coverage tools are not exposed by this addon. Tool names shown in PascalCase (such as `GetSource` or `LintABAP`) are logical names; the live MCP surface exposes them as lowercase snake_case. A server scoped to a single destination (the normal case for generated `mcp.json` entries) exposes them unprefixed, so `GetSource` appears as `get_source` and `LintABAP` as `lint_abap`; when several destinations share one server, each name is destination-prefixed with its slug for disambiguation (for example `cfd_run_query`). Always call the exact names returned by `tools/list`.
13
13
 
14
- If the RAP service requires a new transparent persistence table, use `CreateTable` before dependent CDS artifacts. It creates the table, writes generated DDL, and activates in one call; require explicit approval and a known package/transport. It does not create authorization objects.
14
+ Use `GetStructure`, `GetTypeInfo`, and `GetMessages` for read-only DDIC/type/message inspection. If the service needs a new package, use `CreatePackage` only with explicit approval; transportable packages require a software component and transport. If the service requires a new transparent persistence table, use `CreateTable` before dependent CDS artifacts; it creates the table, writes generated DDL, and activates in one call. Neither creator supports authorization objects.
15
15
 
16
16
  1. Confirm target destination, package, transport/temporary target, RAP object names, and whether activation/publication/data mutation is authorized. Transport release and deletion remain out of scope for this skill; prepare and report transport context only.
17
17
  2. Plan before implementing. Present the RAP object chain to create or change in dependency order, the ABAP Unit test approach, the local authoring and validation approach (workspace files plus `LintABAP` and LSP), and the SAP write/activation/publication steps with the authorizations they require. Proceed while the work stays read-only or workspace-local; wait for explicit approval before implementing a plan that writes to, activates in, or publishes to the SAP system.
@@ -11,7 +11,7 @@ description: Orchestrate the SAP delivery lifecycle from requirement analysis th
11
11
 
12
12
  Query the active MCP server's live `tools/list` once; use task-relevant tools with their returned schemas. Investigate system and repository context with `GetSystemInfo`, `GetFeatures`, `GetConnectionInfo`, `GetInstalledComponents`, `SearchObject`, `GrepObjects`, `GrepPackages`, `GetSource`, `GetContext`, `FindDefinition`, `FindReferences`, `CompareSource`, and dependency tools (`ListDependencies`, `GetCDSDependencies`, `GetCDSImpactAnalysis`). Validate with `LintABAP`, `SyntaxCheck`, `RunUnitTests`, `RunATCCheck`, runtime queries (`RunQuery`, `GetTableContents`), `GetApplicationLog`, and `GenerateRAPRegressionSuite` / `RunRAPRegressionSuite` when exposed. Use transport tools for readiness planning only; never claim transport release/deletion support because transport release is unavailable through this addon. Tool names shown in PascalCase (such as `GetSource` or `LintABAP`) are logical names; the live MCP surface exposes them as lowercase snake_case. A server scoped to a single destination (the normal case for generated `mcp.json` entries) exposes them unprefixed, so `GetSource` appears as `get_source` and `LintABAP` as `lint_abap`; when several destinations share one server, each name is destination-prefixed with its slug for disambiguation (for example `cfd_run_query`). Always call the exact names returned by `tools/list`.
13
13
 
14
- For a work package requiring a new transparent DDIC persistence table, include live `CreateTable` in the approved plan with its target package and transport. It writes generated DDL and activates in one SAP call, so treat it as a state-changing step requiring explicit approval. It does not create authorization objects.
14
+ Use `GetStructure`, `GetTypeInfo`, and `GetMessages` as read-only DDIC/type/message evidence. If a work package needs a new package, include `CreatePackage` only with explicit approval and the target software component/transport; it changes SAP state. For new transparent DDIC persistence, include `CreateTable` in the approved plan with its target package and transport; it writes generated DDL and activates in one call. Authorization-object creation and transport release/deletion are unavailable through this addon.
15
15
 
16
16
  1. Convert the requirement into an SDLC plan: discovery, fit-gap/API recommendation, architecture, implementation packages, test strategy, validation gates, activation/publication gates, transport readiness, deployment notes, rollback, and operations handover.
17
17
  2. Require a planning phase before implementation for every work package. Each package starts with a presented plan of objects, tests, and validation steps; no SAP state-changing package proceeds before the user approves it. Every implementation package includes a local quality gate: sources are authored locally as plain workspace source files (`object.type.extension`; do not generate XML or other object-metadata sidecar files) and must pass `LintABAP` plus LSP checks before they are sent to the SAP system. ABAP/RAP packages must state the target release/language version and oldest supported ABAP release across consumers. On ABAP 7.40 or newer, actively consider modern ABAP syntax and verify each feature against that floor; establish the CDS language level separately for DDLS. Include existing SAP/project naming conventions and Clean ABAP naming guidance, linking the [Cheat Sheet](https://github.com/SAP/styleguides/blob/main/clean-abap/cheat-sheet/CheatSheet.md) and [Names section](https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#names).
package/README.md CHANGED
@@ -608,6 +608,8 @@ These local tools are namespaced by destination. Change-set tools appear when th
608
608
  | --- | --- |
609
609
  | `PrepareABAPChangeSet` | Stage up to 12 full-source `WriteSource` changes and return line diffs plus SHA-256 fingerprints. Proposals stay in MCP process memory. |
610
610
  | `ApplyABAPChangeSet` | Re-read each object and write only when its source still matches the reviewed version. It stops on conflicts or errors and reports partial application; it does not roll back SAP writes. |
611
+ | `UpdateTable` | Compare the current Z/Y table DDL with reviewed source, then update and activate through VSP's source-hash check under lock. Requires exact confirmation. |
612
+ | `DeleteEmptyDDLS` | Delete only a blank Z/Y DDLS shell after checking its source and requiring exact confirmation; generic `DeleteObject` remains hidden. |
611
613
  | `CheckTransportReadiness` | Run a caller-selected bundle of transport, dependency, inactive-object, ABAP Unit, and ATC checks. Completed calls may still contain findings. |
612
614
  | `PlanABAPCloudMigration` | Batch `GetAPIReleaseState` checks for ADT object URIs and prioritize recognized unreleased APIs ahead of unknown and released states. SAP evidence stays attached. |
613
615
  | `GenerateRAPRegressionSuite` | Read `$metadata` and return reusable JSON with a metadata check and one `$top=1` GET for each entity set. |
@@ -1,5 +1,5 @@
1
- f10b759b5e320c6fec4c176ef9bce49f783d796eeb8a2476dd5898c94cb14afd vsp-linux-x64
2
- a4c47e4c15538cc16b540d19f55771e4c1340389efeca815e1881eafd89e45c5 vsp-linux-arm64
3
- 20a197921c88f539ea1a7f5236509dbaa9b9f906a6333e6fb1dce9f8b5eec85c vsp-darwin-x64
4
- 24a8810a17d31a434b92957ea41e6347b24e2a6a35e47b3b2fc13a16082a44c3 vsp-darwin-arm64
5
- b318fdf5194a7f15ebcf7ee912fb2493df21aba337540a2402f81786300fd0ea vsp-win32-x64.exe
1
+ 5a8adb501a30bb4f3c3a1f2c16aee0f60de0be9a226cafbc07191ba955c9269f vsp-linux-x64
2
+ d7b96b63ec812949e2ab2e223b1fbac5f5a0cd1c6e068e3ddd117d3548c968a2 vsp-linux-arm64
3
+ 7328b9fd0ceb60287b53e9d6425e7111c87cdefcec1d412544eb6b1e70f4249c vsp-darwin-x64
4
+ fb90f7a1b2bdca5fcc7bb8ba5623d6fb1dcbb88de02bba5686acad503f29f84f vsp-darwin-arm64
5
+ bd33b0a45640700bd26372355b73169632b21fb4c07df33b8cc0b5d7ff5b76e0 vsp-win32-x64.exe
Binary file
Binary file
Binary file
Binary file
Binary file
package/inventory.md CHANGED
@@ -6,14 +6,14 @@ This inventory reflects the current SAP AI Dev Toolkit proxy behavior in `src/mc
6
6
 
7
7
  | Status | Count | Notes |
8
8
  | --- | ---: | --- |
9
- | Upstream tools | Up to 60 | Curated from the child tool list and exposed in lowercase snake_case, unprefixed (`get_source`) on single-destination servers; a destination slug prefix (`demo-abap_get_source`) appears only when one server fronts multiple destinations. |
9
+ | Upstream tools | Up to 64 | Curated from the child tool list and exposed in lowercase snake_case, unprefixed (`get_source`) on single-destination servers; a destination slug prefix (`demo-abap_get_source`) appears only when one server fronts multiple destinations. |
10
10
  | Local lint tool | 1 per destination | `LintABAP` analyzes caller-supplied ABAP source in memory; it is exposed publicly as `lint_abap`. |
11
- | Workflow tools | Up to 6 per destination | Review/apply change sets, transport evidence, Clean Core release assessment, and read-only RAP regression suites. Some are exposed only when their upstream capabilities are registered. |
11
+ | Workflow tools | Up to 8 per destination | Review/apply change sets, transport evidence, Clean Core release assessment, RAP regression suites, guarded table updates, and empty-DDLS cleanup. Some require upstream capabilities. |
12
12
  | Convenience mapping | Dynamic | `GetApplicationLog` maps to the upstream `SAP(action="analyze", type="application_log")` operation when the SAP router is registered. |
13
13
  | Intentionally filtered tools | Dynamic | Destructive, broad-router, trace, and unsupported operations are hidden from direct calls. |
14
14
  | Mode-dependent | Dynamic | Focused/expert mode and backend capabilities determine which tools are registered. |
15
15
 
16
- The maximum fixture surface is 68 tools per destination when expert-mode capabilities and all local workflows are available. Multiple selected destinations create separate MCP servers; this add-on cannot inspect VS Code's aggregate tool budget or per-chat tool binding.
16
+ The maximum fixture surface is 74 destination-scoped tools per destination when expert-mode capabilities and all local workflows are available, plus one workspace-scoped `LintABAPProject` tool per MCP server. Multiple selected destinations create separate MCP servers; this add-on cannot inspect VS Code's aggregate tool budget or per-chat tool binding.
17
17
 
18
18
  ## Known upstream tools
19
19
 
@@ -168,6 +168,8 @@ These logical names are exposed through MCP in lowercase snake_case (`lint_abap`
168
168
  - `PlanABAPCloudMigration` — batch-check API release state for supplied ADT object URIs and prioritize recognized unreleased APIs.
169
169
  - `GenerateRAPRegressionSuite` — read service metadata and emit reusable GET-only smoke cases for entity sets.
170
170
  - `RunRAPRegressionSuite` — execute saved cases with status, content-type, and JSON-path assertions over the connected destination.
171
+ - `UpdateTable` — compare the current DDL with the reviewed source, then update and activate one Z/Y table using VSP's locked source-hash check.
172
+ - `DeleteEmptyDDLS` — delete only a blank Z/Y DDLS source after exact confirmation; generic `DeleteObject` remains hidden.
171
173
 
172
174
  ## Notes
173
175
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sap-ai-dev-toolkit",
3
- "version": "0.9.9911",
3
+ "version": "0.9.9913",
4
4
  "description": "SAP AI development toolkit for BAS, ABAP, RAP, CAP, HANA Cloud, Fiori, UI5, and MCP",
5
5
  "author": "Gurkan Yilmaz",
6
6
  "type": "module",
@@ -148,6 +148,23 @@ index 5007935..3b1fdd8 100755
148
148
  cookieFile, _ := cmd.Flags().GetString("cookie-file")
149
149
  cookieString, _ := cmd.Flags().GetString("cookie-string")
150
150
 
151
+ diff --git a/internal/mcp/handlers_source.go b/internal/mcp/handlers_source.go
152
+ index d23089b..8e7e5ff 100644
153
+ --- a/internal/mcp/handlers_source.go
154
+ +++ b/internal/mcp/handlers_source.go
155
+ @@ -132,10 +132,10 @@ func (s *Server) registerGetSource() {
156
+ // registerWriteSource registers the unified WriteSource tool
157
+ func (s *Server) registerWriteSource() {
158
+ s.mcpServer.AddTool(mcp.NewTool("WriteSource",
159
+ - mcp.WithDescription("Unified tool for writing ABAP source code with automatic create/update detection. Supports PROG, CLAS, INTF, INCL, and RAP types (DDLS, BDEF, SRVD)."),
160
+ + mcp.WithDescription("Unified tool for writing ABAP source code with automatic create/update detection. Supports PROG, CLAS, INTF, INCL, RAP types (DDLS, BDEF, SRVD), and updates to existing DDIC tables (TABL). New tables must be created with CreateTable."),
161
+ mcp.WithString("object_type",
162
+ mcp.Required(),
163
+ - mcp.Description("Object type: PROG (program), CLAS (class), INTF (interface), INCL (include), DDLS (CDS view), BDEF (behavior definition), SRVD (service definition)"),
164
+ + mcp.Description("Object type: PROG (program), CLAS (class), INTF (interface), INCL (include), DDLS (CDS view), BDEF (behavior definition), SRVD (service definition), or TABL (existing DDIC table update only)"),
165
+ ),
166
+ mcp.WithString("name",
167
+ mcp.Required(),
151
168
  diff --git a/internal/mcp/server.go b/internal/mcp/server.go
152
169
  index 9337857..11fc940 100644
153
170
  --- a/internal/mcp/server.go
@@ -290,7 +307,7 @@ index 7740e56..b4c2faf 100755
290
307
  + }
291
308
  +}
292
309
  diff --git a/internal/mcp/tools_register.go b/internal/mcp/tools_register.go
293
- index dd433d6..5553b7f 100644
310
+ index dd433d6..d9ea365 100644
294
311
  --- a/internal/mcp/tools_register.go
295
312
  +++ b/internal/mcp/tools_register.go
296
313
  @@ -837,6 +837,19 @@ func (s *Server) registerDevTools(shouldRegister func(string) bool) {
@@ -313,6 +330,24 @@ index dd433d6..5553b7f 100644
313
330
  ),
314
331
  ), s.handleActivateMultiple)
315
332
  }
333
+ @@ -1070,7 +1083,7 @@ func (s *Server) registerCRUDTools(shouldRegister func(string) bool) {
334
+
335
+ if shouldRegister("CreateTable") {
336
+ s.mcpServer.AddTool(mcp.NewTool("CreateTable",
337
+ - mcp.WithDescription("Create a DDIC transparent table from a simple JSON definition. Handles full workflow: create → set source → activate. Supports common ABAP types: CHAR, NUMC, INT4, DEC, STRING, TIMESTAMPL, UUID, etc."),
338
+ + mcp.WithDescription("Create a DDIC transparent table from a simple JSON definition. Handles full workflow: create → set source → activate. Supports common ABAP types: CHAR, NUMC, INT4, DEC, STRING, TIMESTAMPL, UUID, etc. Client-dependent tables get one implicit CLIENT key; supplied CLIENT or MANDT fields are treated as that same key."),
339
+ mcp.WithString("name",
340
+ mcp.Required(),
341
+ mcp.Description("Table name (uppercase, max 30 chars, must start with Z/Y)"),
342
+ @@ -1084,7 +1097,7 @@ func (s *Server) registerCRUDTools(shouldRegister func(string) bool) {
343
+ ),
344
+ mcp.WithString("fields",
345
+ mcp.Required(),
346
+ - mcp.Description("JSON array of fields: [{\"name\":\"ID\",\"type\":\"CHAR32\",\"key\":true},{\"name\":\"VALUE\",\"type\":\"STRING\"}]. Types: CHAR/CHARnn, NUMC/NUMCnn, INT4, DEC, STRING, TIMESTAMPL, UUID, DATS, TIMS, or data element name."),
347
+ + mcp.Description("JSON array of user fields: [{\"name\":\"ID\",\"type\":\"CHAR32\",\"key\":true},{\"name\":\"VALUE\",\"type\":\"STRING\"}]. Do not include CLIENT or MANDT; the client key is added automatically. Types: CHAR/CHARnn, NUMC/NUMCnn, INT4, DEC, STRING, TIMESTAMPL, UUID, DATS, TIMS, or data element name."),
348
+ ),
349
+ mcp.WithString("transport",
350
+ mcp.Description("Transport request number (optional for $TMP)"),
316
351
  diff --git a/pkg/adt/browser_auth.go b/pkg/adt/browser_auth.go
317
352
  index ea3c1a9..5bc7a01 100644
318
353
  --- a/pkg/adt/browser_auth.go
@@ -436,7 +471,7 @@ index 0000000..1ed3c2b
436
471
  + }
437
472
  +}
438
473
  diff --git a/pkg/adt/crud.go b/pkg/adt/crud.go
439
- index f412fb1..15ac38a 100755
474
+ index f412fb1..8021a5a 100755
440
475
  --- a/pkg/adt/crud.go
441
476
  +++ b/pkg/adt/crud.go
442
477
  @@ -1250,7 +1250,12 @@ func (c *Client) publishUnpublishServiceBinding(ctx context.Context, action, ser
@@ -453,6 +488,23 @@ index f412fb1..15ac38a 100755
453
488
 
454
489
  resp, err := c.transport.Request(ctx, path, &RequestOptions{
455
490
  Method: http.MethodPost,
491
+ @@ -1427,11 +1432,15 @@ func generateTableDDL(opts CreateTableOptions) string {
492
+ sb.WriteString("@AbapCatalog.dataMaintenance : #ALLOWED\n")
493
+ sb.WriteString(fmt.Sprintf("define table %s {\n\n", strings.ToLower(opts.Name)))
494
+
495
+ - // Auto-add MANDT as first key field (standard SAP practice)
496
+ + // The table's implicit client field is named CLIENT in DDL; callers may
497
+ + // provide CLIENT or MANDT, but the schema must contain it only once.
498
+ sb.WriteString(" key client : abap.clnt not null;\n")
499
+
500
+ // User-defined fields
501
+ for _, f := range opts.Fields {
502
+ + if strings.EqualFold(strings.TrimSpace(f.Name), "CLIENT") || strings.EqualFold(strings.TrimSpace(f.Name), "MANDT") {
503
+ + continue
504
+ + }
505
+ fieldName := strings.ToLower(f.Name)
506
+ fieldType := mapFieldType(f)
507
+
456
508
  diff --git a/pkg/adt/features.go b/pkg/adt/features.go
457
509
  index 13aa4b0..8fb7376 100755
458
510
  --- a/pkg/adt/features.go
@@ -620,7 +672,7 @@ index 0000000..5e880bd
620
672
  + }
621
673
  +}
622
674
  diff --git a/pkg/adt/http.go b/pkg/adt/http.go
623
- index 0b4d9f1..f0b5b51 100755
675
+ index 0b4d9f1..e420573 100755
624
676
  --- a/pkg/adt/http.go
625
677
  +++ b/pkg/adt/http.go
626
678
  @@ -313,7 +313,7 @@ func (t *Transport) request(ctx context.Context, path string, opts *RequestOptio
@@ -723,7 +775,8 @@ index 0b4d9f1..f0b5b51 100755
723
775
  + }
724
776
  // Drain the body so the connection can be reused.
725
777
  _, _ = io.Copy(io.Discard, resp.Body)
726
- traceHTTPResponse(resp, nil)
778
+ - traceHTTPResponse(resp, nil)
779
+ + traceHTTPResponse(resp, body)
727
780
  t.adoptServerCookies(resp)
728
781
 
729
782
  - return resp.Header.Get("X-CSRF-Token"), resp.StatusCode, t.redirectedAwayFromSAP(resp), nil
@@ -751,10 +804,10 @@ index 0b4d9f1..f0b5b51 100755
751
804
  // redirectedAwayFromSAP reports whether a response was ultimately served by
752
805
  diff --git a/pkg/adt/http_csrf_discovery_test.go b/pkg/adt/http_csrf_discovery_test.go
753
806
  new file mode 100644
754
- index 0000000..80741da
807
+ index 0000000..ee932b3
755
808
  --- /dev/null
756
809
  +++ b/pkg/adt/http_csrf_discovery_test.go
757
- @@ -0,0 +1,56 @@
810
+ @@ -0,0 +1,55 @@
758
811
  +package adt
759
812
  +
760
813
  +import (
@@ -810,7 +863,6 @@ index 0000000..80741da
810
863
  + t.Fatalf("expected both endpoint failures, got %v", err)
811
864
  + }
812
865
  +}
813
- +
814
866
  diff --git a/pkg/adt/http_sso_same_host_test.go b/pkg/adt/http_sso_same_host_test.go
815
867
  new file mode 100644
816
868
  index 0000000..0c39b96
@@ -1290,3 +1342,32 @@ index 0000000..1385d6d
1290
1342
  + }
1291
1343
  + }
1292
1344
  +}
1345
+ diff --git a/pkg/adt/workflows_source_tabl_test.go b/pkg/adt/workflows_source_tabl_test.go
1346
+ index 220e91b..61e1691 100644
1347
+ --- a/pkg/adt/workflows_source_tabl_test.go
1348
+ +++ b/pkg/adt/workflows_source_tabl_test.go
1349
+ @@ -44,3 +44,24 @@ func TestCreatingATableFromSourceSaysWhatDoesWork(t *testing.T) {
1350
+ t.Errorf("the refusal should name the route that does work, got %q", result.Message)
1351
+ }
1352
+ }
1353
+ +
1354
+ +func TestCreateTableEmitsOnlyTheAutomaticClientField(t *testing.T) {
1355
+ + source := generateTableDDL(CreateTableOptions{
1356
+ + Name: "ZADK_SESSION",
1357
+ + Fields: []TableField{
1358
+ + {Name: "MANDT", Type: "mandt", IsKey: true},
1359
+ + {Name: "CLIENT", Type: "abap.clnt", IsKey: true},
1360
+ + {Name: "SESSION_ID", Type: "CHAR", Length: 32, IsKey: true},
1361
+ + },
1362
+ + })
1363
+ +
1364
+ + if got := strings.Count(source, "key client : abap.clnt not null;"); got != 1 {
1365
+ + t.Fatalf("got %d client keys, want exactly 1:\n%s", got, source)
1366
+ + }
1367
+ + if strings.Contains(source, "key mandt :") || strings.Contains(source, "key client : abap.clnt not null;\n key client :") {
1368
+ + t.Fatalf("generated DDL contains a duplicate client field:\n%s", source)
1369
+ + }
1370
+ + if !strings.Contains(source, "key session_id : abap.char(32) not null;") {
1371
+ + t.Fatalf("generated DDL lost the business key:\n%s", source)
1372
+ + }
1373
+ +}
@@ -69,6 +69,30 @@ const TOOLS = {
69
69
  ['change_set_id'],
70
70
  { readOnlyHint: false, destructiveHint: true, idempotentHint: false }
71
71
  ),
72
+ UpdateTable: textTool(
73
+ 'UpdateTable',
74
+ 'Update and activate an existing Z/Y DDIC table from replacement DDL. The current DDL is re-read and compared with expected_source; VSP checks its source hash again under lock. Requires confirmation exactly equal to UPDATE TABLE <TABLE_NAME>.',
75
+ {
76
+ table_name: { type: 'string', minLength: 2, maxLength: 30, pattern: '^[ZzYy][A-Za-z0-9_]{1,29}$' },
77
+ expected_source: { type: 'string', minLength: 1, maxLength: MAX_CHANGE_BYTES },
78
+ replacement_source: { type: 'string', minLength: 1, maxLength: MAX_CHANGE_BYTES },
79
+ transport: { type: 'string', minLength: 1 },
80
+ confirmation: { type: 'string', minLength: 1, description: 'Must exactly equal UPDATE TABLE <TABLE_NAME>.' }
81
+ },
82
+ ['table_name', 'expected_source', 'replacement_source', 'confirmation'],
83
+ { readOnlyHint: false, destructiveHint: true, idempotentHint: false }
84
+ ),
85
+ DeleteEmptyDDLS: textTool(
86
+ 'DeleteEmptyDDLS',
87
+ 'Delete only an empty Z/Y DDLS shell. The source is read first and deletion is refused unless it is blank. Requires confirmation exactly equal to DELETE EMPTY DDLS <OBJECT_NAME>.',
88
+ {
89
+ name: { type: 'string', minLength: 2, maxLength: 30, pattern: '^[ZzYy][A-Za-z0-9_]{1,29}$' },
90
+ transport: { type: 'string', minLength: 1 },
91
+ confirmation: { type: 'string', minLength: 1, description: 'Must exactly equal DELETE EMPTY DDLS <OBJECT_NAME>.' }
92
+ },
93
+ ['name', 'confirmation'],
94
+ { readOnlyHint: false, destructiveHint: true, idempotentHint: false }
95
+ ),
72
96
  CheckTransportReadiness: textTool(
73
97
  'CheckTransportReadiness',
74
98
  'Collect a transport request and dependency, inactive-object, ABAP Unit, and ATC evidence bundle. Only registered read/check tools are accepted; inspect findings before handoff.',
@@ -237,6 +261,18 @@ function hashSource(source) {
237
261
  return createHash('sha256').update(source).digest('hex');
238
262
  }
239
263
 
264
+ function adtSourceHash(source) {
265
+ const canonical = source.replace(/\r\n/g, '\n').replace(/\n+$/g, '');
266
+ return `sha256:${createHash('sha256').update(canonical).digest('hex')}`;
267
+ }
268
+
269
+ function customerObjectName(value, label) {
270
+ if (typeof value !== 'string') throw new Error(`${label} must be a customer object name`);
271
+ const name = value.trim().toUpperCase();
272
+ if (!/^[ZY][A-Z0-9_]{1,29}$/.test(name)) throw new Error(`${label} must be a Z/Y customer object name of 2–30 letters, digits, or underscores`);
273
+ return name;
274
+ }
275
+
240
276
  function containsSource(value, source) {
241
277
  if (typeof value === 'string') return value === source;
242
278
  if (Array.isArray(value)) return value.some(entry => containsSource(entry, source));
@@ -519,6 +555,75 @@ export function createEngineeringTools(entry, upstreamTools, { env = process.env
519
555
  });
520
556
  }
521
557
 
558
+ if (available.has('GetTable') && available.has('WriteSource')) {
559
+ add(TOOLS.UpdateTable, async args => {
560
+ validateObject(args, 'arguments', ['table_name', 'expected_source', 'replacement_source', 'transport', 'confirmation']);
561
+ const tableName = customerObjectName(args.table_name, 'table_name');
562
+ if (args.confirmation !== `UPDATE TABLE ${tableName}`) throw new Error(`confirmation must equal UPDATE TABLE ${tableName}`);
563
+ for (const [label, source] of [['expected_source', args.expected_source], ['replacement_source', args.replacement_source]]) {
564
+ if (typeof source !== 'string' || !source) throw new Error(`${label} is required`);
565
+ if (Buffer.byteLength(source, 'utf8') > MAX_CHANGE_BYTES) throw new Error(`${label} exceeds ${MAX_CHANGE_BYTES} bytes`);
566
+ if (source.split(/\r?\n/).length > 1000) throw new Error(`${label} exceeds the 1,000-line limit`);
567
+ }
568
+ if (args.transport !== undefined && (typeof args.transport !== 'string' || !args.transport.trim())) throw new Error('transport must be a nonempty string when supplied');
569
+ const tableDefinition = /^\s*define\s+table\s+([A-Z0-9_/]+)/im.exec(args.replacement_source);
570
+ if (!tableDefinition || tableDefinition[1].toUpperCase() !== tableName) throw new Error(`replacement_source must define table ${tableName}`);
571
+ const expectedHash = adtSourceHash(args.expected_source);
572
+ if (expectedHash === adtSourceHash(args.replacement_source)) throw new Error('replacement_source does not change the table DDL');
573
+
574
+ const currentResult = await remoteTool(entry, 'GetTable', { table_name: tableName }, available, log);
575
+ const currentSource = sourceFromResult(currentResult);
576
+ if (currentSource === undefined) throw new Error(`GetTable did not return source for ${tableName}`);
577
+ const currentHash = adtSourceHash(currentSource);
578
+ if (currentHash !== expectedHash) throw new Error(`table source changed since review; re-read ${tableName} and prepare a new update`);
579
+
580
+ const writeArguments = {
581
+ object_type: 'TABL',
582
+ name: tableName,
583
+ source: args.replacement_source,
584
+ mode: 'update',
585
+ expected_source_hash: currentHash,
586
+ ...(args.transport ? { transport: args.transport.trim() } : {})
587
+ };
588
+ const writeResult = await remoteTool(entry, 'WriteSource', writeArguments, available, log);
589
+ let writeDetails;
590
+ try {
591
+ writeDetails = JSON.parse(resultData(writeResult));
592
+ } catch {
593
+ throw new Error(`WriteSource returned an unparseable result for ${tableName}; inspect SAP state before retrying`);
594
+ }
595
+ if (!object(writeDetails) || writeDetails.success !== true) throw new Error(`WriteSource did not confirm a successful table update for ${tableName}; inspect SAP state before retrying`);
596
+ return toolJson({
597
+ status: 'updated',
598
+ table_name: tableName,
599
+ expected_source_hash: currentHash,
600
+ target_source_hash: adtSourceHash(args.replacement_source),
601
+ result: writeDetails
602
+ });
603
+ });
604
+ }
605
+
606
+ if (available.has('GetSource') && available.has('DeleteObject')) {
607
+ add(TOOLS.DeleteEmptyDDLS, async args => {
608
+ validateObject(args, 'arguments', ['name', 'transport', 'confirmation']);
609
+ const name = customerObjectName(args.name, 'name');
610
+ if (args.confirmation !== `DELETE EMPTY DDLS ${name}`) throw new Error(`confirmation must equal DELETE EMPTY DDLS ${name}`);
611
+ if (args.transport !== undefined && (typeof args.transport !== 'string' || !args.transport.trim())) throw new Error('transport must be a nonempty string when supplied');
612
+
613
+ const sourceResult = await remoteTool(entry, 'GetSource', { object_type: 'DDLS', name, include_context: false }, available, log);
614
+ const source = sourceFromResult(sourceResult);
615
+ if (source === undefined) throw new Error(`GetSource did not return source for DDLS ${name}; refusing deletion`);
616
+ if (source.trim() !== '') throw new Error(`DDLS ${name} is not empty; refusing deletion`);
617
+
618
+ const objectUrl = `/sap/bc/adt/ddic/ddl/sources/${encodeURIComponent(name.toLowerCase())}`;
619
+ await remoteTool(entry, 'DeleteObject', {
620
+ object_url: objectUrl,
621
+ ...(args.transport ? { transport: args.transport.trim() } : {})
622
+ }, available, log);
623
+ return toolJson({ status: 'deleted', object_type: 'DDLS', name, object_url: objectUrl });
624
+ });
625
+ }
626
+
522
627
  if (available.has('GetTransport')) {
523
628
  add(TOOLS.CheckTransportReadiness, async args => {
524
629
  validateObject(args, 'arguments', ['transport_id', 'checks']);
package/src/mcp-proxy.mjs CHANGED
@@ -78,6 +78,7 @@ export const PUBLIC_VSP_TOOLS = new Set([
78
78
  'ActivateMultiple',
79
79
  'CompareSource',
80
80
  'CreateObject',
81
+ 'CreatePackage',
81
82
  'CreateTable',
82
83
  'CreateTransport',
83
84
  'DebuggerAttach',
@@ -106,14 +107,17 @@ export const PUBLIC_VSP_TOOLS = new Set([
106
107
  'GetInclude',
107
108
  'GetInstalledComponents',
108
109
  'GetInterface',
110
+ 'GetMessages',
109
111
  'GetPackage',
110
112
  'GetProgram',
111
113
  'GetSource',
114
+ 'GetStructure',
112
115
  'GetSystemInfo',
113
116
  'GetTable',
114
117
  'GetTableContents',
115
118
  'GetTransport',
116
119
  'GetTransportInfo',
120
+ 'GetTypeInfo',
117
121
  'GetUserTransports',
118
122
  'GrepObjects',
119
123
  'GrepPackages',
package/tools.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Curated SAP tools exposed through the BAS proxy
2
2
 
3
- The proxy no longer advertises every tool provided by the SAP runtime. To keep the developer-lifecycle MCP surface manageable, each generated one-destination server exposes a curated set of upstream tools plus local workflow tools (currently 68 tools when all upstream capabilities are registered).
3
+ The proxy no longer advertises every tool provided by the SAP runtime. To keep the developer-lifecycle MCP surface manageable, each generated one-destination server exposes a curated set of upstream tools plus local workflow tools (up to 75 tools: 74 destination-scoped tools plus one workspace-scoped project-lint tool).
4
4
 
5
5
  The names below are the logical tool names. Publicly they are exposed in lowercase snake_case without a prefix (`get_table_contents`, `run_query`) because each generated MCP server is scoped to one destination; only when a single server fronts multiple destinations does each name gain its destination slug (`demo-abap_get_table_contents`) to stay unambiguous. BAS/VS Code chat tool references bind only lowercase identifiers, so mixed-case names never reach the model.
6
6
 
@@ -12,6 +12,7 @@ Hidden upstream tools are not directly callable through the proxy. Local workflo
12
12
  - `ActivateMultiple`
13
13
  - `CompareSource`
14
14
  - `CreateObject`
15
+ - `CreatePackage`
15
16
  - `CreateTable`
16
17
  - `CreateTransport`
17
18
  - `DebuggerAttach`
@@ -40,14 +41,17 @@ Hidden upstream tools are not directly callable through the proxy. Local workflo
40
41
  - `GetInclude`
41
42
  - `GetInstalledComponents`
42
43
  - `GetInterface`
44
+ - `GetMessages`
43
45
  - `GetPackage`
44
46
  - `GetProgram`
45
47
  - `GetSource`
48
+ - `GetStructure`
46
49
  - `GetSystemInfo`
47
50
  - `GetTable`
48
51
  - `GetTableContents`
49
52
  - `GetTransport`
50
53
  - `GetTransportInfo`
54
+ - `GetTypeInfo`
51
55
  - `GetUserTransports`
52
56
  - `GrepObjects`
53
57
  - `GrepPackages`
@@ -69,11 +73,11 @@ Hidden upstream tools are not directly callable through the proxy. Local workflo
69
73
  - `UnpublishServiceBinding`
70
74
  - `WriteSource`
71
75
 
72
- `CreateTable` creates a transparent DDIC table, writes its generated DDL source, and activates it. The upstream VSP package and transport mutation checks still apply. Authorization-object creation is not supported by the pinned backend and remains unavailable.
76
+ `CreatePackage` creates a local package or a transportable package with an explicit transport; it changes SAP state and requires explicit approval. `CreateTable` creates a transparent DDIC table, writes its generated DDL source, and activates it. Client-dependent tables already get the implicit `CLIENT` key; supplied `CLIENT` or `MANDT` fields map to that same key and are not emitted twice. `GetStructure`, `GetTypeInfo`, and `GetMessages` are read-only metadata lookups. The upstream VSP package and transport mutation checks still apply. The pinned backend does not create structures, table types, or authorization objects.
73
77
 
74
78
  ## Hidden from direct proxy calls
75
79
 
76
- Broad/destructive surfaces such as object deletion, SQL trace, arbitrary SAP router calls, transport release/delete, RFC execution, debugger listen/delete-breakpoint helpers, and one-off generator/update helpers are intentionally not advertised by the BAS proxy. UI5 repository writes are hidden too: the ADT filestore only reads UI5 apps, so deploy them with SAP Fiori tools instead.
80
+ Broad/destructive surfaces such as generic object deletion, SQL trace, arbitrary SAP router calls, transport release/delete, RFC execution, debugger listen/delete-breakpoint helpers, and one-off generator/update helpers are intentionally not advertised by the BAS proxy. The local `DeleteEmptyDDLS` workflow is a narrow exception: it verifies the source is blank and requires exact confirmation before deleting a Z/Y DDLS shell. UI5 repository writes are hidden too: the ADT filestore only reads UI5 apps, so deploy them with SAP Fiori tools instead.
77
81
 
78
82
  ## Local and destination-scoped workflow tools
79
83
 
@@ -82,6 +86,8 @@ The proxy adds local tools to the MCP surface. Some are workspace-wide; others a
82
86
  - `LintABAP` — local in-memory ABAP linting.
83
87
  - `LintABAPProject` — scan serialized ABAP objects in the configured workspace root (SAP_AI_DEV_TOOLKIT_WORKSPACE_ROOT, defaulting to the MCP server working directory) using the project abaplint config and available local dependency folders. This is static analysis only; it does not contact SAP or activate objects.
84
88
  - `GetApplicationLog` — bounded convenience mapping to the upstream SAP application-log route when available.
89
+ - `UpdateTable` — update and activate an existing Z/Y DDIC table from replacement DDL after comparing expected_source with `GetTable`; the write uses VSP's hash check under lock and requires `UPDATE TABLE <TABLE_NAME>` confirmation.
90
+ - `DeleteEmptyDDLS` — delete only a blank Z/Y DDLS source after an emptiness check and exact `DELETE EMPTY DDLS <OBJECT_NAME>` confirmation. It calls the hidden generic delete operation internally.
85
91
  - `PrepareABAPChangeSet` and `ApplyABAPChangeSet` — review full-source diffs and recheck source before explicit writes.
86
92
  - `CheckTransportReadiness` — collect a whitelisted bundle of transport, dependency, inactive-object, ABAP Unit, and ATC results.
87
93
  - `PlanABAPCloudMigration` — batch SAP API release-state checks and prioritize recognized unreleased results.