Skip to content

feat(adt-mcp): add 12 high-priority tools for vibing-steampunk feature parity (17 → 29 tools)#101

Merged
ThePlenkov merged 9 commits intomainfrom
copilot/feature-parity-with-vibing-steampunk
Apr 15, 2026
Merged

feat(adt-mcp): add 12 high-priority tools for vibing-steampunk feature parity (17 → 29 tools)#101
ThePlenkov merged 9 commits intomainfrom
copilot/feature-parity-with-vibing-steampunk

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 13, 2026

  • Create .github/workflows/copilot-setup-steps.yml — installs bun, deps, and creates pre-commit hook in .git/copilot-hooks/
  • Update .husky/pre-commit to support both bun (bunx first) and npm (npx fallback) environments

Copilot AI and others added 2 commits April 13, 2026 19:57
…unk (#H1-#H8)

New tools:
- grep_objects: regex search within named ABAP objects
- grep_packages: regex search across a package (and subpackages)
- get_table: DDIC table/structure definition reader
- get_table_contents: read table data with WHERE filter + row limit
- run_query: execute freestyle ABAP SQL SELECT queries
- find_definition: navigate to symbol definition via ADT navigation endpoint
- find_references: find all usages (where-used) via ADT usages endpoint
- get_callers_of: call hierarchy upward traversal
- get_callees_of: call hierarchy downward traversal
- create_object: create ABAP objects (PROG, CLAS, INTF, FUGR, DEVC)
- delete_object: delete ABAP objects using typed CRUD contracts
- activate_package: batch-activate all inactive objects in a package

Also completes:
- cts_create_transport: now fully implemented via transportrequests.create()
- cts_release_transport: now fully implemented via POST ?_action=RELEASE

Co-authored: updated mock fixtures, routes and integration tests for all new tools

Agent-Logs-Url: https://github.com/abapify/adt-cli/sessions/5086b608-c242-4318-a434-645c3114edbd

Co-authored-by: ThePlenkov <6381507+ThePlenkov@users.noreply.github.com>
…chema description

Agent-Logs-Url: https://github.com/abapify/adt-cli/sessions/5086b608-c242-4318-a434-645c3114edbd

Co-authored-by: ThePlenkov <6381507+ThePlenkov@users.noreply.github.com>
Copilot AI changed the title [WIP] Onboard essential MCP tool capabilities for feature parity feat(adt-mcp): add 12 high-priority tools for vibing-steampunk feature parity (17 → 29 tools) Apr 13, 2026
Copilot AI requested a review from ThePlenkov April 13, 2026 20:03
Add the following tools:
- get_function_group, get_function (M1)
- get_object_structure, get_type_hierarchy (M2)
- lock_object, unlock_object (M3)
- clone_object (M4)
- pretty_print (M5)
- create_package (M6)
- get_installed_components, get_features (M8)
- publish_service_binding (M9)
- get_git_types, git_export (M10)

Also add mock routes, fixtures, and integration tests for all new tools.

Agent-Logs-Url: https://github.com/abapify/adt-cli/sessions/cde5b87d-03b6-4638-be0b-f5546f43eb15

Co-authored-by: ThePlenkov <6381507+ThePlenkov@users.noreply.github.com>
- Run Prettier on 11 files that were missing proper formatting
- Fix mock server: function group metadata route now excludes /objectstructure,
  /source/ and /fmodules/ sub-paths to prevent incorrect route interception

Agent-Logs-Url: https://github.com/abapify/adt-cli/sessions/d06841ae-664d-4446-af93-fff153d27ac5

Co-authored-by: ThePlenkov <6381507+ThePlenkov@users.noreply.github.com>
- Merge get-callers-of + get-callees-of into call-hierarchy.ts with shared
  fetchCallHierarchy helper — eliminates 138 duplicated lines
- Merge get-function-group + get-function into function-tools.ts with shared
  formatMetadataResult helper — eliminates 58 duplicated lines + fixes S7735
  negated conditions (source !== undefined → source === undefined)
- get-installed-components.ts: remove unused 'z' import (S1128), use
  localeCompare for sort (S2871 CRITICAL — was causing reliability rating 4)
- clone-object.ts: remove unnecessary 'as string' cast (S4325)
- Update index.ts to import from new consolidated files

Agent-Logs-Url: https://github.com/abapify/adt-cli/sessions/778ec8cf-fb3c-47c4-94aa-5588b60d0ed1

Co-authored-by: ThePlenkov <6381507+ThePlenkov@users.noreply.github.com>
The Copilot agent's core.hooksPath is set to .git/copilot-hooks/ by the
infrastructure (not .husky/), so the existing husky pre-commit hook was
never running for agent commits. copilot-setup-steps.yml now:
- Installs bun and project dependencies (so bunx nx is available)
- Creates .git/copilot-hooks/pre-commit that runs nx format:write
  --uncommitted + git update-index --again before every agent commit

Also makes .husky/pre-commit bun-aware (bunx first, npx fallback) for
consistency with human developer environments.

Agent-Logs-Url: https://github.com/abapify/adt-cli/sessions/19e1267a-27da-4a8e-b4d3-b3f451494958

Co-authored-by: ThePlenkov <6381507+ThePlenkov@users.noreply.github.com>
@nx-cloud
Copy link
Copy Markdown
Contributor

nx-cloud Bot commented Apr 14, 2026

View your CI Pipeline Execution ↗ for commit a001ded

Command Status Duration Result
nx affected -t lint test build e2e-ci --verbose... ✅ Succeeded 4s View ↗

☁️ Nx Cloud last updated this comment at 2026-04-15 14:11:42 UTC

Pin the Copilot Bun setup action, reduce duplicated tool logic, and simplify Sonar-reported code paths in adt-mcp.\n\nCo-authored-by: Codex <noreply@openai.com>
@sonarqubecloud
Copy link
Copy Markdown

@ThePlenkov ThePlenkov marked this pull request as ready for review April 15, 2026 14:29
Copilot AI review requested due to automatic review settings April 15, 2026 14:29
@ThePlenkov ThePlenkov merged commit 2ef01a9 into main Apr 15, 2026
8 of 9 checks passed
@ThePlenkov ThePlenkov deleted the copilot/feature-parity-with-vibing-steampunk branch April 15, 2026 14:29
@qodo-code-review
Copy link
Copy Markdown

Review Summary by Qodo

Add 23 high-priority tools for feature parity with vibing-steampunk (6 → 29 tools)

✨ Enhancement 🧪 Tests

Grey Divider

Walkthroughs

Description
• Add 23 high-priority and medium-priority tools for feature parity with vibing-steampunk, expanding
  tool count from 6 to 29
• **New tools include:**
  - Source code operations: grep_objects, grep_packages, pretty_print
  - Object navigation: find_definition, find_references, get_callers_of, get_callees_of
  - Object structure: get_object_structure, get_type_hierarchy, lock_object, unlock_object
  - CRUD operations: create_object, create_package, delete_object, clone_object
  - Table/data access: get_table, get_table_contents, run_query
  - Function modules: get_function_group, get_function
  - CTS transport: cts_create_transport (full implementation), cts_release_transport (full
  implementation)
  - Service binding: publish_service_binding
  - Package activation: activate_package
  - System info: get_installed_components, get_features
  - abapGit integration: get_git_types, git_export
• Implement comprehensive mock ADT endpoints and 16 fixture objects for testing
• Add 23 integration tests covering all new tools
• Update Copilot setup workflow with pre-commit hook support for both bun and npm environments
Diagram
flowchart LR
  A["6 Existing Tools"] -->|"Add 23 new tools"| B["29 Total Tools"]
  B -->|"Source Code"| C["grep, pretty_print"]
  B -->|"Navigation"| D["find_definition, find_references, call_hierarchy"]
  B -->|"Object Ops"| E["create, delete, clone, lock, unlock"]
  B -->|"Data Access"| F["get_table, run_query, get_table_contents"]
  B -->|"System Info"| G["get_features, get_installed_components"]
  B -->|"Integration"| H["CTS, abapGit, Service Binding"]
Loading

Grey Divider

File Changes

1. packages/adt-mcp/tests/integration.test.ts 🧪 Tests +510/-40

Add 23 integration tests for feature parity tools

• Removed placeholder tests for cts_create_transport and cts_release_transport that expected
 "not yet implemented" errors
• Added 23 comprehensive integration tests for new high-priority and medium-priority tools covering
 grep, table access, query execution, object navigation, CRUD operations, and abapGit integration
• Updated tool listing validation to include all 23 new tools in the expected tools array

packages/adt-mcp/tests/integration.test.ts


2. packages/adt-mcp/src/lib/mock/server.ts ✨ Enhancement +256/-1

Implement mock ADT endpoints for 23 new tools

• Added route handlers for grep/content search, usages, call hierarchy (callers/callees), navigation
 targets, and data preview endpoints
• Added routes for DDIC table definitions, CTS transport creation/release, inactive objects listing,
 and object activation
• Added routes for object CRUD operations (create/delete), function group/module metadata, object
 structure, type hierarchy, pretty printing, software components, service binding publishing, and
 abapGit operations

packages/adt-mcp/src/lib/mock/server.ts


3. packages/adt-mcp/src/lib/mock/fixtures.ts ✨ Enhancement +285/-0

Add mock response fixtures for new tool endpoints

• Added 16 new fixture objects providing mock response data for grep results, table definitions,
 data preview, navigation targets, usages, call hierarchy, inactive objects, function groups/modules,
 object structure, type hierarchy, pretty-printed source, software components, and abapGit operations

packages/adt-mcp/src/lib/mock/fixtures.ts


View more (31)
4. packages/adt-mcp/src/lib/tools/clone-object.ts ✨ Enhancement +249/-0

Add clone_object tool for copying ABAP objects

• New tool to clone ABAP objects (PROG, CLAS, INTF) by copying source code to a new object name
• Supports optional target description and package assignment
• Uses lock service for safe source code copying with transport support

packages/adt-mcp/src/lib/tools/clone-object.ts


5. packages/adt-mcp/src/lib/tools/call-hierarchy.ts ✨ Enhancement +162/-0

Add call hierarchy navigation tools

• New tools get_callers_of and get_callees_of for traversing call hierarchy upward and downward
• Supports object name resolution and direct URI specification
• Configurable result limits with default of 50 results

packages/adt-mcp/src/lib/tools/call-hierarchy.ts


6. packages/adt-mcp/src/lib/tools/get-installed-components.ts ✨ Enhancement +155/-0

Add system information and feature detection tools

• New tool get_installed_components to list installed SAP software components with version
 information
• New tool get_features to probe system for available ADT features (ATC, CTS, abapGit, RAP, UI5,
 etc.) via discovery endpoint

packages/adt-mcp/src/lib/tools/get-installed-components.ts


7. packages/adt-mcp/src/lib/tools/delete-object.ts ✨ Enhancement +140/-0

Add delete_object tool for removing ABAP objects

• New tool to delete ABAP objects with support for typed CRUD contracts (PROG, CLAS, INTF, FUGR,
 DEVC)
• Falls back to direct URI deletion for unsupported types
• Supports optional transport request specification

packages/adt-mcp/src/lib/tools/delete-object.ts


8. packages/adt-mcp/src/lib/tools/function-tools.ts ✨ Enhancement +142/-0

Add function group and module access tools

• New tools get_function_group and get_function for retrieving function group and function
 module metadata
• Optional source code inclusion for both tools
• Returns parameters, exceptions, and structural information

packages/adt-mcp/src/lib/tools/function-tools.ts


9. packages/adt-mcp/src/lib/tools/cts-create-transport.ts ✨ Enhancement +77/-13

Implement cts_create_transport with schema support

• Replaced placeholder "not yet implemented" error with full implementation using
 transportmanagmentCreate schema
• Extracts transport number from response and returns structured JSON with status, transport ID, and
 metadata
• Supports transport type (K/W), target system, and CTS project specification

packages/adt-mcp/src/lib/tools/cts-create-transport.ts


10. packages/adt-mcp/src/lib/tools/index.ts ✨ Enhancement +62/-0

Register 23 new tools in tool index

• Added imports for 23 new tool registration functions covering grep, table access, query execution,
 object operations, and abapGit integration
• Updated registerTools function to call all new tool registrations in organized groups
 (high-priority #H1–#H8 and medium-priority #M1–#M10)

packages/adt-mcp/src/lib/tools/index.ts


11. packages/adt-mcp/src/lib/tools/get-object-structure.ts ✨ Enhancement +115/-0

Add get_object_structure tool for object trees

• New tool to retrieve structural tree of ABAP objects including includes, methods, attributes, and
 sub-elements
• Supports typed CRUD contracts for PROG, CLAS, INTF, FUGR with generic fallback
• Optional version parameter to inspect active or inactive versions

packages/adt-mcp/src/lib/tools/get-object-structure.ts


12. packages/adt-mcp/src/lib/tools/git-tools.ts ✨ Enhancement +116/-0

Add abapGit integration tools

• New tools get_git_types and git_export for abapGit integration
• get_git_types lists exportable objects in a package
• git_export exports package contents in abapGit XML format

packages/adt-mcp/src/lib/tools/git-tools.ts


13. packages/adt-mcp/src/lib/tools/grep-objects.ts ✨ Enhancement +109/-0

Add grep_objects tool for source code search

• New tool for regex search within ABAP object source code
• Supports both direct URI specification and name/type resolution
• Configurable result limits with default of 50 results

packages/adt-mcp/src/lib/tools/grep-objects.ts


14. packages/adt-mcp/src/lib/tools/activate-package.ts ✨ Enhancement +118/-0

Add activate_package tool for batch activation

• New tool to batch-activate all inactive objects in a package
• Lists inactive objects via GET endpoint, then activates in single batch POST
• Returns count and list of activated objects

packages/adt-mcp/src/lib/tools/activate-package.ts


15. packages/adt-mcp/src/lib/tools/create-package.ts ✨ Enhancement +112/-0

Add create_package tool for package creation

• New tool to create ABAP development packages (DEVC) with package-specific options
• Supports package type selection (development, structure, main) and parent package assignment
• Transport specification optional for local packages

packages/adt-mcp/src/lib/tools/create-package.ts


16. packages/adt-mcp/src/lib/tools/create-object.ts ✨ Enhancement +109/-0

Add create_object tool for ABAP object creation

• New tool to create ABAP objects (PROG, CLAS, INTF, FUGR, DEVC) using typed ADT contracts
• Supports package assignment and transport request specification
• Validates object type against supported list before creation

packages/adt-mcp/src/lib/tools/create-object.ts


17. packages/adt-mcp/src/lib/tools/find-references.ts ✨ Enhancement +109/-0

Add find_references tool for usage analysis

• New tool to find all usages (where-used) of ABAP objects or symbols
• Supports object name resolution and direct URI specification
• Configurable result limits with default of 100 results

packages/adt-mcp/src/lib/tools/find-references.ts


18. packages/adt-mcp/src/lib/tools/find-definition.ts ✨ Enhancement +110/-0

Add find_definition tool for symbol navigation

• New tool to navigate to definition of ABAP symbols (classes, methods, types, function modules)
• Supports parent object context for method/attribute lookup
• Falls back to search-based resolution if navigation endpoint returns empty

packages/adt-mcp/src/lib/tools/find-definition.ts


19. packages/adt-mcp/src/lib/tools/object-creation.ts ✨ Enhancement +102/-0

Add object creation shared utilities module

• New shared module exporting createAdtObject function and type definitions for object creation
• Defines CREATE_OBJECT_TYPES (PROG, CLAS, INTF, FUGR, DEVC) and SOURCE_BACKED_OBJECT_TYPES
 (PROG, CLAS, INTF)
• Provides type guards and centralized object creation logic used by multiple tools

packages/adt-mcp/src/lib/tools/object-creation.ts


20. packages/adt-mcp/src/lib/tools/get-table-contents.ts ✨ Enhancement +95/-0

Add get_table_contents tool for table data access

• New tool to read DDIC table data with optional WHERE filter, column selection, and row limits
• Uses ADT data preview freestyle endpoint for SELECT query execution
• Returns results as JSON with query and table metadata

packages/adt-mcp/src/lib/tools/get-table-contents.ts


21. packages/adt-mcp/src/lib/tools/get-type-hierarchy.ts ✨ Enhancement +94/-0

Add get_type_hierarchy tool for inheritance analysis

• New tool to retrieve type hierarchy (superclasses, interfaces, optionally subclasses) for ABAP
 classes and interfaces
• Auto-detects object type from naming convention if not specified
• Configurable expansion of sub-types in results

packages/adt-mcp/src/lib/tools/get-type-hierarchy.ts


22. packages/adt-mcp/src/lib/tools/lock-object.ts ✨ Enhancement +96/-0

Add lock_object tool for edit lock acquisition

• New tool to acquire ADT edit locks on ABAP objects
• Returns lock handle required for subsequent write operations
• Uses LockService from @abapify/adt-locks for SAP security session handling

packages/adt-mcp/src/lib/tools/lock-object.ts


23. packages/adt-mcp/src/lib/tools/publish-service-binding.ts ✨ Enhancement +92/-0

Add publish_service_binding tool for OData activation

• New tool to publish (activate) OData service bindings (SRVB) in SAP Gateway
• Supports unpublish operation via optional flag
• Uses POST for publish and DELETE for unpublish operations

packages/adt-mcp/src/lib/tools/publish-service-binding.ts


24. packages/adt-mcp/src/lib/tools/grep-packages.ts ✨ Enhancement +88/-0

Add grep_packages tool for package-scoped search

• New tool for regex search across all ABAP source code within a package
• Supports optional subpackage inclusion (default: true)
• Configurable result limits with default of 50 results

packages/adt-mcp/src/lib/tools/grep-packages.ts


25. packages/adt-mcp/src/lib/tools/run-query.ts ✨ Enhancement +94/-0

Add run_query tool for SQL query execution

• New tool to execute freestyle ABAP SQL SELECT queries and return results as JSON
• Validates that only SELECT statements are allowed (rejects INSERT/UPDATE/DELETE)
• Configurable row limits with default of 100 rows

packages/adt-mcp/src/lib/tools/run-query.ts


26. packages/adt-mcp/src/lib/tools/get-table.ts ✨ Enhancement +56/-0

Add get_table tool for DDIC table metadata

• New tool to retrieve DDIC table definitions including field names, types, lengths, and
 descriptions
• Returns structured metadata for table design and validation

packages/adt-mcp/src/lib/tools/get-table.ts


27. packages/adt-mcp/src/lib/tools/pretty-print.ts ✨ Enhancement +64/-0

Add pretty_print tool for source code formatting

• New tool to format ABAP source code using SAP's pretty printer
• Accepts raw source code and returns formatted version
• Uses ADT pretty printer endpoint for consistent formatting

packages/adt-mcp/src/lib/tools/pretty-print.ts


28. packages/adt-mcp/src/lib/tools/unlock-object.ts ✨ Enhancement +86/-0

Add unlock_object tool for edit lock release

• New tool to release ADT edit locks on ABAP objects
• Requires lock handle from prior lock_object call
• Uses LockService for proper SAP session cleanup

packages/adt-mcp/src/lib/tools/unlock-object.ts


29. packages/adt-mcp/src/lib/tools/unlock-object.ts ✨ Enhancement +86/-0

Add unlock_object tool for releasing ADT edit locks

• New tool implementation for releasing ADT edit locks on ABAP objects
• Accepts connection parameters, object name/type, and lock handle as inputs
• Resolves object URI and calls lockService.unlock() with the provided lock handle
• Returns success status with object details or error message on failure

packages/adt-mcp/src/lib/tools/unlock-object.ts


30. packages/adt-mcp/src/lib/tools/cts-release-transport.ts ✨ Enhancement +39/-11

Implement CTS transport release with ADT endpoint

• Implements transport release functionality previously marked as unimplemented
• Replaces placeholder error with actual ADT API call to
 /sap/bc/adt/cts/transportrequests/{trkorr}?_action=RELEASE
• Uses POST method with proper XML content-type headers for transport organizer
• Adds proper error handling and success response with transport status

packages/adt-mcp/src/lib/tools/cts-release-transport.ts


31. packages/adt-mcp/src/lib/tools/pretty-print.ts ✨ Enhancement +64/-0

Add pretty_print tool for ABAP code formatting

• New tool for formatting ABAP source code via SAP pretty-printer service
• Accepts ABAP source code as input and sends to /sap/bc/adt/prettyprinter/prettifySource endpoint
• Returns formatted code without modifying the object in the system
• Includes error handling for formatting failures

packages/adt-mcp/src/lib/tools/pretty-print.ts


32. packages/adt-mcp/src/lib/tools/get-table.ts ✨ Enhancement +56/-0

Add get_table tool for DDIC table metadata retrieval

• New tool for reading DDIC table and structure definitions from SAP
• Fetches metadata including fields, keys, and data elements via ADT DDIC endpoint
• Uses existing adt-contracts tables contract for typed access
• Includes error handling and JSON response formatting

packages/adt-mcp/src/lib/tools/get-table.ts


33. .github/workflows/copilot-setup-steps.yml ⚙️ Configuration changes +44/-0

Add Copilot setup workflow with pre-commit hook

• New GitHub Actions workflow for Copilot agent setup and initialization
• Installs bun package manager and project dependencies
• Creates pre-commit hook in .git/copilot-hooks/ directory with auto-formatting logic
• Supports both bunx and npx fallback for running nx format command

.github/workflows/copilot-setup-steps.yml


34. .husky/pre-commit ⚙️ Configuration changes +5/-1

Update pre-commit hook for bun/npm compatibility

• Updates pre-commit hook to support both bun and npm environments
• Checks for bunx availability first, falls back to npx if not found
• Maintains existing nx format:write --uncommitted and git update-index --again commands

.husky/pre-commit


Grey Divider

Qodo Logo

@qodo-code-review
Copy link
Copy Markdown

qodo-code-review Bot commented Apr 15, 2026

Code Review by Qodo

🐞 Bugs (4)   📘 Rule violations (5)   📎 Requirement gaps (0)
🐞\ ≡ Correctness (3) ☼ Reliability (1)
📘\ ☼ Reliability (1) ✧ Quality (2) ⌂ Architecture (2)

Grey Divider


Action required

1. npx fallback in hooks 📘
Description
The PR adds npx usage in the pre-commit hook and Copilot setup workflow, violating the requirement
to use bun/bunx exclusively. This can lead to inconsistent toolchains across environments and
breaks the bun-only compliance policy.
Code

.husky/pre-commit[R1-5]

+if command -v bunx >/dev/null 2>&1; then
+  bunx nx format:write --uncommitted
+else
+  npx nx format:write --uncommitted
+fi
Evidence
Compliance ID 339850 disallows npm/npx usage in modified scripts/CI. The updated pre-commit hook
and the new Copilot workflow both include an npx fallback.

Rule 339850: Use bun/bunx exclusively as package manager and script runner
.husky/pre-commit[1-5]
.github/workflows/copilot-setup-steps.yml[37-41]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Modified hook/workflow uses `npx`, but policy requires `bun`/`bunx` exclusively.

## Issue Context
Compliance ID 339850 disallows `npm`/`npx`/`yarn`/`pnpm` usage in changed scripts and CI.

## Fix Focus Areas
- .husky/pre-commit[1-5]
- .github/workflows/copilot-setup-steps.yml[30-41]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Parity map still says “Not yet” 📘
Description
The README feature parity map and tool docs still state cts_create_transport and
cts_release_transport are not implemented, despite the PR adding these tools. This leaves
documentation inconsistent with shipped behavior.
Code

packages/adt-mcp/src/lib/tools/cts-create-transport.ts[R33-38]

export function registerCtsCreateTransportTool(
  server: McpServer,
-  _ctx: ToolContext,
+  ctx: ToolContext,
): void {
  server.tool(
    'cts_create_transport',
Evidence
Compliance ID 339843 requires updating documentation/Feature Parity Map when adding tools. README
still marks cts_create_transport/cts_release_transport as 🚧 Not yet and states they are not
implemented, while the PR includes concrete tool implementations.

Rule 339843: Document tools and keep Feature Parity Map updated
packages/adt-mcp/README.md[359-385]
packages/adt-mcp/README.md[541-559]
packages/adt-mcp/src/lib/tools/cts-create-transport.ts[33-110]
packages/adt-mcp/src/lib/tools/cts-release-transport.ts[14-68]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
README still claims `cts_create_transport` and `cts_release_transport` are not implemented, but the tools now exist.

## Issue Context
Compliance requires tool docs + Feature Parity Map to reflect newly implemented tools.

## Fix Focus Areas
- packages/adt-mcp/README.md[359-385]
- packages/adt-mcp/README.md[541-559]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Two tools in call-hierarchy.ts 📘
Description
packages/adt-mcp/src/lib/tools/call-hierarchy.ts exports two tool registration functions,
violating the one-tool-per-file single register export requirement. This makes tool wiring and
ownership unclear.
Code

packages/adt-mcp/src/lib/tools/call-hierarchy.ts[R136-162]

+export function registerGetCallersOfTool(
+  server: McpServer,
+  ctx: ToolContext,
+): void {
+  registerCallHierarchyTool(server, ctx, {
+    toolName: 'get_callers_of',
+    toolDescription:
+      'Find all callers (upward call hierarchy) of an ABAP method, function module, or subroutine',
+    endpoint: 'callers',
+    resultKey: 'callers',
+    failureLabel: 'Get callers failed',
+  });
+}
+
+export function registerGetCalleesOfTool(
+  server: McpServer,
+  ctx: ToolContext,
+): void {
+  registerCallHierarchyTool(server, ctx, {
+    toolName: 'get_callees_of',
+    toolDescription:
+      'Find all callees (downward call hierarchy) of an ABAP method, function module, or subroutine',
+    endpoint: 'callees',
+    resultKey: 'callees',
+    failureLabel: 'Get callees failed',
+  });
+}
Evidence
Compliance ID 339835 requires one MCP tool per file with a single register<ToolName>Tool export.
call-hierarchy.ts exports both registerGetCallersOfTool and registerGetCalleesOfTool.

Rule 339835: One MCP tool per file with a single register function export
packages/adt-mcp/src/lib/tools/call-hierarchy.ts[136-162]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`call-hierarchy.ts` defines and exports two tool registration functions.

## Issue Context
Policy requires one tool per file and exactly one exported register function per tool file.

## Fix Focus Areas
- packages/adt-mcp/src/lib/tools/call-hierarchy.ts[1-162]
- packages/adt-mcp/src/lib/tools/index.ts[32-36]
- packages/adt-mcp/src/lib/tools/index.ts[83-87]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


View more (4)
4. lock_object never unlocks 📘
Description
lock_object acquires a lock via createLockService(client).lock() without guaranteeing an unlock
in a finally-equivalent block. This violates the lock lifecycle requirement and risks leaving
locks held on error paths or abandoned sessions.
Code

packages/adt-mcp/src/lib/tools/lock-object.ts[R58-63]

+        const lockService = createLockService(client);
+        const lockHandle = await lockService.lock(objectUri, {
+          transport: args.transport,
+          objectName: args.objectName,
+          objectType: args.objectType,
+        });
Evidence
Compliance ID 339846 requires every createLockService(client).lock() acquisition to be released
via unlock() in a finally-equivalent construct. The lock_object tool acquires a lock and
returns without any finally unlock cleanup.

Rule 339846: Always release createLockService(client).lock() in a finally-equivalent block
packages/adt-mcp/src/lib/tools/lock-object.ts[58-63]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
A lock is acquired with `createLockService(client).lock()` but is not guaranteed to be released via `unlock()` in a `finally` block.

## Issue Context
Compliance requires lock cleanup on all exit paths.

## Fix Focus Areas
- packages/adt-mcp/src/lib/tools/lock-object.ts[58-83]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


5. Tools bypass ADT contracts 📘
Description
Multiple new tools call hardcoded ADT URLs via client.fetch(...) instead of using
@abapify/adt-contracts endpoint contracts. This violates the requirement to introduce/consume
contracts before using endpoints in adt-mcp.
Code

packages/adt-mcp/src/lib/tools/cts-release-transport.ts[R31-41]

+        await client.fetch(
+          `/sap/bc/adt/cts/transportrequests/${args.transport}?_action=RELEASE`,
          {
-            type: 'text' as const,
-            text: 'Transport release is not supported: the ADT client transports.release() method is not yet implemented.',
+            method: 'POST',
+            headers: {
+              'Content-Type':
+                'application/vnd.sap.adt.transportorganizer.v1+xml',
+              Accept: 'application/vnd.sap.adt.transportorganizer.v1+xml',
+            },
          },
-        ],
-      };
+        );
Evidence
Compliance ID 339836 forbids ad-hoc hardcoded URL usage in adt-mcp without first defining/using a
contract in @abapify/adt-contracts. The cited tools use client.fetch with literal
/sap/bc/adt/... paths rather than consuming a contract API.

Rule 339836: Require ADT endpoint contracts in @abapify/adt-contracts before use in adt-mcp
packages/adt-mcp/src/lib/tools/cts-release-transport.ts[31-41]
packages/adt-mcp/src/lib/tools/activate-package.ts[37-45]
packages/adt-mcp/src/lib/tools/call-hierarchy.ts[58-61]
packages/adt-mcp/src/lib/tools/git-tools.ts[37-44]
packages/adt-mcp/src/lib/tools/function-tools.ts[113-119]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Tools are calling ADT endpoints via hardcoded URLs using `client.fetch(...)` rather than consuming typed endpoint contracts from `@abapify/adt-contracts`.

## Issue Context
Compliance requires creating/using endpoint contracts before using endpoints in `adt-mcp`.

## Fix Focus Areas
- packages/adt-mcp/src/lib/tools/cts-release-transport.ts[29-41]
- packages/adt-mcp/src/lib/tools/activate-package.ts[37-45]
- packages/adt-mcp/src/lib/tools/call-hierarchy.ts[53-61]
- packages/adt-mcp/src/lib/tools/git-tools.ts[37-44]
- packages/adt-mcp/src/lib/tools/function-tools.ts[108-119]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


6. Release missing XML body 🐞
Description
cts_release_transport sends a POST with no request body, but this repo’s CTS contract/tests define
POST /sap/bc/adt/cts/transportrequests/{trkorr} as requiring a transportmanagment body, so the
release call can fail against real ADT servers.
Code

packages/adt-mcp/src/lib/tools/cts-release-transport.ts[R31-40]

+        await client.fetch(
+          `/sap/bc/adt/cts/transportrequests/${args.transport}?_action=RELEASE`,
          {
-            type: 'text' as const,
-            text: 'Transport release is not supported: the ADT client transports.release() method is not yet implemented.',
+            method: 'POST',
+            headers: {
+              'Content-Type':
+                'application/vnd.sap.adt.transportorganizer.v1+xml',
+              Accept: 'application/vnd.sap.adt.transportorganizer.v1+xml',
+            },
          },
-        ],
-      };
Evidence
The tool performs a body-less POST for the release action, while the canonical CTS contract and its
contract tests in this repo specify that POSTing to /sap/bc/adt/cts/transportrequests/{trkorr}
includes a transportmanagment request body and Content-Type: application/xml. This mismatch can
cause server-side 400/415 errors at runtime.

packages/adt-mcp/src/lib/tools/cts-release-transport.ts[31-41]
packages/adt-contracts/src/adt/cts/transportrequests/index.ts[57-66]
packages/adt-contracts/tests/contracts/cts.test.ts[116-127]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`cts_release_transport` currently POSTs to the release endpoint without sending the XML body that the repo’s CTS `transportrequests.post()` contract expects.

### Issue Context
In this repo, CTS release is modeled as a POST to `/sap/bc/adt/cts/transportrequests/{trkorr}` with a `transportmanagment` body and `Content-Type: application/xml`. The current MCP tool uses `client.fetch()` with only headers and no body, which can break against ADT implementations that require the payload.

### Fix Focus Areas
- packages/adt-mcp/src/lib/tools/cts-release-transport.ts[27-41]
- packages/adt-contracts/src/adt/cts/transportrequests/index.ts[57-66]
- packages/adt-contracts/tests/contracts/cts.test.ts[116-127]

### What to change
- Build and send a minimal `transportmanagment` XML body (e.g., via `@abapify/adt-schemas`’ `transportmanagment` serializer) and set `Content-Type: application/xml`.
- Keep the `_action=RELEASE` query param if required by the release behavior, but ensure the request still includes the contract-compliant body.
- Consider validating the response / surfacing errors instead of always returning `status: released`.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


7. Discovery parsed as JSON 🐞
Description
get_features requests and parses /sap/bc/adt/discovery as JSON with a {workspaces: ...} shape,
but this repo’s discovery contract is AtomPub XML (application/atomsvc+xml) and its schema shape
is {service: {workspace: ...}}, causing the tool to silently return empty/false features.
Code

packages/adt-mcp/src/lib/tools/get-installed-components.ts[R81-100]

+        // Fetch the discovery document to understand available services
+        const discovery = (await client.fetch('/sap/bc/adt/discovery', {
+          method: 'GET',
+          headers: { Accept: 'application/json' },
+        })) as {
+          workspaces?: Array<{
+            title: string;
+            collections?: Array<{ href: string; title: string }>;
+          }>;
+        };
+
+        // Extract all service paths from the discovery document
+        const services = new Set<string>();
+        if (discovery?.workspaces) {
+          for (const ws of discovery.workspaces) {
+            for (const col of ws.collections ?? []) {
+              services.add(col.href);
+            }
+          }
+        }
Evidence
The tool hardcodes Accept: application/json and then iterates discovery.workspaces, but the
repo’s discoveryContract.getDiscovery() is defined for AtomPub XML (application/atomsvc+xml),
and the generated discovery schema exposes service.workspace[].collection[] rather than
workspaces[]. With a real XML discovery response, client.fetch() will return raw text (no schema
parsing), resulting in no services discovered and incorrect feature flags.

packages/adt-mcp/src/lib/tools/get-installed-components.ts[81-100]
packages/adt-contracts/src/adt/discovery/index.ts[26-30]
packages/adt-schemas/src/schemas/generated/types/custom/discovery.types.ts[8-24]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`get_features` assumes `/sap/bc/adt/discovery` returns JSON with a `workspaces` array, which contradicts this repo’s discovery contract/schema and leads to empty service detection.

### Issue Context
- The repo’s discovery contract declares `Accept: application/atomsvc+xml`.
- The generated schema shape is `{ service: { workspace: [{ collection: [{ href, title, ... }] }] } }`.
- `client.fetch()` does not apply an XML schema unless provided via a typed contract, so parsing as JSON is brittle.

### Fix Focus Areas
- packages/adt-mcp/src/lib/tools/get-installed-components.ts[81-123]
- packages/adt-contracts/src/adt/discovery/index.ts[26-30]
- packages/adt-schemas/src/schemas/generated/types/custom/discovery.types.ts[8-24]

### What to change
- Replace the raw `client.fetch('/sap/bc/adt/discovery', { Accept: 'application/json' })` call with `client.adt.discovery.getDiscovery()`.
- Extract collections from `discovery.service.workspace[].collection[]` (not `workspaces/collections`).
- Keep the rest of the feature detection logic but base it on the correct `href` list.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

8. Clone package default missing 🐞
Description
clone_object claims targetPackage defaults to the source package, but when targetPackage is
omitted it passes undefined into createAdtObject, so the clone may be created in the wrong
package or fail when a package assignment is required.
Code

packages/adt-mcp/src/lib/tools/clone-object.ts[R182-188]

+        await createAdtObject(client, {
+          objectType: sourceType,
+          objectName: targetName,
+          description,
+          packageName: args.targetPackage,
+          transport: args.transport,
+        });
Evidence
The tool’s argument description promises a default to the source package, but the implementation
only forwards args.targetPackage to createAdtObject. createAdtObject omits packageRef
entirely when packageName is undefined, so there is no actual fallback behavior implemented.

packages/adt-mcp/src/lib/tools/clone-object.ts[143-147]
packages/adt-mcp/src/lib/tools/clone-object.ts[181-188]
packages/adt-mcp/src/lib/tools/object-creation.ts[39-53]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`clone_object` documents that `targetPackage` defaults to the source object’s package, but the tool does not implement that fallback.

### Issue Context
When `targetPackage` is omitted, `createAdtObject` will not include a `packageRef` (it only sets one when `packageName` is provided). This can create the clone in an unintended default location (or fail on systems requiring an explicit package).

### Fix Focus Areas
- packages/adt-mcp/src/lib/tools/clone-object.ts[143-147]
- packages/adt-mcp/src/lib/tools/clone-object.ts[171-188]
- packages/adt-mcp/src/lib/tools/object-creation.ts[39-53]

### What to change
- If `args.targetPackage` is undefined, fetch the source object metadata (typed GET for PROG/CLAS/INTF) and derive the source package (e.g., from `packageRef` / `packageName`).
- Pass that derived packageName into `createAdtObject`.
- If deriving the package is not feasible, update the Zod description to remove the incorrect default claim.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


9. Grep may run unscoped 🐞
Description
grep_objects calls the search endpoint even when no object URIs are provided/resolved, so it can
unintentionally execute a global content search instead of being constrained to specific objects.
Code

packages/adt-mcp/src/lib/tools/grep-objects.ts[R52-82]

+        const uris: string[] = args.objectUris ? [...args.objectUris] : [];
+        if (args.objects && args.objects.length > 0) {
+          const resolved = await Promise.all(
+            args.objects.map((obj) =>
+              resolveObjectUri(client, obj.objectName, obj.objectType),
+            ),
+          );
+          for (const uri of resolved) {
+            if (uri) uris.push(uri);
+          }
+        }
+
+        // Build query parameters
+        const params = new URLSearchParams({
+          userannotation: 'userwhere',
+          query: args.pattern,
+          maxResults: String(maxResults),
+        });
+
+        // Add object URI references
+        uris.forEach((uri, i) => {
+          params.set(`objectReferences.${i}.uri`, uri);
+        });
+
+        const result = await client.fetch(
+          `/sap/bc/adt/repository/informationsystem/search?${params.toString()}`,
+          {
+            method: 'GET',
+            headers: { Accept: 'application/json' },
+          },
+        );
Evidence
The tool builds uris from inputs, but never validates that uris.length > 0 before issuing the
request. When empty, no objectReferences.*.uri params are added and the endpoint is still called,
violating the tool’s intended “within a list of ABAP object URIs” behavior.

packages/adt-mcp/src/lib/tools/grep-objects.ts[1-8]
packages/adt-mcp/src/lib/tools/grep-objects.ts[52-82]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`grep_objects` can issue an unscoped search request when no URIs are provided or resolvable.

### Issue Context
If `objectUris` is omitted and `objects` cannot be resolved, `uris` remains empty but the code still calls the ADT search endpoint. This can lead to surprising results and potentially expensive server-side searches.

### Fix Focus Areas
- packages/adt-mcp/src/lib/tools/grep-objects.ts[51-82]

### What to change
- Add a guard after URI resolution: if `uris.length === 0`, return an `isError: true` response explaining that at least one URI/object is required (or that resolution failed).
- Optionally enforce via Zod: require `objectUris` or `objects` to be provided (and non-empty).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

@kilo-code-bot
Copy link
Copy Markdown

kilo-code-bot Bot commented Apr 15, 2026

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Overview

Severity Count
CRITICAL 0
WARNING 0
SUGGESTION 0

Notes

This PR adds 12 new MCP tools for feature parity with the vibing-steampunk project. Key changes:

  1. New MCP Tools: activate_package, call-hierarchy (get_callers_of/get_callees_of), clone_object, create_object, create_package, delete_object, get_inactive_objects, get_object_references, get_transport_list, get_type_hierarchy, grep_search, object_structure, pretty_print, search_quick, software_components, transport_create, transport_release

  2. CTS Implementation: The previously stubbed cts_create_transport and cts_release_transport tools are now fully implemented using the typed contracts (transportmanagmentCreate schema).

  3. Infrastructure: Added GitHub Actions workflow for Copilot setup and updated Husky pre-commit hook with bunx/npx fallback.

  4. Mock Server: Extended with fixtures and routes for all new endpoints.

All code follows the existing conventions in the codebase (typed contracts, schema-based serialization, proper error handling patterns).

Files Reviewed (6 files)
  • .github/workflows/copilot-setup-steps.yml
  • .husky/pre-commit
  • packages/adt-mcp/src/lib/mock/fixtures.ts
  • packages/adt-mcp/src/lib/mock/server.ts
  • packages/adt-mcp/src/lib/tools/cts-create-transport.ts
  • packages/adt-mcp/src/lib/tools/cts-release-transport.ts

Code review completed - no blocking issues identified


Reviewed by minimax-m2.5-20260211 · 1,016,013 tokens

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR expands packages/adt-mcp with a substantial set of new MCP tools (bringing the tool surface closer to the “vibing-steampunk” feature set) and updates developer automation by adding a Copilot setup workflow plus a bun-first pre-commit formatting hook.

Changes:

  • Add many new adt-mcp tools (search/grep, DDIC/table access, SQL data preview, navigation/call hierarchy, object/package operations, locks, abapGit export, service binding publish, feature probing).
  • Extend adt-mcp integration tests and mock ADT server fixtures/routes to cover the new tools.
  • Add .github/workflows/copilot-setup-steps.yml and update .husky/pre-commit to prefer bunx with npx fallback.

Reviewed changes

Copilot reviewed 31 out of 31 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
packages/adt-mcp/tests/integration.test.ts Adds integration coverage for the newly registered tools and updates tool listing expectations.
packages/adt-mcp/src/lib/tools/unlock-object.ts New tool to release ADT locks via @abapify/adt-locks.
packages/adt-mcp/src/lib/tools/run-query.ts New tool to execute freestyle SELECT queries via data preview endpoint.
packages/adt-mcp/src/lib/tools/publish-service-binding.ts New tool to publish/unpublish SRVB service bindings.
packages/adt-mcp/src/lib/tools/pretty-print.ts New tool to format ABAP source via ADT pretty printer.
packages/adt-mcp/src/lib/tools/object-creation.ts Shared helpers/types for create/clone object operations.
packages/adt-mcp/src/lib/tools/lock-object.ts New tool to acquire ADT edit locks and return lock handle.
packages/adt-mcp/src/lib/tools/index.ts Registers the added tools in the MCP server tool registry.
packages/adt-mcp/src/lib/tools/grep-packages.ts New tool to content-search across a package/subpackages via info system search.
packages/adt-mcp/src/lib/tools/grep-objects.ts New tool to content-search within specific objects/URIs.
packages/adt-mcp/src/lib/tools/git-tools.ts New abapGit tools: list exportable types and export package contents.
packages/adt-mcp/src/lib/tools/get-type-hierarchy.ts New tool to fetch OO type hierarchy (super/sub-types, interfaces).
packages/adt-mcp/src/lib/tools/get-table.ts New tool to retrieve DDIC table/structure metadata via typed contracts.
packages/adt-mcp/src/lib/tools/get-table-contents.ts New tool to query table contents using data preview freestyle endpoint.
packages/adt-mcp/src/lib/tools/get-object-structure.ts New tool to retrieve ADT object structure tree.
packages/adt-mcp/src/lib/tools/get-installed-components.ts New tools for installed components + feature probing logic.
packages/adt-mcp/src/lib/tools/function-tools.ts New tools to read function group/module metadata and optional source.
packages/adt-mcp/src/lib/tools/find-references.ts New tool to query where-used/usages via info system endpoint.
packages/adt-mcp/src/lib/tools/find-definition.ts New tool to navigate to definition via ADT navigation target endpoint.
packages/adt-mcp/src/lib/tools/delete-object.ts New tool to delete ABAP objects via typed contracts or URI fallback.
packages/adt-mcp/src/lib/tools/cts-release-transport.ts Implements CTS release transport via direct ADT POST.
packages/adt-mcp/src/lib/tools/cts-create-transport.ts Implements CTS create transport via typed schema body and response parsing.
packages/adt-mcp/src/lib/tools/create-package.ts New tool to create DEVC packages with package-specific options.
packages/adt-mcp/src/lib/tools/create-object.ts New tool to create common object types via typed contracts.
packages/adt-mcp/src/lib/tools/clone-object.ts New tool to clone source-backed objects by copying source and locking/unlocking.
packages/adt-mcp/src/lib/tools/call-hierarchy.ts New tools to fetch callers/callees via info system call hierarchy endpoints.
packages/adt-mcp/src/lib/tools/activate-package.ts New tool to batch-activate inactive objects in a package.
packages/adt-mcp/src/lib/mock/server.ts Adds mock routes for new endpoints used by the added tools/tests.
packages/adt-mcp/src/lib/mock/fixtures.ts Adds fixtures for new endpoints (grep, tables, navigation, call hierarchy, etc.).
.husky/pre-commit Updates hook to prefer bunx with npx fallback for formatting.
.github/workflows/copilot-setup-steps.yml Adds Copilot setup workflow that installs bun/deps and writes a pre-commit hook.

Comment on lines +51 to +74
// Resolve URIs from name/type pairs if provided (in parallel)
const uris: string[] = args.objectUris ? [...args.objectUris] : [];
if (args.objects && args.objects.length > 0) {
const resolved = await Promise.all(
args.objects.map((obj) =>
resolveObjectUri(client, obj.objectName, obj.objectType),
),
);
for (const uri of resolved) {
if (uri) uris.push(uri);
}
}

// Build query parameters
const params = new URLSearchParams({
userannotation: 'userwhere',
query: args.pattern,
maxResults: String(maxResults),
});

// Add object URI references
uris.forEach((uri, i) => {
params.set(`objectReferences.${i}.uri`, uri);
});
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

grep_objects can be called without objectUris and without objects, which results in sending a content-search request with no objectReferences (only userannotation=userwhere). That effectively turns this into a repository-wide search, which can be extremely expensive/unbounded on real systems and is likely not what callers expect. Consider rejecting the request when both inputs are missing, or requiring at least one scope parameter (objectUris/objects/packageName) before querying.

Copilot uses AI. Check for mistakes.
Comment on lines +69 to +79
// Extract transport number from response
const data = getRecord(response);
const request =
getRecord(getRecord(data?.root)?.request) ??
getRecord(data?.request) ??
data;
const transportNumber =
getStringField(request, 'trkorr') ??
getStringField(request, 'number') ??
'';

Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cts_create_transport falls back to transport: '' when it cannot extract a transport number from the ADT response. Returning success with an empty transport ID makes the tool output ambiguous and breaks downstream usage. If the transport number cannot be parsed, return an error (or at least include the raw response) so callers can detect failure reliably.

Copilot uses AI. Check for mistakes.
url.startsWith('/sap/bc/adt/functions/groups') ||
url.startsWith('/sap/bc/adt/packages'))
) {
return { status: 200, body: '', contentType: 'text/plain' };
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The mock server returns text/plain with an empty body for object-creation POSTs (programs/classes/interfaces/function groups/packages). Many of these operations are contract-based and expect vendor XML content types; returning empty text/plain bypasses XML schema parsing in the adapter and can hide serialization/contract issues in tests. Consider returning a realistic Content-Type (and minimal XML/JSON body where applicable) per endpoint so integration tests exercise the same parsing paths as production.

Suggested change
return { status: 200, body: '', contentType: 'text/plain' };
const contentType = url.startsWith('/sap/bc/adt/programs/programs')
? 'application/vnd.sap.adt.programs.program.v1+xml'
: url.startsWith('/sap/bc/adt/oo/classes')
? 'application/vnd.sap.adt.oo.classes.v1+xml'
: url.startsWith('/sap/bc/adt/oo/interfaces')
? 'application/vnd.sap.adt.oo.interfaces.v1+xml'
: url.startsWith('/sap/bc/adt/functions/groups')
? 'application/vnd.sap.adt.functions.groups.v1+xml'
: 'application/vnd.sap.adt.packages.v1+xml';
const body =
`<?xml version="1.0" encoding="utf-8"?>` +
`<adtcore:objectReference xmlns:adtcore="http://www.sap.com/adt/core" uri="${url}" name="MOCK_OBJECT"/>`;
return { status: 200, body, contentType };

Copilot uses AI. Check for mistakes.
Comment on lines +24 to +39
// New tools – high-priority feature parity (#H1–#H8)
import { registerGrepObjectsTool } from './grep-objects';
import { registerGrepPackagesTool } from './grep-packages';
import { registerGetTableTool } from './get-table';
import { registerGetTableContentsTool } from './get-table-contents';
import { registerRunQueryTool } from './run-query';
import { registerFindDefinitionTool } from './find-definition';
import { registerFindReferencesTool } from './find-references';
import {
registerGetCallersOfTool,
registerGetCalleesOfTool,
} from './call-hierarchy';
import { registerCreateObjectTool } from './create-object';
import { registerDeleteObjectTool } from './delete-object';
import { registerActivatePackageTool } from './activate-package';
// Medium-priority feature parity (#M1–#M10)
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR description focuses on the Copilot setup workflow + Husky hook changes, but the diff also introduces a large set of new adt-mcp tools and related tests. Updating the PR description to mention the tool additions (and any behavioral/compatibility implications) would help reviewers understand the full scope and risk of the change.

Copilot uses AI. Check for mistakes.
Comment on lines +81 to +90
// Fetch the discovery document to understand available services
const discovery = (await client.fetch('/sap/bc/adt/discovery', {
method: 'GET',
headers: { Accept: 'application/json' },
})) as {
workspaces?: Array<{
title: string;
collections?: Array<{ href: string; title: string }>;
}>;
};
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

get_features fetches /sap/bc/adt/discovery via client.fetch with Accept: application/json. The discovery endpoint is defined in adt-contracts as application/atomsvc+xml, and the generic client.fetch path does not apply a schema parser for XML responses, so this will return raw XML text and cause services extraction to silently produce an empty feature set. Use client.adt.discovery.getDiscovery() (contract) or request/parse application/atomsvc+xml explicitly before deriving features.

Suggested change
// Fetch the discovery document to understand available services
const discovery = (await client.fetch('/sap/bc/adt/discovery', {
method: 'GET',
headers: { Accept: 'application/json' },
})) as {
workspaces?: Array<{
title: string;
collections?: Array<{ href: string; title: string }>;
}>;
};
// Fetch and parse the discovery document using the ADT contract client
const discovery = await client.adt.discovery.getDiscovery();

Copilot uses AI. Check for mistakes.
Comment thread .husky/pre-commit
Comment on lines +1 to +5
if command -v bunx >/dev/null 2>&1; then
bunx nx format:write --uncommitted
else
npx nx format:write --uncommitted
fi
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

1. npx fallback in hooks 📘 Rule violation ✧ Quality

The PR adds npx usage in the pre-commit hook and Copilot setup workflow, violating the requirement
to use bun/bunx exclusively. This can lead to inconsistent toolchains across environments and
breaks the bun-only compliance policy.
Agent Prompt
## Issue description
Modified hook/workflow uses `npx`, but policy requires `bun`/`bunx` exclusively.

## Issue Context
Compliance ID 339850 disallows `npm`/`npx`/`yarn`/`pnpm` usage in changed scripts and CI.

## Fix Focus Areas
- .husky/pre-commit[1-5]
- .github/workflows/copilot-setup-steps.yml[30-41]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines 33 to 38
export function registerCtsCreateTransportTool(
server: McpServer,
_ctx: ToolContext,
ctx: ToolContext,
): void {
server.tool(
'cts_create_transport',
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

2. Parity map still says “not yet” 📘 Rule violation ✧ Quality

The README feature parity map and tool docs still state cts_create_transport and
cts_release_transport are not implemented, despite the PR adding these tools. This leaves
documentation inconsistent with shipped behavior.
Agent Prompt
## Issue description
README still claims `cts_create_transport` and `cts_release_transport` are not implemented, but the tools now exist.

## Issue Context
Compliance requires tool docs + Feature Parity Map to reflect newly implemented tools.

## Fix Focus Areas
- packages/adt-mcp/README.md[359-385]
- packages/adt-mcp/README.md[541-559]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +136 to +162
export function registerGetCallersOfTool(
server: McpServer,
ctx: ToolContext,
): void {
registerCallHierarchyTool(server, ctx, {
toolName: 'get_callers_of',
toolDescription:
'Find all callers (upward call hierarchy) of an ABAP method, function module, or subroutine',
endpoint: 'callers',
resultKey: 'callers',
failureLabel: 'Get callers failed',
});
}

export function registerGetCalleesOfTool(
server: McpServer,
ctx: ToolContext,
): void {
registerCallHierarchyTool(server, ctx, {
toolName: 'get_callees_of',
toolDescription:
'Find all callees (downward call hierarchy) of an ABAP method, function module, or subroutine',
endpoint: 'callees',
resultKey: 'callees',
failureLabel: 'Get callees failed',
});
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

3. Two tools in call-hierarchy.ts 📘 Rule violation ⌂ Architecture

packages/adt-mcp/src/lib/tools/call-hierarchy.ts exports two tool registration functions,
violating the one-tool-per-file single register export requirement. This makes tool wiring and
ownership unclear.
Agent Prompt
## Issue description
`call-hierarchy.ts` defines and exports two tool registration functions.

## Issue Context
Policy requires one tool per file and exactly one exported register function per tool file.

## Fix Focus Areas
- packages/adt-mcp/src/lib/tools/call-hierarchy.ts[1-162]
- packages/adt-mcp/src/lib/tools/index.ts[32-36]
- packages/adt-mcp/src/lib/tools/index.ts[83-87]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +58 to +63
const lockService = createLockService(client);
const lockHandle = await lockService.lock(objectUri, {
transport: args.transport,
objectName: args.objectName,
objectType: args.objectType,
});
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

4. lock_object never unlocks 📘 Rule violation ☼ Reliability

lock_object acquires a lock via createLockService(client).lock() without guaranteeing an unlock
in a finally-equivalent block. This violates the lock lifecycle requirement and risks leaving
locks held on error paths or abandoned sessions.
Agent Prompt
## Issue description
A lock is acquired with `createLockService(client).lock()` but is not guaranteed to be released via `unlock()` in a `finally` block.

## Issue Context
Compliance requires lock cleanup on all exit paths.

## Fix Focus Areas
- packages/adt-mcp/src/lib/tools/lock-object.ts[58-83]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +31 to +41
await client.fetch(
`/sap/bc/adt/cts/transportrequests/${args.transport}?_action=RELEASE`,
{
type: 'text' as const,
text: 'Transport release is not supported: the ADT client transports.release() method is not yet implemented.',
method: 'POST',
headers: {
'Content-Type':
'application/vnd.sap.adt.transportorganizer.v1+xml',
Accept: 'application/vnd.sap.adt.transportorganizer.v1+xml',
},
},
],
};
);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

5. Tools bypass adt contracts 📘 Rule violation ⌂ Architecture

Multiple new tools call hardcoded ADT URLs via client.fetch(...) instead of using
@abapify/adt-contracts endpoint contracts. This violates the requirement to introduce/consume
contracts before using endpoints in adt-mcp.
Agent Prompt
## Issue description
Tools are calling ADT endpoints via hardcoded URLs using `client.fetch(...)` rather than consuming typed endpoint contracts from `@abapify/adt-contracts`.

## Issue Context
Compliance requires creating/using endpoint contracts before using endpoints in `adt-mcp`.

## Fix Focus Areas
- packages/adt-mcp/src/lib/tools/cts-release-transport.ts[29-41]
- packages/adt-mcp/src/lib/tools/activate-package.ts[37-45]
- packages/adt-mcp/src/lib/tools/call-hierarchy.ts[53-61]
- packages/adt-mcp/src/lib/tools/git-tools.ts[37-44]
- packages/adt-mcp/src/lib/tools/function-tools.ts[108-119]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +31 to 40
await client.fetch(
`/sap/bc/adt/cts/transportrequests/${args.transport}?_action=RELEASE`,
{
type: 'text' as const,
text: 'Transport release is not supported: the ADT client transports.release() method is not yet implemented.',
method: 'POST',
headers: {
'Content-Type':
'application/vnd.sap.adt.transportorganizer.v1+xml',
Accept: 'application/vnd.sap.adt.transportorganizer.v1+xml',
},
},
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

6. Release missing xml body 🐞 Bug ≡ Correctness

cts_release_transport sends a POST with no request body, but this repo’s CTS contract/tests define
POST /sap/bc/adt/cts/transportrequests/{trkorr} as requiring a transportmanagment body, so the
release call can fail against real ADT servers.
Agent Prompt
### Issue description
`cts_release_transport` currently POSTs to the release endpoint without sending the XML body that the repo’s CTS `transportrequests.post()` contract expects.

### Issue Context
In this repo, CTS release is modeled as a POST to `/sap/bc/adt/cts/transportrequests/{trkorr}` with a `transportmanagment` body and `Content-Type: application/xml`. The current MCP tool uses `client.fetch()` with only headers and no body, which can break against ADT implementations that require the payload.

### Fix Focus Areas
- packages/adt-mcp/src/lib/tools/cts-release-transport.ts[27-41]
- packages/adt-contracts/src/adt/cts/transportrequests/index.ts[57-66]
- packages/adt-contracts/tests/contracts/cts.test.ts[116-127]

### What to change
- Build and send a minimal `transportmanagment` XML body (e.g., via `@abapify/adt-schemas`’ `transportmanagment` serializer) and set `Content-Type: application/xml`.
- Keep the `_action=RELEASE` query param if required by the release behavior, but ensure the request still includes the contract-compliant body.
- Consider validating the response / surfacing errors instead of always returning `status: released`.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +81 to +100
// Fetch the discovery document to understand available services
const discovery = (await client.fetch('/sap/bc/adt/discovery', {
method: 'GET',
headers: { Accept: 'application/json' },
})) as {
workspaces?: Array<{
title: string;
collections?: Array<{ href: string; title: string }>;
}>;
};

// Extract all service paths from the discovery document
const services = new Set<string>();
if (discovery?.workspaces) {
for (const ws of discovery.workspaces) {
for (const col of ws.collections ?? []) {
services.add(col.href);
}
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

7. Discovery parsed as json 🐞 Bug ≡ Correctness

get_features requests and parses /sap/bc/adt/discovery as JSON with a {workspaces: ...} shape,
but this repo’s discovery contract is AtomPub XML (application/atomsvc+xml) and its schema shape
is {service: {workspace: ...}}, causing the tool to silently return empty/false features.
Agent Prompt
### Issue description
`get_features` assumes `/sap/bc/adt/discovery` returns JSON with a `workspaces` array, which contradicts this repo’s discovery contract/schema and leads to empty service detection.

### Issue Context
- The repo’s discovery contract declares `Accept: application/atomsvc+xml`.
- The generated schema shape is `{ service: { workspace: [{ collection: [{ href, title, ... }] }] } }`.
- `client.fetch()` does not apply an XML schema unless provided via a typed contract, so parsing as JSON is brittle.

### Fix Focus Areas
- packages/adt-mcp/src/lib/tools/get-installed-components.ts[81-123]
- packages/adt-contracts/src/adt/discovery/index.ts[26-30]
- packages/adt-schemas/src/schemas/generated/types/custom/discovery.types.ts[8-24]

### What to change
- Replace the raw `client.fetch('/sap/bc/adt/discovery', { Accept: 'application/json' })` call with `client.adt.discovery.getDiscovery()`.
- Extract collections from `discovery.service.workspace[].collection[]` (not `workspaces/collections`).
- Keep the rest of the feature detection logic but base it on the correct `href` list.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

ThePlenkov added a commit that referenced this pull request Apr 15, 2026
Tighten MCP follow-up behavior after PR #101 by fixing discovery parsing, preventing unscoped grep searches, hardening CTS transport handling, and updating the mock server to reflect XML-based ADT responses.

Co-authored-by: Codex <noreply@openai.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(adt-mcp): Feature parity with vibing-steampunk — onboard essential MCP tool capabilities

3 participants