create_autonumber_column
Add an AutoNumber column to Dataverse tables that automatically generates unique alphanumeric identifiers using sequential numbers, random strings, and datetime placeholders with custom formatting.
Instructions
Creates a new AutoNumber column in a Dataverse table with specified format. AutoNumber columns automatically generate alphanumeric strings using sequential numbers, random strings, and datetime placeholders. Requires a solution context to be set first.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| autoNumberFormat | Yes | AutoNumber format using placeholders like "PREFIX-{SEQNUM:4}-{RANDSTRING:3}-{DATETIMEUTC:yyyyMMdd}" | |
| description | No | Description of the AutoNumber column | |
| displayName | Yes | Display name for the AutoNumber column (e.g., "Serial Number") | |
| entityLogicalName | Yes | Logical name of the table to add the AutoNumber column to | |
| isAuditEnabled | No | Whether auditing is enabled for this column | |
| isValidForAdvancedFind | No | Whether the column appears in Advanced Find | |
| isValidForCreate | No | Whether the column can be set during create | |
| isValidForUpdate | No | Whether the column can be updated | |
| maxLength | No | Maximum length for the column (default: 100, ensure enough room for format expansion) | |
| requiredLevel | No | Required level of the column | None |
| schemaName | No | Schema name for the column (auto-generated if not provided) |
Implementation Reference
- src/tools/autonumber-tools.ts:86-161 (handler)The core handler function that implements the 'create_autonumber_column' tool logic. It retrieves the customization prefix, generates schema names, constructs the AutoNumber column metadata, and creates the column via the Dataverse Metadata API.async (params) => { try { // Get the customization prefix from the solution context const prefix = client.getCustomizationPrefix(); if (!prefix) { throw new Error('No customization prefix available. Please set a solution context using set_solution_context tool first.'); } // Generate schema name if not provided const schemaName = params.schemaName || generateColumnSchemaName(params.displayName, prefix); // Prepare the column metadata const columnMetadata = { "@odata.type": "Microsoft.Dynamics.CRM.StringAttributeMetadata", "AttributeType": "String", "SchemaName": schemaName, "DisplayName": createLocalizedLabel(params.displayName), "Format": "Text", // Required for AutoNumber columns "AutoNumberFormat": params.autoNumberFormat, "RequiredLevel": { "Value": params.requiredLevel, "CanBeChanged": true, "ManagedPropertyLogicalName": "canmodifyrequirementlevelsettings" }, "MaxLength": params.maxLength, "IsCustomAttribute": true, ...(params.description && { "Description": createLocalizedLabel(params.description) }), ...(params.isAuditEnabled !== undefined && { "IsAuditEnabled": { "Value": params.isAuditEnabled, "CanBeChanged": true, "ManagedPropertyLogicalName": "canmodifyauditsettings" } }), ...(params.isValidForAdvancedFind !== undefined && { "IsValidForAdvancedFind": params.isValidForAdvancedFind }), ...(params.isValidForCreate !== undefined && { "IsValidForCreate": params.isValidForCreate }), ...(params.isValidForUpdate !== undefined && { "IsValidForUpdate": params.isValidForUpdate }) }; const result = await client.postMetadata( `EntityDefinitions(LogicalName='${params.entityLogicalName}')/Attributes`, columnMetadata ); return { content: [ { type: "text", text: `Successfully created AutoNumber column '${schemaName}' with display name '${params.displayName}' in table '${params.entityLogicalName}'.\n\nAutoNumber Format: ${params.autoNumberFormat}\nMax Length: ${params.maxLength}\nRequired Level: ${params.requiredLevel}\n\nResponse: ${JSON.stringify(result, null, 2)}` } ] }; } catch (error: any) { // Provide specific error messages for common issues let errorMessage = `Error creating AutoNumber column: ${error instanceof Error ? error.message : 'Unknown error'}`; if (error.message?.includes('Invalid Argument')) { errorMessage += '\n\nTip: Check AutoNumber format syntax. Use {SEQNUM:length}, {RANDSTRING:1-6}, {DATETIMEUTC:format}'; } return { content: [ { type: "text", text: errorMessage } ], isError: true }; } } );
- src/tools/autonumber-tools.ts:69-85 (schema)The tool specification including title, description, and Zod inputSchema for validating parameters like entityLogicalName, displayName, autoNumberFormat (validated by autoNumberFormatSchema), requiredLevel, maxLength, etc.{ title: 'Create AutoNumber Column', description: 'Creates a new AutoNumber column in a Dataverse table with specified format. AutoNumber columns automatically generate alphanumeric strings using sequential numbers, random strings, and datetime placeholders. Requires a solution context to be set first.', inputSchema: { entityLogicalName: z.string().describe('Logical name of the table to add the AutoNumber column to'), displayName: z.string().describe('Display name for the AutoNumber column (e.g., "Serial Number")'), schemaName: z.string().optional().describe('Schema name for the column (auto-generated if not provided)'), description: z.string().optional().describe('Description of the AutoNumber column'), autoNumberFormat: autoNumberFormatSchema.describe('AutoNumber format using placeholders like "PREFIX-{SEQNUM:4}-{RANDSTRING:3}-{DATETIMEUTC:yyyyMMdd}"'), requiredLevel: z.enum(['None', 'SystemRequired', 'ApplicationRequired', 'Recommended']).default('None').describe('Required level of the column'), maxLength: z.number().min(1).max(4000).default(100).describe('Maximum length for the column (default: 100, ensure enough room for format expansion)'), isAuditEnabled: z.boolean().optional().describe('Whether auditing is enabled for this column'), isValidForAdvancedFind: z.boolean().optional().describe('Whether the column appears in Advanced Find'), isValidForCreate: z.boolean().optional().describe('Whether the column can be set during create'), isValidForUpdate: z.boolean().optional().describe('Whether the column can be updated') } },
- src/tools/autonumber-tools.ts:66-162 (registration)The exported createAutoNumberColumnTool function that calls server.registerTool to register the 'create_autonumber_column' tool with its schema and handler.export function createAutoNumberColumnTool(server: McpServer, client: DataverseClient) { server.registerTool( 'create_autonumber_column', { title: 'Create AutoNumber Column', description: 'Creates a new AutoNumber column in a Dataverse table with specified format. AutoNumber columns automatically generate alphanumeric strings using sequential numbers, random strings, and datetime placeholders. Requires a solution context to be set first.', inputSchema: { entityLogicalName: z.string().describe('Logical name of the table to add the AutoNumber column to'), displayName: z.string().describe('Display name for the AutoNumber column (e.g., "Serial Number")'), schemaName: z.string().optional().describe('Schema name for the column (auto-generated if not provided)'), description: z.string().optional().describe('Description of the AutoNumber column'), autoNumberFormat: autoNumberFormatSchema.describe('AutoNumber format using placeholders like "PREFIX-{SEQNUM:4}-{RANDSTRING:3}-{DATETIMEUTC:yyyyMMdd}"'), requiredLevel: z.enum(['None', 'SystemRequired', 'ApplicationRequired', 'Recommended']).default('None').describe('Required level of the column'), maxLength: z.number().min(1).max(4000).default(100).describe('Maximum length for the column (default: 100, ensure enough room for format expansion)'), isAuditEnabled: z.boolean().optional().describe('Whether auditing is enabled for this column'), isValidForAdvancedFind: z.boolean().optional().describe('Whether the column appears in Advanced Find'), isValidForCreate: z.boolean().optional().describe('Whether the column can be set during create'), isValidForUpdate: z.boolean().optional().describe('Whether the column can be updated') } }, async (params) => { try { // Get the customization prefix from the solution context const prefix = client.getCustomizationPrefix(); if (!prefix) { throw new Error('No customization prefix available. Please set a solution context using set_solution_context tool first.'); } // Generate schema name if not provided const schemaName = params.schemaName || generateColumnSchemaName(params.displayName, prefix); // Prepare the column metadata const columnMetadata = { "@odata.type": "Microsoft.Dynamics.CRM.StringAttributeMetadata", "AttributeType": "String", "SchemaName": schemaName, "DisplayName": createLocalizedLabel(params.displayName), "Format": "Text", // Required for AutoNumber columns "AutoNumberFormat": params.autoNumberFormat, "RequiredLevel": { "Value": params.requiredLevel, "CanBeChanged": true, "ManagedPropertyLogicalName": "canmodifyrequirementlevelsettings" }, "MaxLength": params.maxLength, "IsCustomAttribute": true, ...(params.description && { "Description": createLocalizedLabel(params.description) }), ...(params.isAuditEnabled !== undefined && { "IsAuditEnabled": { "Value": params.isAuditEnabled, "CanBeChanged": true, "ManagedPropertyLogicalName": "canmodifyauditsettings" } }), ...(params.isValidForAdvancedFind !== undefined && { "IsValidForAdvancedFind": params.isValidForAdvancedFind }), ...(params.isValidForCreate !== undefined && { "IsValidForCreate": params.isValidForCreate }), ...(params.isValidForUpdate !== undefined && { "IsValidForUpdate": params.isValidForUpdate }) }; const result = await client.postMetadata( `EntityDefinitions(LogicalName='${params.entityLogicalName}')/Attributes`, columnMetadata ); return { content: [ { type: "text", text: `Successfully created AutoNumber column '${schemaName}' with display name '${params.displayName}' in table '${params.entityLogicalName}'.\n\nAutoNumber Format: ${params.autoNumberFormat}\nMax Length: ${params.maxLength}\nRequired Level: ${params.requiredLevel}\n\nResponse: ${JSON.stringify(result, null, 2)}` } ] }; } catch (error: any) { // Provide specific error messages for common issues let errorMessage = `Error creating AutoNumber column: ${error instanceof Error ? error.message : 'Unknown error'}`; if (error.message?.includes('Invalid Argument')) { errorMessage += '\n\nTip: Check AutoNumber format syntax. Use {SEQNUM:length}, {RANDSTRING:1-6}, {DATETIMEUTC:format}'; } return { content: [ { type: "text", text: errorMessage } ], isError: true }; } } ); }
- src/index.ts:240-240 (registration)Invocation of createAutoNumberColumnTool in the main index file, which executes the registration of the tool.createAutoNumberColumnTool(server, dataverseClient);
- src/tools/autonumber-tools.ts:26-56 (helper)Zod refinement schema used to validate the autoNumberFormat parameter, ensuring valid placeholders and length constraints for RANDSTRING (1-6) and SEQNUM (>=1).const autoNumberFormatSchema = z.string().refine((format) => { // Validate AutoNumber format placeholders const validPlaceholders = /^[^{}]*(\{(SEQNUM|RANDSTRING|DATETIMEUTC):[0-9]+\}[^{}]*)*$/; const hasValidPlaceholders = validPlaceholders.test(format); // Check RANDSTRING length constraints (1-6) const randStringMatches = format.match(/\{RANDSTRING:(\d+)\}/g); if (randStringMatches) { for (const match of randStringMatches) { const length = parseInt(match.match(/\{RANDSTRING:(\d+)\}/)![1]); if (length < 1 || length > 6) { return false; } } } // Check SEQNUM length constraints (minimum 1) const seqNumMatches = format.match(/\{SEQNUM:(\d+)\}/g); if (seqNumMatches) { for (const match of seqNumMatches) { const length = parseInt(match.match(/\{SEQNUM:(\d+)\}/)![1]); if (length < 1) { return false; } } } return hasValidPlaceholders; }, { message: "Invalid AutoNumber format. Use placeholders like {SEQNUM:4}, {RANDSTRING:3} (1-6), {DATETIMEUTC:yyyyMMdd}" });