Microsoft Dynamics 365 Finance & Operations client
Project description
Dynamics 365 Finance & Operations Client and MCP Server
A comprehensive Python client library and MCP server for Microsoft Dynamics 365 Finance & Operations (D365 F&O) that provides easy access to OData endpoints, metadata operations, label management, and AI assistant integration.
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
- ๐ Authentication: Azure AD integration with default credentials and service principal 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 12 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
Installation
# Install from PyPI
pip install d365fo-client
# Or install from source
git clone https://github.com/mafzaal/d365fo-client.git
cd d365fo-client
uv sync # Installs with exact dependencies from uv.lock
Note: The package includes MCP (Model Context Protocol) dependencies by default, enabling AI assistant integration. Both d365fo-client CLI and d365fo-mcp-server commands will be available after installation.
Quick Start
Command Line Interface (CLI)
d365fo-client provides a comprehensive CLI with hierarchical commands for interacting with Dynamics 365 Finance & Operations APIs and metadata. The CLI supports all major operations including entity management, metadata discovery, and system administration.
Usage
# Use the installed CLI command
d365fo-client [GLOBAL_OPTIONS] COMMAND [SUBCOMMAND] [OPTIONS]
# Alternative: Module execution
python -m d365fo_client.main [OPTIONS] COMMAND [ARGS]
Command Categories
Entity Operations
# List entities with filtering
d365fo-client entities list --pattern "customer" --limit 10
# Get entity details and schema
d365fo-client entities get CustomersV3 --properties --keys --labels
# CRUD operations
d365fo-client entities create Customers --data '{"CustomerAccount":"US-999","Name":"Test"}'
d365fo-client entities update Customers US-999 --data '{"Name":"Updated Name"}'
d365fo-client entities delete Customers US-999
Metadata Operations
# Search and discover entities
d365fo-client metadata entities --search "sales" --output json
# Get available actions
d365fo-client metadata actions --pattern "calculate" --limit 5
# Enumerate system enumerations
d365fo-client metadata enums --search "status" --output table
# Synchronize metadata cache
d365fo-client metadata sync --force-refresh
Version Information
# Get application versions
d365fo-client version app
d365fo-client version platform
d365fo-client version build
Label Operations
# Resolve single label
d365fo-client labels resolve "@SYS13342"
# Search labels by pattern
d365fo-client labels search "customer" --language "en-US"
Global Options
--base-url URLโ Specify D365 F&O environment URL--profile NAMEโ Use named configuration profile--output FORMATโ Output format: json, table, csv, yaml (default: table)--verboseโ Enable verbose output for debugging--timeout SECONDSโ Request timeout (default: 30)
Configuration Profiles
Create reusable configurations in ~/.d365fo-client/config.yaml:
profiles:
production:
base_url: "https://prod.dynamics.com"
use_default_credentials: true
timeout: 60
development:
base_url: "https://dev.dynamics.com"
client_id: "${AZURE_CLIENT_ID}"
client_secret: "${AZURE_CLIENT_SECRET}"
tenant_id: "${AZURE_TENANT_ID}"
use_cache_first: true
default_profile: "development"
Examples
# Quick entity discovery
d365fo-client entities list --pattern "cust.*" --output json
# Get comprehensive entity information
d365fo-client entities get CustomersV3 --properties --keys --labels --output yaml
# Search for calculation actions
d365fo-client metadata actions --pattern "calculate|compute" --output table
# Test environment connectivity
d365fo-client version app --verbose
For a complete command reference:
d365fo-client --help
d365fo-client entities --help
d365fo-client metadata --help
Basic Usage
import asyncio
from d365fo_client import D365FOClient, FOClientConfig
async def main():
# Simple configuration with default credentials
config = FOClientConfig(
base_url="https://your-fo-environment.dynamics.com",
use_default_credentials=True # Uses Azure Default Credential
)
async with D365FOClient(config) as client:
# Test connection
if await client.test_connection():
print("โ
Connected successfully!")
# Get environment information
env_info = await client.get_environment_info()
print(f"Environment: {env_info.application_version}")
# Search for entities (uses metadata cache v2)
customer_entities = await client.search_entities("customer")
print(f"Found {len(customer_entities)} customer entities")
# Get customers with query options
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())
Using Convenience Function
from d365fo_client import create_client
# Quick client creation with enhanced defaults
async with create_client("https://your-fo-environment.dynamics.com") as client:
customers = await client.get_data("/data/CustomersV3", top=5)
Configuration
Authentication Options
from d365fo_client import FOClientConfig
# Option 1: Default Azure credentials (recommended)
config = FOClientConfig(
base_url="https://your-fo-environment.dynamics.com",
use_default_credentials=True
)
# Option 2: Client credentials
config = FOClientConfig(
base_url="https://your-fo-environment.dynamics.com",
client_id="your-client-id",
client_secret="your-client-secret",
tenant_id="your-tenant-id",
use_default_credentials=False
)
# Option 3: With custom settings
config = FOClientConfig(
base_url="https://your-fo-environment.dynamics.com",
use_default_credentials=True,
verify_ssl=False, # For development environments
timeout=60, # Request timeout in seconds
metadata_cache_dir="./my_cache", # Custom cache directory
use_label_cache=True, # Enable label caching
label_cache_expiry_minutes=120 # Cache for 2 hours
)
Core Operations
CRUD Operations
async with D365FOClient(config) as client:
# CREATE - Create new customer (supports composite keys)
new_customer = {
"CustomerAccount": "US-999",
"Name": "Test Customer",
"SalesCurrencyCode": "USD"
}
created = await client.create_data("/data/CustomersV3", new_customer)
# READ - Get single customer by key
customer = await client.get_data("/data/CustomersV3('US-001')")
# UPDATE - Update customer with optimistic concurrency
updates = {"Name": "Updated Customer Name"}
updated = await client.update_data("/data/CustomersV3('US-001')", updates)
# DELETE - Delete customer
success = await client.delete_data("/data/CustomersV3('US-999')")
print(f"Delete successful: {success}")
Advanced Querying
from d365fo_client import QueryOptions
# Complex query with multiple options
options = QueryOptions(
select=["CustomerAccount", "Name", "SalesCurrencyCode", "CustomerGroupId"],
filter="SalesCurrencyCode eq 'USD' and contains(Name, 'Corp')",
expand=["CustomerGroup"],
orderby=["Name desc", "CustomerAccount"],
top=50,
skip=10,
count=True
)
result = await client.get_data("/data/CustomersV3", options)
print(f"Total count: {result.get('@odata.count')}")
Action Execution
# Unbound action
result = await client.post_data("/data/calculateTax", {
"amount": 1000.00,
"taxGroup": "STANDARD"
})
# Bound action on entity set
result = await client.post_data("/data/CustomersV3/calculateBalances", {
"asOfDate": "2024-12-31"
})
# Bound action on specific entity instance
result = await client.post_data("/data/CustomersV3('US-001')/calculateBalance", {
"asOfDate": "2024-12-31"
})
Metadata Operations
# Intelligent metadata synchronization (v2 system)
sync_manager = await client.get_sync_manager()
await sync_manager.smart_sync()
# Search entities with enhanced filtering
sales_entities = await client.search_entities("sales")
print("Sales-related entities:", [e.name for e in sales_entities])
# Get detailed entity information with labels
entity_info = await client.get_public_entity_info("CustomersV3")
if entity_info:
print(f"Entity: {entity_info.name}")
print(f"Label: {entity_info.label_text}")
print(f"Data Service Enabled: {entity_info.data_service_enabled}")
# Search actions with caching
calc_actions = await client.search_actions("calculate")
print("Calculation actions:", [a.name for a in calc_actions])
# Get enumeration information
enum_info = await client.get_public_enumeration_info("NoYes")
if enum_info:
print(f"Enum: {enum_info.name}")
for member in enum_info.members:
print(f" {member.name} = {member.value}")
Label Operations
# Get specific label (v2 caching system)
label_text = await client.get_label_text("@SYS13342")
print(f"Label text: {label_text}")
# Get multiple labels efficiently
labels = await client.get_labels_batch([
"@SYS13342", "@SYS9490", "@GLS63332"
])
for label_id, text in labels.items():
print(f"{label_id}: {text}")
# Enhanced entity info with resolved labels
entity_info = await client.get_public_entity_info_with_labels("CustomersV3")
if entity_info.label_text:
print(f"Entity display name: {entity_info.label_text}")
# Access enhanced properties with labels
for prop in entity_info.enhanced_properties[:5]:
if hasattr(prop, 'label_text') and prop.label_text:
print(f"{prop.name}: {prop.label_text}")
Error Handling
from d365fo_client import D365FOClientError, AuthenticationError, ConnectionError
try:
async with D365FOClient(config) as client:
customer = await client.get_data("/data/CustomersV3('NON-EXISTENT')")
except ConnectionError as e:
print(f"Connection failed: {e}")
except AuthenticationError as e:
print(f"Authentication failed: {e}")
except D365FOClientError as e:
print(f"Client operation failed: {e}")
print(f"Status code: {e.status_code}")
print(f"Response: {e.response_text}")
Development
Setting up Development Environment
# Clone the repository
git clone https://github.com/mafzaal/d365fo-client.git
cd d365fo-client
# Install with development dependencies using uv
uv sync --dev
# Run tests
uv run pytest
# Run integration tests
.\tests\integration\integration-test-simple.ps1 test-sandbox
# Format code
uv run black .
uv run isort .
# Type checking
uv run mypy src/
# Quality checks
.\make.ps1 quality-check # Windows PowerShell
# or
make quality-check # Unix/Linux/macOS
Project Structure
d365fo-client/
โโโ src/
โ โโโ d365fo_client/
โ โโโ __init__.py # Public API exports
โ โโโ main.py # CLI entry point
โ โโโ cli.py # CLI command handlers
โ โโโ client.py # Enhanced D365FOClient class
โ โโโ config.py # Configuration management
โ โโโ auth.py # Authentication management
โ โโโ session.py # HTTP session management
โ โโโ crud.py # CRUD operations
โ โโโ query.py # OData query utilities
โ โโโ metadata.py # Legacy metadata operations
โ โโโ metadata_api.py # Metadata API client
โ โโโ metadata_cache.py # Metadata caching layer V2
โ โโโ metadata_sync.py # Metadata synchronization V2
โ โโโ labels.py # Label operations V2
โ โโโ profiles.py # Profile data models
โ โโโ profile_manager.py # Profile management
โ โโโ models.py # Data models and configurations
โ โโโ output.py # Output formatting
โ โโโ utils.py # Utility functions
โ โโโ exceptions.py # Custom exceptions
โ โโโ mcp/ # Model Context Protocol server
โ โโโ __init__.py # MCP server exports
โ โโโ main.py # MCP server entry point
โ โโโ server.py # Core MCP server implementation
โ โโโ client_manager.py# D365FO client connection pooling
โ โโโ models.py # MCP-specific data models
โ โโโ tools/ # MCP tool implementations (12 tools)
โ โ โโโ connection_tools.py
โ โ โโโ crud_tools.py
โ โ โโโ metadata_tools.py
โ โ โโโ label_tools.py
โ โโโ resources/ # MCP resource handlers (4 types)
โ โ โโโ entity_handler.py
โ โ โโโ metadata_handler.py
โ โ โโโ environment_handler.py
โ โ โโโ query_handler.py
โ โโโ prompts/ # MCP prompt templates
โโโ tests/ # Comprehensive test suite
โ โโโ unit/ # Unit tests (pytest-based)
โ โโโ integration/ # Multi-tier integration testing
โ โ โโโ mock_server/ # Mock D365 F&O API server
โ โ โโโ test_mock_server.py # Mock server tests
โ โ โโโ test_sandbox.py # Sandbox environment tests โ
โ โ โโโ test_live.py # Live environment tests
โ โ โโโ conftest.py # Shared pytest fixtures
โ โ โโโ test_runner.py # Python test execution engine
โ โ โโโ integration-test-simple.ps1 # PowerShell automation
โ โโโ test_mcp_server.py # MCP server unit tests โ
โโโ scripts/ # Metadata discovery scripts
โ โโโ search_data_entities.ps1 # PowerShell entity search
โ โโโ get_data_entity_schema.ps1 # PowerShell schema retrieval
โ โโโ search_enums.py # Python enumeration search
โ โโโ get_enumeration_info.py # Python enumeration info
โ โโโ search_actions.ps1 # PowerShell action search
โ โโโ get_action_info.py # Python action information
โโโ docs/ # Comprehensive documentation
โโโ pyproject.toml # Project configuration
โโโ README.md # This file
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 |
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
# Use custom cache directory
config = FOClientConfig(
base_url="https://your-fo-environment.dynamics.com",
metadata_cache_dir="/custom/cache/path"
)
# Or get the default cache directory programmatically
from d365fo_client import get_user_cache_dir
cache_dir = get_user_cache_dir("my-app") # Platform-appropriate cache dir
config = FOClientConfig(
base_url="https://your-fo-environment.dynamics.com",
metadata_cache_dir=str(cache_dir)
)
Testing
This project includes comprehensive testing at multiple levels to ensure reliability and quality.
Unit Tests
Run standard unit tests for core functionality:
# Run all unit tests
uv run pytest
# Run with coverage
uv run pytest --cov=d365fo_client --cov-report=html
# Run specific test file
uv run pytest tests/test_client.py -v
Integration Tests
The project includes a sophisticated multi-tier integration testing framework:
Quick Start
# Run sandbox integration tests (recommended)
.\tests\integration\integration-test-simple.ps1 test-sandbox
# Run mock server tests (no external dependencies)
.\tests\integration\integration-test-simple.ps1 test-mock
# Run with verbose output
.\tests\integration\integration-test-simple.ps1 test-sandbox -VerboseOutput
Test Levels
-
Mock Server Tests - Fast, isolated tests against a simulated D365 F&O API
- No external dependencies
- Complete API simulation
- Ideal for CI/CD pipelines
-
Sandbox Tests โญ (Default) - Tests against real D365 F&O test environments
- Validates authentication
- Tests real API behavior
- Requires test environment access
-
Live Tests - Optional tests against production environments
- Final validation
- Performance benchmarking
- Use with caution
Configuration
Set up integration testing with environment variables:
# Copy the template and configure
cp tests/integration/.env.template tests/integration/.env
# Edit .env file with your settings:
INTEGRATION_TEST_LEVEL=sandbox
D365FO_SANDBOX_BASE_URL=https://your-test.dynamics.com
AZURE_CLIENT_ID=your-client-id
AZURE_CLIENT_SECRET=your-client-secret
AZURE_TENANT_ID=your-tenant-id
Available Commands
# Test environment setup
.\tests\integration\integration-test-simple.ps1 setup
# Dependency checking
.\tests\integration\integration-test-simple.ps1 deps-check
# Run specific test levels
.\tests\integration\integration-test-simple.ps1 test-mock
.\tests\integration\integration-test-simple.ps1 test-sandbox
.\tests\integration\integration-test-simple.ps1 test-live
# Coverage and reporting
.\tests\integration\integration-test-simple.ps1 coverage
# Clean up test artifacts
.\tests\integration\integration-test-simple.ps1 clean
Test Coverage
Integration tests cover:
- โ Connection & Authentication - Azure AD integration, SSL/TLS validation
- โ Version Methods - Application, platform, and build version retrieval
- โ Metadata Operations - Entity discovery, metadata API validation
- โ Data Operations - CRUD operations, OData query validation
- โ Error Handling - Network failures, authentication errors, invalid requests
- โ Performance - Response time validation, concurrent operations
For detailed information, see Integration Testing Documentation.
Test Results
Recent sandbox integration test results:
โ
17 passed, 0 failed, 2 warnings in 37.67s
======================================================
โ
TestSandboxConnection::test_connection_success
โ
TestSandboxConnection::test_metadata_connection_success
โ
TestSandboxVersionMethods::test_get_application_version
โ
TestSandboxVersionMethods::test_get_platform_build_version
โ
TestSandboxVersionMethods::test_get_application_build_version
โ
TestSandboxVersionMethods::test_version_consistency
โ
TestSandboxMetadataOperations::test_download_metadata
โ
TestSandboxMetadataOperations::test_search_entities
โ
TestSandboxMetadataOperations::test_get_data_entities
โ
TestSandboxMetadataOperations::test_get_public_entities
โ
TestSandboxDataOperations::test_get_available_entities
โ
TestSandboxDataOperations::test_odata_query_options
โ
TestSandboxAuthentication::test_authenticated_requests
โ
TestSandboxErrorHandling::test_invalid_entity_error
โ
TestSandboxErrorHandling::test_invalid_action_error
โ
TestSandboxPerformance::test_response_times
โ
TestSandboxPerformance::test_concurrent_operations
Model Context Protocol (MCP) Server
d365fo-client includes a production-ready Model Context Protocol (MCP) server that exposes the full capabilities of the D365 Finance & Operations client to AI assistants and other MCP-compatible tools. This enables sophisticated Dynamics 365 integration workflows through standardized protocol interactions.
Overview
The MCP server provides:
- 12 functional tools covering all major D365 F&O operations
- 4 resource types with comprehensive metadata exposure
- Production-ready implementation with proper error handling and authentication
- Performance optimization with connection pooling and intelligent caching V2
- Comprehensive testing with 14 unit tests (100% pass rate)
- Profile support for multi-environment configurations
Quick Start
Installation and Setup
# Install d365fo-client with MCP dependencies
pip install d365fo-client
# Set up environment variables
export D365FO_BASE_URL="https://your-environment.dynamics.com"
export AZURE_CLIENT_ID="your-client-id" # Optional with default credentials
export AZURE_CLIENT_SECRET="your-client-secret" # Optional with default credentials
export AZURE_TENANT_ID="your-tenant-id" # Optional with default credentials
# Start the MCP server
d365fo-mcp-server
Alternative: Programmatic Usage
from d365fo_client.mcp import D365FOMCPServer
# Create and run server with custom configuration
config = {
"default_environment": {
"base_url": "https://your-environment.dynamics.com",
"use_default_credentials": True
}
}
server = D365FOMCPServer(config)
await server.run()
MCP Tools
The server provides 12 comprehensive tools organized into functional categories:
Connection Tools (2 tools)
d365fo_test_connection- Test environment connectivity and healthd365fo_get_environment_info- Get comprehensive environment details, versions, and statistics
CRUD Operations (5 tools)
d365fo_query_entities- Advanced OData querying with filters, selections, and paginationd365fo_get_entity_record- Retrieve specific records by key with expansion optionsd365fo_create_entity_record- Create new entity records with validationd365fo_update_entity_record- Update existing records with optimistic concurrencyd365fo_delete_entity_record- Delete entity records with conflict detection
Metadata Tools (5 tools)
d365fo_search_entities- Search entities by pattern with advanced filtering and FTS5 searchd365fo_get_entity_schema- Get detailed entity schemas with properties and relationshipsd365fo_search_actions- Search available OData actions and functionsd365fo_search_enums- Search system enumerations with filteringd365fo_get_enum_info- Get detailed enumeration information and values
Label Tools (2 tools)
d365fo_get_label- Get single label text by ID with language supportd365fo_get_labels_batch- Get multiple labels efficiently in batch operations
MCP Resources
The server exposes four types of resources for discovery and access:
Entity Resources
Access entity metadata and sample data:
d365fo://entities/CustomersV3 # Customer entity with metadata and sample data
d365fo://entities/SalesOrders # Sales order entity information
d365fo://entities/Products # Product entity details
Metadata Resources
Access system-wide metadata:
d365fo://metadata/entities # All data entities metadata (V2 cache)
d365fo://metadata/actions # Available OData actions
d365fo://metadata/enumerations # System enumerations
d365fo://metadata/labels # System labels and translations
Environment Resources
Access environment status and information:
d365fo://environment/status # Environment health and connectivity
d365fo://environment/version # Version information (app, platform, build)
d365fo://environment/cache # Cache status and statistics V2
Query Resources
Access predefined and templated queries:
d365fo://queries/customers_recent # Recent customers query template
d365fo://queries/sales_summary # Sales summary query with parameters
Database Resources (New in V2)
Access metadata database queries:
d365fo://database/entities # SQL-based entity searches with FTS5
d365fo://database/actions # Action discovery with metadata
d365fo://database/statistics # Cache and performance statistics
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": {}
}
Authentication & Configuration
Default Credentials (Recommended)
Uses Azure Default Credential chain (Managed Identity, Azure CLI, etc.):
export D365FO_BASE_URL="https://your-environment.dynamics.com"
# No additional auth environment variables needed
d365fo-mcp-server
Explicit Credentials
For service principal authentication:
export D365FO_BASE_URL="https://your-environment.dynamics.com"
export AZURE_CLIENT_ID="your-client-id"
export AZURE_CLIENT_SECRET="your-client-secret"
export AZURE_TENANT_ID="your-tenant-id"
d365fo-mcp-server
Advanced Configuration
Create a configuration file or set additional environment variables:
# Optional: Logging configuration
export D365FO_LOG_LEVEL="DEBUG"
# Optional: Cache settings
export D365FO_CACHE_DIR="/custom/cache/path"
# Optional: Performance tuning
export D365FO_CONNECTION_TIMEOUT="60"
export D365FO_MAX_CONCURRENT_REQUESTS="10"
Integration with AI Assistants
The MCP server seamlessly integrates with AI assistants and development tools:
Claude Desktop Integration
Add to your Claude Desktop configuration:
{
"mcpServers": {
"d365fo": {
"command": "d365fo-mcp-server",
"env": {
"D365FO_BASE_URL": "https://your-environment.dynamics.com" //Optional
}
}
}
}
VS Code Integration
Option 1: Default Credentials (Recommended)
Add to your VS Code mcp.json for GitHub Copilot with MCP:
{
"servers": {
"d365fo-mcp-server": {
"type": "stdio",
"command": "uvx",
"args": [
"--from",
"d365fo-client",
"d365fo-mcp-server"
],
"env": {
"D365FO_BASE_URL": "https://your-environment.dynamics.com",
"D365FO_LOG_LEVEL": "INFO"
}
}
}
}
Option 2: Explicit Credentials
For environments requiring service principal authentication:
{
"servers": {
"d365fo-mcp-server": {
"type": "stdio",
"command": "uvx",
"args": [
"--from",
"d365fo-client",
"d365fo-mcp-server"
],
"env": {
"D365FO_BASE_URL": "https://your-environment.dynamics.com",
"D365FO_LOG_LEVEL": "DEBUG",
"D365FO_CLIENT_ID": "${input:client_id}",
"D365FO_CLIENT_SECRET": "${input:client_secret}",
"D365FO_TENANT_ID": "${input:tenant_id}"
}
}
},
"inputs": [
{
"id": "tenant_id",
"type": "promptString",
"description": "Azure AD Tenant ID for D365 F&O authentication",
"password": true
},
{
"id": "client_id",
"type": "promptString",
"description": "Azure AD Client ID for D365 F&O authentication",
"password": true
},
{
"id": "client_secret",
"type": "promptString",
"description": "Azure AD Client Secret for D365 F&O authentication",
"password": true
}
]
}
Benefits of uvx approach:
- Always uses the latest version from the repository
- No local installation required
- Automatic dependency management
- Works across different environments
Custom MCP Clients
Connect using any MCP-compatible client library:
from mcp import Client
async with Client("d365fo-mcp-server") as client:
# Discover available tools
tools = await client.list_tools()
# Execute operations
result = await client.call_tool(
"d365fo_query_entities",
{"entityName": "Customers", "top": 5}
)
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
Troubleshooting
Common Issues
Connection Failures
# Test connectivity
d365fo-client get-version --base-url https://your-environment.dynamics.com
# Check logs
tail -f ~/.d365fo-mcp/logs/mcp-server.log
Authentication Issues
# Verify Azure CLI authentication
az account show
# Test with explicit credentials
export AZURE_CLIENT_ID="your-client-id"
# ... set other variables
d365fo-mcp-server
Performance Issues
# Enable debug logging
export D365FO_LOG_LEVEL="DEBUG"
# Adjust connection settings
export D365FO_CONNECTION_TIMEOUT="120"
export D365FO_MAX_CONCURRENT_REQUESTS="5"
Getting Help
- Logs: Check
~/.d365fo-mcp/logs/mcp-server.logfor detailed error information - Environment: Use
d365fo_get_environment_infotool to check system status - Documentation: See MCP Implementation Summary for technical details
- Issues: Report problems at GitHub Issues
Contributing
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes
- Run tests (
uv run pytest) - Run integration tests (
.\tests\integration\integration-test-simple.ps1 test-sandbox) - Format code (
uv run black . && uv run isort .) - Commit changes (
git commit -m 'Add amazing feature') - Push to branch (
git push origin feature/amazing-feature) - Open a Pull Request
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
- ๐ง Email: mo@thedataguy.pro
- ๐ Issues: GitHub Issues
Related Projects
- Microsoft Dynamics 365
- OData
- Azure Identity
- Model Context Protocol (MCP) - For AI assistant integration
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file d365fo_client-0.2.1.tar.gz.
File metadata
- Download URL: d365fo_client-0.2.1.tar.gz
- Upload date:
- Size: 152.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
19ae83abea8b8c10eadd1443c51dfe3eaacc98e2e3254cd7167c5b626e6e80d9
|
|
| MD5 |
f41f9022f6ff53a608e36b7fcf8d0062
|
|
| BLAKE2b-256 |
a6129c1d639b3f670740f54cd472fd9896eb672430d145533db384dc6b753736
|
Provenance
The following attestation bundles were made for d365fo_client-0.2.1.tar.gz:
Publisher:
publish.yml on mafzaal/d365fo-client
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
d365fo_client-0.2.1.tar.gz -
Subject digest:
19ae83abea8b8c10eadd1443c51dfe3eaacc98e2e3254cd7167c5b626e6e80d9 - Sigstore transparency entry: 428236058
- Sigstore integration time:
-
Permalink:
mafzaal/d365fo-client@4dbbcf6c4f3e009ebb45579a80c04c2762c7f052 -
Branch / Tag:
refs/tags/v0.2.1 - Owner: https://github.com/mafzaal
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@4dbbcf6c4f3e009ebb45579a80c04c2762c7f052 -
Trigger Event:
release
-
Statement type:
File details
Details for the file d365fo_client-0.2.1-py3-none-any.whl.
File metadata
- Download URL: d365fo_client-0.2.1-py3-none-any.whl
- Upload date:
- Size: 157.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
efb0384aa1381289626a8e48f5a8307a989829798733b73105e8e83bd4641504
|
|
| MD5 |
d140cd659a259856a317e831db3ace81
|
|
| BLAKE2b-256 |
4133036239bd42b5eda520f56d91103a45ebef1ef7a6ba25084ee34c2ba12a5c
|
Provenance
The following attestation bundles were made for d365fo_client-0.2.1-py3-none-any.whl:
Publisher:
publish.yml on mafzaal/d365fo-client
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
d365fo_client-0.2.1-py3-none-any.whl -
Subject digest:
efb0384aa1381289626a8e48f5a8307a989829798733b73105e8e83bd4641504 - Sigstore transparency entry: 428236078
- Sigstore integration time:
-
Permalink:
mafzaal/d365fo-client@4dbbcf6c4f3e009ebb45579a80c04c2762c7f052 -
Branch / Tag:
refs/tags/v0.2.1 - Owner: https://github.com/mafzaal
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@4dbbcf6c4f3e009ebb45579a80c04c2762c7f052 -
Trigger Event:
release
-
Statement type: