Skip to main content
Glama
rededis

dataverse-mcp-server

by rededis

dataverse-mcp-server

npm version npm downloads CI Node.js TypeScript License: MIT

MCP (Model Context Protocol) server for Microsoft Dataverse API with safe-by-default configuration. Works with any Dataverse / Dynamics 365 environment.

Tools

Data operations

Tool

Description

list_entities

List Dataverse tables with optional prefix and solution filters

list_solutions

List Dataverse solutions (use uniquename to filter list_entities)

get_entity_schema

Get attributes of a specific table — choice columns carry an option_set summary

query_records

Query records with OData $filter, $select, $top, $orderby, $expand

get_record

Get a single record by ID

create_record

Create a record

update_record

Update a record

delete_record

Delete a record (disabled by default, see Safety)

Note: solution / DATAVERSE_SOLUTION_NAME only scopes list_entities (schema browsing). Data tools (query_records, get_record, create_record, …) keep full access to any table regardless of solution membership — shared tables like account or contact remain reachable.

Schema operations

Tool

Description

create_entity

Create a new table with attributes

add_attribute

Add a column to an existing table (Choice columns can bind to a Global OptionSet)

update_attribute

Update column metadata (display name, required level, bounds, …)

delete_attribute

Delete a column (disabled by default, see Safety)

get_attribute_dependencies

List CRM components (forms, views, workflows, …) that reference a column — use after delete_attribute fails with 0x8004f01f

create_relationship

Create relationships between tables (1:N, N:N)

list_entity_keys

List alternate keys on a table (returns key_attributes, entity_key_index_status, …)

add_entity_key

Create an alternate key (single or composite) — enables race-safe keyed-PATCH upserts

delete_entity_key

Delete an alternate key and its supporting unique index (disabled by default, see Safety)

Dataverse does not allow changing a column's logical name or type. To "rename" or change type: create a new column, migrate data via update_record, then delete_attribute on the old one.

Choice columns: local values or a shared Global OptionSet

A Picklist attribute takes exactly one of two fields. options defines the values inline and produces a Local OptionSet owned by that single column:

{ "logical_name": "contoso_source", "type": "Picklist", "display_name": "Source",
  "options": [ { "label": "Website", "value": 909890000 } ] }

global_option_set instead binds the column to an existing Global OptionSet by name, so several columns across several tables share one list and cannot drift apart:

{ "logical_name": "contoso_source", "type": "Picklist", "display_name": "Source",
  "global_option_set": "contoso_sourceset" }

Supplying both is rejected. That check is not cosmetic: Dataverse itself accepts the pair and then silently ignores the binding, leaving a local copy that looks bound. An unknown set name fails as Global OptionSet not found: '<name>' before anything is created — including in create_entity, which resolves names and validates every attribute before the table exists, so a rejected column cannot leave a half-built table behind.

Verify the result with get_picklist_options: a bound column reports is_global: true and the global set's own metadata_id.

Picklist option management

Tool

Description

get_picklist_options

Read a Local or Global OptionSet — its identity plus [{ value, label }]

add_picklist_option

Add an option to an existing OptionSet (InsertOptionValue)

update_picklist_option

Rename an option on an OptionSet (UpdateOptionValue)

delete_picklist_option

Remove an option from an OptionSet (DeleteOptionValue)

Picklist tools accept either entity_logical_name + attribute_logical_name (a column) or option_set_name (a Global OptionSet) — the two modes are mutually exclusive. Write operations require Customizer or System Administrator role on the connected service principal. Deleting an option does not update existing records that hold its numeric value — they are left with an orphan integer.

Telling a Global OptionSet from a local copy

get_picklist_options returns the set's identity alongside its options:

{
  "option_set": {
    "name": "fundai_source",
    "is_global": true,                                   // bound to a shared Global OptionSet
    "metadata_id": "ea6ab542-9c2e-f111-88b3-00224805d253"
  },
  "options": [ { "value": 909890000, "label": "Website" }, /* … */ ]
}

is_global is the answer to "does this column reuse an org-wide list, or does it own a private copy?" — matching values prove nothing on their own, and a column with a local set reports an auto-generated name like opportunity_prioritycode with is_global: false. To confirm which global set a column is bound to, compare its metadata_id against the one returned by get_picklist_options { option_set_name: … }.

The lookup covers Choice, Status, State and MultiSelect columns, so statecode / statuscode can be read the same way as a custom choice column.

get_entity_schema reports the same identity per column as a compact option_set summary with an option_count instead of the values themselves — read the values for a single column with get_picklist_options:

{
  "LogicalName": "fundai_source",
  "AttributeType": "Picklist",
  "option_set": { "name": "fundai_source", "is_global": true, "metadata_id": "ea6ab542-…", "option_count": 6 }
}

Actions & functions

Tool

Description

invoke_action

Invoke a Web API action (POST), bound or unbound — for operations outside plain CRUD (e.g. PublishDuplicateRule, QualifyLead)

invoke_function

Invoke a Web API function (GET), bound or unbound — read-only operations exposed as functions (e.g. WhoAmI)

Pass entity_set + id for a bound call (POST /<entity_set>(<id>)/Microsoft.Dynamics.CRM.<name>); omit both for an unbound call (POST /<name>). For invoke_action, parameters is the JSON request body; for invoke_function, parameters is inlined as OData function arguments. Bare operation names are namespaced automatically for bound calls — pass a fully-qualified name to override.

Examples:

// Publish a draft duplicate-detection rule.
// PublishDuplicateRule is a BOUND action on duplicaterule (returns an async job).
invoke_action({ name: "PublishDuplicateRule", entity_set: "duplicaterules", id: "<guid>" })

// Unpublish is an UNBOUND action taking DuplicateRuleId — note the asymmetry.
invoke_action({ name: "UnpublishDuplicateRule", parameters: { DuplicateRuleId: "<guid>" } })

// Qualify a lead into Account/Contact/Opportunity (bound action on lead).
invoke_action({ name: "QualifyLead", entity_set: "leads", id: "<guid>",
                parameters: { CreateAccount: true, CreateContact: true, CreateOpportunity: true, Status: 3 } })

Whether an operation is bound or unbound is defined in the Web API $metadata, not by intuition — e.g. PublishDuplicateRule is bound but UnpublishDuplicateRule is unbound. Check $metadata (look for IsBound="true" and the binding Parameter) if a call returns 404 "Resource not found for the segment".

⚠️ invoke_action can perform arbitrary mutating operations. It is currently ungated by design; capability-based access control (a safe-by-default policy gating writes/actions) is tracked separately in #45 / #46. invoke_function is read-only.

Related MCP server: xrm-mcp

Quick start (no clone)

Add to .mcp.json in your project root:

{
  "mcpServers": {
    "dataverse": {
      "command": "npx",
      "args": ["-y", "@rededis/dataverse-mcp-server"]
    }
  }
}

Create a .env file next to it with the four required variables (see Environment variables below) and restart your MCP client. The -y flag tells npx to auto-confirm the package install.

Setup

Environment variables

DATAVERSE_TENANT_ID=your-azure-tenant-id
DATAVERSE_CLIENT_ID=your-app-registration-client-id
DATAVERSE_CLIENT_SECRET=your-client-secret
DATAVERSE_RESOURCE_URL=https://your-org.crm.dynamics.com
DATAVERSE_ENTITY_PREFIX=contoso_          # optional, default prefix filter for list_entities
DATAVERSE_SOLUTION_NAME=MySolution        # optional, default solution unique name for list_entities
DATAVERSE_ALLOW_DELETE=true               # optional, enable delete operations (disabled by default)
DATAVERSE_REQUEST_TIMEOUT_MS=30000        # optional, per-request timeout in ms for Dataverse and token calls (default 30000, max 120000)
DATAVERSE_MAX_CONCURRENCY=8               # optional, requests sent to Dataverse at once (default 8, 1 to 100)
DATAVERSE_MAX_QUEUE_LENGTH=100            # optional, requests that may wait for a free slot (default 100, 0 to 10000)
DATAVERSE_MAX_QUEUE_WAIT_MS=10000         # optional, longest wait for a free slot in ms (default 10000, max 120000)
DATAVERSE_MAX_ATTEMPTS=3                  # optional, times a throttled request is sent, the first try included (default 3, 1 to 10)
DATAVERSE_MAX_RETRY_WAIT_MS=15000         # optional, longest wait on throttling per request in ms (default 15000, max 120000)

DATAVERSE_REQUEST_TIMEOUT_MS bounds how long a tool call waits for Dataverse. Dataverse itself cancels any operation after 2 minutes, hence the maximum. Schema changes such as create_entity with many columns can take longer than the 30-second default. When that happens the tool reports a timeout, but Dataverse still finishes the change, so check before retrying, or raise the value.

Service protection limits

Dataverse throttles each user with service protection limits and answers 429 Too Many Requests when one is reached. Parallel tool calls can reach them even from one machine. The server handles this in two ways, and all five DATAVERSE_MAX_* variables above are optional:

  • It limits what it sends. At most DATAVERSE_MAX_CONCURRENCY requests are in flight; the rest wait in arrival order. A request is turned away with a "Dataverse is busy" error when DATAVERSE_MAX_QUEUE_LENGTH requests are already waiting, or when it has waited DATAVERSE_MAX_QUEUE_WAIT_MS without getting a slot.

  • It retries a 429. The server waits for as long as the Retry-After header says, then resends, up to DATAVERSE_MAX_ATTEMPTS sends in total. While it waits, no other request is sent either, because Dataverse extends the wait for a client that keeps sending. Other requests are held back for the wait Dataverse asked for, but never longer than DATAVERSE_MAX_RETRY_WAIT_MS: a Retry-After of several minutes fails the call that received it and does not stop the rest for that long. If the waits of one request would add up to more than DATAVERSE_MAX_RETRY_WAIT_MS, the tool call fails at once with an error that says in how many seconds to retry.

With the defaults, these limits add at most 25 seconds of waiting to one request: 10 in the queue and 15 on throttling. With one request at the default 30-second timeout that makes 55 seconds, inside the 60 seconds a client built on the MCP TypeScript SDK waits for an answer unless configured otherwise. That figure assumes a 429 arrives promptly, and it does not always: in a live test, heavy requests that hit the execution-time limit were answered with 429 only after 28 to 75 seconds. The bound that holds whatever happens is 115 seconds: the 25 seconds of waiting plus three sends that each take the whole request timeout. A request that slow is cut off by DATAVERSE_REQUEST_TIMEOUT_MS first and reported as a timeout, not retried. A tool that sends several requests can take that long for each of them. If you raise the waits or DATAVERSE_REQUEST_TIMEOUT_MS, raise the tool-call timeout of your MCP client to match.

The concurrency limit alone does not prevent throttling, since Dataverse also limits combined execution time. The defaults are deliberately conservative choices of this server, not values published by Microsoft. A value that is set but out of range is reported through dataverse_setup, like a missing variable.

Azure App Registration

  1. Register an app in Azure AD

  2. Add API permission: Dynamics CRM > user_impersonation (or Application permissions)

  3. Create a client secret

  4. Grant the app a security role in Dataverse (e.g. System Administrator for full access)

Build

npm install
npm run build

Claude Code configuration (local build)

If you cloned the repo instead of using npx:

{
  "mcpServers": {
    "dataverse": {
      "command": "node",
      "args": ["./dist/index.js"]
    }
  }
}

Create a .env file with your credentials (see .env.example).

Safety

Destructive operations are disabled by default to prevent accidental data loss. All four delete tools are gated behind the same DATAVERSE_ALLOW_DELETE=true flag:

  • delete_record — removes a row and all its data

  • delete_attribute — removes a column along with ALL values across every record (no recovery short of a full environment restore)

  • delete_picklist_option — removes an option from an OptionSet; records that hold the option's integer value are left with an orphan number (no label in UI, broken reports)

  • delete_entity_key — drops an alternate key and its supporting unique index; any keyed-PATCH upsert flows relying on it stop working

When the flag is off, each tool registers as a stub that returns an instructional error instead of performing the delete. To enable, add DATAVERSE_ALLOW_DELETE=true to your .env file and restart the MCP server.

License

MIT

Available Tools

23 tools
add_attributeC

Add a column (attribute) to an existing Dataverse table

ParametersJSON Schema
NameRequiredDescriptionDefault
attributeYes
entity_logical_nameYesLogical name of the entity

TDQS

C2.9/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are supplied, so the description carries the full behavioral burden, yet it only implies a write via the word 'Add'. It says nothing about required Dataverse privileges, that the new column is immediately persisted to the table's schema, or that some choices (e.g. DateTimeBehavior) are effectively irreversible.

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?

A single front-loaded sentence with zero waste. It is efficient, though its brevity is closer to under-specification than to disciplined conciseness, which caps it below a 5.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a schema-mutating tool with a nested object parameter, no annotations and no output schema, the description omits permissions, side effects, error conditions, and any hint about how the required nested attribute fields must be combined. An agent cannot call this confidently from the description alone.

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?

Top-level schema coverage is only 50% (attribute has no description; entity_logical_name does), and the description contributes no parameter detail. However, the nested attribute object documents its own fields thoroughly, including mutual exclusivity of options vs global_option_set and defaults, so the schema largely does the heavy lifting.

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

Purpose4/5

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

States a specific verb+resource ('Add a column (attribute) to an existing Dataverse table'), which maps cleanly onto the tool name and distinguishes it in kind from delete_attribute and update_attribute. It does not name or contrast those siblings explicitly, but the operation is unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No when-to-use guidance, no mention of prerequisites (the table must already exist, the attribute logical name must be unique), and no routing to alternatives such as update_attribute for modifying an existing column or add_picklist_option for extending a choice list.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
display_nameYesDisplay name for the key
logical_nameYesLogical name of the new key with publisher prefix (e.g. 'contoso_contactproviderkey')
key_attributesYesLogical names of attributes that compose the key (one for a single-column key, multiple for a composite key). Lookups and supported primitive types only — Dataverse rejects keys over Memo, image, or file columns.
entity_logical_nameYesLogical name of the entity
solution_unique_nameNoSolution unique name (defaults to the Default Solution)

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and delivers meaningful behavior: the unique index is built asynchronously and the key is unusable for keyed lookups until EntityKeyIndexStatus is 'Active'. It omits auth/permission requirements and failure modes (e.g. duplicate data), keeping it from a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tight sentences ordered purpose → use cases → critical caveat. The async warning is front-loaded with a NOTE marker, and every sentence carries non-redundant information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a mutation tool with no annotations and no output schema, the description supplies the crucial async/lifecycle context and the polling path. It does not address required permissions or how create failures surface, leaving a small gap.

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?

Schema coverage is 100%, so all five parameters are already documented in the schema. The description reinforces key_attributes (composite support) but adds no syntax or format detail beyond what the schema provides, so the baseline 3 applies.

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?

Starts with a specific verb+resource ('Create an alternate key on a Dataverse table') and immediately clarifies the composite-key capability. It is clearly distinguishable from siblings like add_attribute, add_picklist_option, and create_relationship, which create different object types.

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?

Explicitly states two use cases ('race-safe upserts via keyed-PATCH' and 'enforce a uniqueness constraint that the primary key doesn't cover') and routes the agent to list_entity_keys for polling. It stops short of an explicit when-not-to-use, so it lands just below the top tier.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
labelYesUI label for the new option (e.g. 'Queued')
valueNoExplicit option value. Must fall within the publisher's customization prefix range (e.g. 909890XXX). If omitted, Dataverse assigns the next free value.
descriptionNoOptional description
language_codeNoLanguage code for the label (default: 1033 = English)
option_set_nameNoGlobal OptionSet name. Mutually exclusive with entity_logical_name/attribute_logical_name.
entity_logical_nameNoEntity logical name (Local OptionSet; pair with attribute_logical_name). Mutually exclusive with option_set_name.
solution_unique_nameNoSolution unique name (defaults to the Default Solution)
attribute_logical_nameNoPicklist attribute logical name (Local OptionSet; pair with entity_logical_name). Mutually exclusive with option_set_name.

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It does disclose a genuine behavioral trait — the authorization requirement and the HTTP 403 consequence — which is real value. But it says nothing about what happens on duplicate labels, whether the option is immediately visible, or what the call returns, leaving significant gaps for a mutation tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two compact sentences, front-loading the core purpose before the permission caveat. Every clause earns its place; no filler.

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?

The description covers purpose and authorization, and the schema fully documents inputs, but with no annotations and no output schema the agent still cannot tell what the call returns (e.g. the assigned option value) or whether the change is persisted to a solution. Adequate but not complete for a mutation tool.

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?

Schema description coverage is 100%, so the schema already explains all eight parameters including the value-range constraint and the option_set_name vs entity/attribute mutual exclusivity. The description only echoes the Local/Global distinction already captured in the schema, adding no new parameter-level meaning. Baseline 3 applies.

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?

States a specific verb (add) and resource (option to an existing Local or Global OptionSet), and even names the underlying Dataverse action. It is clearly distinguishable from sibling update_picklist_option and delete_picklist_option, which modify or remove existing options.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied (create a new option rather than modify one), and the description usefully states the required Customizer/System Administrator role and the 403 failure mode. However, it never explicitly contrasts this with update_picklist_option for existing options, nor states any other preconditions or exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

create_entityC

Create a new Dataverse table (entity) with specified attributes

ParametersJSON Schema
NameRequiredDescriptionDefault
attributesNoAdditional attributes to create with the entity
descriptionNoTable description
display_nameYesDisplay name
logical_nameYesLogical name with publisher prefix (e.g. 'contoso_newtable')
ownership_typeNoOwnership type (default: UserOwned)
primary_attribute_nameNoLogical name for primary name attribute (default: '{prefix}_name')
display_collection_nameYesPlural display name
primary_attribute_display_nameNoDisplay name for primary name attribute (default: 'Name')

TDQS

C2.9/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full behavioral burden and largely fails: it does not state that this is an irreversible schema mutation, whether it requires specific privileges or an unmanaged solution context, whether the entity and its attributes are created atomically, or what happens on partial failure. Only the bare act of creation is conveyed.

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?

A single, front-loaded sentence with no filler or repetition. It is efficient, though arguably terse to the point of under-specification rather than over-specification.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a high-impact schema-mutation tool with no annotations, no output schema, and eight parameters including a nested attribute list, the description is too thin. An agent would want to know about irreversibility, solution/publisher scoping, and creation semantics, none of which are covered.

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?

Schema description coverage is 100%, so parameters like logical_name, ownership_type, and the nested attribute definitions are already documented in the schema; baseline 3 applies. The phrase 'with specified attributes' nods at the attributes array but adds no meaning beyond the schema's own descriptions and defaults.

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

Purpose4/5

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

The description gives a specific verb and resource ('Create a new Dataverse table (entity)'), and the parenthetical distinguishes entity from its siblings like create_record, add_attribute, and delete_entity. It stops short of explicitly naming an alternative tool, so it is clear but not fully sibling-differentiating.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to use this tool versus add_attribute, create_record, or create_relationship, nor any prerequisite (e.g., that a publisher prefix and target solution context are needed). The agent must infer usage entirely from the name and schema.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

create_recordC

Create a new record in a Dataverse table

ParametersJSON Schema
NameRequiredDescriptionDefault
dataYesRecord fields as key-value pairs
entity_setYesEntity set name (plural, e.g. 'accounts', 'contacts')

TDQS

C2.9/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full behavioral burden, yet it discloses nothing about side effects, required permissions, whether the call is idempotent, or what happens on duplicate/conflicting data. For a mutation tool this is a significant gap, though 'Create a new record' at least correctly signals a write rather than a read.

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?

A single short sentence with no waste and the verb front-loaded. It is efficient, but the brevity is partly under-specification rather than disciplined conciseness, so it does not reach a 5.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

This is a mutation tool with no annotations and no output schema, and the description says nothing about return values, error behavior, or permission requirements. The fully-covered input schema compensates for parameter documentation but not for the behavioral context an agent needs before performing a write.

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?

Schema description coverage is 100%: both entity_set (plural entity set name with examples) and data (key-value record fields) are documented in the schema itself. The description adds no syntax, format, or constraint detail beyond that, so the baseline 3 applies.

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

Purpose4/5

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

States a specific verb (Create) and resource (a new record in a Dataverse table), so an agent immediately knows this is the write counterpart to get_record/update_record/delete_record. It stops short of explicitly naming a sibling or distinguishing its scope from create_entity, which operates on table metadata rather than rows.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to use this tool versus the many siblings (update_record, create_entity, query_records), nor any stated prerequisites such as required permissions or the need for a valid entity_set. The agent must infer usage entirely from the name.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

create_relationshipC

Create a relationship between two Dataverse tables

ParametersJSON Schema
NameRequiredDescriptionDefault
typeYesRelationship type
lookup_nameNoLogical name for lookup attribute (OneToMany only)
schema_nameYesUnique schema name for the relationship
primary_entityYesPrimary (referenced) entity logical name
related_entityYesRelated (referencing) entity logical name
lookup_display_nameNoDisplay name for lookup attribute (OneToMany only)

TDQS

C2.9/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full behavioral burden, yet it discloses nothing beyond the implied mutation. It does not mention required privileges, whether the relationship can be removed (no delete_relationship sibling exists), what happens if the relationship already exists, or the implications of choosing a relationship type.

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 a single efficient sentence with zero waste and the core action front-loaded. It is concise, though arguably too terse for a six-parameter metadata mutation tool, keeping it just below a perfect score.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the absence of annotations and no output schema, the description should compensate with behavioral and usage context. Instead it provides only a one-line purpose, leaving significant gaps around permissions, reversibility, and relationship-type implications for an agent to infer.

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?

Schema description coverage is 100%, so the schema already documents all six parameters, including the OneToMany-only nature of lookup_name and lookup_display_name and the enum for type. The description adds no additional parameter meaning, which matches the baseline of 3 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.

Purpose4/5

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

The description states a specific verb ('Create') and resource ('relationship between two Dataverse tables'), making the tool's purpose immediately clear. It does not, however, explicitly differentiate this tool from siblings like add_attribute or create_entity, so it falls short of the 5-level criterion for sibling differentiation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no when-to-use guidance, prerequisites, or alternatives. It does not say when to choose OneToMany versus ManyToMany, nor when to use this tool instead of manually adding attributes. This is a bare purpose statement with no usage direction.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

delete_attributeA

Delete a column from a Dataverse table (currently disabled for safety)

ParametersJSON Schema
NameRequiredDescriptionDefault
entity_logical_nameYesLogical name of the entity
attribute_logical_nameYesLogical name of the column

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden, and it does disclose one important behavioral fact: the tool is disabled for safety. However, it omits the destructive/irreversible nature of dropping a column, what happens to existing data, and any permission requirements for when it is re-enabled.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with zero filler; the safety caveat is placed where it will be read. Every clause earns its place.

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 destructive two-parameter mutation with no annotations and no output schema, the description covers the headline fact (disabled) but leaves the agent without the irreversibility/permission context it would need if the tool were active. Adequate minimum, clear gaps.

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?

Schema description coverage is 100%, so both parameters are already documented as logical names for the entity and column. The description's use of "column" and "table" only loosely maps to attribute_logical_name and entity_logical_name, adding little beyond the schema.

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

Purpose4/5

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

The description names a specific verb and resource (delete a column from a Dataverse table), which distinguishes it from sibling mutations such as delete_entity_key, delete_picklist_option, and delete_record. It stops short of explicitly naming which sibling to prefer, but the scope is unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

"Currently disabled for safety" is valuable usage information telling the agent the call will not succeed, but it gives no alternative path (e.g. update_attribute or a migration route) and no stated conditions under which deletion would be appropriate. Usage is implied rather than specified.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

delete_entity_keyC

Delete an alternate key from a Dataverse table (currently disabled for safety)

ParametersJSON Schema
NameRequiredDescriptionDefault
key_logical_nameYesLogical name of the alternate key to delete
entity_logical_nameYesLogical name of the entity

TDQS

C2.9/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It notes the tool is 'currently disabled,' which is a valuable behavioral disclosure, but for a destructive mutation tool it says nothing about irreversibility, permission requirements, or what happens to dependent records when an alternative key is removed.

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?

One compact sentence that front-loads the action. The parenthetical is efficiently placed. Slightly underspecified rather than bloated.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

A destructive mutation tool with no annotations and no output schema needs to carry more of the burden: irreversibility, permissions, prerequisite lookups. The 'disabled' note is the one piece of essential behavior it does include, leaving several gaps.

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?

Schema description coverage is 100%, so both parameters are documented in the schema; the description adds no syntax, format, or naming-convention detail beyond what the schema provides. Baseline 3 applies.

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

Purpose4/5

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

Specific verb (delete) + resource (alternate key) + platform (Dataverse table), which distinguishes it from sibling delete_attribute and from add_entity_key. The parenthetical '(currently disabled for safety)' adds a meaningful operational qualifier.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No explicit when-to-use guidance, no routing to alternatives (e.g., list_entity_keys to find key names before deletion). The 'disabled for safety' note implies the tool won't work, which is critical context, but it doesn't explain under what conditions one would attempt this.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

delete_picklist_optionA

Remove an option from a Local or Global OptionSet (currently disabled for safety)

ParametersJSON Schema
NameRequiredDescriptionDefault
valueYesNumeric value of the option to remove
option_set_nameNoGlobal OptionSet name. Mutually exclusive with entity_logical_name/attribute_logical_name.
entity_logical_nameNoEntity logical name (Local OptionSet; pair with attribute_logical_name). Mutually exclusive with option_set_name.
solution_unique_nameNoSolution unique name (defaults to the Default Solution)
attribute_logical_nameNoPicklist attribute logical name (Local OptionSet; pair with entity_logical_name). Mutually exclusive with option_set_name.

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It does disclose one meaningful behavioral trait — the tool is currently disabled — which is genuinely useful for an agent. However, it says nothing about the destructive permanence of removing an option, whether existing records holding that value are affected, or required permissions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single sentence that front-loads the operation and the resource, with the critical disabled-status caveat attached rather than buried. Nothing is wasted.

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 5-parameter mutation tool with no annotations and no output schema, the description covers purpose and disabled status but leaves the destructive consequences, permission requirements, and the reason for the disable unexplained. The schema covers parameter semantics well, so the gap is behavioral rather than structural.

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?

Schema description coverage is 100%, so every parameter (value, option_set_name, entity_logical_name, attribute_logical_name, solution_unique_name) is already documented, including the mutually exclusive pairing rules. The description adds no parameter meaning beyond what the schema provides, so the baseline 3 applies.

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?

States a specific verb (Remove) and resource (an option from a Local or Global OptionSet), and the parenthetical scope note distinguishes it from add_picklist_option and update_picklist_option in the sibling list. An agent can identify the operation without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The '(currently disabled for safety)' note implicitly tells the agent not to rely on this tool, and the schema covers the Local-vs-Global mutually exclusive paths. But there is no explicit when-to-use guidance, no statement of what to do instead, and no prerequisites (permissions, solution context) called out.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

delete_recordB

Delete a record from a Dataverse table (currently disabled for safety)

ParametersJSON Schema
NameRequiredDescriptionDefault
idYesRecord GUID
entity_setYesEntity set name

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full behavioral burden, and it does disclose one important trait: the operation is disabled for safety. Beyond that it is silent on permission requirements, reversibility, and the failure mode an agent will actually observe when calling it, leaving meaningful gaps for a destructive operation.

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?

A single compact sentence with the operation front-loaded and the critical disabled status attached inline. It is not padded, though the parenthetical could have been a clearly separated clause for faster scanning.

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 destructive two-parameter tool with no annotations and no output schema, the description covers the core fact (disabled) but omits permission requirements, expected error behavior, and any alternative path. It is minimally adequate rather than complete.

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?

Schema description coverage is 100% (id as Record GUID, entity_set as Entity set name), so the schema already fully documents both parameters. The description adds no syntax, format, or constraint information beyond the schema, matching the baseline of 3.

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

Purpose4/5

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

The description states a specific verb and resource ("Delete a record from a Dataverse table"), making the operation immediately identifiable and distinguishing it from record-mutation siblings like create_record/update_record. It does not explicitly contrast against adjacent delete tools such as delete_attribute, so it stops short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The parenthetical "currently disabled for safety" implicitly signals the tool should not be invoked, which is a usable constraint. However, there is no explicit when-to-use guidance, no routing to alternatives for retiring data, and no statement of what the agent should do instead.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
entity_logical_nameYesLogical name of the entity
attribute_logical_nameYesLogical name of the column

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations exist, so the description carries full burden and does disclose key traits: best-effort name resolution with nulls, and the backing implementation (RetrieveDependenciesForDelete). It doesn't state permissions/auth needs or output shape, but the null-resolution caveat and the underlying function name give meaningful behavioral context beyond what the empty annotation set provides.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tight sentences, front-loaded with the verb and scope, then usage triggers, then a caveat. Every clause earns its place; nothing is redundant.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only dependency-lookup tool with no annotations and no output schema, the description covers purpose, triggering conditions, and a name-resolution caveat. It could say more about the failure-mode semantics (why 0x8004f01f means dependencies exist) but is sufficient to invoke correctly.

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?

Schema coverage is 100% – both parameters are fully described in the schema (logical names of entity and column). The description adds no format/syntax detail beyond the schema, so baseline 3 applies.

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?

States a specific verb (List) and resource (CRM components that reference a column) and enumerates the component types (forms, views, workflows, business rules, plugins). This is clearly distinguishable from siblings like delete_attribute or update_attribute without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit trigger conditions: 'when delete_attribute fails with 0x8004f01f' and 'before any destructive change to a column.' This ties directly to sibling tools (delete_attribute, update_attribute) and tells the agent exactly when to reach for this tool versus proceeding.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
entity_logical_nameYesLogical name of the entity (e.g. 'account', 'contact', 'contoso_bankaccount')

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full behavioral burden. It does disclose a concrete output trait — choice-style columns carry an option_set summary with is_global and option_count — which is genuinely useful. However, it says nothing about pagination, permissions, or how large tables are handled, leaving meaningful gaps.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three compact sentences, front-loaded with the core purpose, then the choice-column detail, then the handoff to a sibling. Every sentence earns its place with no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description must convey the return shape; it covers the choice-column case well but is silent on the general shape of returned attribute metadata (types, required flags, etc.). For a single-parameter read tool with no annotations this is close to, but not fully, complete.

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?

Only one parameter and schema description coverage is 100%, so the schema already documents entity_logical_name with examples. The description adds no naming-format or syntax guidance beyond that, which is the expected baseline when the schema does the work.

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

Purpose4/5

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

States a specific verb and resource: 'Get attributes (columns) of a specific Dataverse table.' An agent can distinguish this from data-reading siblings (get_record, query_records) and from list_entities, though the distinction is implied rather than stated. It also explicitly positions get_picklist_options as a complementary tool.

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?

Provides clear context for when this tool pays off ('one dump shows which choice lists are shared org-wide') and routes to get_picklist_options when per-column option values are needed. It lacks an explicit when-not or prerequisite statement (e.g., needing an existing connection/solution), so it stops short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
option_set_nameNoGlobal OptionSet name. Mutually exclusive with entity_logical_name/attribute_logical_name.
entity_logical_nameNoEntity logical name (Local OptionSet; pair with attribute_logical_name). Mutually exclusive with option_set_name.
attribute_logical_nameNoPicklist attribute logical name (Local OptionSet; pair with entity_logical_name). Mutually exclusive with option_set_name.

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden. It adds real value by disclosing the return structure (no output schema exists) and the subtle caveat that matching values alone don't prove a Global OptionSet binding, but it omits permissions, error behavior, and what happens on ambiguous local/global inputs.

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?

Front-loads the verb and return shape, then adds the interpretive caveat in a tight second sentence. Dense but every sentence earns its place; no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Since there is no output schema, the description correctly compensates by spelling out the response shape and the meaning of is_global. Given no annotations, it could say more about read-only safety, but nothing essential for calling the tool is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3. The description goes beyond it by clarifying the local-vs-global distinction behind the two parameter groups (option_set_name vs entity/attribute pair) and naming the attribute types the third parameter applies to.

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

Purpose4/5

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

States a specific verb+resource ('Read a Local or Global OptionSet') and even gives the exact return shape, so the operation is unambiguous. It does not explicitly name its sibling mutations (add/update/delete_picklist_option), but 'Read' distinguishes it well enough in context.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No when-to-use or when-not-to-use guidance relative to alternatives such as get_entity_schema or get_attribute_dependencies. The only implied scope is 'Works for Choice, Status, State and MultiSelect columns', which describes applicability rather than selection criteria.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_recordC

Get a single record by ID from a Dataverse table

ParametersJSON Schema
NameRequiredDescriptionDefault
idYesRecord GUID
expandNoRelated entities to expand ($expand)
selectNoComma-separated list of columns to return ($select)
entity_setYesEntity set name (plural, e.g. 'accounts', 'contacts')

TDQS

C2.9/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full behavioral burden. 'Get' implies a read, but there is no mention of permissions required, behavior on a missing/invalid GUID, throttling, or whether a null/error is returned — significant gaps for a tool with zero annotation coverage.

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?

A single front-loaded sentence with zero waste. It is appropriately sized, though its brevity is arguably under-specification rather than true conciseness.

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 simple single-record read with all four parameters documented in the schema, the essentials are present. With no output schema and no annotations, the description could still say what the response contains or how errors surface, so it is only minimally adequate.

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?

Schema description coverage is 100%, so the schema already documents id, entity_set, expand, and select. The description adds no syntax or format detail beyond that, so the baseline 3 applies.

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

Purpose4/5

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

The description states a specific verb (Get) and resource (a single record) scoped by ID from a Dataverse table, which implicitly separates it from query_records (bulk) and the create/update/delete siblings. It does not explicitly name or contrast with any sibling, so it falls short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no when-to-use guidance: nothing says to prefer this over query_records when you lack an ID, nor what to do if the record is missing. The only usage signal is the phrase 'by ID', which the agent must infer from.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
idNoRecord GUID the bound action targets. Required iff entity_set is set.
nameYesAction name, e.g. 'PublishDuplicateRule', 'QualifyLead'. Bare names are namespaced automatically for bound calls; pass a fully-qualified name to override.
entity_setNoEntity set (plural, e.g. 'leads') for a bound action. Omit for unbound actions.
parametersNoAction parameters sent as the JSON request body (e.g. { DuplicateRuleId } for PublishDuplicateRule, { CreateAccount, CreateContact, Status } for QualifyLead).

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden: it discloses the HTTP verb (POST), that it is a mutation-style call, how binding is determined ($metadata), the entity_set+id pairing rule, and that parameters become the request body, plus the bare-vs-fully-qualified name override. It stops short of permissions, error behavior, or return shape, which keeps it out of the top band.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tight sentences, front-loaded with purpose before mechanics. Every clause carries actionable information — no filler, no restatement of the tool name.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For an open-ended POST-invocation tool with no annotations and no output schema, the description covers invocation semantics thoroughly enough to call it correctly. The one remaining gap is what comes back (arbitrary action responses), though with no output schema and free-form payloads that is hard to specify usefully.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3, but the description adds a genuine cross-parameter constraint the schema states only per-field: 'Pass entity_set+id for bound actions, neither for unbound.' The namespacing override note and the body-mapping note are reinforced but largely duplicate the schema.

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?

States a specific verb and resource ('Invoke a Dataverse Web API action (POST)') plus the bound/unbound axis, and explicitly positions itself against plain CRUD. An agent can distinguish it from create_record/update_record and the other siblings without opening the schema.

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?

Gives a clear selection rule — 'use for operations that are not plain CRUD' — with concrete examples (PublishDuplicateRule, QualifyLead, UnpublishDuplicateRule) and the mechanical rule for bound vs unbound calls. It does not explicitly route the agent away from the closely-related invoke_function sibling, which is the one ambiguity left.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
idNoRecord GUID the bound function targets. Required iff entity_set is set.
nameYesFunction name, e.g. 'WhoAmI'. Bare names are namespaced automatically for bound calls; pass a fully-qualified name to override.
entity_setNoEntity set (plural) for a bound function. Omit for unbound functions.
parametersNoFunction parameters, inlined as OData arguments. Strings are quoted, GUIDs/numbers/booleans passed as-is.

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does well: it discloses the HTTP method/read-only nature, how parameters are inlined as OData arguments, and the binding requirements. It omits auth/permission needs, error semantics, and return shape for a tool with no output schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tight sentences with no filler, front-loading the verb/resource and the GET/read-only constraint before the usage and parameter rules. Every sentence carries instructional value.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a four-parameter tool with a nested object parameter, no annotations, and no output schema, the description covers binding, call shape, and argument encoding adequately. It leaves the return payload undefined, which is a real gap only because no output schema exists to compensate.

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?

Schema coverage is 100%, so the schema already documents all four parameters including the binding conditions and quoting rules. The description restates the entity_set+id binding rule and the OData inlining behavior, adding reinforcement but little genuinely new semantics beyond the schema.

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

Purpose4/5

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

The description states a specific verb and resource ('Invoke a Dataverse Web API function (GET)') and its scope (bound or unbound), which separates it from mutation tools. However, it never explicitly names the sibling 'invoke_action' as the alternative for side-effecting operations, leaving the contrast implicit through '(GET)' and 'read-only'.

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?

It gives concrete selection criteria: use for read-only operations exposed as functions, with concrete examples (WhoAmI unbound, RetrieveDuplicates) and the bound-vs-unbound parameter rule ('Pass entity_set+id for bound functions, neither for unbound'). It stops short of stating when NOT to use it (e.g. for actions/updates, use invoke_action).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_entitiesC

List Dataverse tables (entities) with optional prefix and solution filters

ParametersJSON Schema
NameRequiredDescriptionDefault
prefixNoFilter entities by logical name prefix (e.g. 'contoso_'). Uses DATAVERSE_ENTITY_PREFIX env if not specified.
solutionNoFilter entities by solution unique name (e.g. 'MySolution'). Uses DATAVERSE_SOLUTION_NAME env if not specified. Pass an empty string to disable the default filter.

TDQS

C2.9/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full behavioral burden, yet it discloses nothing about pagination, result ordering, permissions, or the fact that a default solution filter is silently applied when 'solution' is omitted. That default-filter behavior is material to interpreting results and is only visible in the schema, not the description.

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?

A single front-loaded sentence naming the resource and both filters, with no filler. It is tightly sized, though the terseness leaves room for the missing behavioral detail noted elsewhere.

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 two-optional-parameter read-only listing tool with full schema coverage and no output schema, minimal description is tolerable. However, with zero annotation coverage the description should at least confirm read-only semantics and the default solution filtering, neither of which it provides.

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?

Schema description coverage is 100%, so both parameters (prefix, solution) already document their formats, env-var fallbacks, and the empty-string escape hatch. The description merely names 'prefix and solution filters' without adding meaning, so the baseline 3 applies.

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

Purpose4/5

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

Specific verb+resource: 'List Dataverse tables (entities)' clearly states the operation and target. It is distinguishable from siblings like get_entity_schema (single-table detail) and list_solutions, though it never names an alternative. Clear but without explicit sibling differentiation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives no when-to-use or when-not-to-use guidance and never mentions the alternatives (get_entity_schema, list_solutions) an agent must choose between. Filtering hints ('optional prefix and solution filters') describe capability, not usage conditions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
entity_logical_nameYesLogical name of the entity

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations, so the description carries the burden, and it adds real behavioral context: the returned fields and crucially that alt keys are not usable until index status is Active. It doesn't cover auth/permissions or whether this is a safe read (implicitly read-only by name), so short of full disclosure.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences, front-loaded with purpose, then return shape, then the critical index-status caveat. No filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-param read tool with no output schema, it adequately describes the return array and a key operational constraint. Missing only error/edge-case behavior (e.g., unknown table) and explicit read-only assurance.

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?

Schema description coverage is 100% with a single well-documented parameter, so baseline is 3. The description adds no extra syntax or format detail for entity_logical_name beyond what the schema provides.

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?

Specific verb+resource: 'List alternate keys defined on a Dataverse table', with a precise return shape. Distinguishes from siblings like get_entity_schema or list_entities by naming the exact sub-resource (alternate keys).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Implied usage (inspect keys before composing a keyed-PATCH upsert), but no explicit when-to-use vs alternatives such as get_entity_schema or add_entity_key. The index-status note hints at a precondition but doesn't state how or when to call this tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_solutionsB

List Dataverse solutions (uniquename is used to filter list_entities)

ParametersJSON Schema
NameRequiredDescriptionDefault
include_managedNoInclude managed solutions (default: false — only unmanaged are returned)

TDQS

B3.2/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full behavioral burden, and it discloses almost nothing: no read-only confirmation, no permissions, no return shape or pagination. The only behavioral fact (default excludes managed solutions) already lives in the schema, not the description.

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?

One short sentence with a front-loaded verb+resource and a compact parenthetical. Efficient, though the parenthetical is slightly cryptic about what exactly is returned.

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 simple one-parameter read tool with no output schema, the description is adequate but thin: it never states what a listed solution contains (names, uniquenames, managed flags), which matters since no output schema documents the return.

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?

There is a single parameter with 100% schema description coverage, so the schema already explains include_managed and its default. The description adds no syntax or semantics beyond that, making the baseline 3 correct.

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

Purpose4/5

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

States a specific verb and resource: 'List Dataverse solutions'. The parenthetical ties it to list_entities, hinting at its role in the tool family, though it does not fully distinguish it from other listing siblings such as list_entities.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The parenthetical implies a workflow (list solutions to obtain a uniquename, then pass it to list_entities), which is useful implied usage. However, there is no explicit when-to-use/when-not guidance and no named alternative to pick instead.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

query_recordsC

Query records from a Dataverse table with OData filters

ParametersJSON Schema
NameRequiredDescriptionDefault
topNoMaximum number of records to return ($top)
expandNoRelated entities to expand ($expand)
filterNoOData filter expression ($filter)
selectNoComma-separated list of columns to return ($select)
orderbyNoOrder by expression ($orderby)
entity_setYesEntity set name (plural, e.g. 'accounts', 'contacts')

TDQS

C2.9/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full behavioral burden and discloses very little. It does not state the return shape (a collection of records), default/actual paging behavior, server-side row limits, error behavior on invalid filters, or auth requirements. 'OData filters' is the only behavioral hint.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with zero filler; the verb, resource, and filtering mechanism come first. Nothing is wasted or buried.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a six-parameter, no-annotation, no-output-schema tool, the description is too thin: it omits return structure, paging defaults, and when to prefer it over get_record or the write siblings. An agent could call it, but only by inferring everything from parameter names.

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?

Schema description coverage is 100%, so all six parameters (including required entity_set with a plural-name example) are documented in the schema itself. The description adds 'OData filters' framing but no syntax, escaping, or format details beyond what the schema already provides, so the baseline 3 applies.

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

Purpose4/5

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

States a specific verb ('query'), resource ('records from a Dataverse table') and a distinguishing mechanism ('OData filters'), which separates it from single-record siblings like get_record. It does not, however, explicitly name any sibling or scope (e.g. all records vs. filtered), so differentiation is implicit.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to use this over get_record, list_entities, or invoke_action, nor any stated prerequisites (auth, permissions, table existence). The mention of OData filters hints at the intended use case but does not constitute routing guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
typeYesCurrent type of the attribute (required to build the correct metadata discriminator; must match the existing type — type changes are not allowed)
requiredNoNew required level
max_valueNoNew max value (numeric types only)
min_valueNoNew min value (numeric types only)
precisionNoNew precision (Decimal/Money only)
max_lengthNoNew max length (String/Memo only)
date_formatNoDateTime only: change UI presentation. See add_attribute for semantics.
descriptionNoNew description
display_nameNoNew display name
merge_labelsNoIf true, preserve existing localized labels in other languages; if false (default), replace all localized labels with just the new one.
date_behaviorNoDateTime only: change storage semantics. ONE-WAY per Microsoft — you can switch from UserLocal to DateOnly or TimeZoneIndependent once, but cannot switch back or between the non-UserLocal values. Dataverse will return 400 if the behavior is already locked.
language_codeNoLanguage code for labels (default: 1033)
entity_logical_nameYesLogical name of the entity
attribute_logical_nameYesLogical name of the column to update

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations the description carries the full burden, and it discloses real constraints: type/logical-name immutability and the Dataverse migration path. It stops short of stating whether unspecified fields are left unchanged, permission/auth requirements, or reversibility of other edits, so it is strong but not exhaustive.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, zero padding: the mutable-field summary is front-loaded and the immutability/migration caveat follows. Every clause earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 14-parameter mutation tool with no annotations and no output schema, the description plus rich schema covers the essentials — what can change, what cannot, and the workaround. Missing only operational context like auth requirements and post-update behavior.

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?

Schema description coverage is 100%, so every parameter is already documented in the schema, including enums and the one-way date_behavior lock. The description's field list merely restates those parameters and adds no syntax or format detail beyond them.

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?

States a specific verb (Update) and resource (metadata of an existing column) and enumerates the mutable fields, immediately distinguishing it from add_attribute and delete_attribute.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states what cannot be done (type and logical name are fixed at creation) and supplies the exact alternative workflow — add_attribute, migrate with update_record, then delete_attribute. An agent knows both when to use this and when to route elsewhere.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
labelYesNew UI label
valueYesNumeric value of the option to update
descriptionNoNew description
merge_labelsNoIf true, merge the new label with existing localized labels (other languages kept); if false (default), replace all localized labels with just the new one.
language_codeNoLanguage code for the label (default: 1033)
option_set_nameNoGlobal OptionSet name. Mutually exclusive with entity_logical_name/attribute_logical_name.
entity_logical_nameNoEntity logical name (Local OptionSet; pair with attribute_logical_name). Mutually exclusive with option_set_name.
solution_unique_nameNoSolution unique name (defaults to the Default Solution)
attribute_logical_nameNoPicklist attribute logical name (Local OptionSet; pair with entity_logical_name). Mutually exclusive with option_set_name.

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden. It usefully discloses the required role/permission, which is real auth context. However, it omits behavioral traits such as whether the change replaces all localized labels, solution/transport implications, and reversibility (the merge/replace nuance lives only in the schema).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences with the action and scope front-loaded, followed by the permission prerequisite. No filler, nothing redundant.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a nine-parameter mutation tool with no annotations and no output schema, the description supplies purpose and the key role requirement while the rich schema covers parameter semantics. Missing only peripheral context like preconditions (option must exist) and solution-scoping behavior, so it is largely sufficient.

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?

Schema description coverage is 100%, so the schema fully documents all nine parameters (including the subtle merge_labels replace-vs-merge semantics and the mutually exclusive option_set_name vs entity/attribute pairing). The description adds no parameter-level meaning beyond re-mentioning label/description, so the baseline of 3 applies.

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

Purpose4/5

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

The description states a specific verb (Update) and resource (an existing option's label/description) and scopes it to Local or Global OptionSet, plus names the underlying Dataverse action. It does not explicitly differentiate itself from siblings like add_picklist_option or delete_picklist_option, but the mutation target is unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives one real prerequisite (Customizer or System Administrator role) and identifying context (Local vs Global OptionSet), but never states when to choose this over add_picklist_option or delete_picklist_option, nor what conditions must hold (e.g., option must already exist). Usage is implied rather than guided.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

update_recordC

Update an existing record in a Dataverse table

ParametersJSON Schema
NameRequiredDescriptionDefault
idYesRecord GUID
dataYesFields to update as key-value pairs
entity_setYesEntity set name (plural, e.g. 'accounts', 'contacts')

TDQS

C2.9/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden of behavioral disclosure. It implies a mutation but does not state whether the update is partial or full (the 'data' field hints at partial, but the description never confirms), what permissions are needed, what happens if the record id does not exist, or whether changes are reversible.

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?

A single short sentence with zero waste, front-loading the action and resource. It is appropriately sized even if arguably too thin to be maximally useful.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a mutation tool with no annotations, no output schema, and a nested free-form data object, the description is inadequate. It never explains update semantics (partial vs replace), error behavior, or return shape, leaving the agent to guess at call behavior.

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?

Schema description coverage is 100%, so the schema already documents id (GUID), entity_set (plural set name) and data (key-value fields to update). The description adds nothing beyond the schema, so the baseline of 3 is appropriate.

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

Purpose4/5

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

States a specific verb (Update) and resource (an existing record in a Dataverse table), which is enough to tell it apart from create_record, delete_record and get_record by verb alone. It is clear but adds no sibling differentiation beyond the verb, and says nothing about the table/entity scope beyond 'Dataverse table'.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No when-to-use guidance, no exclusions, and no mention of alternatives such as update_attribute or create_record. The agent must infer that this is the write path for an existing row purely from the name.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 23 tool updatesv0.9.0
    • Changedadd_attribute1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedadd_entity_key1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedadd_picklist_option1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedcreate_entity1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedcreate_record1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedcreate_relationship1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changeddelete_attribute1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changeddelete_entity_key1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changeddelete_picklist_option1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changeddelete_record1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedget_attribute_dependencies1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedget_entity_schema1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedget_picklist_options1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedget_record1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedinvoke_action1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedinvoke_function1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedlist_entities1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedlist_entity_keys1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedlist_solutions1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedquery_records1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedupdate_attribute1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedupdate_picklist_option1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • Changedupdate_record1 field changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
  2. 2 tool updatesv0.7.1
    • Changedadd_attribute2 fields changed
      • addedInput schema / properties / attribute / properties / global_option_set
        Added value: +{
        +  "description": "Picklist only: bind the column to an existing Global OptionSet by its set name (e.g. 'contoso_sourceset') so the column shares one org-wide list instead of a private copy. Mutually exclusive with options.",
        +  "minLength": 1,
        +  "type": "string"
        +}
      • changedInput schema / properties / attribute / properties / options / description
        Previous value: -"Options for Boolean (2 items: false=0, true=1) or Picklist types"New value: +"Options for Boolean (2 items: false=0, true=1) or Picklist types. Creates a Local OptionSet owned by this one column; mutually exclusive with global_option_set."
    • Changedcreate_entity2 fields changed
      • addedInput schema / properties / attributes / items / properties / global_option_set
        Added value: +{
        +  "description": "Picklist only: bind the column to an existing Global OptionSet by its set name (e.g. 'contoso_sourceset') so the column shares one org-wide list instead of a private copy. Mutually exclusive with options.",
        +  "minLength": 1,
        +  "type": "string"
        +}
      • changedInput schema / properties / attributes / items / properties / options / description
        Previous value: -"Options for Boolean (2 items: false=0, true=1) or Picklist types"New value: +"Options for Boolean (2 items: false=0, true=1) or Picklist types. Creates a Local OptionSet owned by this one column; mutually exclusive with global_option_set."
  3. 23 tool updatesv0.5.0
    • First observedadd_attribute
    • First observedadd_entity_key
    • First observedadd_picklist_option
    • First observedcreate_entity
    • First observedcreate_record
    • First observedcreate_relationship
    • First observeddelete_attribute
    • First observeddelete_entity_key
    • First observeddelete_picklist_option
    • First observeddelete_record
    • First observedget_attribute_dependencies
    • First observedget_entity_schema
    • First observedget_picklist_options
    • First observedget_record
    • First observedinvoke_action
    • First observedinvoke_function
    • First observedlist_entities
    • First observedlist_entity_keys
    • First observedlist_solutions
    • First observedquery_records
    • First observedupdate_attribute
    • First observedupdate_picklist_option
    • First observedupdate_record

TDQS

A3.6/5.0

Scored across 23 tools

Disambiguation4/5

Each tool targets a distinct resource and action (records, entities, attributes, keys, option sets, relationships, solutions, actions/functions), and the two invoke_* tools are cleanly separated by HTTP verb (POST action vs GET function). A few adjacent metadata tools (add/update/delete_attribute, get_entity_schema) sit close together, but descriptions make the boundaries clear.

Naming Consistency5/5

Every tool follows a strict verb_noun snake_case pattern (get_record, create_record, update_record, delete_record, add_attribute, list_entity_keys, update_picklist_option, invoke_action, etc.). No mixed conventions or stray verbs.

Tool Count4/5

23 tools is on the heavier side of the ideal range, but Dataverse's surface (record CRUD, metadata CRUD, option sets, alternate keys, relationships, actions/functions) is genuinely broad, so each tool earns its place. Slightly more than strictly needed but well-scoped.

Completeness4/5

Strong coverage: full record CRUD, entity/attribute create+update+delete, option set full CRUD, alternate key add/list/delete, plus invoke_action/invoke_function escape hatches. Gaps like entity update/delete and relationship deletion exist, but the generic invoke_* tools let agents work around them.

Maintenance

ActivityMaintained
ResponsivenessResponsive

Related MCP Connectors

Related MCP Servers

  • F
    license
    A
    quality
    D
    maintenance
    A 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.
    8
    19
    -
  • A
    license
    A
    quality
    C
    maintenance
    Model Context Protocol (MCP) server for Microsoft Dynamics 365 Business Central. Provides AI assistants with direct access to Business Central data through properly formatted API v2.0 calls.
    6
    21 npm
    8
    MIT
  • F
    license
    Not graded
    quality
    C
    maintenance
    An MCP server for OData v4 endpoints, especially Microsoft Dataverse/Dynamics 365, enabling authentication, schema discovery, querying, CRUD, and more via natural language.
    -