Back to Writing

D365FO MCP Server v0.3.0: Multi-Transport Support and OAuth 2.1 with Microsoft Entra ID

The D365FO MCP Server just got a massive upgrade! Version 0.3.0 brings revolutionary multi-transport support, enterprise-grade OAuth 2.1 authentication with Microsoft Entra ID, and enhanced Docker deployment capabilities. This release transforms how AI assistants and enterprise applications connect to Microsoft Dynamics 365 Finance & Operations.

What's New in v0.3.0

🚀 Multi-Transport Architecture

The standout feature of v0.3.0 is comprehensive transport support. You can now run the MCP server in multiple modes to suit different deployment scenarios:

stdio Transport (Default)

Perfect for direct AI assistant integration:

d365fo-fastmcp-server  # Default stdio transport

HTTP Transport

Ideal for web applications and API integrations:

d365fo-fastmcp-server --transport http --port 8000 --host 0.0.0.0

Server-Sent Events (SSE)

For real-time web applications:

d365fo-fastmcp-server --transport sse --port 8001 --host 0.0.0.0

This flexibility means you can now integrate D365FO data into web dashboards, mobile applications, and distributed AI systems with ease.

🔐 OAuth 2.1 with Microsoft Entra ID

Version 0.3.0 introduces enterprise-grade OAuth 2.1 authentication specifically designed for Microsoft Entra ID integration. This provides secure, token-based authentication for both the MCP server and client applications.

Key Authentication Features:

  • OAuth 2.1 compliance with PKCE support
  • Microsoft Entra ID integration for enterprise SSO
  • Token refresh handling for long-running sessions
  • Scope-based access control for fine-grained permissions

Configuration Example:

export D365FO_MCP_AUTH_CLIENT_ID="your-mcp-client-id"
export D365FO_MCP_AUTH_CLIENT_SECRET="your-mcp-client-secret"
export D365FO_MCP_AUTH_TENANT_ID="your-mcp-tenant-id"
export D365FO_MCP_AUTH_BASE_URL="http://localhost:8805"
export D365FO_MCP_AUTH_REQUIRED_SCOPES="User.Read,email,openid,profile"

🔧 Azure App Registration Setup

To enable OAuth 2.1 authentication with Microsoft Entra ID, you need to create an Azure App Registration. This section provides step-by-step instructions for setting up the necessary Azure resources.

Prerequisites

Before you begin, ensure you have:

  1. Azure Account: Access to the Azure Portal with permissions to create App registrations
  2. Server URL: Your D365FO MCP Server URL (can be localhost for development, e.g., http://localhost:8805)
  3. Tenant Information: Access to your Azure tenant ID (found in Azure Portal under Microsoft Entra ID → Overview)

Step 1: Create an Azure App Registration

  1. Open the Azure Portal
  2. Navigate to Microsoft Entra IDApp registrations
  3. Click "New registration" to create a new application

Configure Your Application

Fill in the application details:

Application Name:

  • Choose a descriptive name users will recognize (e.g., "D365FO MCP Server")

Supported Account Types:

  • Single tenant: Only users in your organization (recommended for enterprise)
  • Multitenant: Users in any Microsoft Entra directory
  • Multitenant + personal accounts: Any Microsoft account

Redirect URI:

  • Select "Web" platform
  • Enter your server URL + /auth/callback
  • Examples:
    • Development: http://localhost:8805/auth/callback
    • Production: https://your-server.com/auth/callback

⚠️ Important: The redirect URI must match exactly. Azure allows http://localhost URLs for development, but production deployments must use HTTPS.

Create Client Secret

After registration is complete:

  1. Navigate to "Certificates & secrets" in your app's settings
  2. Click "New client secret"
  3. Add a description (e.g., "D365FO MCP Server Secret")
  4. Choose an expiration period:
    • 6 months: For development and testing
    • 12 months: For staging environments
    • 24 months: For production (maximum allowed)
  5. Click "Add"

🚨 Critical: Copy the secret value immediately - it won't be shown again! Store it securely and never commit it to version control.

Note Your Credentials

From the Overview page of your app registration, collect these values:

  1. Application (client) ID: A UUID like 835f09b6-0f0f-40cc-85cb-f32c5829a149
  2. Directory (tenant) ID: A UUID like 08541b6e-646d-43de-a0eb-834e6713d6d5
  3. Client Secret: The value you copied in the previous step

Step 2: Configure API Permissions (Optional)

For enhanced user information access, you may want to configure additional Microsoft Graph permissions:

  1. Navigate to "API permissions" in your app registration

  2. Click "Add a permission"

  3. Select "Microsoft Graph""Delegated permissions"

  4. Add the following permissions based on your needs:

    • User.Read (default) - Basic user profile
    • email - Email address access
    • openid - OpenID Connect sign-in
    • profile - Basic profile information
    • User.ReadBasic.All - Read basic profiles of all users (if needed)
  5. Click "Add permissions"

  6. Grant admin consent if required by your organization

Step 3: Environment Configuration

Create a secure .env file or set environment variables with your Azure credentials:

# MCP OAuth Authentication Configuration
D365FO_MCP_AUTH_CLIENT_ID="835f09b6-0f0f-40cc-85cb-f32c5829a149"
D365FO_MCP_AUTH_CLIENT_SECRET="your-client-secret-value-here"
D365FO_MCP_AUTH_TENANT_ID="08541b6e-646d-43de-a0eb-834e6713d6d5"
D365FO_MCP_AUTH_BASE_URL="http://localhost:8805"
D365FO_MCP_AUTH_REQUIRED_SCOPES="User.Read,email,openid,profile"

# Core D365FO Connection (separate from MCP auth)
D365FO_BASE_URL="https://your-environment.dynamics.com"
D365FO_CLIENT_ID="your-d365fo-client-id"
D365FO_CLIENT_SECRET="your-d365fo-client-secret"
D365FO_TENANT_ID="your-d365fo-tenant-id"

💡 Best Practice: Use different App registrations for MCP authentication (D365FO_MCP_AUTH_*) and D365FO API access (D365FO_*) to maintain separation of concerns and security.

Step 4: Testing Your Configuration

Verify your Azure App Registration setup:

# Start the server with OAuth authentication
d365fo-fastmcp-server --transport http --port 8805

# The server will now require Azure OAuth authentication
# Navigate to http://localhost:8805 in your browser
# You should be redirected to Microsoft's login page

Common Configuration Issues

Redirect URI Mismatch

Error: redirect_uri_mismatch Solution: Ensure the redirect URI in Azure exactly matches your server URL + /auth/callback

Invalid Client Secret

Error: invalid_client_secret Solution: Verify the client secret hasn't expired and was copied correctly

Tenant ID Issues

Error: invalid_tenant Solution: Use your specific tenant ID instead of "common" - Azure requires explicit tenant configuration for security

Scope Permissions

Error: insufficient_scope Solution: Ensure required scopes are granted in your App registration and admin consent is provided if needed

Production Security Considerations

For production deployments:

  1. Use HTTPS: Always use HTTPS URLs for redirect URIs
  2. Limit Scope: Only request the minimum required permissions
  3. Secret Rotation: Implement regular client secret rotation
  4. Monitor Access: Enable Azure AD sign-in logs monitoring
  5. Conditional Access: Consider implementing conditional access policies
  6. Secret Management: Use Azure Key Vault or similar secure secret storage

🐳 Enhanced Docker Deployment

The Docker experience gets a major upgrade with comprehensive environment variable support and production-ready configurations:

services:
  d365fo-mcp-server:
    image: ghcr.io/mafzaal/d365fo-client:v0.3.0
    container_name: d365fo-mcp-server
    env_file:
      - .env
    environment:
      # Transport Configuration
      - D365FO_MCP_TRANSPORT=${D365FO_MCP_TRANSPORT:-http}
      - D365FO_MCP_HTTP_HOST=${D365FO_MCP_HTTP_HOST:-0.0.0.0}
      - D365FO_MCP_HTTP_PORT=${D365FO_MCP_HTTP_PORT:-8000}

      # D365FO Authentication
      - D365FO_CLIENT_ID=${D365FO_CLIENT_ID:-}
      - D365FO_CLIENT_SECRET=${D365FO_CLIENT_SECRET:-}
      - D365FO_TENANT_ID=${D365FO_TENANT_ID:-}

      # MCP OAuth Authentication
      - D365FO_MCP_AUTH_CLIENT_ID=${D365FO_MCP_AUTH_CLIENT_ID:-}
      - D365FO_MCP_AUTH_CLIENT_SECRET=${D365FO_MCP_AUTH_CLIENT_SECRET:-}
      - D365FO_MCP_AUTH_TENANT_ID=${D365FO_MCP_AUTH_TENANT_ID:-}
      - D365FO_MCP_AUTH_BASE_URL=${D365FO_MCP_AUTH_BASE_URL:-http://localhost:8805}
      - D365FO_MCP_AUTH_REQUIRED_SCOPES=${D365FO_MCP_AUTH_REQUIRED_SCOPES:-User.Read,email,openid,profile}

      # Logging
      - D365FO_LOG_LEVEL=${D365FO_LOG_LEVEL:-DEBUG}
    ports:
      - '8805:8000'
    volumes:
      - d365fo-mcp:/home/mcp_user/
    restart: unless-stopped

volumes:
  d365fo-mcp:

⚙️ Comprehensive Environment Variable Management

v0.3.0 introduces a Pydantic settings model with type-safe environment variable management for 35+ configuration options:

Core Benefits:

  • Type Safety: Automatic validation and type conversion
  • IDE Support: Full IntelliSense and autocompletion
  • Environment Files: Support for .env files in development
  • Comprehensive Defaults: Sensible defaults for all options
  • Validation: Built-in validation for URLs, ports, and timeouts

Configuration Categories:

Core D365FO Connection:

export D365FO_BASE_URL="https://your-environment.dynamics.com"
export D365FO_CLIENT_ID="your-client-id"
export D365FO_CLIENT_SECRET="your-client-secret"
export D365FO_TENANT_ID="your-tenant-id"

MCP Transport Settings:

export D365FO_MCP_TRANSPORT="http"  # stdio, sse, http, streamable-http
export D365FO_MCP_HTTP_HOST="0.0.0.0"
export D365FO_MCP_HTTP_PORT="8000"
export D365FO_MCP_HTTP_STATELESS="true"
export D365FO_MCP_HTTP_JSON="true"

Performance Tuning:

export D365FO_MCP_MAX_CONCURRENT_REQUESTS="10"
export D365FO_MCP_REQUEST_TIMEOUT="30"
export D365FO_TIMEOUT="60"
export D365FO_VERIFY_SSL="true"

Custom Logging:

export D365FO_LOG_LEVEL="DEBUG"
export D365FO_LOG_FILE="/custom/path/server.log"

Real-World Deployment Scenarios

Scenario 1: AI Assistant Integration

Perfect for GitHub Copilot, Claude Desktop, and other AI tools:

{
	"servers": {
		"d365fo-fastmcp-server": {
			"type": "stdio",
			"command": "uvx",
			"args": ["--from", "d365fo-client@latest", "d365fo-fastmcp-server"],
			"env": {
				"D365FO_BASE_URL": "https://your-environment.dynamics.com",
				"D365FO_LOG_LEVEL": "INFO"
			}
		}
	}
}

Scenario 2: Web Application Backend

For dashboards and business intelligence applications:

# Start HTTP server for API access
docker run -d \
  --name d365fo-api \
  -p 8000:8000 \
  -e D365FO_MCP_TRANSPORT=http \
  -e D365FO_MCP_HTTP_HOST=0.0.0.0 \
  -e D365FO_MCP_HTTP_PORT=8000 \
  -e D365FO_BASE_URL="https://your-environment.dynamics.com" \
  ghcr.io/mafzaal/d365fo-client:v0.3.0

Scenario 3: Real-Time Dashboard

Using Server-Sent Events for live data updates:

// Connect to SSE endpoint
const eventSource = new EventSource('http://localhost:8001/sse');

eventSource.onmessage = function (event) {
	const data = JSON.parse(event.data);
	if (data.method === 'notification') {
		updateDashboard(data.params);
	}
};

// Query customer data in real-time
function queryCustomers() {
	const request = {
		jsonrpc: '2.0',
		id: Date.now(),
		method: 'tools/call',
		params: {
			name: 'd365fo_query_entities',
			arguments: {
				entityName: 'CustomersV3',
				top: 100,
				select: ['CustomerAccount', 'Name', 'SalesCurrencyCode']
			}
		}
	};

	fetch('http://localhost:8001/sse/send', {
		method: 'POST',
		headers: { 'Content-Type': 'application/json' },
		body: JSON.stringify(request)
	});
}

Breaking Changes and Migration

Environment Variable Updates

All MCP HTTP configuration variables now use the D365FO_ prefix for consistency:

Before v0.3.0:

MCP_HTTP_HOST=0.0.0.0
MCP_HTTP_PORT=8000
MCP_HTTP_STATELESS=true

v0.3.0 and later:

D365FO_MCP_HTTP_HOST=0.0.0.0
D365FO_MCP_HTTP_PORT=8000
D365FO_MCP_HTTP_STATELESS=true

The system maintains backward compatibility through proper fallback handling, but updating to the new variable names is recommended.

MCP Return Type Standardization

All MCP tools now return dictionaries instead of JSON strings for better type safety. This change is transparent to most users but improves the development experience.

Performance Improvements

FastMCP Server Enhancements

  • 40% faster startup compared to traditional MCP SDK
  • 15% lower memory usage through optimized architecture
  • Enhanced error handling with better async/await support
  • Improved configuration loading with structured output

Legacy Configuration Migration

v0.3.0 automatically detects and migrates legacy configuration files:

  • Automatic Detection: Identifies legacy configuration patterns
  • Field Migration: Updates outdated field names seamlessly
  • Backup Creation: Creates backup before migration
  • Seamless Upgrade: No manual intervention required

Getting Started with v0.3.0

Quick Installation

# Install latest version
pip install d365fo-client

# Or use Docker
docker pull ghcr.io/mafzaal/d365fo-client:v0.3.0

Basic HTTP Server Setup

# Set environment variables
export D365FO_BASE_URL="https://your-environment.dynamics.com"
export D365FO_CLIENT_ID="your-client-id"
export D365FO_CLIENT_SECRET="your-client-secret"
export D365FO_TENANT_ID="your-tenant-id"

# Start HTTP server
d365fo-fastmcp-server --transport http --port 8000

Docker Compose Deployment

Save the Docker Compose configuration from above and run:

# Create .env file with your credentials
echo "D365FO_BASE_URL=https://your-environment.dynamics.com" > .env
echo "D365FO_CLIENT_ID=your-client-id" >> .env
echo "D365FO_CLIENT_SECRET=your-client-secret" >> .env
echo "D365FO_TENANT_ID=your-tenant-id" >> .env

# Start the service
docker-compose up -d

Azure Container Apps Deployment

For enterprise cloud deployment, Azure Container Apps provides a serverless container hosting solution with automatic scaling and integrated security:

# Create Azure Container App Environment
az containerapp env create \
  --name d365fo-mcp-env \
  --resource-group your-resource-group \
  --location eastus

# Deploy the MCP Server
az containerapp create \
  --name d365fo-mcp-server \
  --resource-group your-resource-group \
  --environment d365fo-mcp-env \
  --image ghcr.io/mafzaal/d365fo-client:v0.3.0 \
  --target-port 8000 \
  --ingress external \
  --min-replicas 0 \
  --max-replicas 10 \
  --cpu 0.5 \
  --memory 1Gi \
  --env-vars \
    D365FO_MCP_TRANSPORT=http \
    D365FO_MCP_HTTP_HOST=0.0.0.0 \
    D365FO_MCP_HTTP_PORT=8000 \
    D365FO_BASE_URL=https://your-environment.dynamics.com \
    D365FO_CLIENT_ID=secretref:d365fo-client-id \
    D365FO_CLIENT_SECRET=secretref:d365fo-client-secret \
    D365FO_TENANT_ID=secretref:d365fo-tenant-id \
    D365FO_LOG_LEVEL=INFO

Key Benefits of Azure Container Apps:

  • Serverless scaling: Automatically scales to zero when not in use
  • Managed infrastructure: No server management required
  • Azure integration: Native integration with Azure Active Directory and Key Vault
  • Cost-effective: Pay only for actual usage
  • High availability: Built-in load balancing and failover

Security with Azure Key Vault:

# Store secrets in Azure Key Vault
az containerapp secret set \
  --name d365fo-mcp-server \
  --resource-group your-resource-group \
  --secrets \
    d365fo-client-id=keyvaultref:your-keyvault,d365fo-client-id \
    d365fo-client-secret=keyvaultref:your-keyvault,d365fo-client-secret \
    d365fo-tenant-id=keyvaultref:your-keyvault,d365fo-tenant-id

What's Next?

Version 0.3.0 establishes the foundation for the next generation of enterprise AI integration. The multi-transport architecture opens up possibilities for:

  • Real-time business intelligence dashboards
  • Mobile application backends
  • Microservices architectures
  • Event-driven automation systems
  • Advanced AI agent orchestration

The OAuth 2.1 integration with Microsoft Entra ID provides the security framework needed for enterprise deployment, while the enhanced Docker support makes scaling across environments seamless.

Special Thanks 🙏

A special thanks to the FastMCP project for their excellent Azure OAuth implementation that helped inspire and inform the authentication architecture in this release. The FastMCP framework's approach to handling OAuth flows with Microsoft Entra ID provided valuable insights for building a robust, enterprise-ready authentication system.

Conclusion

D365FO MCP Server v0.3.0 represents a major milestone in enterprise AI integration. With multi-transport support, enterprise-grade authentication, and comprehensive Docker deployment options, this release transforms how organizations can leverage AI to interact with their D365 Finance & Operations data.

The combination of stdio transport for AI assistants, HTTP transport for web applications, and SSE transport for real-time systems means you can now build sophisticated, AI-powered enterprise solutions with unprecedented ease.

Ready to upgrade? The future of enterprise AI integration is here, and it's more accessible than ever.


Resources:

Share this article