๐ Dynamics 365 Finance & Operations MCP Server
This is a production-ready Model Context Protocol (MCP) server that unlocks the full potential of Microsoft Dynamics 365 Finance & Operations (D365 F&O) for AI assistants and other MCP-compatible tools. It enables sophisticated integration workflows through standardized protocol interactions.

๐ Quick Start
Installation
You can install the server in multiple ways:
One-Click Installation for VS Code
Docker Installation for VS Code
Deploy to Azure Container Apps
You can deploy the MCP server as a secure, internet-accessible HTTP endpoint with OAuth or API Key authentication.
Option 1: Using Bash Script (Recommended)
curl -O https://raw.githubusercontent.com/mafzaal/d365fo-client/main/deploy-aca.sh
chmod +x deploy-aca.sh
export D365FO_MCP_AUTH_CLIENT_ID="your-client-id"
export D365FO_MCP_AUTH_CLIENT_SECRET="your-client-secret"
export D365FO_MCP_AUTH_TENANT_ID="your-tenant-id"
export D365FO_MCP_API_KEY_VALUE="your-secret-key"
./deploy-aca.sh
Option 2: Using ARM Template
- Download azure-deploy.json
- Go to Azure Portal โ Deploy a custom template
- Click "Build your own template in the editor"
- Paste the contents of
azure-deploy.json
- Fill in the parameters and deploy
Setup
pip install d365fo-client
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 the Server
FastMCP Server (Recommended)
d365fo-fastmcp-server
d365fo-fastmcp-server --transport http --port 8000 --host 0.0.0.0
d365fo-fastmcp-server --transport sse --port 8001 --host 0.0.0.0
โจ Features
MCP Server Features
- 49 comprehensive tools covering all major D365 F&O operations across 9 functional categories
- 12 resource types with comprehensive metadata exposure and discovery capabilities
- 2 prompt templates for advanced workflow assistance
- Multi-transport support (FastMCP): stdio, HTTP, Server-Sent Events (SSE)
- Production-ready implementation with proper error handling, authentication, and security validation
- Enhanced performance (FastMCP): 40% faster startup, 15% lower memory usage
- Advanced profile management supporting multiple environments with secure credential storage
- Database analysis capabilities with secure SQL querying and metadata insights
- Session-based synchronization with detailed progress tracking and multiple sync strategies
- Multi-language support with label resolution and localization capabilities
- Enterprise security with Azure AD integration, Key Vault support, and audit logging
New in v0.3.0
- ๐ง Pydantic Settings Model: Type-safe environment variable management with validation for 35+ configuration options
- ๐ Custom Log File Support:
D365FO_LOG_FILE environment variable for flexible log file paths
- ๐ Legacy Config Migration: Automatic detection and migration of legacy configuration files
- ๐ Environment Variable Standardization: All MCP HTTP variables now use
D365FO_ prefix for consistency
- โก Enhanced FastMCP Server: Improved startup configuration, error handling, and graceful shutdown
- ๐ MCP Return Type Standardization: All MCP tools now return dictionaries instead of JSON strings for better type safety
- ๐ ๏ธ Enhanced Configuration: Support for
.env files and comprehensive environment variable documentation
Python Client Library Features
- ๐ OData Client: Full CRUD operations on D365 F&O data entities with composite key support
- ๐ Metadata Management V2: Enhanced caching system with intelligent synchronization and FTS5 search
- ๐ท๏ธ Label Operations V2: Multilingual label caching with performance improvements and async support
- ๐ Advanced Querying: Support for all OData query parameters ($select, $filter, $expand, etc.)
- โก Action Execution: Execute bound and unbound OData actions with comprehensive parameter handling
- ๏ฟฝ๏ธ JSON Services: Generic access to D365 F&O JSON service endpoints (/api/services pattern)
- ๏ฟฝ๐ Authentication: Azure AD integration with default credentials, service principal, and Azure Key Vault support
- ๐พ Intelligent Caching: Cross-environment cache sharing with module-based version detection
- ๐ Async/Await: Modern async/await patterns with optimized session management
- ๐ Type Hints: Full type annotation support with enhanced data models
- ๐ค MCP Server: Production-ready Model Context Protocol server with 49 tools and 4 resource types
- ๐ฅ๏ธ Comprehensive CLI: Hierarchical command-line interface for all D365 F&O operations
- ๐งช Multi-tier Testing: Mock, sandbox, and live integration testing framework (17/17 tests passing)
- ๐ Metadata Scripts: PowerShell and Python utilities for entity, enumeration, and action discovery
- ๐ Enhanced Credential Management: Support for Azure Key Vault and multiple credential sources
- ๐ Advanced Sync Management: Session-based synchronization with detailed progress tracking
- ๐ง NEW v0.3.0: Pydantic settings model with type-safe environment variable validation
- ๐ NEW v0.3.0: Custom log file path support and flexible logging configuration
- ๐ NEW v0.3.0: Automatic legacy configuration migration and compatibility layer
๐ป Usage Examples
Basic Tool Execution
{
"tool": "d365fo_query_entities",
"arguments": {
"entityName": "CustomersV3",
"select": ["CustomerAccount", "Name", "Email"],
"filter": "CustomerGroup eq 'VIP'",
"top": 10
}
}
Entity Schema Discovery
{
"tool": "d365fo_get_entity_schema",
"arguments": {
"entityName": "CustomersV3",
"includeProperties": true,
"resolveLabels": true,
"language": "en-US"
}
}
Environment Information
{
"tool": "d365fo_get_environment_info",
"arguments": {}
}
Web Integration with FastMCP
HTTP Transport for Web APIs
import aiohttp
import json
async def call_d365fo_api():
"""Example: Using HTTP transport for web API integration"""
mcp_request = {
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "d365fo_query_entities",
"arguments": {
"entityName": "CustomersV3",
"top": 10,
"select": ["CustomerAccount", "Name"]
}
}
}
async with aiohttp.ClientSession() as session:
async with session.post(
"http://localhost:8000/mcp",
json=mcp_request,
headers={"Content-Type": "application/json"}
) as response:
result = await response.json()
print(json.dumps(result, indent=2))
SSE Transport for Real-time Applications
const eventSource = new EventSource('http://localhost:8001/sse');
eventSource.onmessage = function(event) {
const data = JSON.parse(event.data);
console.log('Received D365FO data:', data);
if (data.method === 'notification') {
updateDashboard(data.params);
}
};
function queryCustomers() {
const request = {
jsonrpc: "2.0",
id: Date.now(),
method: "tools/call",
params: {
name: "d365fo_search_entities",
arguments: {
pattern: "customer",
limit: 50
}
}
};
fetch('http://localhost:8001/sse/send', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(request)
});
}
Python Client Basic Usage
import asyncio
from d365fo_client import D365FOClient, FOClientConfig
async def main():
config = FOClientConfig(
base_url="https://your-fo-environment.dynamics.com",
use_default_credentials=True
)
async with D365FOClient(config) as client:
if await client.test_connection():
print("โ
Connected successfully!")
env_info = await client.get_environment_info()
print(f"Environment: {env_info.application_version}")
customer_entities = await client.search_entities("customer")
print(f"Found {len(customer_entities)} customer entities")
from d365fo_client import QueryOptions
options = QueryOptions(
select=["CustomerAccount", "Name", "SalesCurrencyCode"],
top=10,
orderby=["Name"]
)
customers = await client.get_data("/data/CustomersV3", options)
print(f"Retrieved {len(customers['value'])} customers")
if __name__ == "__main__":
asyncio.run(main())
๐ Documentation
MCP Tools Documentation
For detailed information about all MCP tools including usage examples and best practices, see the Comprehensive MCP Tools Introduction.
AI Agent Guide
For AI agents and assistants, see the AI Agent Guide for structured workflows, best practices, and automation patterns.
๐ง Technical Details
Architecture Benefits
For AI Assistants
- Standardized Interface: Consistent MCP protocol access to D365 F&O
- Rich Metadata: Self-describing entities and operations
- Type Safety: Schema validation for all operations
- Error Context: Detailed error information for troubleshooting
For Developers
- Minimal Integration: Standard MCP client libraries
- Comprehensive Coverage: Full D365 F&O functionality exposed
- Performance Optimized: Efficient connection and caching strategies
- Well Documented: Complete API documentation and examples
For Organizations
- Secure Access: Enterprise-grade authentication (Azure AD, Managed Identity)
- Audit Logging: Complete operation tracking and monitoring
- Scalable Design: Connection pooling and session management
- Maintenance Friendly: Clear architecture and comprehensive test coverage
Configuration Options
| Option |
Type |
Default |
Description |
base_url |
str |
Required |
D365 F&O base URL |
client_id |
str |
None |
Azure AD client ID |
client_secret |
str |
None |
Azure AD client secret |
tenant_id |
str |
None |
Azure AD tenant ID |
use_default_credentials |
bool |
True |
Use Azure Default Credential |
credential_source |
str |
"environment" |
Credential source: "environment", "keyvault" |
keyvault_url |
str |
None |
Azure Key Vault URL for credential storage |
verify_ssl |
bool |
False |
Verify SSL certificates |
timeout |
int |
30 |
Request timeout in seconds |
metadata_cache_dir |
str |
Platform-specific user cache |
Metadata cache directory |
use_label_cache |
bool |
True |
Enable label caching V2 |
label_cache_expiry_minutes |
int |
60 |
Label cache expiry time |
use_cache_first |
bool |
False |
Enable cache-first mode with background sync |
Cache Directory Behavior
By default, the client uses platform-appropriate user cache directories:
- Windows:
%LOCALAPPDATA%\d365fo-client (e.g., C:\Users\username\AppData\Local\d365fo-client)
- macOS:
~/Library/Caches/d365fo-client (e.g., /Users/username/Library/Caches/d365fo-client)
- Linux:
~/.cache/d365fo-client (e.g., /home/username/.cache/d365fo-client)
You can override this by explicitly setting metadata_cache_dir:
from d365fo_client import FOClientConfig
config = FOClientConfig(
base_url="https://your-fo-environment.dynamics.com",
metadata_cache_dir="/custom/cache/path"
)
from d365fo_client import get_user_cache_dir
cache_dir = get_user_cache_dir("my-app")
config = FOClientConfig(
base_url="https://your-fo-environment.dynamics.com",
metadata_cache_dir=str(cache_dir)
)
๐ฆ Installation
Install the Python Client Library
pip install d365fo-client
git clone https://github.com/mafzaal/d365fo-client.git
cd d365fo-client
uv sync
docker pull ghcr.io/mafzaal/d365fo-client:latest
docker run --rm -it \
-e D365FO_BASE_URL="https://your-environment.dynamics.com" \
-e D365FO_CLIENT_ID="your-client-id" \
-e D365FO_CLIENT_SECRET="your-client-secret" \
-e D365FO_TENANT_ID="your-tenant-id" \
-v d365fo-mcp:/home/mcp_user/ \
ghcr.io/mafzaal/d365fo-client:latest
Breaking Change in v0.2.3
AZURE_CLIENT_ID โ D365FO_CLIENT_ID
AZURE_CLIENT_SECRET โ D365FO_CLIENT_SECRET
AZURE_TENANT_ID โ D365FO_TENANT_ID
Please update your environment variables accordingly when upgrading.
๐ License
This project is licensed under the MIT License - see the LICENSE file for details.
๐ Changelog
See CHANGELOG.md for a list of changes and version history.
๐ ๏ธ Support
๐ Related Projects