ABAP-ADT-API MCP-Server

by mario-andreschak
Verified
import { McpError, ErrorCode } from "@modelcontextprotocol/sdk/types.js"; import { BaseHandler } from './BaseHandler'; import type { ToolDefinition } from '../types/tools'; interface InactiveObject { "adtcore:uri": string; "adtcore:type": string; "adtcore:name": string; "adtcore:parentUri": string; } interface ActivationResultMessage { objDescr: string; type: string; line: number; href: string; forceSupported: boolean; shortText: string; } interface ActivationResult { success: boolean; messages: ActivationResultMessage[]; inactive: InactiveObjectRecord[]; } interface InactiveObjectElement extends InactiveObject { user: string; deleted: boolean; } interface InactiveObjectRecord { object?: InactiveObjectElement; transport?: InactiveObjectElement; } export class ObjectManagementHandlers extends BaseHandler { getTools(): ToolDefinition[] { return [ { name: 'activateObjects', description: 'Activate ABAP objects using object references', inputSchema: { type: 'object', properties: { objects: { type: 'string', description: 'JSON array of objects to activate. Each object must have adtcore:uri, adtcore:type, adtcore:name, and adtcore:parentUri properties' }, preauditRequested: { type: 'boolean', description: 'Whether to perform pre-audit checks', optional: true } }, required: ['objects'] } }, { name: 'activateByName', description: 'Activate an ABAP object using name and URL', inputSchema: { type: 'object', properties: { objectName: { type: 'string', description: 'Name of the object' }, objectUrl: { type: 'string', description: 'URL of the object' }, mainInclude: { type: 'string', description: 'Main include context', optional: true }, preauditRequested: { type: 'boolean', description: 'Whether to perform pre-audit checks', optional: true } }, required: ['objectName', 'objectUrl'] } }, { name: 'inactiveObjects', description: 'Get list of inactive objects', inputSchema: { type: 'object', properties: {} } } ]; } async handle(toolName: string, args: any): Promise<any> { switch (toolName) { case 'activateObjects': return this.handleActivateObjects(args); case 'activateByName': return this.handleActivateByName(args); case 'inactiveObjects': return this.handleInactiveObjects(args); default: throw new McpError(ErrorCode.MethodNotFound, `Unknown object management tool: ${toolName}`); } } async handleActivateObjects(args: any): Promise<any> { const startTime = performance.now(); try { if (!args.objects || typeof args.objects !== 'string') { throw new McpError(ErrorCode.InvalidParams, "objects parameter must be a JSON string"); } let objects: InactiveObject[]; try { objects = JSON.parse(args.objects); if (!Array.isArray(objects)) { throw new Error("Parsed objects must be an array"); } // Validate each object has required properties objects.forEach((obj, index) => { if (!obj["adtcore:uri"] || !obj["adtcore:type"] || !obj["adtcore:name"] || !obj["adtcore:parentUri"]) { throw new Error(`Object at index ${index} is missing required properties`); } }); } catch (parseError: any) { throw new McpError( ErrorCode.InvalidParams, `Invalid objects JSON: ${parseError.message}` ); } const result = await this.adtclient.activate(objects, args.preauditRequested); this.trackRequest(startTime, true); return { content: [{ type: 'text', text: JSON.stringify(result) }] }; } catch (error: any) { this.trackRequest(startTime, false); if (error instanceof McpError) { throw error; } throw new McpError( ErrorCode.InternalError, `Failed to activate objects: ${error.message || 'Unknown error'}` ); } } async handleActivateByName(args: any): Promise<any> { const startTime = performance.now(); try { if (!args.objectName || !args.objectUrl) { throw new McpError(ErrorCode.InvalidParams, "objectName and objectUrl parameters are required"); } const result = await this.adtclient.activate( args.objectName, args.objectUrl, args.mainInclude, args.preauditRequested ); this.trackRequest(startTime, true); return { content: [{ type: 'text', text: JSON.stringify(result) }] }; } catch (error: any) { this.trackRequest(startTime, false); if (error instanceof McpError) { throw error; } throw new McpError( ErrorCode.InternalError, `Failed to activate object: ${error.message || 'Unknown error'}` ); } } async handleInactiveObjects(args: any): Promise<any> { const startTime = performance.now(); try { const result: InactiveObjectRecord[] = await this.adtclient.inactiveObjects(); this.trackRequest(startTime, true); return { content: [{ type: 'text', text: JSON.stringify(result) }] }; } catch (error: any) { this.trackRequest(startTime, false); if (error instanceof McpError) { throw error; } throw new McpError( ErrorCode.InternalError, `Failed to get inactive objects: ${error.message || 'Unknown error'}` ); } } }