Skip to main content
Glama

UpdateServiceDefinition

Update or create an ABAP service definition: locks the object, updates source code, unlocks, and optionally activates. Requires service definition name and source code.

Instructions

Operation: Update, Create. Subject: ServiceDefinition. Will be useful for updating or creating service definition. Update source code of an existing ABAP service definition. Locks, updates, unlocks, and optionally activates.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
service_definition_nameYesService definition name (e.g., ZSD_MY_SERVICE). Must exist in the system.
source_codeYesComplete service definition source code.
transport_requestNoTransport request number (e.g., E19K905635). Optional if object is local or already in transport.
activateNoActivate service definition after update. Default: true.

Implementation Reference

  • Main handler function for UpdateServiceDefinition tool. Locks the service definition, updates source code, checks it, unlocks it, optionally activates it, and parses activation warnings.
    export async function handleUpdateServiceDefinition(
      context: HandlerContext,
      args: UpdateServiceDefinitionArgs,
    ) {
      const { connection, logger } = context;
      try {
        const {
          service_definition_name,
          source_code,
          transport_request,
          activate = true,
        } = args as UpdateServiceDefinitionArgs;
    
        // Validation
        if (!service_definition_name || !source_code) {
          return return_error(
            new Error('service_definition_name and source_code are required'),
          );
        }
    
        // Get connection from session context (set by ProtocolHandler)
        // Connection is managed and cached per session, with proper token refresh via AuthBroker
        const serviceDefinitionName = service_definition_name.toUpperCase();
    
        logger?.info(
          `Starting service definition source update: ${serviceDefinitionName}`,
        );
    
        try {
          // Create client
          const client = createAdtClient(connection, logger);
    
          // Build operation chain: lock -> update -> check -> unlock -> (activate)
          // Note: No validation needed for update - service definition must already exist
          const shouldActivate = activate !== false; // Default to true if not specified
    
          // Lock
          let lockHandle: string | undefined;
          let activateResponse: any | undefined;
    
          try {
            lockHandle = await client
              .getServiceDefinition()
              .lock({ serviceDefinitionName });
    
            // Update source code
            await client.getServiceDefinition().update(
              {
                serviceDefinitionName,
                sourceCode: source_code,
                transportRequest: args.transport_request,
              },
              { lockHandle },
            );
    
            // Check
            try {
              await safeCheckOperation(
                () =>
                  client.getServiceDefinition().check({ serviceDefinitionName }),
                serviceDefinitionName,
                {
                  debug: (message: string) =>
                    logger?.debug(`[UpdateServiceDefinition] ${message}`),
                },
              );
            } catch (checkError: any) {
              // If error was marked as "already checked", continue silently
              if (!(checkError as any).isAlreadyChecked) {
                // Real check error - rethrow
                throw checkError;
              }
            }
          } finally {
            if (lockHandle) {
              try {
                await client
                  .getServiceDefinition()
                  .unlock({ serviceDefinitionName }, lockHandle);
                logger?.info(
                  `[UpdateServiceDefinition] Service definition unlocked: ${serviceDefinitionName}`,
                );
              } catch (unlockError: any) {
                logger?.warn(
                  `Failed to unlock service definition ${serviceDefinitionName}: ${unlockError?.message || unlockError}`,
                );
              }
            }
          }
    
          // Wait for object to be ready after update (long polling)
          try {
            await client
              .getServiceDefinition()
              .read({ serviceDefinitionName }, 'inactive', {
                withLongPolling: true,
              });
          } catch {
            // Continue anyway — activation will fail explicitly if object isn't ready
          }
    
          // 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(
            `✅ UpdateServiceDefinition completed successfully: ${serviceDefinitionName}`,
          );
    
          // Return success result
          const stepsCompleted = ['lock', 'update', 'check', 'unlock'];
          if (shouldActivate) {
            stepsCompleted.push('activate');
          }
    
          const result = {
            success: true,
            service_definition_name: serviceDefinitionName,
            transport_request: transport_request || 'local',
            activated: shouldActivate,
            message: shouldActivate
              ? `Service Definition ${serviceDefinitionName} updated and activated successfully`
              : `Service Definition ${serviceDefinitionName} updated successfully (not activated)`,
            uri: `/sap/bc/adt/ddic/srvd/sources/${encodeSapObjectName(serviceDefinitionName)}`,
            steps_completed: stepsCompleted,
            activation_warnings:
              activationWarnings.length > 0 ? activationWarnings : undefined,
            source_size_bytes: source_code.length,
          };
    
          return return_response({
            data: JSON.stringify(result, null, 2),
            status: 200,
            statusText: 'OK',
            headers: {},
            config: {} as any,
          });
        } catch (error: any) {
          logger?.error(
            `Error updating service definition source ${serviceDefinitionName}:`,
            error,
          );
    
          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 update service definition: ${errorMessage}`),
          );
        }
      } catch (error: any) {
        return return_error(error);
      }
    }
  • Input schema and tool definition for UpdateServiceDefinition. Declares the tool name, available environments, description, and input schema with required fields: service_definition_name and source_code.
    export const TOOL_DEFINITION = {
      name: 'UpdateServiceDefinition',
      available_in: ['onprem', 'cloud'] as const,
      description:
        'Operation: Update, Create. Subject: ServiceDefinition. Will be useful for updating or creating service definition. Update source code of an existing ABAP service definition. Locks, updates, unlocks, and optionally activates.',
      inputSchema: {
        type: 'object',
        properties: {
          service_definition_name: {
            type: 'string',
            description:
              'Service definition name (e.g., ZSD_MY_SERVICE). Must exist in the system.',
          },
          source_code: {
            type: 'string',
            description: 'Complete service definition source code.',
          },
          transport_request: {
            type: 'string',
            description:
              'Transport request number (e.g., E19K905635). Optional if object is local or already in transport.',
          },
          activate: {
            type: 'boolean',
            description: 'Activate service definition after update. Default: true.',
          },
        },
        required: ['service_definition_name', 'source_code'],
      },
    } as const;
  • TypeScript interface for the UpdateServiceDefinition handler arguments.
    interface UpdateServiceDefinitionArgs {
      service_definition_name: string;
      source_code: string;
      transport_request?: string;
      activate?: boolean;
    }
  • Registration of UpdateServiceDefinition in the HighLevelHandlersGroup, mapping its tool definition to the handler wrapped with context.
    {
      toolDefinition: UpdateServiceDefinition_Tool,
      handler: withContext(handleUpdateServiceDefinition),
    },
  • Registration of handleUpdateServiceDefinition as the 'update' operation in the SERVICE_DEFINITION compact router.
    update: handleUpdateServiceDefinition as unknown as CompactHandler,
    delete: handleDeleteServiceDefinition as unknown as CompactHandler,
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description must disclose behavior. It mentions 'Locks, updates, unlocks, and optionally activates', which gives a basic workflow. However, it lacks details on failure scenarios, side effects, or prerequisites like authorization needs. Adequate but not thorough.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness2/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description contains redundant phrases like 'Operation: Update, Create. Subject: ServiceDefinition.' and 'Will be useful for updating or creating service definition.' This could be condensed into a single clear sentence. The front-loading is acceptable but not optimal.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Without an output schema, the description should explain what the tool returns (e.g., success message, transport request) and mention error conditions. It does not address prerequisites (e.g., transport request for non-local objects) or post-conditions. Given the complexity of a mutation tool, this is incomplete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has 100% description coverage, so the parameters are already documented. The description's mention of 'update source code' relates to the source_code parameter but adds no new semantic detail beyond the schema. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly identifies the tool as updating (and possibly creating) a ServiceDefinition, specifying 'Update source code of an existing ABAP service definition'. It distinguishes from sibling tools like CreateServiceDefinition, though the mention of 'Create' is slightly confusing given the schema requires an existing name.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides minimal guidance on when to use this tool, only stating it is useful for updating or creating. It does not mention when not to use it (e.g., for new definitions, use CreateServiceDefinition) or list alternatives. With many sibling update and create tools, more explicit direction is needed.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

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