GetEnhancementImpl
Retrieve the source code of an ABAP enhancement implementation by specifying the enhancement spot and implementation name.
Instructions
[read-only] Retrieve source code of a specific enhancement implementation by its name and enhancement spot.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| enhancement_spot | Yes | Name of the enhancement spot | |
| enhancement_name | Yes | [read-only] Name of the enhancement implementation |
Implementation Reference
- Tool definition (name, description, inputSchema) for GetEnhancementImpl. Input requires enhancement_spot and enhancement_name strings.
import type { HandlerContext } from '../../../lib/handlers/interfaces'; import { ErrorCode, encodeSapObjectName, logger, McpError, makeAdtRequestWithTimeout, } from '../../../lib/utils'; import { writeResultToFile } from '../../../lib/writeResultToFile'; export const TOOL_DEFINITION = { name: 'GetEnhancementImpl', available_in: ['onprem', 'cloud'] as const, description: '[read-only] Retrieve source code of a specific enhancement implementation by its name and enhancement spot.', inputSchema: { type: 'object', properties: { enhancement_spot: { type: 'string', description: 'Name of the enhancement spot', }, enhancement_name: { type: 'string', description: '[read-only] Name of the enhancement implementation', }, }, required: ['enhancement_spot', 'enhancement_name'], }, } as const; - Main handler function handleGetEnhancementImpl that retrieves the source code of a specific enhancement implementation by its name and enhancement spot. Makes an ADT API request to /sap/bc/adt/enhancements/{spot}/{name}/source/main, parses the XML response to extract source code (supporting base64-encoded and CDATA formats), and falls back to spot metadata retrieval if the implementation is not found.
export async function handleGetEnhancementImpl( context: HandlerContext, args: any, ) { const { connection, logger } = context; try { logger?.info('handleGetEnhancementByName called with args:', args); if (!args?.enhancement_spot) { throw new McpError( ErrorCode.InvalidParams, 'Enhancement spot is required', ); } if (!args?.enhancement_name) { throw new McpError( ErrorCode.InvalidParams, 'Enhancement name is required', ); } const enhancementSpot = args.enhancement_spot; const enhancementName = args.enhancement_name; logger?.info( `Getting enhancement: ${enhancementName} from spot: ${enhancementSpot}`, ); // Build the ADT URL for the specific enhancement // Format: /sap/bc/adt/enhancements/{enhancement_spot}/{enhancement_name}/source/main const url = `/sap/bc/adt/enhancements/${encodeSapObjectName(enhancementSpot)}/${encodeSapObjectName(enhancementName)}/source/main`; logger?.info(`Enhancement URL: ${url}`); const response = await makeAdtRequestWithTimeout( connection, url, 'GET', 'default', ); if (response.status === 200 && response.data) { // Parse the XML to extract source code const sourceCode = parseEnhancementSourceFromXml(response.data); const enhancementResponse: EnhancementByNameResponse = { enhancement_spot: enhancementSpot, enhancement_name: enhancementName, source_code: sourceCode, }; const result = { isError: false, content: [ { type: 'json', json: enhancementResponse, }, ], }; if (args.filePath) { writeResultToFile(JSON.stringify(result, null, 2), args.filePath); } return result; } else { logger?.warn( `Enhancement ${enhancementName} not found in spot ${enhancementSpot}. Status: ${response.status}. Attempting to retrieve spot metadata as fallback.`, ); // Fallback to retrieve metadata about the enhancement spot const spotUrl = `/sap/bc/adt/enhancements/${encodeSapObjectName(enhancementSpot)}`; logger?.info(`Fallback enhancement spot URL: ${spotUrl}`); const spotResponse = await makeAdtRequestWithTimeout( connection, spotUrl, 'GET', 'default', { Accept: 'application/vnd.sap.adt.enhancements.v1+xml', }, ); if (spotResponse.status === 200 && spotResponse.data) { // Parse metadata if possible const metadata: { description?: string } = {}; const descriptionMatch = spotResponse.data.match( /<adtcore:description>([^<]*)<\/adtcore:description>/, ); if (descriptionMatch?.[1]) { metadata.description = descriptionMatch[1]; } const fallbackResult = { isError: false, content: [ { type: 'json', json: { enhancement_spot: enhancementSpot, enhancement_name: enhancementName, status: 'not_found', message: `Enhancement implementation ${enhancementName} not found in spot ${enhancementSpot}.`, spot_metadata: metadata, }, }, ], }; if (args.filePath) { writeResultToFile( JSON.stringify(fallbackResult, null, 2), args.filePath, ); } return fallbackResult; } else { throw new McpError( ErrorCode.InternalError, `Failed to retrieve enhancement ${enhancementName} from spot ${enhancementSpot}. Status: ${response.status}. Fallback to retrieve spot metadata also failed. Status: ${spotResponse.status}`, ); } } } catch (error) { // MCP-compliant error response: always return content[] with type "text" return { isError: true, content: [ { type: 'text', text: `ADT error: ${String(error)}`, }, ], }; } } - Helper function parseEnhancementSourceFromXml that extracts source code from XML response. Supports base64-encoded source tags and CDATA-wrapped text source tags.
function parseEnhancementSourceFromXml(xmlData: string): string { try { // Look for source code in various possible formats // Try to find base64 encoded source in <source> or similar tags const base64SourceRegex = /<(?:source|enh:source)[^>]*>([^<]*)<\/(?:source|enh:source)>/; const base64Match = xmlData.match(base64SourceRegex); if (base64Match?.[1]) { try { // Decode base64 source code const decodedSource = Buffer.from(base64Match[1], 'base64').toString( 'utf-8', ); return decodedSource; } catch (decodeError) { logger?.warn('Failed to decode base64 source code:', decodeError); } } // Try to find plain text source code const textSourceRegex = /<(?:source|enh:source)[^>]*>\s*<!\[CDATA\[(.*?)\]\]>\s*<\/(?:source|enh:source)>/s; const textMatch = xmlData.match(textSourceRegex); if (textMatch?.[1]) { return textMatch[1]; } // If no specific source tags found, return the entire XML as fallback logger?.warn( 'Could not find source code in expected format, returning raw XML', ); return xmlData; } catch (parseError) { logger?.error('Failed to parse enhancement source XML:', parseError); return xmlData; // Return raw XML as fallback } } - src/lib/handlers/groups/ReadOnlyHandlersGroup.ts:21-24 (registration)Import of TOOL_DEFINITION (as GetEnhancementImpl_Tool) and handleGetEnhancementImpl from the handler file.
import { TOOL_DEFINITION as GetEnhancementImpl_Tool, handleGetEnhancementImpl, } from '../../../handlers/enhancement/readonly/handleGetEnhancementImpl'; - src/lib/handlers/groups/ReadOnlyHandlersGroup.ts:173-176 (registration)Registration of GetEnhancementImpl_Tool with its handler function in the ReadOnlyHandlersGroup entries.
{ toolDefinition: GetEnhancementImpl_Tool, handler: (args: any) => handleGetEnhancementImpl(this.context, args), },