Dataverse MCP server

Integrates with Microsoft Dataverse to enable schema operations, data management, and configuration tasks across Power Platform environments through over 50 tools for creating tables, columns, relationships, security roles, and solutions with support for Power Pages WebAPI integration.
Back to servers
Setup instructions
Provider
mwhesse
Release date
Jul 27, 2025
Language
TypeScript

The Dataverse MCP Server provides a comprehensive interface for managing Microsoft Dataverse schema through the Model Context Protocol (MCP). This server enables you to create and manage tables, columns, relationships, and option sets using the Dataverse Web API.

Prerequisites

You need the following before getting started:

  1. A Microsoft Dataverse environment
  2. An Azure AD app registration with appropriate permissions
  3. Client credentials (Client ID, Client Secret, and Tenant ID)

Setup

Azure App Registration

  1. Go to the Azure Portal
  2. Navigate to Azure Active Directory > App registrations
  3. Click New registration
  4. Provide a name (e.g., "Dataverse MCP Server")
  5. Select Accounts in this organizational directory only
  6. Click Register

Create Client Secret

  1. Go to Certificates & secrets
  2. Click New client secret
  3. Provide a description and expiration
  4. Click Add
  5. Copy the secret value immediately (you won't be able to see it again)

Create Application User in Dataverse

  1. Navigate to Dataverse Admin Center

  2. Create Application User

    • Click + New app user
    • Click + Add an app
    • Search for and select your Azure app registration (by Client ID)
    • Enter a Business unit (usually the root business unit)
    • Click Create
  3. Assign Security Roles

    • Select the newly created application user
    • Click Manage roles
    • Assign appropriate security roles (System Administrator recommended for development/testing)
  4. Verify Application User Status

    • Ensure the application user is Enabled
    • Verify it shows as Application type (not User)
    • Confirm the Application ID matches your Azure app registration Client ID

Get Required Information

Gather the following information:

  • Tenant ID: Found in Azure AD > Overview
  • Client ID: Found in your app registration > Overview
  • Client Secret: The secret you created
  • Dataverse URL: Your Dataverse environment URL (e.g., https://yourorg.crm.dynamics.com)

Installation

  1. Install dependencies:
npm install
  1. Build the server:
npm run build
  1. Copy the full path to the built index.js file (e.g., /Users/yourname/path/to/mcp-dataverse/build/index.js)

Configuration

There are three approaches to configuration:

Option 1: Using .env file (Development)

  1. Create a .env file by copying .env.example:
cp .env.example .env
  1. Configure the MCP server in your MCP settings file:
{
  "mcpServers": {
    "dataverse": {
      "command": "node",
      "args": ["/path/to/mcp-dataverse/build/index.js"],
      "disabled": false,
      "timeout": 900
    }
  }
}

Option 2: Using MCP environment variables (Production)

Configure environment variables directly in MCP settings:

{
  "mcpServers": {
    "dataverse": {
      "command": "node",
      "args": ["/path/to/mcp-dataverse/build/index.js"],
      "env": {
        "DATAVERSE_URL": "https://yourorg.crm.dynamics.com",
        "DATAVERSE_CLIENT_ID": "your-client-id",
        "DATAVERSE_CLIENT_SECRET": "your-client-secret",
        "DATAVERSE_TENANT_ID": "your-tenant-id"
      },
      "disabled": false,
      "timeout": 900
    }
  }
}

Usage Examples

Solution-Based Architecture

Before creating schema, set up a publisher and solution:

// 1. Create publisher with custom prefix
await use_mcp_tool("dataverse", "create_dataverse_publisher", {
  friendlyName: "XYZ Test Publisher",
  uniqueName: "xyzpublisher",
  customizationPrefix: "xyz",
  customizationOptionValuePrefix: 20000
});

// 2. Create solution linked to publisher
await use_mcp_tool("dataverse", "create_dataverse_solution", {
  friendlyName: "XYZ Test Solution",
  uniqueName: "xyzsolution",
  publisherUniqueName: "xyzpublisher"
});

// 3. Set solution context (persisted across server restarts)
await use_mcp_tool("dataverse", "set_solution_context", {
  solutionUniqueName: "xyzsolution"
});

Creating a Custom Table

// Create a new custom table
await use_mcp_tool("dataverse", "create_dataverse_table", {
  displayName: "Project",
  description: "Custom table for managing projects",
  ownershipType: "UserOwned",
  hasActivities: true,
  hasNotes: true
});

Adding Columns to a Table

// String column with email format
await use_mcp_tool("dataverse", "create_dataverse_column", {
  entityLogicalName: "xyz_project",
  displayName: "Contact Email",
  columnType: "String",
  format: "Email",
  maxLength: 100,
  requiredLevel: "ApplicationRequired"
});

// Integer column with constraints
await use_mcp_tool("dataverse", "create_dataverse_column", {
  entityLogicalName: "xyz_project",
  displayName: "Priority Score",
  columnType: "Integer",
  minValue: 1,
  maxValue: 10,
  defaultValue: 5
});

// Boolean column with custom labels
await use_mcp_tool("dataverse", "create_dataverse_column", {
  entityLogicalName: "xyz_project",
  displayName: "Is Active",
  columnType: "Boolean",
  trueOptionLabel: "Active",
  falseOptionLabel: "Inactive",
  defaultValue: true
});

// Picklist column with local options
await use_mcp_tool("dataverse", "create_dataverse_column", {
  entityLogicalName: "xyz_project",
  displayName: "Status",
  columnType: "Picklist",
  options: [
    { value: 1, label: "Planning" },
    { value: 2, label: "In Progress" },
    { value: 3, label: "On Hold" },
    { value: 4, label: "Completed" }
  ]
});

// Lookup column
await use_mcp_tool("dataverse", "create_dataverse_column", {
  entityLogicalName: "xyz_project",
  displayName: "Account",
  columnType: "Lookup",
  targetEntity: "account"
});

Creating Relationships

// Create a One-to-Many relationship
await use_mcp_tool("dataverse", "create_dataverse_relationship", {
  relationshipType: "OneToMany",
  schemaName: "new_account_project",
  referencedEntity: "account",
  referencingEntity: "new_project",
  referencingAttributeLogicalName: "new_accountid",
  referencingAttributeDisplayName: "Account",
  cascadeDelete: "RemoveLink"
});

Managing Option Sets

// Create a global option set
await use_mcp_tool("dataverse", "create_dataverse_optionset", {
  name: "new_priority",
  displayName: "Priority Levels",
  options: [
    { value: 1, label: "Low", color: "#00FF00" },
    { value: 2, label: "Medium", color: "#FFFF00" },
    { value: 3, label: "High", color: "#FF0000" }
  ]
});

WebAPI Call Generator

// Generate a simple retrieve operation
await use_mcp_tool("dataverse", "generate_webapi_call", {
  operation: "retrieve",
  entitySetName: "accounts",
  entityId: "12345678-1234-1234-1234-123456789012",
  select: ["name", "emailaddress1", "telephone1"]
});

// Generate a create operation with return preference
await use_mcp_tool("dataverse", "generate_webapi_call", {
  operation: "create",
  entitySetName: "accounts",
  data: {
    name: "Test Account",
    emailaddress1: "[email protected]",
    telephone1: "555-1234"
  },
  prefer: ["return=representation"]
});

Exporting Solution Schema

// Export custom schema only
await use_mcp_tool("dataverse", "export_solution_schema", {
  outputPath: "my-solution-schema.json"
});

// Export with system entities included
await use_mcp_tool("dataverse", "export_solution_schema", {
  outputPath: "complete-schema.json",
  includeSystemTables: true,
  includeSystemColumns: true,
  includeSystemOptionSets: true
});

Troubleshooting

Common Issues

  1. Authentication Failed

    • Verify client ID, secret, and tenant ID
    • Check that the app registration is properly configured
  2. Permission Denied

    • Verify the application user exists in Dataverse
    • Ensure it has appropriate security roles (System Administrator for full access)
    • Check that the application user is enabled
  3. Entity Not Found

    • Verify entity logical names are correct
    • Check if entities exist in the target environment

Debug Mode

For verbose logging, set the DEBUG environment variable:

DEBUG=true node build/index.js

Security Considerations

  1. Never commit client secrets to version control
  2. Use environment variables for configuration
  3. Grant only necessary permissions to your application user
  4. Monitor API usage
  5. Rotate client secrets regularly

How to install this MCP server

For Claude Code

To add this MCP server to Claude Code, run this command in your terminal:

claude mcp add-json "dataverse" '{"command":"node","args":["/path/to/mcp-dataverse/build/index.js"],"env":{"DATAVERSE_URL":"https://yourorg.crm.dynamics.com","DATAVERSE_CLIENT_ID":"your-client-id","DATAVERSE_CLIENT_SECRET":"your-client-secret","DATAVERSE_TENANT_ID":"your-tenant-id"},"disabled":false,"alwaysAllow":[],"disabledTools":[],"timeout":900}'

See the official Claude Code MCP documentation for more details.

For Cursor

There are two ways to add an MCP server to Cursor. The most common way is to add the server globally in the ~/.cursor/mcp.json file so that it is available in all of your projects.

If you only need the server in a single project, you can add it to the project instead by creating or adding it to the .cursor/mcp.json file.

Adding an MCP server to Cursor globally

To add a global MCP server go to Cursor Settings > Tools & Integrations and click "New MCP Server".

When you click that button the ~/.cursor/mcp.json file will be opened and you can add your server like this:

{
    "mcpServers": {
        "dataverse": {
            "command": "node",
            "args": [
                "/path/to/mcp-dataverse/build/index.js"
            ],
            "env": {
                "DATAVERSE_URL": "https://yourorg.crm.dynamics.com",
                "DATAVERSE_CLIENT_ID": "your-client-id",
                "DATAVERSE_CLIENT_SECRET": "your-client-secret",
                "DATAVERSE_TENANT_ID": "your-tenant-id"
            },
            "disabled": false,
            "alwaysAllow": [],
            "disabledTools": [],
            "timeout": 900
        }
    }
}

Adding an MCP server to a project

To add an MCP server to a project you can create a new .cursor/mcp.json file or add it to the existing one. This will look exactly the same as the global MCP server example above.

How to use the MCP server

Once the server is installed, you might need to head back to Settings > MCP and click the refresh button.

The Cursor agent will then be able to see the available tools the added MCP server has available and will call them when it needs to.

You can also explicitly ask the agent to use the tool by mentioning the tool name and describing what the function does.

For Claude Desktop

To add this MCP server to Claude Desktop:

1. Find your configuration file:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json
  • Linux: ~/.config/Claude/claude_desktop_config.json

2. Add this to your configuration file:

{
    "mcpServers": {
        "dataverse": {
            "command": "node",
            "args": [
                "/path/to/mcp-dataverse/build/index.js"
            ],
            "env": {
                "DATAVERSE_URL": "https://yourorg.crm.dynamics.com",
                "DATAVERSE_CLIENT_ID": "your-client-id",
                "DATAVERSE_CLIENT_SECRET": "your-client-secret",
                "DATAVERSE_TENANT_ID": "your-tenant-id"
            },
            "disabled": false,
            "alwaysAllow": [],
            "disabledTools": [],
            "timeout": 900
        }
    }
}

3. Restart Claude Desktop for the changes to take effect

Want to 10x your AI skills?

Get a free account and learn to code + market your apps using AI (with or without vibes!).

Nah, maybe later