MCP Hub
Back to servers

MCP Dataverse

50 tools for Microsoft Dataverse: query, CRUD, metadata, search, files, audit, batch, and more.

Updated
Feb 22, 2026

Quick Install

npx -y mcp-dataverse

MCP Dataverse Server

MCP Dataverse Logo

Node 20+ TypeScript MCP npm License: MIT

MCP server that exposes the Microsoft Dataverse Web API as 50 AI-callable tools — enabling GitHub Copilot, Claude, and other MCP clients to query, create, and manage Dataverse records without hallucinating schema.

Install

One-click (VS Code)

Install in VS Code Install in VS Code Insiders

VS Code will prompt for your Dataverse URL, auth mode, and PAC profile during installation.

Command line

# VS Code
code --add-mcp '{"name":"dataverse","type":"stdio","command":"npx","args":["-y","mcp-dataverse"],"env":{"DATAVERSE_ENV_URL":"https://yourorg.crm.dynamics.com","AUTH_MODE":"pac"}}'

# VS Code Insiders
code-insiders --add-mcp '{"name":"dataverse","type":"stdio","command":"npx","args":["-y","mcp-dataverse"],"env":{"DATAVERSE_ENV_URL":"https://yourorg.crm.dynamics.com","AUTH_MODE":"pac"}}'

Replace https://yourorg.crm.dynamics.com with your actual Dataverse environment URL.

Manual (mcp.json)

Add to your .vscode/mcp.json (or user settings):

{
  "servers": {
    "dataverse": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "mcp-dataverse"],
      "env": {
        "DATAVERSE_ENV_URL": "https://yourorg.crm.dynamics.com",
        "AUTH_MODE": "pac"
      }
    }
  }
}

Prerequisites

  • Node.js 20+
  • PAC CLI installed & authenticated → aka.ms/PowerAppsCLI
  • VS Code + GitHub Copilot (Agent mode)

Quick Start (< 5 min)

1. Clone & install

git clone <repo-url> mcp-dataverse && cd mcp-dataverse
npm install

2. Configure

cp config.example.json config.json

Edit config.json:

FieldDescription
environmentUrlYour org URL, e.g. https://yourorg.crm.dynamics.com
authMode"pac" (recommended) or "msal"
pacProfileNamePAC CLI profile name (default: "default")
requestTimeoutMsHTTP timeout in ms (default: 30000)
maxRetriesRetry count on transient errors (default: 3)

3. Authenticate

npm run auth:setup

Runs device code authentication. Follow the URL printed to the terminal — sign in with your Power Platform account. Token is cached in .msal-cache.json for silent reuse.

Only required for authMode: "pac". Skip if PAC CLI (pac auth create) is already authenticated.

4. Build

npm run build

5. Verify the connection

npx tsx tests/live/test-whoami.ts

Expected output:

WhoAmI result: { UserId: 'xxxxxxxx-...', BusinessUnitId: 'xxxxxxxx-...', OrganizationId: 'xxxxxxxx-...' }

6. Configure VS Code

.vscode/mcp.json is already present in this repo. If you need to add it manually:

{
  "servers": {
    "dataverse": {
      "type": "stdio",
      "command": "node",
      "args": ["${workspaceFolder}/dist/server.js"],
      "env": {}
    }
  }
}
  1. Restart VS Code
  2. Open GitHub Copilot chat → switch to Agent mode (⚡)
  3. Test: "List the Dataverse tables in my environment"

Tools (50)

ToolCategoryDescription
dataverse_whoamiAuthVerify connection; returns UserId, BusinessUnitId, OrgId
dataverse_list_tablesMetadataList all tables (customOnly filter available)
dataverse_get_table_metadataMetadataFull schema: columns, types, logical names
dataverse_get_relationshipsMetadataAll 1:N, N:1, N:N relationships for a table; filter by relationshipType
dataverse_list_global_option_setsMetadataAll global option sets in the environment
dataverse_get_option_setMetadataOptions and values for a specific option set
dataverse_get_entity_keyMetadataAlternate key definitions for a table (fields, index status, customizable flag)
dataverse_queryQueryOData query with $select, $filter, $orderby, $expand, $count
dataverse_execute_fetchxmlQueryRaw FetchXML for aggregations and complex joins
dataverse_retrieve_multiple_with_pagingQueryPaginated query following @odata.nextLink, with configurable maxTotal cap
dataverse_getCRUDRetrieve a single record by GUID
dataverse_createCRUDCreate a record; returns the new GUID
dataverse_updateCRUDPatch a record — only specified fields are changed
dataverse_deleteCRUDDelete a record (requires explicit confirm)
dataverse_upsertCRUDCreate-or-update via alternate key
dataverse_assignCRUDAssign a record to a different user or team owner
dataverse_associateRelationsAssociate two records via a named relationship
dataverse_disassociateRelationsRemove an association between two records
dataverse_execute_actionActionsExecute a global (unbound) Dataverse action
dataverse_execute_functionActionsExecute a global read-only function (e.g. WhoAmI)
dataverse_execute_bound_actionActionsExecute an action bound to a specific record
dataverse_execute_bound_functionActionsExecute an OData bound function on a specific record
dataverse_retrieve_dependencies_for_deleteActionsCheck what components block deletion of a Dataverse component
dataverse_list_dependenciesActionsList component dependencies before modifying or deleting
dataverse_batch_executeBatchUp to 1000 operations in a single HTTP batch request; optional atomic changeset
dataverse_change_detectionTrackingDelta tracking using change tokens to detect record changes since last sync
dataverse_solution_componentsSolutionList all components in a named solution; filter by component type code
dataverse_publish_customizationsSolutionPublish pending customizations (all or targeted entities/web resources/option sets)
dataverse_impersonateImpersonationExecute any tool on behalf of another Dataverse user via MSCRMCallerId
dataverse_list_custom_actionsCustomizationLists custom actions (custom API / SDK messages) in the environment
dataverse_list_plugin_stepsCustomizationLists plugin step registrations with stage, mode, entity, and state
dataverse_get_environment_variableEnvironmentRetrieve an environment variable definition and current value
dataverse_set_environment_variableEnvironmentSet or update an environment variable value
dataverse_get_plugin_trace_logsTraceRetrieve plugin execution trace logs for debugging
dataverse_get_workflow_trace_logsTraceRetrieve async workflow/system job execution logs
dataverse_searchSearchFull-text Relevance Search across all configured tables
dataverse_get_audit_logAuditRetrieve audit trail for a record showing change history
dataverse_detect_duplicatesQualityCheck for potential duplicates before creating a record
dataverse_get_annotationsAnnotationsRetrieve notes and file attachments linked to a record
dataverse_list_usersUsersSearch system users by name or email with BU filtering
dataverse_get_user_rolesUsersSecurity roles assigned to a system user
dataverse_create_annotationAnnotationsCreate a note or file attachment linked to a record
dataverse_get_attribute_option_setMetadataLocal/entity-specific option set values (statecode, statuscode, picklist)
dataverse_list_solutionsSolutionList all solutions in the environment
dataverse_set_workflow_stateCustomizationEnable or disable a workflow or process
dataverse_list_viewsViewsList system and personal saved views for a table
dataverse_upload_file_columnFilesUpload binary content to a file/image column on a record
dataverse_download_file_columnFilesDownload binary content from a file/image column on a record
dataverse_list_business_unitsOrgList business units in the environment (org hierarchy)
dataverse_list_teamsTeamsList Dataverse teams with optional filter by team type

Advanced Configuration (MSAL)

For service-principal auth (CI/CD, unattended), set authMode: "msal" in config.json:

{
  "environmentUrl": "https://yourorg.crm.dynamics.com",
  "authMode": "msal",
  "tenantId": "<azure-ad-tenant-id>",
  "clientId": "<app-registration-client-id>",
  "clientSecret": "<client-secret>"
}

The app registration must have the Dynamics CRM → user_impersonation API permission and the corresponding Dataverse security role.


Scripts

CommandDescription
npm run buildCompile TypeScript → dist/
npm run devWatch mode — no build step needed
npm startStart the compiled server
npm run auth:setupOne-time device code authentication
npm run typecheckType-check without emitting output
npm run lintESLint on src/
npm run test:unitUnit tests only
npm run test:integrationIntegration tests
npm testAll tests

Architecture

TypeScript MCP server over stdio transport. An AuthProvider (PAC CLI or MSAL) injects Bearer tokens into a native-fetch-based HttpClient wrapped by DataverseClient. Each tool module registers handlers with the MCP Server instance.

GitHub Copilot → stdio → MCP Server → Tool Router → DataverseClient → Dataverse Web API v9.2
                                                           └── AuthProvider (PAC CLI | MSAL)

Security

  • Never commit config.json or .msal-cache.json — both are in .gitignore
  • Tokens are never logged; only diagnostic messages are written to stderr
  • PAC CLI tokens are scoped to the authenticated user — no privilege escalation
  • Service principal (msal) should be assigned the least-privilege Dataverse security role

Troubleshooting

SymptomFix
No MSAL accounts foundRun npm run auth:setup to re-authenticate
"https://" is requiredCheck environmentUrl in config.json — must start with https://
pac: command not foundInstall PAC CLI and run pac auth create --environment <url>
Server not appearing in Copilot Agent modeRestart VS Code; check Output → MCP panel for errors

Reviews

No reviews yet

Sign in to write a review