feat(adt-mcp): add 12 high-priority tools for vibing-steampunk feature parity (17 → 29 tools)#101
Conversation
…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>
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>
|
View your CI Pipeline Execution ↗ for commit a001ded
☁️ Nx Cloud last updated this comment at |
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>
|
Review Summary by QodoAdd 23 high-priority tools for feature parity with vibing-steampunk (6 → 29 tools)
WalkthroughsDescription• 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 Diagramflowchart 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"]
File Changes1. packages/adt-mcp/tests/integration.test.ts
|
Code Review by Qodo
|
Code Review SummaryStatus: No Issues Found | Recommendation: Merge Overview
NotesThis PR adds 12 new MCP tools for feature parity with the vibing-steampunk project. Key changes:
All code follows the existing conventions in the codebase (typed contracts, schema-based serialization, proper error handling patterns). Files Reviewed (6 files)
Code review completed - no blocking issues identified Reviewed by minimax-m2.5-20260211 · 1,016,013 tokens |
There was a problem hiding this comment.
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-mcptools (search/grep, DDIC/table access, SQL data preview, navigation/call hierarchy, object/package operations, locks, abapGit export, service binding publish, feature probing). - Extend
adt-mcpintegration tests and mock ADT server fixtures/routes to cover the new tools. - Add
.github/workflows/copilot-setup-steps.ymland update.husky/pre-committo preferbunxwithnpxfallback.
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. |
| // 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); | ||
| }); |
There was a problem hiding this comment.
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.
| // 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') ?? | ||
| ''; | ||
|
|
There was a problem hiding this comment.
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.
| url.startsWith('/sap/bc/adt/functions/groups') || | ||
| url.startsWith('/sap/bc/adt/packages')) | ||
| ) { | ||
| return { status: 200, body: '', contentType: 'text/plain' }; |
There was a problem hiding this comment.
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.
| 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 }; |
| // 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) |
There was a problem hiding this comment.
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.
| // 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 }>; | ||
| }>; | ||
| }; |
There was a problem hiding this comment.
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.
| // 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(); |
| if command -v bunx >/dev/null 2>&1; then | ||
| bunx nx format:write --uncommitted | ||
| else | ||
| npx nx format:write --uncommitted | ||
| fi |
There was a problem hiding this comment.
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
| export function registerCtsCreateTransportTool( | ||
| server: McpServer, | ||
| _ctx: ToolContext, | ||
| ctx: ToolContext, | ||
| ): void { | ||
| server.tool( | ||
| 'cts_create_transport', |
There was a problem hiding this comment.
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
| 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', | ||
| }); | ||
| } |
There was a problem hiding this comment.
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
| const lockService = createLockService(client); | ||
| const lockHandle = await lockService.lock(objectUri, { | ||
| transport: args.transport, | ||
| objectName: args.objectName, | ||
| objectType: args.objectType, | ||
| }); |
There was a problem hiding this comment.
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
| 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', | ||
| }, | ||
| }, | ||
| ], | ||
| }; | ||
| ); |
There was a problem hiding this comment.
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
| 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', | ||
| }, | ||
| }, |
There was a problem hiding this comment.
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
| // 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); | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
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
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>



.github/workflows/copilot-setup-steps.yml— installs bun, deps, and createspre-commithook in.git/copilot-hooks/.husky/pre-committo support both bun (bunx first) and npm (npx fallback) environments