dataverse-mcp-server
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| DATAVERSE_CLIENT_ID | Yes | Your app registration client ID | |
| DATAVERSE_TENANT_ID | Yes | Your Azure tenant ID | |
| DATAVERSE_ALLOW_DELETE | No | Optional flag to enable delete operations (set to 'true' to enable) | |
| DATAVERSE_RESOURCE_URL | Yes | Your Dataverse environment URL (e.g., https://your-org.crm.dynamics.com) | |
| DATAVERSE_CLIENT_SECRET | Yes | Your client secret | |
| DATAVERSE_ENTITY_PREFIX | No | Optional default prefix filter for list_entities | |
| DATAVERSE_SOLUTION_NAME | No | Optional default solution unique name for list_entities |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": true
} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| list_entitiesC | List Dataverse tables (entities) with optional prefix and solution filters |
| get_entity_schemaA | Get attributes (columns) of a specific Dataverse table. Choice-style columns (Choice, Status, State, MultiSelect) carry an option_set summary with is_global and option_count, so one dump shows which choice lists are shared org-wide. Read the option values per column with get_picklist_options. |
| get_picklist_optionsB | Read a Local or Global OptionSet as { option_set: { name, is_global, metadata_id }, options: [{ value, label }] }. Use is_global to tell whether a column holds a local copy of the values or is bound to a shared Global OptionSet — matching values alone do not prove a binding. Works for Choice, Status, State and MultiSelect columns. |
| list_entity_keysA | List alternate keys defined on a Dataverse table. Returns a flat array of { logical_name, schema_name, display_name, key_attributes, entity_key_index_status, metadata_id }. entity_key_index_status reflects the background index build (Pending → Active, or Failed) — alt keys are not usable for keyed-PATCH upserts until Active. |
| query_recordsC | Query records from a Dataverse table with OData filters |
| get_recordC | Get a single record by ID from a Dataverse table |
| create_recordC | Create a new record in a Dataverse table |
| update_recordC | Update an existing record in a Dataverse table |
| delete_recordB | Delete a record from a Dataverse table (currently disabled for safety) |
| invoke_actionA | Invoke a Dataverse Web API action (POST) — bound or unbound. Use for operations that are not plain CRUD, e.g. PublishDuplicateRule (bound to a duplicaterule) or QualifyLead (bound to a lead), or UnpublishDuplicateRule (unbound, takes DuplicateRuleId). Whether an action is bound is defined in the Web API $metadata. Pass entity_set+id for bound actions, neither for unbound. parameters becomes the JSON request body. |
| invoke_functionA | Invoke a Dataverse Web API function (GET) — bound or unbound. Use for read-only operations exposed as functions, e.g. WhoAmI (unbound) or RetrieveDuplicates. Pass entity_set+id for bound functions, neither for unbound. parameters are inlined into the URL as OData function arguments. |
| list_solutionsB | List Dataverse solutions (uniquename is used to filter list_entities) |
| create_entityC | Create a new Dataverse table (entity) with specified attributes |
| add_attributeC | Add a column (attribute) to an existing Dataverse table |
| create_relationshipC | Create a relationship between two Dataverse tables |
| update_attributeA | Update metadata of an existing column: display name, description, required level, max length, min/max value, precision. Dataverse fixes a column's type and logical name at creation — to change either, add_attribute a new column, migrate the values with update_record, then delete_attribute the old one. |
| delete_attributeA | Delete a column from a Dataverse table (currently disabled for safety) |
| get_attribute_dependenciesA | List CRM components that reference a column — forms, views, workflows, business rules, plugins. Call this when delete_attribute fails with 0x8004f01f, or before any destructive change to a column. Component names are best-effort: resolved for common types, null otherwise. Backed by the Dataverse RetrieveDependenciesForDelete function. |
| add_entity_keyA | Create an alternate key on a Dataverse table (composite supported via key_attributes). Use for race-safe upserts via keyed-PATCH or to enforce a uniqueness constraint that the primary key doesn't cover. NOTE: Dataverse builds the supporting unique index asynchronously — the key is not usable for keyed lookups until its EntityKeyIndexStatus becomes 'Active'. Poll with list_entity_keys. |
| delete_entity_keyC | Delete an alternate key from a Dataverse table (currently disabled for safety) |
| add_picklist_optionA | Add an option to an existing Local or Global OptionSet (Dataverse InsertOptionValue action). Requires Customizer or System Administrator role; HTTP 403 otherwise. |
| update_picklist_optionA | Update an existing option's label/description on a Local or Global OptionSet (Dataverse UpdateOptionValue action). Requires Customizer or System Administrator role. |
| delete_picklist_optionA | Remove an option from a Local or Global OptionSet (currently disabled for safety) |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 23 tools
Most tools are cleanly separated by resource + action (entity vs record vs attribute vs key vs picklist), and generic escape hatches (invoke_action vs invoke_function) are distinguished by POST/GET semantics. Minor overlap remains between get_entity_schema and get_picklist_options (schema dump already summarizes option sets), and create_entity vs create_record could briefly confuse newcomers to Dataverse terminology.
Every tool follows a consistent snake_case verb_noun pattern (list_entities, create_record, update_attribute, delete_picklist_option, get_attribute_dependencies). The only deviation is 'query_records' using a different read verb, but it remains within the same convention and clearly signals a filter-based read versus a list.
23 tools is on the heavy side but is justified by the genuinely broad domain: records, tables, columns, alternate keys, option sets, relationships, solutions, plus two escape hatches. There is little obvious redundancy, though the set is at the upper edge of comfortable before it becomes unwieldy.
Record CRUD and attribute/key/picklist lifecycles are largely covered, but there are notable gaps: relationships can be created but not listed or deleted, tables can be created but not updated or deleted, and solutions are read-only. Several delete operations (record, entity key, picklist option, attribute) are explicitly disabled for safety, which will leave agents at dead ends when cleanup is required.