Dataverse Plugin MCP
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Dataverse Plugin MCP Generate an xray report for the assembly MyAssembly"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Dataverse Plugin MCP
An MCP server that lets an AI assistant (Claude, etc.) scaffold, build, register, query, and diagnose Microsoft Dataverse (Power Platform / Dynamics 365) plug-ins directly from a conversation — no need to leave the editor to open the Plugin Registration Tool or hand-write Web API calls.
Instead of reimplementing the registration logic from scratch, this MCP orchestrates tools you already use and already have authenticated on your machine:
Power Platform CLI (
pac) — project scaffolding, build, and push of already-registered packages.Azure CLI (
az) — reuses your already-authenticated session (same account/tenant aspac) to get a token and talk directly to the Dataverse Web API (query and register SDK message processing steps, images, execution logs, etc.).
Why this exists
Registering a Dataverse plug-in normally means switching between several tools: pac plugin init for the project skeleton, the Plugin Registration Tool (GUI) for the first registration, and either the PRT or manual Web API calls to bind messages/entities/stages and configure pre/post images. This MCP brings that whole flow into tools an AI assistant can call directly, including operations that usually only exist in the GUI (a full assembly diagnostic report, step editing, trace logs).
Related MCP server: MCP Dataverse
Prerequisites
Tool | Purpose | Install |
Runs the MCP server | — | |
Manages the environment/dependencies |
| |
Scaffolding, build, push, PRT |
| |
Web API access token | official installer | |
.NET SDK | Builds the |
Authenticate both CLIs once, with the same account that has access to the target Dataverse environment:
pac auth create --environment https://YOUR-ENVIRONMENT.crm.dynamics.com
az loginThe server never stores or asks for credentials — it always delegates to these two already-authenticated sessions.
Installation
git clone https://github.com/lucasjesus0311/dataverse-plugin-mcp.git
cd dataverse-plugin-mcp
uv syncConfigure in Claude Code
claude mcp add dataverse-plugins -- uv --directory "PATH/TO/dataverse-plugin-mcp" run dataverse_plugins_server.pyConfigure in Claude Desktop
Edit claude_desktop_config.json (under %APPDATA%\Claude\, or if the app was installed from the Microsoft Store, under %LOCALAPPDATA%\Packages\<PackageId>\LocalCache\Roaming\Claude\):
{
"mcpServers": {
"dataverse-plugins": {
"command": "C:\\PATH\\TO\\uv.exe",
"args": [
"--directory", "C:\\PATH\\TO\\dataverse-plugin-mcp",
"run", "dataverse_plugins_server.py"
]
}
}
}Use the full path to uv.exe (find it with where uv on Windows or which uv on macOS/Linux) — GUI apps don't always inherit the shell PATH. Fully restart Claude Desktop after saving.
Available tools
24 tools, organized by stage of a plug-in's lifecycle. Full reference with every parameter in docs/TOOLS.md.
Category | Tools |
Environment |
|
Local development |
|
Registration |
|
Steps (CRUD) |
|
Images (CRUD) |
|
Query |
|
Deletion |
|
Diagnostics |
|
xray_assembly deserves a callout: it generates a complete report of a registered assembly in a single call — classes, steps with every setting, images, and the latest trace log entries.
⚠️ Security notice
Several tools perform real writes to the configured Dataverse environment (creating/editing/deleting steps, images, assemblies, packages; toggling tracing; updating the running code via push_plugin_update). They act with the same permissions as your pac/az session — always test in a development environment, never directly in production. Each tool's docstring clearly flags when an operation is destructive or irreversible.
Known limitations
First-time registration of a package/assembly: there is no CLI command or simple Web API call for this — Microsoft reserves this step for the Plugin Registration Tool or the Visual Studio extension (which reflect over the assembly to auto-discover its classes). Use
open_registration_tool()for this one-time step; after that,push_plugin_update()covers every update via CLI.PATCHonsdkmessageprocessingstepimages: the Dataverse Web API rejects direct updates to this table with a generic, undocumented error (0x80040216).update_image()works around this by deleting and recreating the image.$expandonpackageidofpluginassemblies: returns400 Bad Request. The code uses_packageid_valueplus a separate lookup instead of$expand.
Project structure
.
├── dataverse_plugins_server.py # main server (24 tools)
├── docs/
│ └── TOOLS.md # full reference for every tool
├── examples/
│ └── hello_world_mcp_server.py # minimal example MCP (3 trivial tools)
├── plugins/ # C# plug-in projects generated/registered locally
└── pyproject.tomlMinimal example
If you're just getting started with MCP, examples/hello_world_mcp_server.py is a 3-tool trivial server (add, current time, reverse text) — a good starting point before diving into the main server.
License
Available Tools
24 toolsbuild_pluginC
Build the plug-in project with 'dotnet build' and return the build output.
Inputs: project_path (required), configuration. Returns: result
configure_tracingA
Turn the environment's Plug-in Trace Log on/off (required for list_execution_logs to work).
level: 'Off', 'Exception' (only logs when the plug-in throws an exception), or 'All' (always logs). Remember to switch back to 'Off' or 'Exception' after debugging -- logs consume the organization's storage space.
Inputs: level (required), environment. Returns: result
create_plugin_projectA
Create a new C# Dataverse plug-in project (pac plugin init) under plugins/.
Generates a .NET (net462) project with a sample Plugin1 class ready to edit. Does not register anything in Dataverse -- it only creates the code locally.
name: must be a valid C# identifier (no hyphens/spaces) -- it becomes the project namespace. sign: defaults to True -- generates a .snk key and signs the assembly with a strong name (required by classic assembly registration). Use False (--skip-signing) only if the package bundles unsigned third-party dependent assemblies.
Inputs: name (required), sign, author. Returns: result
create_stepA
Register a new SDK message processing step, binding a plug-in class to a message/entity/stage.
plugin_type_name_or_id: typename (Namespace.Class), friendlyname, or GUID of the plugintype -- use list_plugin_types() to find it. message: Dataverse message name, e.g. 'Create', 'Update', 'Delete'. entity: logical name of the table (e.g. 'account'); empty = all entities that support the message. stage: 'PreValidation', 'PreOperation', or 'PostOperation'. filtering_attributes: comma-separated list of columns (only meaningful for 'Update'). rank: execution order among steps in the same stage/message/entity (lower runs first). configuration: free text (unsecure configuration) passed to the plugin's constructor. impersonate_user_id: GUID of a systemuser to run the step as ("Run in User's Context"); empty = runs as the user who triggered the operation. WARNING: this creates a real record in the environment -- the plug-in starts executing for real.
Inputs: message (required), plugin_type_name_or_id (required), rank, stage, +7 more.
create_step_imageA
Register a pre/post image on an existing step, so the plug-in can read values before/after the operation.
step_id: GUID of the step (returned by create_step or list_steps). attributes: comma-separated list of columns to include (e.g. 'description,firstname'); empty = all columns. image_type: 'PreImage' (values before the operation), 'PostImage' (after), or 'Both'. Pre-Image is not available for the 'Create' message (the row does not exist yet); Post-Image is not available for 'Delete'. alias: name used in the C# code to access the image (e.g. localPluginContext.PluginExecutionContext.PreEntityImages["PreImage"]). Empty uses 'image_type' itself as the alias.
Inputs: step_id (required), alias, attributes, image_type, +1 more.
delete_assemblyA
Delete a registered PluginAssembly (without a PluginPackage).
Only works if no SDK message processing steps depend on classes from this assembly -- delete the steps first with delete_step(). Dataverse rejects the deletion otherwise.
Inputs: assembly_name_or_id (required), environment. Returns: result
delete_imageB
Delete a pre/post image from a step, without deleting the step itself.
Inputs: image_id (required), environment. Returns: result
delete_packageA
Delete a registered PluginPackage (Nuget package).
WARNING: this also deletes every assembly, plug-in class, and step inside the package.
Inputs: package_name_or_id (required), environment. Returns: result
delete_stepA
Delete an SDK message processing step (its images are removed in cascade).
WARNING: the plug-in stops executing for this message/entity/stage combination.
Inputs: step_id (required), environment. Returns: result
list_available_messagesA
List the Dataverse message names (Create, Update, Delete, Assign, ...) supported by a table.
Useful to know what to pass as 'message' to create_step() before attempting to register it.
Inputs: entity (required), environment. Returns: result
list_environmentsA
List the authentication profiles (Dataverse environments) configured in the pac CLI.
Inputs: no named parameters. Returns: result
list_execution_logsA
Read the latest Plug-in Trace Log entries (Trace()/exception logs from the plug-in).
plugin_type_name: filters by typename (e.g. 'MyFirstPlugin.Plugin1'); empty = all plug-ins. Requires tracing to be enabled in the environment -- see configure_tracing().
Inputs: limit, environment, plugin_type_name. Returns: result
list_imagesC
List the pre/post images registered on an SDK message processing step.
Inputs: step_id (required), environment. Returns: result
list_plugin_typesA
List the plug-in classes (plugintypes) of an assembly, given the assembly's name or GUID.
Inputs: assembly_name_or_id (required), environment. Returns: result
list_registered_pluginsB
List the plug-in packages (pluginpackages) and assemblies (pluginassemblies) registered in the environment.
Inputs: environment.
list_stepsB
List the SDK message processing steps (message/entity/stage) of a plug-in class.
Inputs: plugin_type_name_or_id (required), environment. Returns: result
open_registration_toolA
Open the Plugin Registration Tool (PRT) for the FIRST registration of a plug-in package.
'pac plugin push' only UPDATES a package that already exists in Dataverse (it needs the pluginId). The first-time registration of a new package still requires the PRT or the Visual Studio extension -- there is no CLI command to create the package from scratch. After registering it for the first time in the PRT, copy the package/assembly GUID shown there and use it in push_plugin_update() for every following update.
Inputs: no named parameters. Returns: result
push_plugin_updateA
Rebuild and push (upload) a plug-in that is ALREADY REGISTERED in Dataverse.
plugin_id: GUID of the PluginPackage (or PluginAssembly), obtained from the first registration via the PRT. environment: index, name, or URL from list_environments(); empty uses the pac active environment. item_type: 'Nuget' (package generated by pac plugin init, plugin_id = PluginPackage) or 'Assembly' (loose dll, plugin_id = PluginAssembly -- requires file_path pointing to the compiled .dll, e.g. bin/Debug/net462/ProjectName.dll). file_path: relative to project_path; required when item_type='Assembly'. WARNING: this replaces the code currently running in the given environment.
Inputs: plugin_id (required), project_path (required), file_path, item_type, +2 more. Returns: result
select_environmentA
Set which authentication profile/Dataverse environment is active (index from list_environments).
Inputs: index (required). Returns: result
set_secure_configurationA
Set the Secure Configuration of a step (text only accessible to the plug-in, not shown in the PRT/UI).
Creates the secure configuration record if the step doesn't have one yet, or updates the existing one.
Inputs: value (required), step_id (required), environment. Returns: result
toggle_stepB
Enable or disable an existing SDK message processing step.
Inputs: enabled (required), step_id (required), environment. Returns: result
update_imageA
"Update" the attributes, alias, or type of an already-registered pre/post image.
The Dataverse Web API rejects direct PATCH on sdkmessageprocessingstepimages (it always returns the generic, undocumented 0x80040216 error -- confirmed by testing; it looks like an undocumented platform limitation for this table). So this tool recreates the image instead: it reads the current values, deletes it, and creates a new one with the merged fields, bound to the same step. The image 'id' changes -- use the value returned by this call. Leave a parameter out (None) to keep its current value.
Inputs: image_id (required), alias, attributes, image_type, +1 more.
update_stepA
Update properties of an existing SDK message processing step.
Each optional parameter is only changed if provided (None/empty = keep the current value), except filtering_attributes and configuration: pass an explicit empty string to clear the field.
Inputs: step_id (required), name, rank, stage, +4 more. Returns: result
xray_assemblyA
Generate a complete report of a registered plug-in assembly, in a single call: assembly metadata, every class (plugintype), every step with ALL its configuration (message, entity, stage, mode, rank, filtering attributes, whether it has a configuration/secure configuration, impersonation user), and each step's images.
include_logs: appends, per class, the last 5 Plug-in Trace Log entries (duration and error, if any). Only returns something if tracing is enabled -- see configure_tracing().
Inputs: assembly_name_or_id (required), environment, include_logs.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 24 tools
Each tool targets a distinct resource and action: environments, projects, builds, registrations, steps, images, assemblies, packages, available messages, logs, and tracing. Even similar delete/update/list tools are clearly differentiated by their object type (image vs assembly vs package, etc.).
All tool names follow a consistent verb_noun snake_case pattern (e.g., list_steps, create_step, update_step, delete_step, toggle_step, configure_tracing). Compound verbs like open_registration_tool and push_plugin_update still adhere to the same structural pattern, maintaining predictability throughout.
At 24 tools, the set is slightly above the typical 3-15 well-scoped range, but each tool serves a distinct purpose within the plugin development lifecycle. The count is justified by the broad domain coverage, from project creation to deployment and diagnostics, without redundant or trivial tools.
The tool set covers the full lifecycle: project scaffolding, build, registration (with a manual PRT step workaround), CRUD for steps and images, environment management, secure configuration, tracing, and a comprehensive xray_assembly report. There are no obvious dead ends or missing critical operations for the plugin development workflow.
Maintenance
Related MCP Connectors
MCP server for your apps' tools and custom tools, plus hosted AI agents and approval-gated workflows
MCP server that lets your AI assistant build and deploy apps, hosting each one at a live URL.
MCP server for AI agents to plan, verify, and deploy Cloudflare-native apps.
MCP server unifying ERPs, CRMs, APIs and knowledge base for Claude, ChatGPT and Gemini.
Related MCP Servers
- AlicenseBqualityCmaintenanceA Model Context Protocol (MCP) server that provides intelligent access to PowerPlatform/Dataverse entities and records. This tool offers context-aware assistance, entity exploration and metadata access.3893 npm45MIT
- AlicenseNot gradedqualityBmaintenanceThe most complete MCP server for Microsoft Dataverse.218 npm18MIT
- FlicenseAqualityCmaintenanceA minimal MCP server that gives AI coding agents clean read and write access to Microsoft Dataverse environments via the Dataverse Web API v9.2. It works as a drop-in alternative to Microsoft's own MCP server, without requiring Copilot Credits or managed environments.821-
- AlicenseBqualityCmaintenanceMCP server for Microsoft Fabric REST APIs that enables data engineers and analysts to manage Fabric components using AI assistants.21929 npmAGPL 3.0