npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@dav3/mcp-dynamics365-server

v2.1.0

Published

Generic MCP server for Dynamics 365 CRM operations (AI-generated side project with limited maintenance)

Readme

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

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

Option 1: Manual Configuration (Recommended)

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

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

Option 2: VS Code Extension (Recommended for VS Code Users)

🚀 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": "[email protected]"
  }
}

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": "[email protected]"
  }
}

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

Expanding Related Records

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.