CreateServiceDefinition
Create a new ABAP service definition in an SAP system. Provide a name and package; optionally add source code and activate after creation.
Instructions
Operation: Create. Subject: ServiceDefinition. Will be useful for creating service definition. Create a new ABAP service definition in SAP system. Creates the service definition object in initial state.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| service_definition_name | Yes | Service definition name (e.g., ZSD_MY_SERVICE). Must follow SAP naming conventions (start with Z or Y). | |
| description | No | Service definition description. If not provided, service_definition_name will be used. | |
| package_name | Yes | Package name (e.g., ZOK_LOCAL, $TMP for local objects) | |
| transport_request | No | Transport request number (e.g., E19K905635). Required for transportable packages. | |
| source_code | No | Service definition source code (optional). If not provided, a minimal template will be created. | |
| activate | No | Activate service definition after creation. Default: true. |
Implementation Reference
- Main handler function for CreateServiceDefinition MCP tool. Validates inputs (name, package, transport), creates an ABAP service definition via AdtClient, optionally activates it, and parses any activation warnings. Returns success/error response.
export async function handleCreateServiceDefinition( context: HandlerContext, args: CreateServiceDefinitionArgs, ) { const { connection, logger } = context; try { // Validate required parameters if (!args?.service_definition_name) { return return_error(new Error('service_definition_name is required')); } if (!args?.package_name) { return return_error(new Error('package_name is required')); } // Validate transport_request: required for non-$TMP packages try { validateTransportRequest(args.package_name, args.transport_request); } catch (error) { return return_error(error as Error); } const typedArgs = args as CreateServiceDefinitionArgs; // Get connection from session context (set by ProtocolHandler) // Connection is managed and cached per session, with proper token refresh via AuthBroker const serviceDefinitionName = typedArgs.service_definition_name.toUpperCase(); logger?.info( `Starting service definition creation: ${serviceDefinitionName}`, ); try { // Create client const client = createAdtClient(connection, logger); const shouldActivate = typedArgs.activate !== false; // Default to true if not specified let activateResponse: any | undefined; // Validate await client.getServiceDefinition().validate({ serviceDefinitionName, description: typedArgs.description || serviceDefinitionName, }); // Create const createConfig: Partial<IServiceDefinitionConfig> & Pick< IServiceDefinitionConfig, 'serviceDefinitionName' | 'packageName' | 'description' > = { serviceDefinitionName, description: typedArgs.description || serviceDefinitionName, packageName: typedArgs.package_name.toUpperCase(), transportRequest: typedArgs.transport_request, ...(typedArgs.source_code && { sourceCode: typedArgs.source_code }), }; const createState = await client .getServiceDefinition() .create(createConfig); const createResult = createState.createResult; if (!createResult) { throw new Error( `Create did not return a response for service definition ${serviceDefinitionName}`, ); } // Activate if requested if (shouldActivate) { const activateState = await client .getServiceDefinition() .activate({ serviceDefinitionName }); activateResponse = activateState.activateResult; } // Parse activation warnings if activation was performed let activationWarnings: string[] = []; if ( shouldActivate && activateResponse && typeof activateResponse.data === 'string' && activateResponse.data.includes('<chkl:messages') ) { const parser = new XMLParser({ ignoreAttributes: false, attributeNamePrefix: '@_', }); const result = parser.parse(activateResponse.data); const messages = result?.['chkl:messages']?.msg; if (messages) { const msgArray = Array.isArray(messages) ? messages : [messages]; activationWarnings = msgArray.map( (msg: any) => `${msg['@_type']}: ${msg.shortText?.txt || 'Unknown'}`, ); } } logger?.info( `✅ CreateServiceDefinition completed successfully: ${serviceDefinitionName}`, ); // Return success result const stepsCompleted = ['validate', 'create']; if (shouldActivate) { stepsCompleted.push('activate'); } const result = { success: true, service_definition_name: serviceDefinitionName, package_name: typedArgs.package_name.toUpperCase(), transport_request: typedArgs.transport_request || null, type: 'SRVD/SRV', message: shouldActivate ? `Service Definition ${serviceDefinitionName} created and activated successfully` : `Service Definition ${serviceDefinitionName} created successfully (not activated)`, uri: `/sap/bc/adt/ddic/srvd/sources/${encodeSapObjectName(serviceDefinitionName)}`, steps_completed: stepsCompleted, activation_warnings: activationWarnings.length > 0 ? activationWarnings : undefined, }; return return_response({ data: JSON.stringify(result, null, 2), status: 200, statusText: 'OK', headers: {}, config: {} as any, }); } catch (error: any) { logger?.error( `Error creating service definition ${serviceDefinitionName}:`, error, ); // Check if service definition already exists if ( error.message?.includes('already exists') || error.response?.status === 409 ) { return return_error( new Error( `Service Definition ${serviceDefinitionName} already exists. Please delete it first or use a different name.`, ), ); } const errorMessage = error.response?.data ? typeof error.response.data === 'string' ? error.response.data : JSON.stringify(error.response.data) : error.message || String(error); return return_error( new Error(`Failed to create service definition: ${errorMessage}`), ); } } catch (error: any) { logger?.error('CreateServiceDefinition handler error:', error); return return_error(error); } } - TOOL_DEFINITION constant defining tool name ('CreateServiceDefinition'), availability, description, and inputSchema with properties: service_definition_name, description, package_name, transport_request, source_code, activate.
export const TOOL_DEFINITION = { name: 'CreateServiceDefinition', available_in: ['onprem', 'cloud'] as const, description: 'Operation: Create. Subject: ServiceDefinition. Will be useful for creating service definition. Create a new ABAP service definition in SAP system. Creates the service definition object in initial state.', inputSchema: { type: 'object', properties: { service_definition_name: { type: 'string', description: 'Service definition name (e.g., ZSD_MY_SERVICE). Must follow SAP naming conventions (start with Z or Y).', }, description: { type: 'string', description: 'Service definition description. If not provided, service_definition_name will be used.', }, package_name: { type: 'string', description: 'Package name (e.g., ZOK_LOCAL, $TMP for local objects)', }, transport_request: { type: 'string', description: 'Transport request number (e.g., E19K905635). Required for transportable packages.', }, source_code: { type: 'string', description: 'Service definition source code (optional). If not provided, a minimal template will be created.', }, activate: { type: 'boolean', description: 'Activate service definition after creation. Default: true.', }, }, required: ['service_definition_name', 'package_name'], }, } as const; - TypeScript interface CreateServiceDefinitionArgs defining the typed arguments for the handler.
interface CreateServiceDefinitionArgs { service_definition_name: string; description?: string; package_name: string; transport_request?: string; source_code?: string; activate?: boolean; } - src/lib/handlers/groups/HighLevelHandlersGroup.ts:328-331 (registration)Import of TOOL_DEFINITION and handleCreateServiceDefinition from the handler file into HighLevelHandlersGroup.
import { TOOL_DEFINITION as CreateServiceDefinition_Tool, handleCreateServiceDefinition, } from '../../../handlers/service_definition/high/handleCreateServiceDefinition'; - src/lib/handlers/groups/HighLevelHandlersGroup.ts:721-724 (registration)Registration of CreateServiceDefinition tool in the high-level handlers group with its tool definition and handler wrapped with context.
{ toolDefinition: CreateServiceDefinition_Tool, handler: withContext(handleCreateServiceDefinition), },