Skip to main content
Glama
handleCreateTransport.ts6.21 kB
/** * CreateTransport Handler - Create new ABAP transport request via ADT API * * Uses TransportBuilder from @mcp-abap-adt/adt-clients for all operations. * Session and lock management handled internally by builder. * * Workflow: create */ import { McpError, ErrorCode, AxiosResponse } from '../lib/utils'; import { return_error, return_response, logger, getManagedConnection } from '../lib/utils'; import { CrudClient } from '@mcp-abap-adt/adt-clients'; export const TOOL_DEFINITION = { name: "CreateTransport", description: "Create a new ABAP transport request in SAP system for development objects.", inputSchema: { type: "object", properties: { transport_type: { type: "string", description: "Transport type: 'workbench' (cross-client) or 'customizing' (client-specific)", enum: ["workbench", "customizing"], default: "workbench" }, description: { type: "string", description: "Transport request description (mandatory)" }, target_system: { type: "string", description: "Target system for transport (optional, e.g., 'PRD', 'QAS'). If not provided or empty, uses 'LOCAL'" }, owner: { type: "string", description: "Transport owner (optional, defaults to current user)" } }, required: ["description"] } } as const; interface CreateTransportArgs { transport_type?: string; description: string; target_system?: string; owner?: string; } /** * Main handler for CreateTransport MCP tool * * Uses TransportBuilder from @mcp-abap-adt/adt-clients for all operations * Session and lock management handled internally by builder */ export async function handleCreateTransport(args: any) { try { // Validate required parameters if (!args?.description) { throw new McpError(ErrorCode.InvalidParams, 'Transport description is required'); } const typedArgs = args as CreateTransportArgs; const connection = getManagedConnection(); logger.info(`Starting transport creation: ${typedArgs.description}`); try { // Create client const client = new CrudClient(connection); // Create transport await client.createTransport( typedArgs.description, typedArgs.transport_type === 'customizing' ? 'customizing' : 'workbench' ); // Get create result const createResult = client.getCreateResult(); logger.info(`✅ CreateTransport completed successfully`); // Parse response data if available let transportInfo: any = {}; let transportNumber: string | undefined; let taskNumber: string | undefined; if (createResult?.data) { if (typeof createResult.data === 'string') { // If data is XML string, try to parse it try { const { XMLParser } = require('fast-xml-parser'); const parser = new XMLParser({ ignoreAttributes: false, attributeNamePrefix: '', parseAttributeValue: true, }); const result = parser.parse(createResult.data); const root = result['tm:root'] || result['root']; const request = root?.['tm:request'] || {}; const task = request?.['tm:task'] || {}; transportInfo = { transport_number: request['tm:number'] || transportNumber, description: request['tm:desc'] || request['tm:description'] || typedArgs.description, type: request['tm:type'], target_system: request['tm:target'], target_desc: request['tm:target_desc'], cts_project: request['tm:cts_project'], uri: request['tm:uri'], owner: task['tm:owner'] || request['tm:owner'] || typedArgs.owner }; } catch (parseError) { // If parsing fails, use basic info transportInfo = { transport_number: transportNumber, description: typedArgs.description, type: typedArgs.transport_type === 'customizing' ? 'T' : 'K', owner: typedArgs.owner }; } } else if (typeof createResult.data === 'object') { transportInfo = createResult.data; } } // Use builder state if response parsing didn't provide transport number if (!transportInfo.transport_number && transportNumber) { transportInfo.transport_number = transportNumber; } if (!transportInfo.task_number && taskNumber) { transportInfo.task_number = taskNumber; } return return_response({ data: JSON.stringify({ success: true, transport_request: transportInfo.transport_number || transportNumber, task_number: transportInfo.task_number || taskNumber, description: transportInfo.description || typedArgs.description, type: transportInfo.type || (typedArgs.transport_type === 'customizing' ? 'T' : 'K'), target_system: transportInfo.target_system || typedArgs.target_system || 'LOCAL', target_desc: transportInfo.target_desc, cts_project: transportInfo.cts_project, owner: transportInfo.owner || typedArgs.owner, uri: transportInfo.uri, message: `Transport request ${transportInfo.transport_number || transportNumber || 'unknown'} created successfully` }, null, 2), status: createResult?.status || 200, statusText: createResult?.statusText || 'OK', headers: createResult?.headers || {}, config: createResult?.config || {} as any }); } catch (error: any) { logger.error(`Error creating transport:`, error); const errorMessage = error.response?.data ? (typeof error.response.data === 'string' ? error.response.data : JSON.stringify(error.response.data)) : error.message || String(error); throw new McpError( ErrorCode.InternalError, `Failed to create transport: ${errorMessage}` ); } } catch (error: any) { if (error instanceof McpError) { throw error; } return return_error(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