Skip to main content
Glama

execute_table_operation

Perform CRUD operations on ServiceNow tables to create, read, update, and delete records with query support and batch processing capabilities.

Instructions

CRUD operations on ServiceNow tables via Table API. Supports GET/POST/PUT/PATCH/DELETE with query syntax and batch operations. ⚠️ SANDBOX ONLY - reads/modifies data. 🛡️ Auto-limits large results. Use pagination for big datasets. 📁 Use {{file:path}} for large data.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
operationYesThe operation to perform on the table. Required.
tableYesThe ServiceNow table name (e.g., "incident", "sys_user"). Required.
sys_idNoSystem ID for single record operations (GET, PUT, PATCH, DELETE).
sys_idsNoArray of system IDs for batch operations.
queryNoServiceNow encoded query string (e.g., "active=true^priority=1").
fieldsNoComma-separated list of fields to return.
limitNoMaximum number of records to return (default: 1000).
offsetNoNumber of records to skip for pagination.
display_valueNoReturn display values for reference fields.
exclude_reference_linkNoExclude reference link fields from response.
dataNoRecord data for POST/PUT/PATCH 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.
validate_fieldsNoEnable field validation warnings to catch typos and invalid field names. Default: true (validation enabled by default).
context_overflow_preventionNoEnable context overflow prevention to limit large result sets. Default: true. Set to false to disable automatic truncation (use with caution).
strict_fieldsNoStrict field filtering - only return requested fields and strip large fields (script, html, css) unless explicitly requested. Default: false.
response_modeNoResponse verbosity: full (all data), minimal (essential only), compact (summarized). Default: full

Implementation Reference

  • Core implementation of executeTableOperation: validates request, routes to CRUD methods (getRecord, createRecord, etc.), handles batch/single operations, applies field filtering/response modes/context overflow prevention, builds metadata, and returns structured result.
    async executeTableOperation(request: TableOperationRequest): Promise<TableOperationResult> { const startTime = Date.now(); try { // Validate input this.validateTableRequest(request); // Route to appropriate operation let result: TableRecord[]; let recordCount: number; let contextOverflowPrevention = false; let downloadHint = false; // Initialize response data const responseData: any = { records: [], count: 0, }; switch (request.operation) { case 'GET': if (isSingleRecordOperation(request)) { result = [await this.getRecord(request.table, request.sys_id!)]; recordCount = 1; } else { // Apply strict fields filtering at query level if enabled let queryParams = this.buildQueryParams(request); if (request.strict_fields && request.fields) { // Ensure only requested fields are returned from ServiceNow queryParams.sysparm_fields = request.fields; } const queryResult = await this.queryRecordsWithMetadata(request.table, queryParams); result = queryResult.records; recordCount = result.length; // Store overflow prevention metadata for later use contextOverflowPrevention = queryResult.contextOverflowPrevention; downloadHint = queryResult.downloadHint; if (queryResult.summary) { responseData.summary = queryResult.summary; } } break; case 'POST': if (isBatchOperation(request)) { result = await this.createRecords(request.table, request.data as Record<string, any>[]); recordCount = result.length; } else { result = [await this.createRecord(request.table, request.data as Record<string, any>)]; recordCount = 1; } break; case 'PUT': case 'PATCH': if (isBatchOperation(request)) { result = await this.updateRecords(request.table, request.data as Record<string, any>[], request.operation); recordCount = result.length; } else { result = [await this.updateRecord(request.table, request.sys_id!, request.data as Record<string, any>, request.operation)]; recordCount = 1; } break; case 'DELETE': if (isBatchOperation(request)) { result = await this.deleteRecords(request.table, request.sys_ids!); recordCount = result.length; } else { result = [await this.deleteRecord(request.table, request.sys_id!)]; recordCount = 1; } break; default: throw new ServiceNowTableError( TABLE_ERROR_CODES.INVALID_OPERATION, undefined, `Invalid operation: ${request.operation}` ); } const executionTime = Date.now() - startTime; // Update response data with results responseData.records = result; responseData.count = recordCount; // Add operation-specific counts switch (request.operation) { case 'GET': responseData.retrieved_count = recordCount; break; case 'POST': responseData.created_count = recordCount; break; case 'PUT': case 'PATCH': responseData.updated_count = recordCount; break; case 'DELETE': responseData.deleted_count = recordCount; break; } // Context overflow prevention is handled in queryRecords method // No additional processing needed here // Apply strict field filtering if requested - this is the critical fix if (request.strict_fields && request.fields) { result = this.filterFieldsStrictly(result, request.fields, request.response_mode); responseData.records = result; } else if (request.response_mode === 'minimal' || request.response_mode === 'compact') { // Apply response mode transformations for non-strict mode result = this.applyResponseMode(result, request.response_mode, request.fields); responseData.records = result; } // Add field validation warnings if any const warnings = this.validateFields(request); // Estimate response size for metadata const responseSize = JSON.stringify(responseData).length; const estimatedTokens = this.estimateTokenCount(JSON.stringify(responseData)); return { success: true, data: responseData, metadata: { operation: request.operation, table: request.table, executionTime, timestamp: new Date().toISOString(), recordCount, batch: isBatchOperation(request), warnings: warnings.length > 0 ? warnings : undefined, // Context overflow prevention metadata responseSize, contextOverflowPrevention: contextOverflowPrevention || responseSize > this.clientConfig.maxResponseSize * 0.8, // Warning threshold downloadHint: downloadHint, // Set by queryRecordsWithMetadata method }, }; } catch (error) { if (error instanceof ServiceNowTableError) { throw error; } throw new ServiceNowTableError( TABLE_ERROR_CODES.NETWORK_ERROR, undefined, `Table operation failed: ${error instanceof Error ? error.message : 'Unknown error'}` ); } }
  • MCP CallToolRequest handler specifically for 'execute_table_operation': initializes client, extracts/validates parameters, resolves file placeholders {{file:...}}, calls tableClient.executeTableOperation, applies global context overflow prevention, handles errors.
    if (request.params.name === 'execute_table_operation') { try { // Check if table client was initialized successfully if (!tableClient) { return { content: [ { type: 'text', text: JSON.stringify({ success: false, error: { code: 'INITIALIZATION_ERROR', message: 'ServiceNow table 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 table = args?.table as string | undefined; const sysId = args?.sys_id as string | undefined; const sysIds = args?.sys_ids as string[] | undefined; const query = args?.query as string | undefined; const fields = args?.fields as string | undefined; const limit = args?.limit as number | undefined; const offset = args?.offset as number | undefined; const displayValue = args?.display_value as string | undefined; const excludeReferenceLink = args?.exclude_reference_link as boolean | undefined; const data = args?.data as Record<string, any> | Record<string, any>[] | undefined; const batch = args?.batch as boolean | undefined; const validateFields = args?.validate_fields as boolean | undefined; const contextOverflowPrevention = args?.context_overflow_prevention as boolean | undefined; const strictFields = args?.strict_fields as boolean | undefined; const responseMode = args?.response_mode as string | undefined; // Validate required parameters if (!operation) { return { content: [ { type: 'text', text: JSON.stringify({ success: false, error: { code: TABLE_ERROR_CODES.MISSING_PARAMETER, message: 'Required parameter "operation" is missing', details: 'Please provide the operation type (GET, POST, PUT, PATCH, DELETE)', }, }), }, ], isError: true, }; } if (!table) { return { content: [ { type: 'text', text: JSON.stringify({ success: false, error: { code: TABLE_ERROR_CODES.MISSING_PARAMETER, message: 'Required parameter "table" is missing', details: 'Please provide the ServiceNow table name', }, }), }, ], isError: true, }; } // Configure context overflow prevention if specified if (contextOverflowPrevention !== undefined) { tableClient.updateConfig({ enableResultSummarization: contextOverflowPrevention, }); } // Resolve file placeholders in the request arguments let resolvedArgs = { operation: operation as any, table, sys_id: sysId, sys_ids: sysIds, query, fields, limit, offset, display_value: displayValue as any, exclude_reference_link: excludeReferenceLink, data, batch, validate_fields: validateFields, strict_fields: strictFields, response_mode: responseMode as any, }; 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; } // Execute the table operation const result = await tableClient.executeTableOperation({ operation: resolvedArgs.operation, table: resolvedArgs.table, sys_id: resolvedArgs.sys_id, sys_ids: resolvedArgs.sys_ids, query: resolvedArgs.query, fields: resolvedArgs.fields, limit: resolvedArgs.limit, offset: resolvedArgs.offset, display_value: resolvedArgs.display_value, exclude_reference_link: resolvedArgs.exclude_reference_link, data: resolvedArgs.data, batch: resolvedArgs.batch, validate_fields: resolvedArgs.validate_fields, strict_fields: resolvedArgs.strict_fields, response_mode: responseMode as any, }); // Apply global context overflow prevention (additional layer of protection) const { response: protectedResult, monitoring } = globalContextOverflowPrevention.monitorResponse(result, 'execute_table_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 ServiceNowTableError) { 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, }; } }
  • src/index.ts:624-701 (registration)
    MCP tool registration in ListToolsRequest handler: defines name 'execute_table_operation', detailed description, and complete inputSchema with all parameters, enums, descriptions, and required fields.
    name: 'execute_table_operation', description: 'CRUD operations on ServiceNow tables via Table API. Supports GET/POST/PUT/PATCH/DELETE with query syntax and batch operations. ⚠️ SANDBOX ONLY - reads/modifies data. 🛡️ Auto-limits large results. Use pagination for big datasets. 📁 Use {{file:path}} for large data.', inputSchema: { type: 'object', properties: { operation: { type: 'string', enum: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'], description: 'The operation to perform on the table. Required.', }, table: { type: 'string', description: 'The ServiceNow table name (e.g., "incident", "sys_user"). Required.', }, sys_id: { type: 'string', description: 'System ID for single record operations (GET, PUT, PATCH, DELETE).', }, sys_ids: { type: 'array', items: { type: 'string' }, description: 'Array of system IDs for batch operations.', }, query: { type: 'string', description: 'ServiceNow encoded query string (e.g., "active=true^priority=1").', }, fields: { type: 'string', description: 'Comma-separated list of fields to return.', }, limit: { type: 'number', description: 'Maximum number of records to return (default: 1000).', }, offset: { type: 'number', description: 'Number of records to skip for pagination.', }, display_value: { type: 'string', enum: ['true', 'false', 'all'], description: 'Return display values for reference fields.', }, exclude_reference_link: { type: 'boolean', description: 'Exclude reference link fields from response.', }, data: { type: 'object', description: 'Record data for POST/PUT/PATCH 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.', }, validate_fields: { type: 'boolean', description: 'Enable field validation warnings to catch typos and invalid field names. Default: true (validation enabled by default).', }, context_overflow_prevention: { type: 'boolean', description: 'Enable context overflow prevention to limit large result sets. Default: true. Set to false to disable automatic truncation (use with caution).', }, strict_fields: { type: 'boolean', description: 'Strict field filtering - only return requested fields and strip large fields (script, html, css) unless explicitly requested. Default: false.', }, response_mode: { type: 'string', enum: ['full', 'minimal', 'compact'], description: 'Response verbosity: full (all data), minimal (essential only), compact (summarized). Default: full', }, }, required: ['operation', 'table'], }, },
  • TypeScript interface TableOperationRequest defining the exact input structure for table operations, matching the MCP tool inputSchema. Includes all optional parameters for queries, batch ops, validation, and response control.
    export interface TableOperationRequest { operation: TableOperation; table: string; sys_id?: string; sys_ids?: string[]; query?: string; fields?: string; limit?: number; offset?: number; display_value?: DisplayValue; exclude_reference_link?: boolean; data?: Record<string, any> | Record<string, any>[]; batch?: boolean; validate_fields?: boolean; // Enable field validation warnings strict_fields?: boolean; // Strict field filtering to prevent large fields response_mode?: ResponseMode; // Response verbosity control }
  • TypeScript interface TableOperationResult defining the output structure: success flag, data with records/summary/truncation info, and metadata including execution time, warnings, response size, and context overflow indicators.
    export interface TableOperationResult { success: boolean; data?: { records: TableRecord[]; count?: number; total_count?: number; has_more?: boolean; // Context overflow prevention summary?: ResultSummary; truncated?: boolean; original_count?: number; }; metadata: { operation: TableOperation; table: string; executionTime: number; timestamp: string; recordCount: number; batch?: boolean; warnings?: string[]; // Context overflow prevention metadata responseSize?: number; contextOverflowPrevention?: boolean; downloadHint?: boolean; // Indicates large fields were truncated }; }

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