Skip to main content
Glama

execute_updateset_operation

Manage ServiceNow update set lifecycle operations including creation, tracking, XML reassignment, and data modifications in sandbox environments with automatic pagination for large datasets.

Instructions

Manage ServiceNow update sets with lifecycle operations, XML reassignment, and working set tracking. ⚠️ SANDBOX ONLY - modifies update sets. 🛡️ Auto-limits large results. Use pagination for big datasets. 📁 Use {{file:path}} for large data.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
operationYesThe update set operation to perform. Required.
nameNoUpdate set name (required for create operation).
descriptionNoUpdate set description (optional for create operation).
scopeNoUpdate set scope (optional, defaults to configured scope).
set_as_workingNoSet the created update set as working set (for create operation).
update_set_sys_idNoUpdate set sys_id for operations that require it.
tableNoTable name for insert/update operations.
sys_idNoRecord sys_id for update operations.
dataNoRecord data for insert/update operations. Can be single object or array for batch operations. Supports {{file:...}} placeholders to load content from local files.
batchNoEnable batch mode for multiple record operations.
xml_sys_idsNoArray of XML sys_ids for rehome operations.
queryNoServiceNow encoded query string for rehome operations.
forceNoForce reassignment even if XML is not in Default update set.
limitNoMaximum number of records to return for list/recent operations.
offsetNoNumber of records to skip for pagination.
filtersNoFilters for list operations (scope, state, created_by, sys_created_on).
response_modeNoResponse verbosity: full (all data), minimal (essential only), compact (summarized). Default: full
quietNoCompact acknowledgment for update operations to avoid RESPONSE_TOO_LARGE errors. Default: false.

Implementation Reference

  • MCP server tool handler for 'execute_updateset_operation'. Validates input, resolves file placeholders, calls the update set client, applies context overflow protection, and returns JSON response.
    if (request.params.name === 'execute_updateset_operation') {
      try {
        // Check if update set client was initialized successfully
        if (!updateSetClient) {
          return {
            content: [
              {
                type: 'text',
                text: JSON.stringify({
                  success: false,
                  error: {
                    code: 'INITIALIZATION_ERROR',
                    message: 'ServiceNow update set client failed to initialize',
                    details:
                      initError instanceof Error ? initError.message : 'Unknown error',
                  },
                }),
              },
            ],
            isError: true,
          };
        }
    
        // Extract parameters from tool arguments
        const args = request.params.arguments as Record<string, unknown> | undefined;
        const operation = args?.operation as string | undefined;
        const name = args?.name as string | undefined;
        const description = args?.description as string | undefined;
        const scope = args?.scope as string | undefined;
        const setAsWorking = args?.set_as_working as boolean | undefined;
        const updateSetSysId = args?.update_set_sys_id as string | undefined;
        const table = args?.table as string | undefined;
        const sysId = args?.sys_id as string | undefined;
        const data = args?.data as Record<string, any> | Record<string, any>[] | undefined;
        const batch = args?.batch as boolean | undefined;
        const xmlSysIds = args?.xml_sys_ids as string[] | undefined;
        const query = args?.query as string | undefined;
        const force = args?.force as boolean | undefined;
        const limit = args?.limit as number | undefined;
        const offset = args?.offset as number | undefined;
        const filters = args?.filters as Record<string, any> | undefined;
        const responseMode = args?.response_mode as string | undefined;
        const quiet = args?.quiet as boolean | undefined;
    
        // Validate required parameters
        if (!operation) {
          return {
            content: [
              {
                type: 'text',
                text: JSON.stringify({
                  success: false,
                  error: {
                    code: UPDATE_SET_ERROR_CODES.MISSING_PARAMETER,
                    message: 'Required parameter "operation" is missing',
                    details: 'Please provide the operation type (create, set_working, show_working, clear_working, insert, update, rehome, contents, recent, list, info, complete, reopen, delete, diff_default)',
                  },
                }),
              },
            ],
            isError: true,
          };
        }
    
        // Resolve file placeholders in the request arguments
        let resolvedArgs = {
          operation: operation as any,
          name,
          description,
          scope,
          set_as_working: setAsWorking,
          update_set_sys_id: updateSetSysId,
          table,
          sys_id: sysId,
          data,
          batch,
          xml_sys_ids: xmlSysIds,
          query,
          force,
          limit,
          offset,
          filters,
          response_mode: responseMode as any,
          quiet,
        };
    
        try {
          const resolution = resolveFilePlaceholders(resolvedArgs);
          resolvedArgs = resolution.data;
        } catch (error) {
          if (error instanceof FilePlaceholderError) {
            return {
              content: [
                {
                  type: 'text',
                  text: JSON.stringify({
                    success: false,
                    error: {
                      code: 'FILE_PLACEHOLDER_ERROR',
                      message: 'Failed to resolve file placeholder',
                      details: `${error.placeholder}: ${error.message}`,
                    },
                  }),
                },
              ],
              isError: true,
            };
          }
          
          // Re-throw unknown errors
          throw error;
        }
    
        // Set timestamp after file placeholder resolution for accurate XML detection
        // Subtract 500ms to account for timing between placeholder resolution and record creation
        const timestampBefore = Date.now() - 500;
    
        // Execute the update set operation
        const result = await updateSetClient.executeUpdateSetOperation({
          operation: resolvedArgs.operation,
          name: resolvedArgs.name,
          description: resolvedArgs.description,
          scope: resolvedArgs.scope,
          set_as_working: resolvedArgs.set_as_working,
          update_set_sys_id: resolvedArgs.update_set_sys_id,
          table: resolvedArgs.table,
          sys_id: resolvedArgs.sys_id,
          data: resolvedArgs.data,
          batch: resolvedArgs.batch,
          xml_sys_ids: resolvedArgs.xml_sys_ids,
          query: resolvedArgs.query,
          force: resolvedArgs.force,
          limit: resolvedArgs.limit,
          offset: resolvedArgs.offset,
          filters: resolvedArgs.filters,
          custom_timestamp_before: timestampBefore,
          response_mode: responseMode as any,
          quiet: resolvedArgs.quiet,
        });
    
        // Apply global context overflow prevention
        const { response: protectedResult, monitoring } = globalContextOverflowPrevention.monitorResponse(result, 'execute_updateset_operation', responseMode);
    
        return {
          content: [
            {
              type: 'text',
              text: JSON.stringify(protectedResult, null, 2),
            },
          ],
        };
    
      } catch (error) {
        const errorResponse = {
          success: false,
          error: {
            code: 'UNKNOWN_ERROR',
            message: 'An unexpected error occurred',
            details: undefined as string | undefined,
          },
        };
    
        if (error instanceof ServiceNowUpdateSetError) {
          errorResponse.error.code = error.code;
          errorResponse.error.message = error.message;
          errorResponse.error.details = `HTTP Status: ${error.statusCode || 'N/A'}`;
        } else if (error instanceof Error) {
          errorResponse.error.message = error.message;
        }
    
        return {
          content: [
            {
              type: 'text',
              text: JSON.stringify(errorResponse),
            },
          ],
          isError: true,
        };
      }
  • Core ServiceNowUpdateSetClient.executeUpdateSetOperation method. Main entry point that validates requests and routes to specific update set operations like create, insert, rehome, etc.
    async executeUpdateSetOperation(request: UpdateSetOperationRequest): Promise<UpdateSetOperationResult> {
      const startTime = Date.now();
    
      try {
        // Validate input
        this.validateUpdateSetRequest(request);
    
        // Route to appropriate operation
        let result: any;
        let metadata: any = {
          operation: request.operation,
          executionTime: 0,
          timestamp: new Date().toISOString(),
          working_set: this.workingUpdateSet,
        };
    
        switch (request.operation) {
          case 'create':
            result = await this.createUpdateSet(request);
            if (request.set_as_working && result.update_set) {
              this.setWorkingSet(result.update_set);
              result.working_set = this.workingUpdateSet;
            }
            break;
    
          case 'set_working':
            if (!request.update_set_sys_id) {
              throw new ServiceNowUpdateSetError(
                UPDATE_SET_ERROR_CODES.MISSING_PARAMETER,
                undefined,
                'update_set_sys_id is required for set_working operation'
              );
            }
            const updateSet = await this.getUpdateSetInfo(request.update_set_sys_id);
            this.setWorkingSet(updateSet);
            result = { working_set: this.workingUpdateSet };
            break;
    
          case 'show_working':
            result = { working_set: this.workingUpdateSet };
            break;
    
          case 'clear_working':
            this.clearWorkingSet();
            result = { working_set: null };
            break;
    
          case 'insert':
            if (!request.table || !request.data) {
              throw new ServiceNowUpdateSetError(
                UPDATE_SET_ERROR_CODES.MISSING_PARAMETER,
                undefined,
                'table and data are required for insert operation'
              );
            }
            result = await this.insertWithReassignment(
              request.table,
              request.data as Record<string, any>,
              request.update_set_sys_id,
              request.custom_timestamp_before
            );
            break;
    
          case 'update':
            if (!request.table || !request.sys_id || !request.data) {
              throw new ServiceNowUpdateSetError(
                UPDATE_SET_ERROR_CODES.MISSING_PARAMETER,
                undefined,
                'table, sys_id, and data are required for update operation'
              );
            }
            result = await this.updateWithReassignment(
              request.table,
              request.sys_id,
              request.data as Record<string, any>,
              request.update_set_sys_id,
              request.custom_timestamp_before
            );
            break;
    
          case 'rehome':
            if (!request.xml_sys_ids && !request.query) {
              throw new ServiceNowUpdateSetError(
                UPDATE_SET_ERROR_CODES.MISSING_PARAMETER,
                undefined,
                'xml_sys_ids or query is required for rehome operation'
              );
            }
            if (request.xml_sys_ids) {
              result = await this.rehomeXMLByIds(
                request.xml_sys_ids,
                request.update_set_sys_id || this.getWorkingSetId(),
                request.force || false
              );
            } else {
              result = await this.rehomeXMLByQuery(
                request.query!,
                request.update_set_sys_id || this.getWorkingSetId(),
                request.force || false
              );
            }
            break;
    
          case 'contents':
            result = await this.getUpdateSetContents(
              request.update_set_sys_id || this.getWorkingSetId(),
              request.response_mode
            );
            break;
    
          case 'recent':
            result = await this.getRecentXML(request.limit || 50, request.response_mode);
            break;
    
          case 'list':
            result = await this.listUpdateSets(request.filters, request.limit, request.offset);
            break;
    
          case 'info':
            if (!request.update_set_sys_id) {
              throw new ServiceNowUpdateSetError(
                UPDATE_SET_ERROR_CODES.MISSING_PARAMETER,
                undefined,
                'update_set_sys_id is required for info operation'
              );
            }
            result = { update_set: await this.getUpdateSetInfo(request.update_set_sys_id) };
            break;
    
          case 'complete':
            if (!request.update_set_sys_id) {
              throw new ServiceNowUpdateSetError(
                UPDATE_SET_ERROR_CODES.MISSING_PARAMETER,
                undefined,
                'update_set_sys_id is required for complete operation'
              );
            }
            result = await this.completeUpdateSet(request.update_set_sys_id);
            break;
    
          case 'reopen':
            if (!request.update_set_sys_id) {
              throw new ServiceNowUpdateSetError(
                UPDATE_SET_ERROR_CODES.MISSING_PARAMETER,
                undefined,
                'update_set_sys_id is required for reopen operation'
              );
            }
            
            // Check if state changes are disabled
            if (process.env.SKYENET_UPDATESET_DISABLE_STATE_CHANGES === 'true') {
              throw new ServiceNowUpdateSetError(
                UPDATE_SET_ERROR_CODES.OPERATION_DISABLED,
                undefined,
                'Reopen operation is disabled due to ServiceNow business rule limitations. Use create, list, contents, recent, diff, and complete operations instead.'
              );
            }
            
            result = await this.reopenUpdateSet(request.update_set_sys_id);
            break;
    
          case 'delete':
            if (!request.update_set_sys_id) {
              throw new ServiceNowUpdateSetError(
                UPDATE_SET_ERROR_CODES.MISSING_PARAMETER,
                undefined,
                'update_set_sys_id is required for delete operation'
              );
            }
            
            // Check if state changes are disabled
            if (process.env.SKYENET_UPDATESET_DISABLE_STATE_CHANGES === 'true') {
              throw new ServiceNowUpdateSetError(
                UPDATE_SET_ERROR_CODES.OPERATION_DISABLED,
                undefined,
                'Delete operation is disabled due to ServiceNow business rule limitations. Use create, list, contents, recent, diff, and complete operations instead.'
              );
            }
            
            result = await this.deleteUpdateSet(request.update_set_sys_id);
            break;
    
          case 'diff_default':
            result = await this.diffAgainstDefault(
              request.update_set_sys_id || this.getWorkingSetId(),
              request.response_mode
            );
            break;
    
          default:
            throw new ServiceNowUpdateSetError(
              UPDATE_SET_ERROR_CODES.INVALID_OPERATION,
              undefined,
              `Invalid operation: ${request.operation}`
            );
        }
    
        const executionTime = Date.now() - startTime;
        metadata.executionTime = executionTime;
    
        // Estimate response size for metadata
        const responseSize = JSON.stringify(result).length;
        metadata.responseSize = responseSize;
        metadata.contextOverflowPrevention = responseSize > 40000; // 40KB threshold
    
        // Handle quiet mode for update operations - ultra-minimal response
        if (request.quiet && (request.operation === 'insert' || request.operation === 'update' || request.operation === 'set_working')) {
          return {
            success: true,
            data: {
              message: 'Update accepted'
            },
            metadata: {
              operation: request.operation,
              executionTime: 0,
              timestamp: new Date().toISOString(),
              quiet_mode: true
            }
          };
        }
    
        return {
          success: true,
          data: result,
          metadata,
        };
    
      } catch (error) {
        if (error instanceof ServiceNowUpdateSetError) {
          throw error;
        }
        
        throw new ServiceNowUpdateSetError(
          UPDATE_SET_ERROR_CODES.NETWORK_ERROR,
          undefined,
          `Update set operation failed: ${error instanceof Error ? error.message : 'Unknown error'}`
        );
      }
    }
  • src/index.ts:702-787 (registration)
    Tool registration in MCP server's listTools handler, defining name, description, and full input schema with all parameters and enums.
    {
      name: 'execute_updateset_operation',
      description:
        'Manage ServiceNow update sets with lifecycle operations, XML reassignment, and working set tracking. ⚠️ SANDBOX ONLY - modifies update sets. 🛡️ Auto-limits large results. Use pagination for big datasets. 📁 Use {{file:path}} for large data.',
      inputSchema: {
        type: 'object',
        properties: {
          operation: {
            type: 'string',
            enum: ['create', 'set_working', 'show_working', 'clear_working', 'insert', 'update', 'rehome', 'contents', 'recent', 'list', 'info', 'complete', 'reopen', 'delete', 'diff_default'],
            description: 'The update set operation to perform. Required.',
          },
          name: {
            type: 'string',
            description: 'Update set name (required for create operation).',
          },
          description: {
            type: 'string',
            description: 'Update set description (optional for create operation).',
          },
          scope: {
            type: 'string',
            description: 'Update set scope (optional, defaults to configured scope).',
          },
          set_as_working: {
            type: 'boolean',
            description: 'Set the created update set as working set (for create operation).',
          },
          update_set_sys_id: {
            type: 'string',
            description: 'Update set sys_id for operations that require it.',
          },
          table: {
            type: 'string',
            description: 'Table name for insert/update operations.',
          },
          sys_id: {
            type: 'string',
            description: 'Record sys_id for update operations.',
          },
          data: {
            type: 'object',
            description: 'Record data for insert/update operations. Can be single object or array for batch operations. Supports {{file:...}} placeholders to load content from local files.',
          },
          batch: {
            type: 'boolean',
            description: 'Enable batch mode for multiple record operations.',
          },
          xml_sys_ids: {
            type: 'array',
            items: { type: 'string' },
            description: 'Array of XML sys_ids for rehome operations.',
          },
          query: {
            type: 'string',
            description: 'ServiceNow encoded query string for rehome operations.',
          },
          force: {
            type: 'boolean',
            description: 'Force reassignment even if XML is not in Default update set.',
          },
          limit: {
            type: 'number',
            description: 'Maximum number of records to return for list/recent operations.',
          },
          offset: {
            type: 'number',
            description: 'Number of records to skip for pagination.',
          },
          filters: {
            type: 'object',
            description: 'Filters for list operations (scope, state, created_by, sys_created_on).',
          },
          response_mode: {
            type: 'string',
            enum: ['full', 'minimal', 'compact'],
            description: 'Response verbosity: full (all data), minimal (essential only), compact (summarized). Default: full',
          },
          quiet: {
            type: 'boolean',
            description: 'Compact acknowledgment for update operations to avoid RESPONSE_TOO_LARGE errors. Default: false.',
          },
        },
        required: ['operation'],
      },
    },
  • TypeScript type imports for UpdateSetOperationRequest and UpdateSetOperationResult used for input/output validation in the handler.
      UpdateSetOperationRequest,
      UpdateSetOperationResult,
      UpdateSetErrorResponse,
      UpdateSetRecord,
      XMLRecord,
      WorkingSetState,
      UpdateSetContents,
      RecentXMLActivity,
      UpdateSetDiff,
      XMLSummary,
      XMLDetectionResult,
      XMLReassignmentResult,
      UpdateSetFilters,
      UpdateSetClientConfig,
      DEFAULT_UPDATE_SET_CONFIG,
      loadUpdateSetConfig,
      ServiceNowUpdateSetError,
      UPDATE_SET_ERROR_CODES,
      isWorkingSetState,
      isUpdateSetRecord,
      isXMLRecord,
    } from './updateSetTypes.js';
Behavior4/5

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

With no annotations provided, the description carries the full burden of behavioral disclosure. It does well by warning about sandbox-only usage and modification of update sets, mentioning auto-limiting of large results, and providing pagination guidance. It also hints at file handling capabilities. However, it doesn't cover all behavioral aspects like error handling, authentication requirements, or rate limits, which prevents a perfect score.

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

Conciseness4/5

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

The description is appropriately sized and front-loaded with the core purpose. The warning icons and file handling note are useful additions. However, the structure could be slightly improved by separating the core purpose from the usage notes more clearly, and some phrasing ('large data' vs 'big datasets') is slightly redundant.

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

Completeness3/5

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

For a complex tool with 18 parameters, no annotations, and no output schema, the description provides good basic context about sandbox restrictions and data handling. However, it doesn't explain what the tool returns (no output schema), doesn't cover all behavioral aspects, and doesn't differentiate from sibling tools. Given the complexity, more comprehensive guidance would be expected.

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 schema description coverage is 100%, so the schema already documents all 18 parameters thoroughly. The description doesn't add any meaningful parameter semantics beyond what's in the schema - it mentions file placeholders but this is already covered in the 'data' parameter description. This meets the baseline expectation when schema coverage is high.

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 states the tool manages ServiceNow update sets with specific operations (lifecycle, XML reassignment, working set tracking). It specifies the resource (ServiceNow update sets) and general action verbs (manage, track). However, it doesn't explicitly differentiate from sibling tools like execute_background_script or execute_table_operation, which prevents a perfect score.

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

Usage Guidelines4/5

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

The description provides clear usage context with '⚠️ SANDBOX ONLY - modifies update sets' warning and guidance for handling large datasets ('Use pagination for big datasets'). It also offers file handling advice ('📁 Use {{file:path}} for large data'). However, it doesn't explicitly mention when to use this tool versus the sibling tools (execute_background_script, execute_table_operation), which would be needed for a perfect score.

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/ClearSkye/SkyeNet-MCP-ACE'

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