Skip to main content
Glama
mwhesse

Dataverse MCP Server

by mwhesse

Create Dataverse Column

create_dataverse_column

Add custom fields to Dataverse tables with specific data types including text, numbers, dates, lookups, and choice lists to store structured data.

Instructions

Creates a new column (field) in a Dataverse table with the specified data type and configuration. Supports various column types including text, numbers, dates, lookups, and choice lists. Use this to add new fields to store specific data in your tables. Requires a solution context to be set first.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
columnTypeYesType of the column
dateTimeFormatNoFormat for datetime columns
defaultValueNoDefault value for the column
descriptionNoDescription of the column
displayNameYesDisplay name for the column (e.g., 'Customer Email')
entityLogicalNameYesLogical name of the table to add the column to
falseOptionLabelNoLabel for false option in boolean columns (default: 'No')
formatNoFormat for string columns
isAuditEnabledNoWhether auditing is enabled for this column
isValidForAdvancedFindNoWhether the column appears in Advanced Find
isValidForCreateNoWhether the column can be set during create
isValidForUpdateNoWhether the column can be updated
maxLengthNoMaximum length for string columns (default: 100)
maxValueNoMaximum value for integer/decimal columns
minValueNoMinimum value for integer/decimal columns
optionSetNameNoName of the option set for picklist columns
optionsNoOptions for picklist columns
precisionNoPrecision for decimal columns (default: 2)
requiredLevelNoRequired level of the columnNone
targetEntityNoTarget entity for lookup columns
trueOptionLabelNoLabel for true option in boolean columns (default: 'Yes')

Implementation Reference

  • The asynchronous handler function that implements the core logic for creating a Dataverse column. It generates logical/schema names, constructs attribute metadata based on the specified columnType (e.g., String, Picklist, Lookup), handles type-specific properties, and posts the metadata to the EntityDefinitions/Attributes endpoint.
    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 the logical name and schema name
        const logicalName = generateColumnLogicalName(params.displayName, prefix);
        const schemaName = generateColumnSchemaName(params.displayName, prefix);
    
        let attributeDefinition: any = {
          LogicalName: logicalName,
          SchemaName: schemaName,
          DisplayName: createLocalizedLabel(params.displayName),
          Description: params.description ? createLocalizedLabel(params.description) : undefined,
          RequiredLevel: {
            Value: params.requiredLevel,
            CanBeChanged: true,
            ManagedPropertyLogicalName: "canmodifyrequirementlevelsettings"
          },
          IsCustomAttribute: true
        };
    
        // Set type-specific properties
        switch (params.columnType) {
          case "String":
            attributeDefinition["@odata.type"] = "Microsoft.Dynamics.CRM.StringAttributeMetadata";
            attributeDefinition.MaxLength = params.maxLength || 100;
            // Remove Format property for now to avoid enum issues
            if (params.defaultValue && typeof params.defaultValue === "string") {
              attributeDefinition.DefaultValue = params.defaultValue;
            }
            break;
    
          case "Integer":
            attributeDefinition["@odata.type"] = "Microsoft.Dynamics.CRM.IntegerAttributeMetadata";
            // Remove Format property for now to avoid enum issues
            if (params.minValue !== undefined) attributeDefinition.MinValue = params.minValue;
            if (params.maxValue !== undefined) attributeDefinition.MaxValue = params.maxValue;
            // Note: IntegerAttributeMetadata doesn't support DefaultValue property
            break;
    
          case "Decimal":
            attributeDefinition["@odata.type"] = "Microsoft.Dynamics.CRM.DecimalAttributeMetadata";
            attributeDefinition.Precision = params.precision || 2;
            if (params.minValue !== undefined) attributeDefinition.MinValue = params.minValue;
            if (params.maxValue !== undefined) attributeDefinition.MaxValue = params.maxValue;
            if (params.defaultValue && typeof params.defaultValue === "number") {
              attributeDefinition.DefaultValue = params.defaultValue;
            }
            break;
    
          case "Money":
            attributeDefinition["@odata.type"] = "Microsoft.Dynamics.CRM.MoneyAttributeMetadata";
            attributeDefinition.Precision = params.precision || 2;
            if (params.minValue !== undefined) attributeDefinition.MinValue = params.minValue;
            if (params.maxValue !== undefined) attributeDefinition.MaxValue = params.maxValue;
            break;
    
          case "Boolean":
            attributeDefinition["@odata.type"] = "Microsoft.Dynamics.CRM.BooleanAttributeMetadata";
            attributeDefinition.OptionSet = {
              "@odata.type": "Microsoft.Dynamics.CRM.BooleanOptionSetMetadata",
              TrueOption: {
                Value: 1,
                Label: createLocalizedLabel(params.trueOptionLabel || "Yes")
              },
              FalseOption: {
                Value: 0,
                Label: createLocalizedLabel(params.falseOptionLabel || "No")
              }
            };
            if (params.defaultValue && typeof params.defaultValue === "boolean") {
              attributeDefinition.DefaultValue = params.defaultValue;
            }
            break;
    
          case "DateTime":
            attributeDefinition["@odata.type"] = "Microsoft.Dynamics.CRM.DateTimeAttributeMetadata";
            // Remove Format property for now to avoid enum issues
            attributeDefinition.DateTimeBehavior = { Value: "UserLocal" };
            break;
    
          case "Memo":
            attributeDefinition["@odata.type"] = "Microsoft.Dynamics.CRM.MemoAttributeMetadata";
            attributeDefinition.MaxLength = params.maxLength || 2000;
            break;
    
          case "Double":
            attributeDefinition["@odata.type"] = "Microsoft.Dynamics.CRM.DoubleAttributeMetadata";
            if (params.minValue !== undefined) attributeDefinition.MinValue = params.minValue;
            if (params.maxValue !== undefined) attributeDefinition.MaxValue = params.maxValue;
            attributeDefinition.Precision = params.precision || 2;
            break;
    
          case "BigInt":
            attributeDefinition["@odata.type"] = "Microsoft.Dynamics.CRM.BigIntAttributeMetadata";
            break;
    
          case "Lookup":
            if (!params.targetEntity) {
              throw new Error("targetEntity is required for Lookup columns");
            }
            attributeDefinition["@odata.type"] = "Microsoft.Dynamics.CRM.LookupAttributeMetadata";
            attributeDefinition.Targets = [params.targetEntity];
            break;
    
          case "Picklist":
            attributeDefinition["@odata.type"] = "Microsoft.Dynamics.CRM.PicklistAttributeMetadata";
            if (params.optionSetName) {
              // Reference an existing global option set using the MetadataId
              // First get the option set to retrieve its MetadataId
              try {
                const globalOptionSet = await client.getMetadata(
                  `GlobalOptionSetDefinitions(Name='${params.optionSetName}')`
                );
                attributeDefinition["GlobalOptionSet@odata.bind"] = `/GlobalOptionSetDefinitions(${globalOptionSet.MetadataId})`;
              } catch (error) {
                throw new Error(`Global option set '${params.optionSetName}' not found: ${error instanceof Error ? error.message : 'Unknown error'}`);
              }
            } else if (params.options && params.options.length > 0) {
              // Create a new local option set
              attributeDefinition.OptionSet = {
                "@odata.type": "Microsoft.Dynamics.CRM.OptionSetMetadata",
                Name: `${params.entityLogicalName}_${logicalName}`,
                DisplayName: createLocalizedLabel(`${params.displayName} Options`),
                IsGlobal: false,
                OptionSetType: "Picklist", // Use string value instead of numeric
                Options: params.options.map(option => ({
                  Value: option.value,
                  Label: createLocalizedLabel(option.label),
                  Description: option.description ? createLocalizedLabel(option.description) : undefined
                }))
              };
            } else {
              throw new Error("Either optionSetName (for global option set) or options array (for local option set) is required for Picklist columns");
            }
            break;
    
          default:
            throw new Error(`Unsupported column type: ${params.columnType}`);
        }
    
        const result = await client.postMetadata(
          `EntityDefinitions(LogicalName='${params.entityLogicalName}')/Attributes`,
          attributeDefinition
        );
    
        return {
          content: [
            {
              type: "text",
              text: `Successfully created column '${logicalName}' with display name '${params.displayName}' of type '${params.columnType}' in table '${params.entityLogicalName}'.\n\nGenerated names:\n- Logical Name: ${logicalName}\n- Schema Name: ${schemaName}\n\nResponse: ${JSON.stringify(result, null, 2)}`
            }
          ]
        };
      } catch (error) {
        return {
          content: [
            {
              type: "text",
              text: `Error creating column: ${error instanceof Error ? error.message : 'Unknown error'}`
            }
          ],
          isError: true
        };
      }
    }
  • The inputSchema using Zod that validates and describes parameters for the tool, including required fields like entityLogicalName, displayName, columnType, and optional type-specific options like maxLength, options for picklists, etc.
    inputSchema: {
      entityLogicalName: z.string().describe("Logical name of the table to add the column to"),
      displayName: z.string().describe("Display name for the column (e.g., 'Customer Email')"),
      description: z.string().optional().describe("Description of the column"),
      columnType: z.enum([
        "String", "Integer", "Decimal", "Money", "Boolean", "DateTime",
        "Picklist", "Lookup", "Memo", "Double", "BigInt"
      ]).describe("Type of the column"),
      requiredLevel: z.enum(["None", "SystemRequired", "ApplicationRequired", "Recommended"]).default("None").describe("Required level of the column"),
      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"),
      // String-specific options
      maxLength: z.number().optional().describe("Maximum length for string columns (default: 100)"),
      format: z.enum(["Email", "Text", "TextArea", "Url", "Phone"]).optional().describe("Format for string columns"),
      // Integer-specific options
      minValue: z.number().optional().describe("Minimum value for integer/decimal columns"),
      maxValue: z.number().optional().describe("Maximum value for integer/decimal columns"),
      // Decimal-specific options
      precision: z.number().optional().describe("Precision for decimal columns (default: 2)"),
      // DateTime-specific options
      dateTimeFormat: z.enum(["DateOnly", "DateAndTime"]).optional().describe("Format for datetime columns"),
      // Boolean-specific options
      trueOptionLabel: z.string().optional().describe("Label for true option in boolean columns (default: 'Yes')"),
      falseOptionLabel: z.string().optional().describe("Label for false option in boolean columns (default: 'No')"),
      defaultValue: z.union([z.string(), z.number(), z.boolean()]).optional().describe("Default value for the column"),
      // Lookup-specific options
      targetEntity: z.string().optional().describe("Target entity for lookup columns"),
      // Picklist-specific options
      optionSetName: z.string().optional().describe("Name of the option set for picklist columns"),
      options: z.array(z.object({
        value: z.number(),
        label: z.string(),
        description: z.string().optional()
      })).optional().describe("Options for picklist columns")
    }
  • The exported createColumnTool function that registers the 'create_dataverse_column' tool with the MCP server, providing title, description, inputSchema, and the handler.
    export function createColumnTool(server: McpServer, client: DataverseClient) {
      server.registerTool(
        "create_dataverse_column",
        {
          title: "Create Dataverse Column",
          description: "Creates a new column (field) in a Dataverse table with the specified data type and configuration. Supports various column types including text, numbers, dates, lookups, and choice lists. Use this to add new fields to store specific data in your tables. Requires a solution context to be set first.",
          inputSchema: {
            entityLogicalName: z.string().describe("Logical name of the table to add the column to"),
            displayName: z.string().describe("Display name for the column (e.g., 'Customer Email')"),
            description: z.string().optional().describe("Description of the column"),
            columnType: z.enum([
              "String", "Integer", "Decimal", "Money", "Boolean", "DateTime",
              "Picklist", "Lookup", "Memo", "Double", "BigInt"
            ]).describe("Type of the column"),
            requiredLevel: z.enum(["None", "SystemRequired", "ApplicationRequired", "Recommended"]).default("None").describe("Required level of the column"),
            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"),
            // String-specific options
            maxLength: z.number().optional().describe("Maximum length for string columns (default: 100)"),
            format: z.enum(["Email", "Text", "TextArea", "Url", "Phone"]).optional().describe("Format for string columns"),
            // Integer-specific options
            minValue: z.number().optional().describe("Minimum value for integer/decimal columns"),
            maxValue: z.number().optional().describe("Maximum value for integer/decimal columns"),
            // Decimal-specific options
            precision: z.number().optional().describe("Precision for decimal columns (default: 2)"),
            // DateTime-specific options
            dateTimeFormat: z.enum(["DateOnly", "DateAndTime"]).optional().describe("Format for datetime columns"),
            // Boolean-specific options
            trueOptionLabel: z.string().optional().describe("Label for true option in boolean columns (default: 'Yes')"),
            falseOptionLabel: z.string().optional().describe("Label for false option in boolean columns (default: 'No')"),
            defaultValue: z.union([z.string(), z.number(), z.boolean()]).optional().describe("Default value for the column"),
            // Lookup-specific options
            targetEntity: z.string().optional().describe("Target entity for lookup columns"),
            // Picklist-specific options
            optionSetName: z.string().optional().describe("Name of the option set for picklist columns"),
            options: z.array(z.object({
              value: z.number(),
              label: z.string(),
              description: z.string().optional()
            })).optional().describe("Options for picklist columns")
          }
        },
        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 the logical name and schema name
            const logicalName = generateColumnLogicalName(params.displayName, prefix);
            const schemaName = generateColumnSchemaName(params.displayName, prefix);
    
            let attributeDefinition: any = {
              LogicalName: logicalName,
              SchemaName: schemaName,
              DisplayName: createLocalizedLabel(params.displayName),
              Description: params.description ? createLocalizedLabel(params.description) : undefined,
              RequiredLevel: {
                Value: params.requiredLevel,
                CanBeChanged: true,
                ManagedPropertyLogicalName: "canmodifyrequirementlevelsettings"
              },
              IsCustomAttribute: true
            };
    
            // Set type-specific properties
            switch (params.columnType) {
              case "String":
                attributeDefinition["@odata.type"] = "Microsoft.Dynamics.CRM.StringAttributeMetadata";
                attributeDefinition.MaxLength = params.maxLength || 100;
                // Remove Format property for now to avoid enum issues
                if (params.defaultValue && typeof params.defaultValue === "string") {
                  attributeDefinition.DefaultValue = params.defaultValue;
                }
                break;
    
              case "Integer":
                attributeDefinition["@odata.type"] = "Microsoft.Dynamics.CRM.IntegerAttributeMetadata";
                // Remove Format property for now to avoid enum issues
                if (params.minValue !== undefined) attributeDefinition.MinValue = params.minValue;
                if (params.maxValue !== undefined) attributeDefinition.MaxValue = params.maxValue;
                // Note: IntegerAttributeMetadata doesn't support DefaultValue property
                break;
    
              case "Decimal":
                attributeDefinition["@odata.type"] = "Microsoft.Dynamics.CRM.DecimalAttributeMetadata";
                attributeDefinition.Precision = params.precision || 2;
                if (params.minValue !== undefined) attributeDefinition.MinValue = params.minValue;
                if (params.maxValue !== undefined) attributeDefinition.MaxValue = params.maxValue;
                if (params.defaultValue && typeof params.defaultValue === "number") {
                  attributeDefinition.DefaultValue = params.defaultValue;
                }
                break;
    
              case "Money":
                attributeDefinition["@odata.type"] = "Microsoft.Dynamics.CRM.MoneyAttributeMetadata";
                attributeDefinition.Precision = params.precision || 2;
                if (params.minValue !== undefined) attributeDefinition.MinValue = params.minValue;
                if (params.maxValue !== undefined) attributeDefinition.MaxValue = params.maxValue;
                break;
    
              case "Boolean":
                attributeDefinition["@odata.type"] = "Microsoft.Dynamics.CRM.BooleanAttributeMetadata";
                attributeDefinition.OptionSet = {
                  "@odata.type": "Microsoft.Dynamics.CRM.BooleanOptionSetMetadata",
                  TrueOption: {
                    Value: 1,
                    Label: createLocalizedLabel(params.trueOptionLabel || "Yes")
                  },
                  FalseOption: {
                    Value: 0,
                    Label: createLocalizedLabel(params.falseOptionLabel || "No")
                  }
                };
                if (params.defaultValue && typeof params.defaultValue === "boolean") {
                  attributeDefinition.DefaultValue = params.defaultValue;
                }
                break;
    
              case "DateTime":
                attributeDefinition["@odata.type"] = "Microsoft.Dynamics.CRM.DateTimeAttributeMetadata";
                // Remove Format property for now to avoid enum issues
                attributeDefinition.DateTimeBehavior = { Value: "UserLocal" };
                break;
    
              case "Memo":
                attributeDefinition["@odata.type"] = "Microsoft.Dynamics.CRM.MemoAttributeMetadata";
                attributeDefinition.MaxLength = params.maxLength || 2000;
                break;
    
              case "Double":
                attributeDefinition["@odata.type"] = "Microsoft.Dynamics.CRM.DoubleAttributeMetadata";
                if (params.minValue !== undefined) attributeDefinition.MinValue = params.minValue;
                if (params.maxValue !== undefined) attributeDefinition.MaxValue = params.maxValue;
                attributeDefinition.Precision = params.precision || 2;
                break;
    
              case "BigInt":
                attributeDefinition["@odata.type"] = "Microsoft.Dynamics.CRM.BigIntAttributeMetadata";
                break;
    
              case "Lookup":
                if (!params.targetEntity) {
                  throw new Error("targetEntity is required for Lookup columns");
                }
                attributeDefinition["@odata.type"] = "Microsoft.Dynamics.CRM.LookupAttributeMetadata";
                attributeDefinition.Targets = [params.targetEntity];
                break;
    
              case "Picklist":
                attributeDefinition["@odata.type"] = "Microsoft.Dynamics.CRM.PicklistAttributeMetadata";
                if (params.optionSetName) {
                  // Reference an existing global option set using the MetadataId
                  // First get the option set to retrieve its MetadataId
                  try {
                    const globalOptionSet = await client.getMetadata(
                      `GlobalOptionSetDefinitions(Name='${params.optionSetName}')`
                    );
                    attributeDefinition["GlobalOptionSet@odata.bind"] = `/GlobalOptionSetDefinitions(${globalOptionSet.MetadataId})`;
                  } catch (error) {
                    throw new Error(`Global option set '${params.optionSetName}' not found: ${error instanceof Error ? error.message : 'Unknown error'}`);
                  }
                } else if (params.options && params.options.length > 0) {
                  // Create a new local option set
                  attributeDefinition.OptionSet = {
                    "@odata.type": "Microsoft.Dynamics.CRM.OptionSetMetadata",
                    Name: `${params.entityLogicalName}_${logicalName}`,
                    DisplayName: createLocalizedLabel(`${params.displayName} Options`),
                    IsGlobal: false,
                    OptionSetType: "Picklist", // Use string value instead of numeric
                    Options: params.options.map(option => ({
                      Value: option.value,
                      Label: createLocalizedLabel(option.label),
                      Description: option.description ? createLocalizedLabel(option.description) : undefined
                    }))
                  };
                } else {
                  throw new Error("Either optionSetName (for global option set) or options array (for local option set) is required for Picklist columns");
                }
                break;
    
              default:
                throw new Error(`Unsupported column type: ${params.columnType}`);
            }
    
            const result = await client.postMetadata(
              `EntityDefinitions(LogicalName='${params.entityLogicalName}')/Attributes`,
              attributeDefinition
            );
    
            return {
              content: [
                {
                  type: "text",
                  text: `Successfully created column '${logicalName}' with display name '${params.displayName}' of type '${params.columnType}' in table '${params.entityLogicalName}'.\n\nGenerated names:\n- Logical Name: ${logicalName}\n- Schema Name: ${schemaName}\n\nResponse: ${JSON.stringify(result, null, 2)}`
                }
              ]
            };
          } catch (error) {
            return {
              content: [
                {
                  type: "text",
                  text: `Error creating column: ${error instanceof Error ? error.message : 'Unknown error'}`
                }
              ],
              isError: true
            };
          }
        }
      );
  • createLocalizedLabel helper: Creates standardized LocalizedLabel objects used for DisplayName, Description, and Option labels.
    function createLocalizedLabel(text: string, languageCode: number = 1033): LocalizedLabel {
      return {
        LocalizedLabels: [
          {
            Label: text,
            LanguageCode: languageCode,
            IsManaged: false,
            MetadataId: "00000000-0000-0000-0000-000000000000"
          }
        ],
        UserLocalizedLabel: {
          Label: text,
          LanguageCode: languageCode,
          IsManaged: false,
          MetadataId: "00000000-0000-0000-0000-000000000000"
        }
      };
  • generateColumnLogicalName and generateColumnSchemaName helpers: Generate unique logical/schema names from displayName and solution prefix.
    function generateColumnLogicalName(displayName: string, prefix: string): string {
      // Convert display name to lowercase, remove spaces and special characters
      const cleanName = displayName.toLowerCase()
        .replace(/[^a-z0-9\s]/g, '') // Remove special characters except spaces
        .replace(/\s+/g, ''); // Remove all spaces
      
      return `${prefix}_${cleanName}`;
    }
    
    // Helper function to generate schema name from display name and prefix
    function generateColumnSchemaName(displayName: string, prefix: string): string {
      // Remove whitespaces and special characters, but preserve original case
      const cleanName = displayName.replace(/\s+/g, '').replace(/[^a-zA-Z0-9]/g, '');
      return `${prefix}_${cleanName}`;
    }
Behavior3/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 correctly identifies this as a creation operation and mentions the solution context requirement, but doesn't address important behavioral aspects like whether this operation is reversible, what permissions are needed, rate limits, or what happens if a column with the same name exists. The description provides basic context but lacks comprehensive behavioral details.

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 efficiently structured in three sentences: the core functionality, supported column types, usage purpose, and prerequisite. Each sentence adds value without redundancy. While very concise, it could potentially benefit from slightly more detail about behavioral aspects given the complexity of the tool.

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 creation tool with 21 parameters and no annotations or output schema, the description provides adequate but minimal context. It covers the basic purpose and prerequisite but doesn't address important contextual aspects like error conditions, response format, or detailed behavioral expectations. The description is complete enough to understand what the tool does but leaves significant gaps in operational understanding.

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?

With 100% schema description coverage, the input schema already documents all 21 parameters thoroughly. The description mentions 'data type and configuration' which aligns with parameters like columnType and various configuration options, but doesn't add significant semantic value beyond what's already in the well-documented schema. The baseline of 3 is appropriate when the schema does the heavy lifting.

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

Purpose5/5

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

The description clearly states the action ('Creates a new column'), specifies the resource ('in a Dataverse table'), and lists key configuration aspects ('data type and configuration'). It distinguishes from siblings like 'create_dataverse_table' (creates tables) and 'update_dataverse_column' (modifies existing columns).

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 context for when to use it ('to add new fields to store specific data in your tables') and includes a prerequisite ('Requires a solution context to be set first'). However, it doesn't explicitly state when NOT to use it or name specific alternatives like 'update_dataverse_column' for modifying existing columns.

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/mwhesse/mcp-dataverse'

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