Skip to main content
Glama
handleGetEnhancementSpot.tsâ€ĸ6.84 kB
import { McpError, ErrorCode } from '../lib/utils'; import { makeAdtRequestWithTimeout, return_error, getBaseUrl, logger, encodeSapObjectName } from '../lib/utils'; import { writeResultToFile } from '../lib/writeResultToFile'; export const TOOL_DEFINITION = { "name": "GetEnhancementSpot", "description": "Retrieve metadata and list of implementations for a specific enhancement spot.", "inputSchema": { "type": "object", "properties": { "enhancement_spot": { "type": "string", "description": "Name of the enhancement spot" } }, "required": [ "enhancement_spot" ] } } as const; /** * Interface for enhancement spot response */ export interface EnhancementSpotResponse { enhancement_spot: string; metadata: { description?: string; type?: string; status?: string; }; } /** * Parses enhancement spot XML to extract metadata and function (implementation) descriptions. * @param xmlData - Raw XML response from ADT * @returns Metadata object with description, type, status, and functions (implementations) */ function parseEnhancementSpotMetadata(xmlData: string): any { const metadata: any = {}; try { // Spot name, description, type, package const nameMatch = xmlData.match(/adtcore:name="([^"]*)"/); if (nameMatch && nameMatch[1]) metadata.name = nameMatch[1]; const descMatch = xmlData.match(/adtcore:description="([^"]*)"/); if (descMatch && descMatch[1]) metadata.description = descMatch[1]; const typeMatch = xmlData.match(/adtcore:type="([^"]*)"/); if (typeMatch && typeMatch[1]) metadata.type = typeMatch[1]; const pkgMatch = xmlData.match(/adtcore:packageRef[^>]+adtcore:name="([^"]*)"/); if (pkgMatch && pkgMatch[1]) metadata.package = pkgMatch[1]; // Interface reference const ifaceMatch = xmlData.match(/<enhs:interface[^>]*adtcore:name="([^"]*)"/); if (ifaceMatch && ifaceMatch[1]) metadata.interface = ifaceMatch[1]; // BAdI definitions const badiDefs: Array<any> = []; const badiDefRegex = /<enhs:badiDefinition[\s\S]*?<\/enhs:badiDefinition>/g; let badiMatch; while ((badiMatch = badiDefRegex.exec(xmlData)) !== null) { const block = badiMatch[0]; const badiName = (block.match(/enhs:name="([^"]*)"/) || [])[1]; const badiShort = (block.match(/enhs:shorttext="([^"]*)"/) || [])[1]; const badiIface = (block.match(/<enhs:interface[^>]*adtcore:name="([^"]*)"/) || [])[1]; badiDefs.push({ name: badiName, shorttext: badiShort, interface: badiIface }); } if (badiDefs.length > 0) metadata.badi_definitions = badiDefs; // All atom:link rels const links: Array<any> = []; const linkRegex = /<atom:link ([^>]+)\/>/g; let linkMatch; while ((linkMatch = linkRegex.exec(xmlData)) !== null) { const attrs = linkMatch[1]; const href = (attrs.match(/href="([^"]*)"/) || [])[1]; const rel = (attrs.match(/rel="([^"]*)"/) || [])[1]; const type = (attrs.match(/type="([^"]*)"/) || [])[1]; const title = (attrs.match(/title="([^"]*)"/) || [])[1]; links.push({ href, rel, type, title }); } if (links.length > 0) metadata.links = links; logger.info(`Parsed structured metadata for enhancement spot:`, metadata); return metadata; } catch (parseError) { logger.error('Failed to parse enhancement spot XML metadata:', parseError); return {}; } } /** * Handler to retrieve metadata for a specific enhancement spot in an ABAP system. * This function uses the SAP ADT API endpoint to fetch details about an enhancement spot, * regardless of whether it has any implementations. It is designed to provide information * about the spot's existence, description, type, and status. * * @param args - Tool arguments containing: * - enhancement_spot: Name of the enhancement spot (e.g., 'enhoxhh'). This is a required parameter. * @returns Response object containing: * - enhancement_spot: The name of the queried enhancement spot. * - metadata: An object with properties like description, type, and status of the enhancement spot. * - raw_xml: The raw XML response from the ADT API for debugging purposes. * - In case of error, an error object with details about the failure. */ export async function handleGetEnhancementSpot(args: any) { try { logger.info('handleGetEnhancementSpot called with args:', args); if (!args?.enhancement_spot) { throw new McpError(ErrorCode.InvalidParams, 'Enhancement spot is required'); } const enhancementSpot = args.enhancement_spot; logger.info(`Getting metadata for enhancement spot: ${enhancementSpot}`); // Build the ADT URL for the specific enhancement spot (Eclipse uses /sap/bc/adt/enhancements/enhsxsb/{spot_name}) const url = `${await getBaseUrl()}/sap/bc/adt/enhancements/enhsxsb/${encodeSapObjectName(enhancementSpot)}`; logger.info(`Enhancement spot URL: ${url}`); const response = await makeAdtRequestWithTimeout(url, 'GET', 'default', { 'Accept': 'application/vnd.sap.adt.enhancements.v1+xml' }); if (response.status === 200 && response.data) { // Parse the XML to extract metadata const metadata = parseEnhancementSpotMetadata(response.data); const enhancementSpotResponse: EnhancementSpotResponse = { enhancement_spot: enhancementSpot, metadata: metadata }; const result = { isError: false, content: [ { type: "json", json: enhancementSpotResponse } ] }; if (args.filePath) { writeResultToFile(JSON.stringify(result, null, 2), args.filePath); } return result; } else { throw new McpError( ErrorCode.InternalError, `Failed to retrieve metadata for enhancement spot ${enhancementSpot}. Status: ${response.status}` ); } } catch (error) { // MCP-compliant error response: always return content[] with type "text" return { isError: true, content: [ { type: "text", text: `ADT error: ${String(error)}` } ] }; } }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/fr0ster/mcp-abap-adt'

If you have feedback or need assistance with the MCP directory API, please join our Discord server