Skip to main content
Glama
dave-palt

mcp-dynamics-365

by dave-palt

Dynamics 365 CRM MCP Server

A comprehensive Model Context Protocol (MCP) server for interacting with Microsoft Dynamics 365 CRM. This server provides AI agents with the ability to perform CRUD operations, query data, fetch schemas, and execute custom operations on Dynamics 365 entities.

Remote Server (HTTP Transport)

This connects to a running HTTP server instance. First, start the server:

# Start server on default port (3300) for local access
pnpm run dev:http

# Or start server for remote access (binds to all interfaces)
pnpm run start:http-remote

For VS Code

Add to your mcp.json:

{
  "servers": {
    "dynamics365-crm-http": {
      "url": "http://localhost:3300/mcp"
    }
  },
  "inputs": []
}

Or, if you need to use OAuth authentication (for protected servers):

{
  "servers": {
    "dynamics365-crm-http": {
      "url": "http://localhost:3300/mcp",
      "oauth": {
        "client_id": "your_github_client_id",
        "client_secret": "your_github_client_secret"
      }
    }
  },
  "inputs": []
}

For remote servers, replace localhost with the server's IP address or hostname:

{
  "servers": {
    "dynamics365-crm-http": {
      "url": "http://your-server-ip:3300/mcp"
    }
  },
  "inputs": []
}

For Claude Desktop

Add to your claude_desktop_config.json:

{
  "mcpServers": {
    "dynamics365-crm-http": {
      "url": "http://localhost:3300/mcp"
    }
  }
}

Or, if you need to use OAuth authentication (for protected servers):

{
  "mcpServers": {
    "dynamics365-crm-http": {
      "url": "http://localhost:3300/mcp",
      "oauth": {
        "client_id": "your_github_client_id",
        "client_secret": "your_github_client_secret"
      }
    }
  }
}

Note: When using HTTP transport, the server must be running separately and environment variables must be configured on the server side (not in the client configuration).

Note: Environment variables must be explicitly specified in the MCP configuration. The server does not automatically load .env files when run via MCP clients.

⚠️ Disclaimer: This project was generated with the assistance of AI as a side project. While functional, it may not receive regular maintenance or updates. Use at your own discretion and consider forking if you need ongoing support.

Features

  • Generic Entity Operations: Query, create, update, and delete any Dynamics 365 entity

  • Schema Discovery: Fetch entity metadata and available entity sets

  • Flexible Querying: Support for OData query parameters (select, filter, orderby, top, skip, expand)

  • Custom OData Queries: Execute direct OData queries for complex scenarios

  • Function Execution: Call Dynamics 365 functions and actions

  • Authentication: Secure OAuth 2.0 client credentials flow

  • Error Handling: Comprehensive error handling and logging

Related MCP server: Dataverse MCP Server

Prerequisites

  • Node.js 18+

  • pnpm (recommended package manager)

  • Dynamics 365 CRM instance

  • Azure AD app registration with appropriate permissions

Package Manager Usage

This project uses pnpm for local development and npm for registry operations:

  • Use pnpm: pnpm install, pnpm run build, pnpm run dev, pnpm run test

  • Use npm: npm publish, npm install -g @dav3/mcp-dynamics365-server

Azure AD App Registration

  1. Go to Azure Portal > Azure Active Directory > App registrations

  2. Create a new registration or use existing one

  3. Note down:

    • Application (client) ID

    • Directory (tenant) ID

  4. Create a client secret and note it down

  5. Grant the following API permissions:

    • Dynamics CRM > user_impersonation

    • Or create custom permissions based on your needs

Installation

  1. Install dependencies:

pnpm install
  1. Copy the environment template:

cp .env.example .env
  1. Configure your environment variables in .env (see consolidated snippet below):

# Dynamics 365 CRM (Backend API)
D365_BASE_URL=https://your-org.crm.dynamics.com         # Your Dynamics 365 organization URL
D365_CLIENT_ID=your-client-id                          # Azure AD application client ID
D365_CLIENT_SECRET=your-client-secret                  # Azure AD application client secret
D365_TENANT_ID=your-tenant-id                         # Azure AD tenant ID
D365_RESOURCE=https://your-org.crm.dynamics.com        # Resource URL for Dynamics 365 API

# MCP OAuth Resource & Provider (Authentication)
# Only required for HTTP transport (not needed for stdio transport)
OAUTH_MCP_RESOURCE=http://localhost:3300
OAUTH_AUTH_URL=https://github.com/login/oauth/authorize
OAUTH_TOKEN_URL=https://github.com/login/oauth/access_token
OAUTH_JWKS_URL=https://api.github.com/meta  # GitHub does not provide JWKS, so use a placeholder
OAUTH_BASE_URL=https://github.com
OAUTH_FLOW=opaque  # Supported values: 'jwt' (for JWT validation), 'opaque' (for API token validation)
OAUTH_OPAQUE_USER_API=https://api.github.com/user  # Optional: endpoint for opaque token validation
OAUTH_TOKEN_CACHE_DURATION_MS=86400000  # Optional: token validation cache duration in milliseconds (default: 24 hours)

# HTTP Transport Configuration (Optional)
MCP_HTTP_PORT=3300        # Port for HTTP transport (default: 3300)
MCP_HTTP_HOST=localhost   # Host for HTTP transport (default: localhost)

Variable Explanations

Dynamics 365 CRM (Backend API):

  • D365_BASE_URL: Your Dynamics 365 organization URL

  • D365_CLIENT_ID: Azure AD application client ID

  • D365_CLIENT_SECRET: Azure AD application client secret

  • D365_TENANT_ID: Azure AD tenant ID

  • D365_RESOURCE: Resource URL for Dynamics 365 API

MCP OAuth Resource & Provider (Authentication):

  • OAUTH_MCP_RESOURCE: The resource identifier exposed to MCP clients (used for OAuth audience)

  • OAUTH_AUTH_URL: OAuth 2.0 authorization endpoint

  • OAUTH_TOKEN_URL: OAuth 2.0 token endpoint

  • OAUTH_JWKS_URL: JWKS endpoint for public key discovery (required for JWT flow)

  • OAUTH_BASE_URL: OAuth provider base URL

  • OAUTH_FLOW: Selects the token validation flow. Use 'jwt' for JWT validation (with JWKS), 'opaque' for API token validation (e.g., GitHub, generic OAuth providers)

    • opaque was tested with github

    • jwt was NOT untested yet

  • OAUTH_OPAQUE_USER_API: (Optional) API endpoint for validating opaque tokens (default: GitHub user API)

HTTP Transport Configuration (Optional):

  • MCP_HTTP_PORT: Port for HTTP transport (default: 3300)

  • MCP_HTTP_HOST: Host for HTTP transport (default: localhost)

Authentication Modes

  • If all OAuth MCP variables are set, the server enforces OAuth authentication for HTTP transport.

  • If any are missing, the server runs in unauthenticated mode (no token required).

  • The protected resource metadata endpoint (/mcp/.well-known/oauth-protected-resource) is only available in authenticated mode.

Usage

Development

pnpm dev

Production

pnpm build
pnpm start

Transport Options

The server supports two transport methods:

1. Stdio Transport (Default)

For direct integration with MCP clients:

# Default transport
node dist/index.js

# Explicitly specify stdio
node dist/index.js --transport=stdio

2. HTTP Transport

For remote access and web-based integrations:

# Default HTTP port (3300)
node dist/index.js --transport=http

# Custom port
node dist/index.js --transport=http --port=8080

HTTP transport features:

  • Streamable HTTP protocol compatible with MCP SDK

  • CORS support for browser-based clients

  • Session management with UUID-based session IDs

  • Default port: 3300

  • Endpoint: /mcp

Command Line Options

# Show help
node dist/index.js --help

# Available options:
--transport=<stdio|http>  Transport type (default: stdio)
--port=<number>          Port for HTTP transport (default: 3300, or MCP_HTTP_PORT env var)
--host=<ip-address>      Host for HTTP transport (default: localhost, or MCP_HTTP_HOST env var)
--help, -h               Show help message

Environment Variables: Default values for --port and --host can be configured using MCP_HTTP_PORT and MCP_HTTP_HOST environment variables in your .env file.

Testing HTTP Transport

Test the HTTP transport using the included test script:

# Start server with HTTP transport
node dist/index.js --transport=http

# In another terminal, run the test
node tests/integration/test-streamable-http.js

MCP Integration

Prerequisites

  1. Install the MCP server globally: npm install -g @dav3/mcp-dynamics365-server

The standard approach is to add the server to your MCP client configuration:

  1. Add to your MCP client configuration (see examples below)

🚀 For the best VS Code experience, use the dedicated extension:

  1. Install the VS Code extension: dav3.mcp-dynamics365-extension

  2. Configure credentials: Use the "Configure MCP Dynamics 365 Server" command

  3. Start HTTP server: Use "Start HTTP Server" command (automatic for production, local dev mode for developers)

📖 Full extension documentation: See vscode-extension/README.md for:

  • Development vs Production command modes

  • Auto-detection features

  • Advanced configuration options

  • Troubleshooting guides

Note: The extension uses HTTP transport by default and provides intelligent command visibility based on your environment (development vs production).

Configuration Examples

You can connect to the MCP server in two ways:

Local Server (Stdio Transport)

This runs the server locally and connects via stdio (standard input/output):

For VS Code

Add to your mcp.json or settings.json:

mcp.json (personally tested)

{
  "servers": {
    "dynamics365-crm": {
      "command": "npx",
      "args": ["@dav3/mcp-dynamics365-server"],
      "env": {
        "D365_CLIENT_ID": "your_client_id",
        "D365_CLIENT_SECRET": "your_client_secret",
        "D365_TENANT_ID": "your_tenant_id",
        "D365_BASE_URL": "https://your-org.crm.dynamics.com",
        "D365_RESOURCE": "https://your-org.crm.dynamics.com"
      }
    }
  },
  "inputs": []
}

settings.json (untested)

{
  "mcp.servers": {
    "dynamics365": {
      "command": "npx",
      "args": ["@dav3/mcp-dynamics365-server"],
      "env": {
        "D365_CLIENT_ID": "your_client_id",
        "D365_CLIENT_SECRET": "your_client_secret",
        "D365_TENANT_ID": "your_tenant_id",
        "D365_BASE_URL": "https://your-org.crm.dynamics.com",
        "D365_RESOURCE": "https://your-org.crm.dynamics.com"
      }
    }
  }
}

For Claude Desktop

Add to your claude_desktop_config.json:

{
  "mcpServers": {
    "dynamics365-crm": {
      "command": "npx",
      "args": ["@dav3/mcp-dynamics365-server"],
      "env": {
        "D365_BASE_URL": "https://your-org.crm.dynamics.com",
        "D365_CLIENT_ID": "your-client-id",
        "D365_CLIENT_SECRET": "your-client-secret",
        "D365_TENANT_ID": "your-tenant-id",
        "D365_RESOURCE": "https://your-org.crm.dynamics.com"
      }
    }
  }
}

Note: Environment variables must be explicitly specified in the MCP configuration. The server does not automatically load .env files when run via MCP clients.

Available Tools

📋 Naming Convention:

  • Metadata operations (get_entity_schema, get_attribute_schema): Use singular entity logical names (e.g., "contact", "account")

  • Data operations (query_entities, get_entity, create_entity, etc.): Use plural entity set names (e.g., "contacts", "accounts")

1. get_entity_schema

Get the schema/metadata for a specific Dynamics 365 entity.

Parameters:

  • entityName (string): The entity logical name in singular form (e.g., "contact", "account")

Example:

{
  "entityName": "contact"
}

2. list_entities

List all available entity sets in Dynamics 365.

Parameters:

  • includeSystem (boolean, optional): Whether to include system entities

Example:

{
  "includeSystem": false
}

3. query_entities

Query entities with flexible filtering, sorting, and selection options.

Parameters:

  • entitySet (string): The entity set name

  • select (array, optional): Fields to select

  • filter (string, optional): OData filter expression

  • orderby (string, optional): OData orderby expression

  • top (number, optional): Maximum number of records

  • skip (number, optional): Number of records to skip

  • expand (string, optional): Related entities to expand

Example:

{
  "entitySet": "contacts",
  "select": ["firstname", "lastname", "emailaddress1"],
  "filter": "firstname eq 'John'",
  "orderby": "createdon desc",
  "top": 10
}

4. get_entity

Get a specific entity record by ID.

Parameters:

  • entitySet (string): The entity set name

  • id (string): The entity ID (GUID)

  • select (array, optional): Specific fields to retrieve

Example:

{
  "entitySet": "contacts",
  "id": "12345678-1234-1234-1234-123456789abc",
  "select": ["firstname", "lastname"]
}

5. create_entity

Create a new entity record.

Parameters:

  • entitySet (string): The entity set name

  • data (object): The entity data to create

Example:

{
  "entitySet": "contacts",
  "data": {
    "firstname": "John",
    "lastname": "Doe",
    "emailaddress1": "john.doe@example.com"
  }
}

6. update_entity

Update an existing entity record.

Parameters:

  • entitySet (string): The entity set name

  • id (string): The entity ID (GUID)

  • data (object): The entity data to update

Example:

{
  "entitySet": "contacts",
  "id": "12345678-1234-1234-1234-123456789abc",
  "data": {
    "emailaddress1": "john.doe.updated@example.com"
  }
}

7. delete_entity

Delete an entity record.

Parameters:

  • entitySet (string): The entity set name

  • id (string): The entity ID (GUID)

Example:

{
  "entitySet": "contacts",
  "id": "12345678-1234-1234-1234-123456789abc"
}

8. execute_odata_query

Execute a custom OData query directly.

Parameters:

  • query (string): The OData query string

Example:

{
  "query": "contacts?$filter=firstname eq 'John' and lastname eq 'Doe'&$select=contactid,fullname"
}

9. execute_function

Execute a Dynamics 365 function or action.

Parameters:

  • functionName (string): The function or action name

  • parameters (object, optional): Function parameters

  • method (string, optional): HTTP method (GET, POST, PATCH, DELETE)

Example:

{
  "functionName": "WhoAmI",
  "method": "GET"
}

Common Entity Sets

  • accounts - Account records

  • contacts - Contact records

  • leads - Lead records

  • opportunities - Opportunity records

  • cases - Case records

  • tasks - Task records

  • appointments - Appointment records

  • emails - Email records

  • phonecalls - Phone call records

OData Query Examples

Basic Filtering

contacts?$filter=firstname eq 'John'

Multiple Conditions

contacts?$filter=firstname eq 'John' and lastname eq 'Doe'

Selecting Specific Fields

contacts?$select=firstname,lastname,emailaddress1

Ordering Results

contacts?$orderby=createdon desc

Limiting Results

contacts?$top=10&$skip=20
contacts?$expand=parentcustomerid

Error Handling

The server provides comprehensive error handling:

  • Authentication errors are logged and returned with appropriate messages

  • API errors include status codes and detailed error descriptions

  • Validation errors for missing required parameters

  • Network and timeout errors are handled gracefully

Security Considerations

  • Store sensitive credentials in environment variables

  • Use least-privilege principle for Azure AD app permissions

  • Implement IP restrictions if needed

  • Monitor and log access patterns

  • Rotate client secrets regularly

Contributing

For detailed development guidelines and conventions, see copilot-instructions.md.

  1. Fork the repository

  2. Create a feature branch

  3. Make your changes

  4. Add tests if applicable

  5. Submit a pull request

Development Setup

# Install dependencies
pnpm install

# Build the project
pnpm run build

# Run tests
pnpm run test:read-tools

# Type checking
pnpm run typecheck

Support

For issues and questions:

  1. Check the troubleshooting section below

  2. Review Dynamics 365 Web API documentation

  3. Create an issue in the repository

Troubleshooting

Authentication Issues

  • Verify client ID, secret, and tenant ID

  • Check Azure AD app permissions

  • Ensure the app has been granted admin consent

  • Verify the resource URL matches your Dynamics 365 instance

Connection Issues

  • Check the base URL format

  • Verify network connectivity

  • Check firewall and proxy settings

  • Validate SSL certificates

Query Issues

  • Review OData syntax

  • Check entity and field names (case sensitive)

  • Verify entity permissions

Contributing & Support

This project was generated with AI assistance as a side project. While contributions are welcome, please note:

  • Limited Maintenance: This project may not receive regular updates or active maintenance

  • Community Driven: The community is encouraged to fork and maintain their own versions

  • Best Effort Support: Issues will be addressed on a best-effort basis when time permits

  • Pull Requests: Well-documented PRs are welcome, but review times may vary

If you need reliable, maintained software for production use, consider:

  • Forking this repository and maintaining your own version

  • Contributing to make this project more robust

  • Looking for alternative commercial solutions

AI Generation Notice

This project was created with the assistance of AI tools. While the code has been reviewed and tested, users should:

  • Thoroughly test in their own environments

  • Review code for security implications

  • Understand the functionality before production use

License

MIT License - see LICENSE file for details.

Available Tools

10 tools
create_entityC

Create a new entity record in Dynamics 365

ParametersJSON Schema
NameRequiredDescriptionDefault
dataYesThe data for the new entity record as key-value pairs
entitySetYesEntity set name (plural form, e.g., "contacts", "accounts", "opportunities")

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 disclosure burden. It says a record is created but omits permissions, duplicate handling, validation behavior, side effects, and what happens on failure, which are important 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?

The description is a single front-loaded sentence with no wasted words. It is appropriately sized for its limited content and immediately communicates the tool's core action.

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 create/mutation tool with no annotations, no output schema, and a nested data object parameter, the description is too thin. It does not explain required permissions, return behavior, error cases, or any operational context needed to invoke it 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 description coverage is 100%, so the schema already documents both parameters and examples for entitySet. The description adds no parameter meaning beyond what the schema provides, making the baseline 3 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 ('Create') and resource ('entity record in Dynamics 365'), making the core action clear. However, it does not explicitly differentiate from sibling tools such as update_entity or delete_entity beyond the verb implying the distinction.

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 offers no guidance on when to use this tool versus alternatives like update_entity, delete_entity, or execute_odata_query. Usage is only implied by the word 'Create'.

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

delete_entityC

Delete an entity record from Dynamics 365

ParametersJSON Schema
NameRequiredDescriptionDefault
entityIdYesThe unique identifier (GUID) of the entity record to delete
entitySetYesEntity set name (plural form, e.g., "contacts", "accounts", "opportunities")

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 burden for a destructive operation. It does not disclose that deletion is permanent/irreversible, whether it is a soft or hard delete, what permissions are required, or how cascading relationships behave. Only the implied mutation semantic 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 efficient sentence with the operation and target front-loaded and no filler. It is terse to the point of omitting necessary warnings, but nothing in it is wasted.

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 destructive tool with no annotations and no output schema, the description omits essentials: irreversibility, required permissions, cascade effects, and failure modes. An agent could call it correctly but without understanding the consequences.

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 entitySet and entityId are fully documented in the schema (including plural-form examples). The description adds no syntax or format detail beyond that, so 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 ('Delete') and resource ('an entity record from Dynamics 365'), so the agent immediately knows the operation. It does not differentiate itself from siblings like update_entity or create_entity, but the verb alone makes the distinction obvious in practice.

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 guidance on when to use this versus update_entity or other siblings, and no prerequisites (e.g., that the record must exist, or that an ID must first be obtained via get_entity/query_entities). The agent is left to infer usage entirely.

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

execute_functionC

Execute a custom Dynamics 365 function or action

ParametersJSON Schema
NameRequiredDescriptionDefault
parametersNoParameters to pass to the function (optional)
functionNameYesThe name of the function or action to execute

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 it discloses almost nothing: not whether execution has side effects, whether it can be destructive, what permissions are required, or that behavior depends entirely on the named function. For an arbitrary-execution tool this is a major gap.

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. It is efficient, though the brevity comes at the cost of the missing detail scored elsewhere rather than being a model of well-structured completeness.

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?

With no output schema, a nested free-form parameters object, and no annotations, the description should explain how an agent discovers valid function names and what happens on success/failure. None of that is present, leaving a real gap for a tool whose contract varies per invocation.

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 in the schema and the baseline of 3 applies. The description adds no extra meaning about how to format the nested free-form 'parameters' object or how functionName relates to 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?

States a specific verb and resource: execute a custom Dynamics 365 function or action. This is clearly distinct from the entity CRUD and query siblings, but the description never explicitly contrasts itself with them or clarifies what 'custom function or action' means in this context (e.g., bound vs unbound actions, plugin messages).

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 alternatives named. The agent is left to infer that this is for invoking arbitrary platform functions rather than using the dedicated CRUD/query siblings, which is exactly the decision that needs guidance.

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

execute_odata_queryB

Execute a custom OData query against Dynamics 365 Web API

ParametersJSON Schema
NameRequiredDescriptionDefault
queryYesRaw OData query (e.g., "contacts?$filter=statecode eq 0&$select=firstname,lastname")

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 burden. It does not disclose whether the query is read-only, whether it can mutate data, rate limits, authentication requirements, or error behavior. 'Execute' is ambiguous about side effects.

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?

Single sentence, front-loaded with verb and resource, zero waste. It is appropriately sized for a one-parameter tool.

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 one-parameter query tool with no annotations and no output schema, the description is minimal. It lacks any behavioral context (read-only, error handling, permissions) and does not clarify how it differs from query_entities.

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%, and the parameter description includes a concrete example of the raw OData query format, so the schema does the heavy lifting. The tool description adds no parameter details beyond what the schema provides; baseline 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 (Execute) and resource (custom OData query against Dynamics 365 Web API). It distinguishes itself from siblings like query_entities and execute_function by emphasizing 'custom OData query' and 'raw' input, though it does not explicitly name alternatives.

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 for cases needing raw OData syntax, but there is no explicit when-to-use or when-not-to-use guidance. An agent must infer that query_entities is for structured queries and this tool is for custom OData.

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

get_attribute_schemaB

Get detailed schema/metadata for a specific attribute of a Dynamics 365 entity, including options for picklists

ParametersJSON Schema
NameRequiredDescriptionDefault
entityNameYesThe entity logical name (singular form, e.g., "contact", "account", "product") - NOT the entity set name
attributeNameYesThe logical name of the attribute (e.g., "statecode", "statuscode", "firstname")

TDQS

B3.1/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 does not disclose that this is a read-only metadata operation, whether it requires authentication or privileges, or what the response shape looks like. Mentioning picklist options hints at output content but does not cover the behavioral profile.

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 efficient sentence that front-loads the verb and resource and appends the picklist nuance without padding.

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?

Adequate for a two-parameter metadata read with full schema coverage, but with no annotations and no output schema, the description should do more to establish the read-only nature and expected return, especially against a rich sibling set of entity/query tools.

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 both parameters fully documented in the schema, including the singular-form warning for entityName and naming-convention for attributeName. The description adds no parameter 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.

Purpose4/5

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

Specific verb (Get) and resource (detailed schema/metadata for a specific attribute of a Dynamics 365 entity), and it explicitly calls out picklist options. It is distinguishable from the sibling get_entity_schema by the attribute-level scope, though the description does not explicitly name that sibling to sharpen the contrast.

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 guidance on when to use this versus get_entity_schema or query_entities. The implied context is schema inspection, but there is no when-not or alternative routing.

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

get_entityB

Get a specific entity record by ID from Dynamics 365

ParametersJSON Schema
NameRequiredDescriptionDefault
selectNoComma-separated list of fields to retrieve (e.g., "firstname,lastname,emailaddress1")
entityIdYesThe unique identifier (GUID) of the entity record
entitySetYesEntity set name (plural form, e.g., "contacts", "accounts", "opportunities")

TDQS

B3.1/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 'Get' only weakly implies a read operation. It does not state that the call is non-mutating, what happens when the ID does not exist (empty vs error), or any permission/scope requirements for the Dynamics 365 entity set.

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 no filler; the verb and lookup key lead the sentence and nothing is repeated from the schema.

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 three-parameter read tool with fully documented parameters, the definition is minimally viable, but it omits what the returned record looks like and how 'select' affects the response, which matters because there is no output schema.

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%, including the comma-separated format and example for 'select' and the plural-form guidance for 'entitySet', so the baseline is 3. The description adds nothing beyond the schema, mentioning only the ID lookup.

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 (Get), resource (entity record), lookup key (by ID), and source system (Dynamics 365), so an agent can distinguish it from list_entities and query_entities at a glance. It stops short of explicitly naming those siblings or the conditions that would route to them.

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 guidance: nothing about preferring this over query_entities/execute_odata_query when a filter or multiple records are needed, and no prerequisite or fallback behavior if the ID is unknown. The 'by ID' phrasing implies single-record retrieval but does not state an alternative.

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

get_entity_schemaC

Get detailed schema information for a specific Dynamics 365 entity

ParametersJSON Schema
NameRequiredDescriptionDefault
entityNameYesThe logical name of the entity (singular, e.g., 'contact', 'account', 'opportunity')

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. It does not state whether the call requires authentication, whether it's read-only, what the returned schema looks like, latency, or any side effects. 'Get' implies read-only but the description never confirms this.

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, efficient sentence that front-loads the action and resource. No wasted words, though it is quite terse given the tool's potential complexity.

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 single-parameter read tool with a fully specified schema, the description is minimally adequate. However, with no annotations and no output schema, it leaves the return shape, read-only nature, and error conditions unaddressed.

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 parameter's meaning and format (singular logical name, with examples) are fully documented in the schema. The description adds no parameter-level detail beyond what the schema already provides, making the baseline of 3 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 (Get) and resource (schema information for a Dynamics 365 entity), clearly distinguishing it from data-retrieval siblings like get_entity or query_entities. It doesn't explicitly differentiate from its closest sibling get_attribute_schema, but the object (entity vs. attribute) is clear.

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 guidance on when to use this tool versus alternatives such as list_entities or get_attribute_schema, nor any prerequisites or exclusions. The agent must infer usage from the name and siblings alone.

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

list_entitiesB

List all available Dynamics 365 entities with their basic information

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

B3/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 does not state that this is a read-only operation, whether results are paginated or capped, whether custom entities are included, or what 'basic information' contains. For a low-risk list call this is a modest but real gap.

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 tight sentence with the action front-loaded and no wasted words. Slightly penalized because 'with their basic information' is vague padding that could have been replaced with concrete return details.

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?

With no output schema and no annotations, the description is the only source of behavioral truth, and it does not define what fields 'basic information' includes or how many entities come back. For a discovery tool an agent needs at least the shape of the response to use it confidently.

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?

The tool takes zero parameters, so the baseline is 4. The description correctly implies no filtering input is accepted, though it could note that server-side filtering requires a different sibling tool.

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 ('List') and resource ('Dynamics 365 entities') with a qualifier on scope ('all available'). It does not distinguish itself from siblings like query_entities, get_entity, or get_entity_schema, leaving the agent to infer the boundary between enumeration and retrieval.

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 explicit when-to-use or when-not-to-use guidance. With nine sibling tools including query_entities, get_entity, and get_entity_schema, the description gives no signal for choosing this discovery call over a filtered query or a single-entity fetch.

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

query_entitiesC

Query entities from Dynamics 365 with optional filtering, sorting, and pagination

ParametersJSON Schema
NameRequiredDescriptionDefault
topNoMaximum number of records to return (default: 10, max: 5000)
filterNoOData filter expression (e.g., "statecode eq 0 and firstname eq 'John'")
selectNoComma-separated list of fields to retrieve (e.g., "firstname,lastname,emailaddress1")
orderbyNoOrder by clause (e.g., "createdon desc" or "lastname asc,firstname asc")
entitySetYesEntity set name (plural form, e.g., "contacts", "accounts", "opportunities") - NOT the entity logical 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, yet it discloses nothing about authentication requirements, throttling/rate limits, default paging behavior, or the shape of results. Beyond the word 'pagination' in passing, an agent gets no operational context for a live CRM query.

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 covering capability and options, with no filler or redundancy. It is efficient, though it is arguably too terse for a tool with this many behavioral unknowns.

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?

With no output schema and no annotations, the description should at least sketch the return shape and note that pagination uses server-side paging rather than the top parameter alone. It remains adequate-but-minimal for a tool of this complexity.

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 five parameters with examples (OData filter syntax, select field lists, orderby clauses, entitySet plural naming). The description restates the parameter categories generically rather than adding syntax or format detail, so 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 names a specific verb (Query) and resource (entities in Dynamics 365) and enumerates the supported operations (filtering, sorting, pagination), so the agent knows what it does. It does not, however, distinguish itself from siblings like list_entities, get_entity, or execute_odata_query, which overlap in the read space.

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 nearby alternatives (execute_odata_query, list_entities, get_entity). The agent must infer routing from names alone, and no prerequisites or exclusions are stated.

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

update_entityC

Update an existing entity record in Dynamics 365

ParametersJSON Schema
NameRequiredDescriptionDefault
dataYesThe data to update as key-value pairs
entityIdYesThe unique identifier (GUID) of the entity record to update
entitySetYesEntity set name (plural form, e.g., "contacts", "accounts", "opportunities")

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 for a mutation operation. It says nothing about partial vs. full update semantics (i.e., whether omitted fields are cleared), optimistic concurrency/ETag requirements, permission needs, or what the response contains.

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 the operation front-loaded and no wasted words. Its brevity is efficient, though it comes at the cost of the behavioral detail noted elsewhere.

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 data object, the description is thin: it omits update semantics, required field expectations, and result shape. The schema covers parameter naming but not the behavior an agent needs before writing to Dynamics 365.

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 entitySet, entityId, and data are all documented in the schema itself. The description adds no further parameter meaning, such as which keys the data object accepts, 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?

States a specific verb (Update) and resource (an existing entity record in Dynamics 365), so an agent knows the operation is a mutation of an existing record. It does not differentiate itself from siblings like create_entity or delete_entity beyond the verb, but those are self-evidently distinct.

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 guidance on when to use this versus create_entity, delete_entity, or execute_odata_query. There is also no mention of prerequisites such as needing the record GUID or the entity set name, though the schema requires both.

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. 10 tool updatesv2.1.0
    • First observedcreate_entity
    • First observeddelete_entity
    • First observedexecute_function
    • First observedexecute_odata_query
    • First observedget_attribute_schema
    • First observedget_entity
    • First observedget_entity_schema
    • First observedlist_entities
    • First observedquery_entities
    • First observedupdate_entity

TDQS

B3.4/5.0

Scored across 10 tools

Disambiguation4/5

Most tools have distinct purposes (e.g., create/update/delete and execute_odata_query vs query_entities). However, query_entities and execute_odata_query could be confused by an agent when deciding between structured querying and raw OData. Also get_entity_schema and get_attribute_schema are clearly different, but get_entity and get_entity_schema share the 'get_entity' prefix, potentially causing slight naming ambiguity.

Naming Consistency5/5

All tool names follow a consistent snake_case verb_noun pattern (e.g., get_entity_schema, list_entities, create_entity). The verbs are standard and the naming is predictable throughout.

Tool Count5/5

10 tools is well-scoped for a Dynamics 365 API wrapper, covering essential CRUD, metadata, and query operations without being excessive. Each tool has a clear, non-redundant role.

Completeness4/5

The surface provides comprehensive CRUD and query capabilities, including schema introspection and custom function execution. However, it lacks tools for bulk operations, association management (e.g., associate/disassociate records), and batch requests, which are common in Dynamics 365.

Maintenance

ActivityInactive
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables AI assistants to explore metadata, query data, and perform write operations across multiple Microsoft Dynamics 365 Finance & Operations environments. It features specialized tools for OData execution and data analysis with built-in read-only safety for production environments.
    21 npm
    10
    MIT
  • A
    license
    A
    quality
    A
    maintenance
    Enables AI agents to query, inspect, and manage Microsoft Dataverse records, metadata, schema, forms, views, and Power Platform environments via the Dataverse OData Web API.
    97
    2
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables AI assistants to interact with Zoho CRM data through secure OAuth authentication, supporting comprehensive CRM operations including record management, search, bulk operations, and lead conversion.
    3
    MIT
  • F
    license
    A
    quality
    D
    maintenance
    Enables direct interaction with Microsoft Dataverse from Claude Desktop, supporting full CRUD, bulk operations, FetchXML queries, actions, and metadata discovery.
    20
    -