{
  "markdown": "# Dynamics 365 Finance & Operations MCP Server\n\n<div align=\"center\">\n  <img src=\"logo.png\" alt=\"D365FO MCP Server Logo\" width=\"200\" />\n  <br />\n  <br />\n</div>\n\n<!-- mcp-name: io.github.mafzaal/d365fo-client -->\n\n**Production-ready Model Context Protocol (MCP) server** that exposes the full capabilities of Microsoft Dynamics 365 Finance & Operations (D365 F&O) to AI assistants and other MCP-compatible tools. This enables sophisticated Dynamics 365 integration workflows through standardized protocol interactions.\n\n[![GitHub watchers](https://img.shields.io/github/watchers/mafzaal/d365fo-client.svg?style=social&label=Watch)](https://github.com/mafzaal/d365fo-client/watchers)\n[![GitHub forks](https://img.shields.io/github/forks/mafzaal/d365fo-client.svg?style=social&label=Fork)](https://github.com/mafzaal/d365fo-client/fork)\n[![GitHub stars](https://img.shields.io/github/stars/mafzaal/d365fo-client?style=social&label=Star)](https://github.com/mafzaal/d365fo-client/stargazers)\n\n\n**🚀 One-Click Installation for VS Code:**\n\n[![Install with UVX in VS Code](https://img.shields.io/badge/VS_Code-Install_D365_FO_MCP_Server-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white)](https://vscode.dev/redirect/mcp/install?name=d365fo&config=%7B%22type%22%3A%22stdio%22%2C%22command%22%3A%22uvx%22%2C%22args%22%3A%5B%22--from%22%2C%22d365fo-client%40latest%22%2C%22d365fo-fastmcp-server%22%5D%2C%22env%22%3A%7B%22D365FO_CLIENT_ID%22%3A%22%24%7Binput%3Aclient_id%7D%22%2C%22D365FO_CLIENT_SECRET%22%3A%22%24%7Binput%3Aclient_secret%7D%22%2C%22D365FO_TENANT_ID%22%3A%22%24%7Binput%3Atenant_id%7D%22%7D%7D&inputs=%5B%7B%22id%22%3A%22tenant_id%22%2C%22type%22%3A%22promptString%22%2C%22description%22%3A%22The%20ID%20of%20the%20tenant%20to%20connect%20to%22%2C%22password%22%3Atrue%7D%2C%7B%22id%22%3A%22client_id%22%2C%22type%22%3A%22promptString%22%2C%22description%22%3A%22The%20ID%20of%20the%20client%20to%20connect%20to%22%2C%22password%22%3Atrue%7D%2C%7B%22id%22%3A%22client_secret%22%2C%22type%22%3A%22promptString%22%2C%22description%22%3A%22The%20secret%20of%20the%20client%20to%20connect%20to%22%2C%22password%22%3Atrue%7D%5D)\n[![Install with UVX in VS Code Insiders](https://img.shields.io/badge/VS_Code_Insiders-Install_D365_FO_MCP_Server-24bfa5?style=flat-square&logo=visualstudiocode&logoColor=white)](https://insiders.vscode.dev/redirect/mcp/install?name=d365fo&quality=insiders&config=%7B%22type%22%3A%22stdio%22%2C%22command%22%3A%22uvx%22%2C%22args%22%3A%5B%22--from%22%2C%22d365fo-client%40latest%22%2C%22d365fo-fastmcp-server%22%5D%2C%22env%22%3A%7B%22D365FO_CLIENT_ID%22%3A%22%24%7Binput%3Aclient_id%7D%22%2C%22D365FO_CLIENT_SECRET%22%3A%22%24%7Binput%3Aclient_secret%7D%22%2C%22D365FO_TENANT_ID%22%3A%22%24%7Binput%3Atenant_id%7D%22%7D%7D&inputs=%5B%7B%22id%22%3A%22tenant_id%22%2C%22type%22%3A%22promptString%22%2C%22description%22%3A%22The%20ID%20of%20the%20tenant%20to%20connect%20to%22%2C%22password%22%3Atrue%7D%2C%7B%22id%22%3A%22client_id%22%2C%22type%22%3A%22promptString%22%2C%22description%22%3A%22The%20ID%20of%20the%20client%20to%20connect%20to%22%2C%22password%22%3Atrue%7D%2C%7B%22id%22%3A%22client_secret%22%2C%22type%22%3A%22promptString%22%2C%22description%22%3A%22The%20secret%20of%20the%20client%20to%20connect%20to%22%2C%22password%22%3Atrue%7D%5D)\n\n**🐳 Docker Installation for VS Code:**\n\n[![Install with Docker in VS Code](https://img.shields.io/badge/VS_Code-Install_D365_FO_MCP_Server_(Docker)-2496ED?style=flat-square&logo=docker&logoColor=white)](https://vscode.dev/redirect/mcp/install?name=d365fo-docker&config=%7B%22type%22%3A%22stdio%22%2C%22command%22%3A%22docker%22%2C%22args%22%3A%5B%22run%22%2C%22--rm%22%2C%22-i%22%2C%22-v%22%2C%22d365fo-mcp%3A%2Fhome%2Fmcp_user%2F%22%2C%22-e%22%2C%22D365FO_CLIENT_ID%3D%24%7Binput%3Aclient_id%7D%22%2C%22-e%22%2C%22D365FO_CLIENT_SECRET%3D%24%7Binput%3Aclient_secret%7D%22%2C%22-e%22%2C%22D365FO_TENANT_ID%3D%24%7Binput%3Atenant_id%7D%22%2C%22ghcr.io%2Fmafzaal%2Fd365fo-client%3Alatest%22%5D%2C%22env%22%3A%7B%22D365FO_LOG_LEVEL%22%3A%22DEBUG%22%2C%22D365FO_CLIENT_ID%22%3A%22%24%7Binput%3Aclient_id%7D%22%2C%22D365FO_CLIENT_SECRET%22%3A%22%24%7Binput%3Aclient_secret%7D%22%2C%22D365FO_TENANT_ID%22%3A%22%24%7Binput%3Atenant_id%7D%22%7D%7D&inputs=%5B%7B%22id%22%3A%22tenant_id%22%2C%22type%22%3A%22promptString%22%2C%22description%22%3A%22Azure%20AD%20Tenant%20ID%20for%20D365%20F%26O%20authentication%22%2C%22password%22%3Atrue%7D%2C%7B%22id%22%3A%22client_id%22%2C%22type%22%3A%22promptString%22%2C%22description%22%3A%22Azure%20AD%20Client%20ID%20for%20D365%20F%26O%20authentication%22%2C%22password%22%3Atrue%7D%2C%7B%22id%22%3A%22client_secret%22%2C%22type%22%3A%22promptString%22%2C%22description%22%3A%22Azure%20AD%20Client%20Secret%20for%20D365%20F%26O%20authentication%22%2C%22password%22%3Atrue%7D%5D)\n[![Install with Docker in VS Code Insiders](https://img.shields.io/badge/VS_Code_Insiders-Install_D365_FO_MCP_Server_(Docker)-24bfa5?style=flat-square&logo=docker&logoColor=white)](https://insiders.vscode.dev/redirect/mcp/install?name=d365fo-docker&quality=insiders&config=%7B%22type%22%3A%22stdio%22%2C%22command%22%3A%22docker%22%2C%22args%22%3A%5B%22run%22%2C%22--rm%22%2C%22-i%22%2C%22-v%22%2C%22d365fo-mcp%3A%2Fhome%2Fmcp_user%2F%22%2C%22-e%22%2C%22D365FO_CLIENT_ID%3D%24%7Binput%3Aclient_id%7D%22%2C%22-e%22%2C%22D365FO_CLIENT_SECRET%3D%24%7Binput%3Aclient_secret%7D%22%2C%22-e%22%2C%22D365FO_TENANT_ID%3D%24%7Binput%3Atenant_id%7D%22%2C%22ghcr.io%2Fmafzaal%2Fd365fo-client%3Alatest%22%5D%2C%22env%22%3A%7B%22D365FO_LOG_LEVEL%22%3A%22DEBUG%22%2C%22D365FO_CLIENT_ID%22%3A%22%24%7Binput%3Aclient_id%7D%22%2C%22D365FO_CLIENT_SECRET%22%3A%22%24%7Binput%3Aclient_secret%7D%22%2C%22D365FO_TENANT_ID%22%3A%22%24%7Binput%3Atenant_id%7D%22%7D%7D&inputs=%5B%7B%22id%22%3A%22tenant_id%22%2C%22type%22%3A%22promptString%22%2C%22description%22%3A%22Azure%20AD%20Tenant%20ID%20for%20D365%20F%26O%20authentication%22%2C%22password%22%3Atrue%7D%2C%7B%22id%22%3A%22client_id%22%2C%22type%22%3A%22promptString%22%2C%22description%22%3A%22Azure%20AD%20Client%20ID%20for%20D365%20F%26O%20authentication%22%2C%22password%22%3Atrue%7D%2C%7B%22id%22%3A%22client_secret%22%2C%22type%22%3A%22promptString%22%2C%22description%22%3A%22Azure%20AD%20Client%20Secret%20for%20D365%20F%26O%20authentication%22%2C%22password%22%3Atrue%7D%5D)\n\n**☁️ Deploy to Azure Container Apps:**\n\nDeploy the MCP server as a secure, internet-accessible HTTP endpoint with OAuth or API Key authentication. Perfect for web integrations and remote AI assistant access.\n\n**Option 1: Using Bash Script (Recommended)**\n```bash\n# Download and run the deployment script\ncurl -O https://raw.githubusercontent.com/mafzaal/d365fo-client/main/deploy-aca.sh\nchmod +x deploy-aca.sh\n\n# Set authentication (choose OAuth or API Key)\nexport D365FO_MCP_AUTH_CLIENT_ID=\"your-client-id\"\nexport D365FO_MCP_AUTH_CLIENT_SECRET=\"your-client-secret\"\nexport D365FO_MCP_AUTH_TENANT_ID=\"your-tenant-id\"\n# OR\nexport D365FO_MCP_API_KEY_VALUE=\"your-secret-key\"\n\n# Deploy\n./deploy-aca.sh\n```\n\n**Option 2: Using ARM Template**\n1. Download [azure-deploy.json](https://raw.githubusercontent.com/mafzaal/d365fo-client/main/azure-deploy.json)\n2. Go to [Azure Portal → Deploy a custom template](https://portal.azure.com/#create/Microsoft.Template)\n3. Click \"Build your own template in the editor\"\n4. Paste the contents of `azure-deploy.json`\n5. Fill in the parameters and deploy\n\n[![PyPI - Downloads](https://img.shields.io/pypi/dm/d365fo-client?label=Downloads)](https://pypi.org/project/d365fo-client/)\n\n**Also includes a comprehensive Python client library** for Microsoft Dynamics 365 Finance & Operations with OData endpoints, metadata operations, label management, and CLI tools.\n\n## MCP Server Overview\n\nThe d365fo-client includes a **production-ready Model Context Protocol (MCP) server** (`d365fo-fastmcp-server`) built on the FastMCP framework that exposes the full capabilities of D365 Finance & Operations to AI assistants and other MCP-compatible tools.\n\nThe server provides multi-transport support (stdio, HTTP, SSE) with enhanced performance and deployment flexibility.\n\n### Key Features\n\n- **49 comprehensive tools** covering all major D365 F&O operations across 9 functional categories\n- **12 resource types** with comprehensive metadata exposure and discovery capabilities\n- **2 prompt templates** for advanced workflow assistance\n- **Multi-transport support** (FastMCP): stdio, HTTP, Server-Sent Events (SSE)\n- **Production-ready** implementation with proper error handling, authentication, and security validation\n- **Enhanced performance** (FastMCP): 40% faster startup, 15% lower memory usage\n- **Advanced profile management** supporting multiple environments with secure credential storage\n- **Database analysis capabilities** with secure SQL querying and metadata insights\n- **Session-based synchronization** with detailed progress tracking and multiple sync strategies\n- **Multi-language support** with label resolution and localization capabilities\n- **Enterprise security** with Azure AD integration, Key Vault support, and audit logging\n\n### New in v0.3.0\n\n- **🔧 Pydantic Settings Model**: Type-safe environment variable management with validation for 35+ configuration options\n- **📂 Custom Log File Support**: `D365FO_LOG_FILE` environment variable for flexible log file paths\n- **🔄 Legacy Config Migration**: Automatic detection and migration of legacy configuration files\n- **🌐 Environment Variable Standardization**: All MCP HTTP variables now use `D365FO_` prefix for consistency\n- **⚡ Enhanced FastMCP Server**: Improved startup configuration, error handling, and graceful shutdown\n- **🔀 MCP Return Type Standardization**: All MCP tools now return dictionaries instead of JSON strings for better type safety\n- **🛠️ Enhanced Configuration**: Support for `.env` files and comprehensive environment variable documentation\n\n### Quick Start\n\n#### Installation and Setup\n\n```bash\n# Install d365fo-client with MCP dependencies\npip install d365fo-client\n\n# Set up environment variables\nexport D365FO_BASE_URL=\"https://your-environment.dynamics.com\"\nexport D365FO_CLIENT_ID=\"your-client-id\"          # Optional with default credentials\nexport D365FO_CLIENT_SECRET=\"your-client-secret\"  # Optional with default credentials  \nexport D365FO_TENANT_ID=\"your-tenant-id\"          # Optional with default credentials\n```\n\n#### FastMCP Server (Recommended)\n\nThe modern FastMCP implementation provides enhanced performance and multiple transport options:\n\n```bash\n# Development (stdio transport - default)\nd365fo-fastmcp-server\n\n# Production HTTP API\nd365fo-fastmcp-server --transport http --port 8000 --host 0.0.0.0\n\n# Real-time Web Applications (SSE)\nd365fo-fastmcp-server --transport sse --port 8001 --host 0.0.0.0\n```\n\n**Key Benefits:**\n- **Optimized performance** with FastMCP framework\n- **Efficient resource usage** through optimized architecture\n- **Multi-transport support**: stdio, HTTP, Server-Sent Events (SSE)\n- **Enhanced error handling** with better async/await support\n- **Production ready** with web transports for API integration\n\n#### Integration with AI Assistants\n\n##### VS Code Integration (Recommended)\n\n**FastMCP Server with Default Credentials:**\nAdd to your VS Code `mcp.json` for GitHub Copilot with MCP:\n\n```json\n{\n  \"servers\": {\n    \"d365fo-fastmcp-server\": {\n      \"type\": \"stdio\",\n      \"command\": \"uvx\",\n      \"args\": [\n        \"--from\",\n        \"d365fo-client@latest\",\n        \"d365fo-fastmcp-server\"\n      ],\n      \"env\": {\n        \"D365FO_BASE_URL\": \"https://your-environment.dynamics.com\",\n        \"D365FO_LOG_LEVEL\": \"INFO\"\n      }\n    }\n  }\n}\n```\n\n**Option 2: Explicit Credentials**\nFor environments requiring service principal authentication:\n\n```json\n{\n  \"servers\": {\n    \"d365fo-fastmcp-server\": {\n      \"type\": \"stdio\", \n      \"command\": \"uvx\",\n      \"args\": [\n        \"--from\",\n        \"d365fo-client\",\n        \"d365fo-fastmcp-server\"\n      ],\n      \"env\": {\n        \"D365FO_BASE_URL\": \"https://your-environment.dynamics.com\",\n        \"D365FO_LOG_LEVEL\": \"DEBUG\",\n        \"D365FO_CLIENT_ID\": \"${input:client_id}\",\n        \"D365FO_CLIENT_SECRET\": \"${input:client_secret}\",\n        \"D365FO_TENANT_ID\": \"${input:tenant_id}\"\n      }\n    }\n  },\n  \"inputs\": [\n    {\n      \"id\": \"tenant_id\",\n      \"type\": \"promptString\",\n      \"description\": \"Azure AD Tenant ID for D365 F&O authentication\",\n      \"password\": true\n    },\n    {\n      \"id\": \"client_id\", \n      \"type\": \"promptString\",\n      \"description\": \"Azure AD Client ID for D365 F&O authentication\",\n      \"password\": true\n    },\n    {\n      \"id\": \"client_secret\",\n      \"type\": \"promptString\", \n      \"description\": \"Azure AD Client Secret for D365 F&O authentication\",\n      \"password\": true\n    }\n  ]\n}\n```\n\n**Option 3: Docker Integration**\nFor containerized environments and enhanced isolation:\n\n```json\n{\n  \"servers\": {\n    \"d365fo-fastmcp-server\": {\n      \"type\": \"stdio\",\n      \"command\": \"docker\",\n      \"args\": [\n        \"run\",\n        \"--rm\",\n        \"-i\",\n        \"-v\",\n        \"d365fo-mcp:/home/mcp_user/\",\n        \"-e\",\n        \"D365FO_CLIENT_ID=${input:client_id}\",\n        \"-e\",\n        \"D365FO_CLIENT_SECRET=${input:client_secret}\",\n        \"-e\",\n        \"D365FO_TENANT_ID=${input:tenant_id}\",\n        \"ghcr.io/mafzaal/d365fo-client:latest\"\n      ],\n      \"env\": {\n        \"D365FO_LOG_LEVEL\": \"DEBUG\",\n        \"D365FO_CLIENT_ID\": \"${input:client_id}\",\n        \"D365FO_CLIENT_SECRET\": \"${input:client_secret}\",\n        \"D365FO_TENANT_ID\": \"${input:tenant_id}\"\n      }\n    }\n  },\n  \"inputs\": [\n    {\n      \"id\": \"tenant_id\",\n      \"type\": \"promptString\",\n      \"description\": \"Azure AD Tenant ID for D365 F&O authentication\",\n      \"password\": true\n    },\n    {\n      \"id\": \"client_id\",\n      \"type\": \"promptString\",\n      \"description\": \"Azure AD Client ID for D365 F&O authentication\",\n      \"password\": true\n    },\n    {\n      \"id\": \"client_secret\",\n      \"type\": \"promptString\",\n      \"description\": \"Azure AD Client Secret for D365 F&O authentication\",\n      \"password\": true\n    }\n  ]\n}\n```\n\n**Benefits of Docker approach:**\n- Complete environment isolation and reproducibility\n- No local Python installation required\n- Consistent runtime environment across different systems\n- Automatic dependency management with pre-built image\n- Enhanced security through containerization\n- Persistent data storage via Docker volume (`d365fo-mcp`)\n\n**Prerequisites:**\n- Docker installed and running\n- Access to Docker Hub or GitHub Container Registry\n- Network access for pulling the container image\n\n##### Claude Desktop Integration\n\n**FastMCP Server:**\nAdd to your Claude Desktop configuration:\n\n```json\n{\n  \"mcpServers\": {\n    \"d365fo-fastmcp\": {\n      \"command\": \"uvx\",\n      \"args\": [\n        \"--from\",\n        \"d365fo-client\",\n        \"d365fo-fastmcp-server\"\n      ],\n      \"env\": {\n        \"D365FO_BASE_URL\": \"https://your-environment.dynamics.com\",\n        \"D365FO_LOG_LEVEL\": \"INFO\"\n      }\n    }\n  }\n}\n```\n\n**Traditional MCP Server (Alternative):**\n```json\n{\n  \"mcpServers\": {\n    \"d365fo\": {\n      \"command\": \"uvx\",\n      \"args\": [\n        \"--from\",\n        \"d365fo-client\",\n        \"d365fo-fastmcp-server\"\n      ],\n      \"env\": {\n        \"D365FO_BASE_URL\": \"https://your-environment.dynamics.com\",\n        \"D365FO_LOG_LEVEL\": \"INFO\"\n      }\n    }\n  }\n}\n```\n\n**Benefits of uvx approach:**\n- Always uses the latest version from the repository\n- No local installation required  \n- Automatic dependency management\n- Works across different environments\n\n#### Web Integration with FastMCP\n\nThe FastMCP server provides HTTP and SSE transports for web application integration:\n\n##### HTTP Transport for Web APIs\n\n```python\nimport aiohttp\nimport json\n\nasync def call_d365fo_api():\n    \"\"\"Example: Using HTTP transport for web API integration\"\"\"\n    \n    # Start FastMCP server with HTTP transport\n    # d365fo-fastmcp-server --transport http --port 8000\n    \n    mcp_request = {\n        \"jsonrpc\": \"2.0\",\n        \"id\": 1,\n        \"method\": \"tools/call\",\n        \"params\": {\n            \"name\": \"d365fo_query_entities\",\n            \"arguments\": {\n                \"entityName\": \"CustomersV3\",\n                \"top\": 10,\n                \"select\": [\"CustomerAccount\", \"Name\"]\n            }\n        }\n    }\n    \n    async with aiohttp.ClientSession() as session:\n        async with session.post(\n            \"http://localhost:8000/mcp\",\n            json=mcp_request,\n            headers={\"Content-Type\": \"application/json\"}\n        ) as response:\n            result = await response.json()\n            print(json.dumps(result, indent=2))\n```\n\n##### SSE Transport for Real-time Applications\n\n```javascript\n// Example: JavaScript client for real-time D365FO data\n// Start FastMCP server: d365fo-fastmcp-server --transport sse --port 8001\n\nconst eventSource = new EventSource('http://localhost:8001/sse');\n\neventSource.onmessage = function(event) {\n    const data = JSON.parse(event.data);\n    console.log('Received D365FO data:', data);\n    \n    // Handle real-time updates from D365FO\n    if (data.method === 'notification') {\n        updateDashboard(data.params);\n    }\n};\n\n// Send MCP requests via SSE\nfunction queryCustomers() {\n    const request = {\n        jsonrpc: \"2.0\",\n        id: Date.now(),\n        method: \"tools/call\",\n        params: {\n            name: \"d365fo_search_entities\",\n            arguments: {\n                pattern: \"customer\",\n                limit: 50\n            }\n        }\n    };\n    \n    fetch('http://localhost:8001/sse/send', {\n        method: 'POST',\n        headers: {'Content-Type': 'application/json'},\n        body: JSON.stringify(request)\n    });\n}\n```\n\n#### Alternative: Programmatic Usage\n\n```python\nfrom d365fo_client.mcp import D365FOMCPServer\n\n# Create and run server with custom configuration\nconfig = {\n    \"default_environment\": {\n        \"base_url\": \"https://your-environment.dynamics.com\",\n        \"use_default_credentials\": True\n    }\n}\n\nserver = D365FOMCPServer(config)\nawait server.run()\n```\n\n#### Custom MCP Clients\nConnect using any MCP-compatible client library:\n\n```python\nfrom mcp import Client\n\nasync with Client(\"d365fo-fastmcp-server\") as client:\n    # Discover available tools\n    tools = await client.list_tools()\n    \n    # Execute operations\n    result = await client.call_tool(\n        \"d365fo_query_entities\",\n        {\"entityName\": \"Customers\", \"top\": 5}\n    )\n```\n\n#### Docker Deployment\n\nFor containerized environments and production deployments:\n\n**Pull the Docker Image:**\n```bash\n# Pull from GitHub Container Registry\ndocker pull ghcr.io/mafzaal/d365fo-client:latest\n\n# Or pull a specific version\ndocker pull ghcr.io/mafzaal/d365fo-client:v0.2.3\n```\n\n**Standalone Docker Usage:**\n```bash\n# Run MCP server with environment variables\ndocker run --rm -i \\\n  -e D365FO_BASE_URL=\"https://your-environment.dynamics.com\" \\\n  -e D365FO_CLIENT_ID=\"your-client-id\" \\\n  -e D365FO_CLIENT_SECRET=\"your-client-secret\" \\\n  -e D365FO_TENANT_ID=\"your-tenant-id\" \\\n  -e D365FO_LOG_LEVEL=\"INFO\" \\\n  -v d365fo-mcp:/home/mcp_user/ \\\n  ghcr.io/mafzaal/d365fo-client:latest\n\n# Run CLI commands with Docker\ndocker run --rm -it \\\n  -e D365FO_BASE_URL=\"https://your-environment.dynamics.com\" \\\n  -e D365FO_CLIENT_ID=\"your-client-id\" \\\n  -e D365FO_CLIENT_SECRET=\"your-client-secret\" \\\n  -e D365FO_TENANT_ID=\"your-tenant-id\" \\\n  ghcr.io/mafzaal/d365fo-client:latest \\\n  d365fo-client entities --limit 10\n```\n\n**Docker Compose Example:**\n```yaml\nversion: '3.8'\nservices:\n  d365fo-mcp:\n    image: ghcr.io/mafzaal/d365fo-client:latest\n    environment:\n      - D365FO_BASE_URL=https://your-environment.dynamics.com\n      - D365FO_CLIENT_ID=${D365FO_CLIENT_ID}\n      - D365FO_CLIENT_SECRET=${D365FO_CLIENT_SECRET}\n      - D365FO_TENANT_ID=${D365FO_TENANT_ID}\n      - D365FO_LOG_LEVEL=INFO\n    volumes:\n      - d365fo-mcp:/home/mcp_user/\n    stdin_open: true\n    tty: true\n\nvolumes:\n  d365fo-mcp:\n```\n\n**Docker Benefits:**\n- Complete environment isolation and reproducibility\n- No local Python installation required\n- Consistent runtime environment across different systems\n- Built-in dependency management\n- Enhanced security through containerization\n- Persistent data storage via Docker volumes\n- Easy integration with orchestration platforms (Kubernetes, Docker Swarm)\n\n### Architecture Benefits\n\n#### For AI Assistants\n- **Standardized Interface**: Consistent MCP protocol access to D365 F&O\n- **Rich Metadata**: Self-describing entities and operations\n- **Type Safety**: Schema validation for all operations\n- **Error Context**: Detailed error information for troubleshooting\n\n#### For Developers  \n- **Minimal Integration**: Standard MCP client libraries\n- **Comprehensive Coverage**: Full D365 F&O functionality exposed\n- **Performance Optimized**: Efficient connection and caching strategies\n- **Well Documented**: Complete API documentation and examples\n\n#### For Organizations\n- **Secure Access**: Enterprise-grade authentication (Azure AD, Managed Identity)\n- **Audit Logging**: Complete operation tracking and monitoring\n- **Scalable Design**: Connection pooling and session management\n- **Maintenance Friendly**: Clear architecture and comprehensive test coverage\n\n### Troubleshooting\n\n#### Common Issues\n\n**Connection Failures**\n```bash\n# Test connectivity\nd365fo-client version app --base-url https://your-environment.dynamics.com\n\n# Check logs\ntail -f ~/.d365fo-mcp/logs/mcp-server.log\n```\n\n**Authentication Issues**\n```bash\n# Verify Azure CLI authentication\naz account show\n\n# Test with explicit credentials\nexport D365FO_CLIENT_ID=\"your-client-id\"\n# ... set other variables\nd365fo-fastmcp-server\n```\n\n**Performance Issues**\n```bash\n# Enable debug logging\nexport D365FO_LOG_LEVEL=\"DEBUG\"\n\n# Adjust connection settings\nexport D365FO_CONNECTION_TIMEOUT=\"120\"\nexport D365FO_MAX_CONCURRENT_REQUESTS=\"5\"\n```\n\n#### Getting Help\n\n- **Logs**: Check `~/.d365fo-mcp/logs/mcp-server.log` for detailed error information\n- **Environment**: Use `d365fo_get_environment_info` tool to check system status\n- **Documentation**: See [MCP Implementation Summary](docs/MCP_IMPLEMENTATION_SUMMARY.md) for technical details\n- **Issues**: Report problems at [GitHub Issues](https://github.com/mafzaal/d365fo-client/issues)\n\n### MCP Tools\n\nThe server provides **49 comprehensive tools** organized into functional categories:\n\n#### Connection & Environment Tools (2 tools)\n- **`d365fo_test_connection`** - Test connectivity and authentication with performance metrics and error diagnostics\n- **`d365fo_get_environment_info`** - Get comprehensive environment details including versions, configurations, and capabilities\n\n#### CRUD Operations Tools (7 tools)\n- **`d365fo_query_entities`** - Simplified OData querying with 'eq' filtering, wildcard patterns, field selection, and pagination\n- **`d365fo_get_entity_record`** - Retrieve specific records by key with expansion options and ETag support\n- **`d365fo_create_entity_record`** - Create new entity records with validation and business logic execution\n- **`d365fo_update_entity_record`** - Update existing records with partial updates and optimistic concurrency control\n- **`d365fo_delete_entity_record`** - Delete entity records with referential integrity checking and cascading rules\n- **`d365fo_call_action`** - Execute OData actions and functions for complex business operations\n- **`d365fo_call_json_service`** - Call generic JSON service endpoints with parameter support and response handling\n\n#### Metadata Discovery Tools (6 tools)\n- **`d365fo_search_entities`** - Search entities by pattern with category filtering and full-text search capabilities\n- **`d365fo_get_entity_schema`** - Get detailed entity schemas with properties, relationships, and label resolution\n- **`d365fo_search_actions`** - Search available OData actions with binding type and parameter information\n- **`d365fo_search_enumerations`** - Search system enumerations with keyword-based filtering\n- **`d365fo_get_enumeration_fields`** - Get detailed enumeration member information with multi-language support\n- **`d365fo_get_installed_modules`** - Retrieve information about installed modules and their configurations\n\n#### Label Management Tools (2 tools)\n- **`d365fo_get_label`** - Get single label text by ID with multi-language support and fallback options\n- **`d365fo_get_labels_batch`** - Get multiple labels efficiently with batch processing and performance optimization\n\n#### Profile Management Tools (14 tools)\n- **`d365fo_list_profiles`** - List all configured D365FO environment profiles with status information\n- **`d365fo_get_profile`** - Get detailed configuration information for specific profiles\n- **`d365fo_create_profile`** - Create new environment profiles with comprehensive authentication options\n- **`d365fo_update_profile`** - Modify existing profile configurations with partial update support\n- **`d365fo_delete_profile`** - Remove environment profiles with proper cleanup and validation\n- **`d365fo_set_default_profile`** - Designate a specific profile as the default for operations\n- **`d365fo_get_default_profile`** - Retrieve information about the currently configured default profile\n- **`d365fo_validate_profile`** - Validate profile configurations for completeness and security compliance\n- **`d365fo_test_profile_connection`** - Test connectivity and authentication for specific profiles\n- **`d365fo_clone_profile`** - Clone existing profiles with customization options for new environments\n- **`d365fo_search_profiles`** - Search profiles by pattern with filtering and sorting capabilities\n- **`d365fo_get_profile_names`** - Get simplified list of available profile names for quick reference\n- **`d365fo_import_profiles`** - Import profile configurations from external sources or backups\n- **`d365fo_export_profiles`** - Export profile configurations for backup or deployment purposes\n\n#### Database Analysis Tools (4 tools)\n- **`d365fo_execute_sql_query`** - Execute SELECT queries against metadata database with security validation\n- **`d365fo_get_database_schema`** - Get comprehensive database schema information including relationships\n- **`d365fo_get_table_info`** - Get detailed information about specific database tables with sample data\n- **`d365fo_get_database_statistics`** - Generate database statistics and analytics for performance monitoring\n\n#### Synchronization Tools (5 tools)\n- **`d365fo_start_sync`** - Initiate metadata synchronization with various strategies and session tracking\n- **`d365fo_get_sync_progress`** - Monitor detailed progress of sync sessions with time estimates\n- **`d365fo_cancel_sync`** - Cancel running sync sessions with graceful cleanup\n- **`d365fo_list_sync_sessions`** - List all active sync sessions with status and progress information\n- **`d365fo_get_sync_history`** - Get history of completed sync sessions with success/failure status and statistics\n\n#### SRS Reporting Tools (6 tools)\n- **`d365fo_download_srs_report`** - Download SQL Server Reporting Services (SRS) reports with parameter support\n- **`d365fo_download_sales_confirmation`** - Download sales confirmation reports in various formats\n- **`d365fo_download_purchase_order`** - Download purchase order documents with formatting options\n- **`d365fo_download_customer_invoice`** - Download customer invoice reports with customization\n- **`d365fo_download_free_text_invoice`** - Download free text invoice documents\n- **`d365fo_download_debit_credit_note`** - Download debit and credit note reports\n\n#### Performance Monitoring Tools (3 tools)\n- **`d365fo_get_server_performance`** - Get server performance metrics and statistics\n- **`d365fo_get_server_config`** - Get server configuration information and system settings\n- **`d365fo_reset_performance_stats`** - Reset performance statistics and counters for fresh monitoring\n\n**📖 For detailed information about all MCP tools including usage examples and best practices, see the [Comprehensive MCP Tools Introduction](docs/MCP_TOOLS_COMPREHENSIVE_INTRODUCTION.md).**\n\n**🤖 For AI agents and assistants, see the [AI Agent Guide](AGENTS.md) for structured workflows, best practices, and automation patterns.**\n\n### MCP Resources\n\nThe server exposes four types of resources for discovery and access:\n\n#### Entity Resources\nAccess entity metadata and sample data:\n```\nd365fo://entities/CustomersV3     # Customer entity with metadata and sample data\nd365fo://entities/SalesOrders     # Sales order entity information\nd365fo://entities/Products        # Product entity details\n```\n\n#### Metadata Resources\nAccess system-wide metadata:\n```\nd365fo://metadata/entities        # All data entities metadata (V2 cache)\nd365fo://metadata/actions         # Available OData actions  \nd365fo://metadata/enumerations    # System enumerations\nd365fo://metadata/labels          # System labels and translations\n```\n\n#### Environment Resources\nAccess environment status and information:\n```\nd365fo://environment/status       # Environment health and connectivity\nd365fo://environment/version      # Version information (app, platform, build)\nd365fo://environment/cache        # Cache status and statistics V2\n```\n\n#### Query Resources\nAccess predefined and templated queries:\n```\nd365fo://queries/customers_recent # Recent customers query template\nd365fo://queries/sales_summary    # Sales summary query with parameters\n```\n\n#### Database Resources (New in V2)\nAccess metadata database queries:\n```\nd365fo://database/entities        # SQL-based entity searches with FTS5\nd365fo://database/actions         # Action discovery with metadata\nd365fo://database/statistics      # Cache and performance statistics\n```\n\n### Usage Examples\n\n#### Basic Tool Execution\n\n```json\n{\n  \"tool\": \"d365fo_query_entities\",\n  \"arguments\": {\n    \"entityName\": \"CustomersV3\",\n    \"select\": [\"CustomerAccount\", \"Name\", \"Email\"],\n    \"filter\": \"CustomerGroup eq 'VIP'\",\n    \"top\": 10\n  }\n}\n```\n\n#### Entity Schema Discovery\n\n```json\n{\n  \"tool\": \"d365fo_get_entity_schema\", \n  \"arguments\": {\n    \"entityName\": \"CustomersV3\",\n    \"includeProperties\": true,\n    \"resolveLabels\": true,\n    \"language\": \"en-US\"\n  }\n}\n```\n\n#### Environment Information\n\n```json\n{\n  \"tool\": \"d365fo_get_environment_info\",\n  \"arguments\": {}\n}\n```\n\n### Authentication & Configuration\n\n#### Default Credentials (Recommended)\nUses Azure Default Credential chain (Managed Identity, Azure CLI, etc.):\n\n```bash\nexport D365FO_BASE_URL=\"https://your-environment.dynamics.com\"\n# No additional auth environment variables needed\nd365fo-fastmcp-server\n```\n\n#### Explicit Credentials\nFor service principal authentication:\n\n```bash\nexport D365FO_BASE_URL=\"https://your-environment.dynamics.com\"\nexport D365FO_CLIENT_ID=\"your-client-id\"\nexport D365FO_CLIENT_SECRET=\"your-client-secret\"\nexport D365FO_TENANT_ID=\"your-tenant-id\"\nd365fo-fastmcp-server\n```\n\n#### Azure Key Vault Integration (New in v0.2.3)\nFor secure credential storage using Azure Key Vault:\n\n```bash\nexport D365FO_BASE_URL=\"https://your-environment.dynamics.com\"\nexport D365FO_CREDENTIAL_SOURCE=\"keyvault\"\nexport D365FO_KEYVAULT_URL=\"https://your-keyvault.vault.azure.net/\"\nd365fo-fastmcp-server\n```\n\n#### Advanced Configuration\n\n**New in v0.3.0**: Comprehensive environment variable management with type safety and validation using Pydantic settings.\n\nCreate a configuration file or set additional environment variables:\n\n```bash\n# === Core D365FO Connection Settings ===\nexport D365FO_BASE_URL=\"https://your-environment.dynamics.com\"\nexport D365FO_CLIENT_ID=\"your-client-id\"\nexport D365FO_CLIENT_SECRET=\"your-client-secret\"\nexport D365FO_TENANT_ID=\"your-tenant-id\"\n\n# === Logging Configuration ===\nexport D365FO_LOG_LEVEL=\"DEBUG\"                        # DEBUG, INFO, WARNING, ERROR, CRITICAL\nexport D365FO_LOG_FILE=\"/custom/path/server.log\"       # Custom log file path\n\n# === MCP Server Transport Settings (v0.3.0+) ===\nexport D365FO_MCP_TRANSPORT=\"stdio\"                    # stdio, sse, http, streamable-http\nexport D365FO_MCP_HTTP_HOST=\"0.0.0.0\"                 # HTTP host (default: 127.0.0.1)\nexport D365FO_MCP_HTTP_PORT=\"8000\"                     # HTTP port (default: 8000)\nexport D365FO_MCP_HTTP_STATELESS=\"true\"                # Enable stateless mode\nexport D365FO_MCP_HTTP_JSON=\"true\"                     # Enable JSON response mode\n\n# === Cache and Performance Settings ===\nexport D365FO_CACHE_DIR=\"/custom/cache/path\"           # General cache directory\nexport D365FO_META_CACHE_DIR=\"/custom/metadata/cache\"  # Metadata cache directory\nexport D365FO_LABEL_CACHE=\"true\"                       # Enable label caching (default: true)\nexport D365FO_LABEL_EXPIRY=\"1440\"                      # Label cache expiry in minutes (24 hours)\nexport D365FO_USE_CACHE_FIRST=\"true\"                   # Use cache before API calls\n\n# === Connection and Performance Tuning ===\nexport D365FO_TIMEOUT=\"60\"                             # General timeout in seconds\nexport D365FO_MCP_MAX_CONCURRENT_REQUESTS=\"10\"         # Max concurrent requests\nexport D365FO_MCP_REQUEST_TIMEOUT=\"30\"                 # Request timeout in seconds\nexport D365FO_VERIFY_SSL=\"true\"                        # Verify SSL certificates\n\n# === MCP Authentication Settings (Advanced) ===\nexport D365FO_MCP_AUTH_CLIENT_ID=\"your-mcp-client-id\"\nexport D365FO_MCP_AUTH_CLIENT_SECRET=\"your-mcp-client-secret\"\nexport D365FO_MCP_AUTH_TENANT_ID=\"your-mcp-tenant-id\"\nexport D365FO_MCP_AUTH_BASE_URL=\"http://localhost:8000\"\nexport D365FO_MCP_AUTH_REQUIRED_SCOPES=\"User.Read,email,openid,profile\"\n\n# === Debug Settings ===\nexport DEBUG=\"true\"                                     # Enable debug mode\n```\n\n**Environment File Support**: You can also create a `.env` file in your project directory with these variables for development convenience.\n\n## Python Client Library\n\n### Features\n\n- 🔗 **OData Client**: Full CRUD operations on D365 F&O data entities with composite key support\n- 📊 **Metadata Management V2**: Enhanced caching system with intelligent synchronization and FTS5 search\n- 🏷️ **Label Operations V2**: Multilingual label caching with performance improvements and async support\n- 🔍 **Advanced Querying**: Support for all OData query parameters ($select, $filter, $expand, etc.)\n- ⚡ **Action Execution**: Execute bound and unbound OData actions with comprehensive parameter handling\n- �️ **JSON Services**: Generic access to D365 F&O JSON service endpoints (/api/services pattern)\n- �🔒 **Authentication**: Azure AD integration with default credentials, service principal, and Azure Key Vault support\n- 💾 **Intelligent Caching**: Cross-environment cache sharing with module-based version detection\n- 🌐 **Async/Await**: Modern async/await patterns with optimized session management\n- 📝 **Type Hints**: Full type annotation support with enhanced data models\n- 🤖 **MCP Server**: Production-ready Model Context Protocol server with 49 tools and 4 resource types\n- 🖥️ **Comprehensive CLI**: Hierarchical command-line interface for all D365 F&O operations\n- 🧪 **Multi-tier Testing**: Mock, sandbox, and live integration testing framework (17/17 tests passing)\n- 📋 **Metadata Scripts**: PowerShell and Python utilities for entity, enumeration, and action discovery\n- 🔐 **Enhanced Credential Management**: Support for Azure Key Vault and multiple credential sources\n- 📊 **Advanced Sync Management**: Session-based synchronization with detailed progress tracking\n- **🔧 NEW v0.3.0**: Pydantic settings model with type-safe environment variable validation\n- **📂 NEW v0.3.0**: Custom log file path support and flexible logging configuration\n- **🔄 NEW v0.3.0**: Automatic legacy configuration migration and compatibility layer\n\n### Installation\n\n```bash\n# Install from PyPI\npip install d365fo-client\n\n# Or install from source\ngit clone https://github.com/mafzaal/d365fo-client.git\ncd d365fo-client\nuv sync  # Installs with exact dependencies from uv.lock\n\n# Or use Docker (no local installation required)\ndocker pull ghcr.io/mafzaal/d365fo-client:latest\n\n# Run with Docker\ndocker run --rm -it \\\n  -e D365FO_BASE_URL=\"https://your-environment.dynamics.com\" \\\n  -e D365FO_CLIENT_ID=\"your-client-id\" \\\n  -e D365FO_CLIENT_SECRET=\"your-client-secret\" \\\n  -e D365FO_TENANT_ID=\"your-tenant-id\" \\\n  -v d365fo-mcp:/home/mcp_user/ \\\n  ghcr.io/mafzaal/d365fo-client:latest\n```\n\n**Note**: The package includes MCP (Model Context Protocol) dependencies by default, enabling AI assistant integration. Both `d365fo-client` CLI and `d365fo-fastmcp-server` commands will be available after installation.\n\n**Breaking Change in v0.2.3**: Environment variable names have been updated for consistency:\n- `AZURE_CLIENT_ID` → `D365FO_CLIENT_ID`\n- `AZURE_CLIENT_SECRET` → `D365FO_CLIENT_SECRET`  \n- `AZURE_TENANT_ID` → `D365FO_TENANT_ID`\n\nPlease update your environment variables accordingly when upgrading.\n\n## Python Client Quick Start\n\n## Command Line Interface (CLI)\n\nd365fo-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.\n\n### Usage\n\n```bash\n# Use the installed CLI command\nd365fo-client [GLOBAL_OPTIONS] COMMAND [SUBCOMMAND] [OPTIONS]\n\n# Alternative: Module execution\npython -m d365fo_client.main [OPTIONS] COMMAND [ARGS]\n```\n\n### Command Categories\n\n#### Entity Operations\n```bash\n# List entities with filtering\nd365fo-client entities list --pattern \"customer\" --limit 10\n\n# Get entity details and schema\nd365fo-client entities get CustomersV3 --properties --keys --labels\n\n# CRUD operations\nd365fo-client entities create Customers --data '{\"CustomerAccount\":\"US-999\",\"Name\":\"Test\"}'\nd365fo-client entities update Customers US-999 --data '{\"Name\":\"Updated Name\"}'\nd365fo-client entities delete Customers US-999\n```\n\n#### Metadata Operations\n```bash\n# Search and discover entities\nd365fo-client metadata entities --search \"sales\" --output json\n\n# Get available actions\nd365fo-client metadata actions --pattern \"calculate\" --limit 5\n\n# Enumerate system enumerations\nd365fo-client metadata enums --search \"status\" --output table\n\n# Synchronize metadata cache\nd365fo-client metadata sync --force-refresh\n```\n\n#### Version Information\n```bash\n# Get application versions\nd365fo-client version app\nd365fo-client version platform  \nd365fo-client version build\n```\n\n#### Label Operations\n```bash\n# Resolve single label\nd365fo-client labels resolve \"@SYS13342\"\n\n# Search labels by pattern\nd365fo-client labels search \"customer\" --language \"en-US\"\n```\n\n#### JSON Service Operations\n```bash\n# Call SQL diagnostic services  \nd365fo-client service sql-diagnostic GetAxSqlExecuting\nd365fo-client service sql-diagnostic GetAxSqlResourceStats --since-minutes 5\nd365fo-client service sql-diagnostic GetAxSqlBlocking --output json\n\n# Generic JSON service calls\nd365fo-client service call SysSqlDiagnosticService SysSqlDiagnosticServiceOperations GetAxSqlExecuting\nd365fo-client service call YourServiceGroup YourServiceName YourOperation --parameters '{\"param1\":\"value1\"}'\n```\n\n### Global Options\n\n- `--base-url URL` — Specify D365 F&O environment URL\n- `--profile NAME` — Use named configuration profile  \n- `--output FORMAT` — Output format: json, table, csv, yaml (default: table)\n- `--verbose` — Enable verbose output for debugging\n- `--timeout SECONDS` — Request timeout (default: 30)\n\n### Configuration Profiles\n\nCreate reusable configurations in `~/.d365fo-client/config.yaml`:\n\n```yaml\nprofiles:\n  production:\n    base_url: \"https://prod.dynamics.com\"\n    use_default_credentials: true\n    timeout: 60\n    \n  development:\n    base_url: \"https://dev.dynamics.com\" \n    client_id: \"${D365FO_CLIENT_ID}\"\n    client_secret: \"${D365FO_CLIENT_SECRET}\"\n    tenant_id: \"${D365FO_TENANT_ID}\"\n    use_cache_first: true\n\ndefault_profile: \"development\"\n```\n\n### Examples\n\n```bash\n# Quick entity discovery\nd365fo-client entities list --pattern \"cust.*\" --output json\n\n# Get comprehensive entity information\nd365fo-client entities get CustomersV3 --properties --keys --labels --output yaml\n\n# Search for calculation actions\nd365fo-client metadata actions --pattern \"calculate|compute\" --output table\n\n# Test environment connectivity\nd365fo-client version app --verbose\n```\n\nFor a complete command reference:\n\n```bash\nd365fo-client --help\nd365fo-client entities --help\nd365fo-client metadata --help\n```\n### Basic Usage\n\n```python\nimport asyncio\nfrom d365fo_client import D365FOClient, FOClientConfig\n\nasync def main():\n    # Simple configuration with default credentials\n    config = FOClientConfig(\n        base_url=\"https://your-fo-environment.dynamics.com\",\n        use_default_credentials=True  # Uses Azure Default Credential\n    )\n    \n    async with D365FOClient(config) as client:\n        # Test connection\n        if await client.test_connection():\n            print(\"✅ Connected successfully!\")\n        \n        # Get environment information\n        env_info = await client.get_environment_info()\n        print(f\"Environment: {env_info.application_version}\")\n        \n        # Search for entities (uses metadata cache v2)\n        customer_entities = await client.search_entities(\"customer\")\n        print(f\"Found {len(customer_entities)} customer entities\")\n        \n        # Get customers with query options\n        from d365fo_client import QueryOptions\n        options = QueryOptions(\n            select=[\"CustomerAccount\", \"Name\", \"SalesCurrencyCode\"],\n            top=10,\n            orderby=[\"Name\"]\n        )\n        \n        customers = await client.get_data(\"/data/CustomersV3\", options)\n        print(f\"Retrieved {len(customers['value'])} customers\")\n\nif __name__ == \"__main__\":\n    asyncio.run(main())\n```\n\n### Using Convenience Function\n\n```python\nfrom d365fo_client import create_client\n\n# Quick client creation with enhanced defaults\nasync with create_client(\"https://your-fo-environment.dynamics.com\") as client:\n    customers = await client.get_data(\"/data/CustomersV3\", top=5)\n```\n\n## Configuration\n\n### Environment Variable Management (New in v0.3.0)\n\nThe d365fo-client now includes a comprehensive **Pydantic settings model** for type-safe environment variable management:\n\n```python\nfrom d365fo_client import D365FOSettings, get_settings\n\n# Get type-safe settings instance\nsettings = get_settings()\n\n# Access settings with full IntelliSense support\nprint(f\"Base URL: {settings.base_url}\")\nprint(f\"Log Level: {settings.log_level}\")\nprint(f\"Cache Directory: {settings.cache_dir}\")\n\n# Check configuration state\nif settings.has_client_credentials():\n    print(\"Client credentials configured\")\n\nstartup_mode = settings.get_startup_mode()  # \"profile_only\", \"default_auth\", \"client_credentials\"\n\n# Convert to environment dictionary for external tools\nenv_vars = settings.to_env_dict()\n```\n\n**Key Benefits:**\n- **Type Safety**: Automatic validation and type conversion for all 35+ environment variables\n- **IDE Support**: Full IntelliSense and autocompletion for configuration options\n- **Environment Files**: Support for `.env` files in development\n- **Comprehensive Defaults**: Sensible defaults for all configuration options\n- **Validation**: Built-in validation for URLs, ports, timeouts, and other settings\n\n### Authentication Options\n\n```python\nfrom d365fo_client import FOClientConfig\n\n# Option 1: Default Azure credentials (recommended)\nconfig = FOClientConfig(\n    base_url=\"https://your-fo-environment.dynamics.com\",\n    use_default_credentials=True\n)\n\n# Option 2: Client credentials\nconfig = FOClientConfig(\n    base_url=\"https://your-fo-environment.dynamics.com\",\n    client_id=\"your-client-id\",\n    client_secret=\"your-client-secret\", \n    tenant_id=\"your-tenant-id\",\n    use_default_credentials=False\n)\n\n# Option 3: Azure Key Vault integration (New in v0.2.3)\nconfig = FOClientConfig(\n    base_url=\"https://your-fo-environment.dynamics.com\",\n    credential_source=\"keyvault\",  # Use Azure Key Vault for credentials\n    keyvault_url=\"https://your-keyvault.vault.azure.net/\"\n)\n\n# Option 4: With custom settings\nconfig = FOClientConfig(\n    base_url=\"https://your-fo-environment.dynamics.com\",\n    use_default_credentials=True,\n    verify_ssl=False,  # For development environments\n    timeout=60,  # Request timeout in seconds\n    metadata_cache_dir=\"./my_cache\",  # Custom cache directory\n    use_label_cache=True,  # Enable label caching\n    label_cache_expiry_minutes=120  # Cache for 2 hours\n)\n```\n\n### Legacy Configuration Migration (New in v0.3.0)\n\nThe d365fo-client automatically detects and migrates legacy configuration files:\n\n- **Automatic Detection**: Identifies legacy configuration patterns (missing `verify_ssl`, outdated field names)\n- **Field Migration**: Updates `cache_dir` → `metadata_cache_dir`, `auth_mode` → `use_default_credentials`\n- **Backup Creation**: Creates backup of original configuration before migration\n- **Seamless Upgrade**: Ensures smooth transition from older versions without manual intervention\n\n```python\n# Legacy configurations are automatically migrated when FastMCP server starts\n# No manual intervention required - migration happens transparently\n```\n\n## Core Operations\n\n### CRUD Operations\n\n```python\nasync with D365FOClient(config) as client:\n    # CREATE - Create new customer (supports composite keys)\n    new_customer = {\n        \"CustomerAccount\": \"US-999\",\n        \"Name\": \"Test Customer\",\n        \"SalesCurrencyCode\": \"USD\"\n    }\n    created = await client.create_data(\"/data/CustomersV3\", new_customer)\n    \n    # READ - Get single customer by key\n    customer = await client.get_data(\"/data/CustomersV3('US-001')\")\n    \n    # UPDATE - Update customer with optimistic concurrency\n    updates = {\"Name\": \"Updated Customer Name\"}\n    updated = await client.update_data(\"/data/CustomersV3('US-001')\", updates)\n    \n    # DELETE - Delete customer\n    success = await client.delete_data(\"/data/CustomersV3('US-999')\")\n    print(f\"Delete successful: {success}\")\n```\n\n### Advanced Querying\n\n```python\nfrom d365fo_client import QueryOptions\n\n# Complex query with multiple options\noptions = QueryOptions(\n    select=[\"CustomerAccount\", \"Name\", \"SalesCurrencyCode\", \"CustomerGroupId\"],\n    filter=\"SalesCurrencyCode eq 'USD' and contains(Name, 'Corp')\",\n    expand=[\"CustomerGroup\"],\n    orderby=[\"Name desc\", \"CustomerAccount\"],\n    top=50,\n    skip=10,\n    count=True\n)\n\nresult = await client.get_data(\"/data/CustomersV3\", options)\nprint(f\"Total count: {result.get('@odata.count')}\")\n```\n\n### Action Execution\n\n```python\n# Unbound action\nresult = await client.post_data(\"/data/calculateTax\", {\n    \"amount\": 1000.00,\n    \"taxGroup\": \"STANDARD\"\n})\n\n# Bound action on entity set\nresult = await client.post_data(\"/data/CustomersV3/calculateBalances\", {\n    \"asOfDate\": \"2024-12-31\"\n})\n\n# Bound action on specific entity instance  \nresult = await client.post_data(\"/data/CustomersV3('US-001')/calculateBalance\", {\n    \"asOfDate\": \"2024-12-31\"\n})\n```\n\n### JSON Service Operations\n\n```python\n# Basic JSON service call (no parameters)\nresponse = await client.post_json_service(\n    service_group=\"SysSqlDiagnosticService\",\n    service_name=\"SysSqlDiagnosticServiceOperations\",\n    operation_name=\"GetAxSqlExecuting\"\n)\n\nif response.success:\n    print(f\"Found {len(response.data)} executing SQL statements\")\n    print(f\"Status: HTTP {response.status_code}\")\nelse:\n    print(f\"Error: {response.error_message}\")\n\n# JSON service call with parameters\nfrom datetime import datetime, timezone, timedelta\n\nend_time = datetime.now(timezone.utc)\nstart_time = end_time - timedelta(minutes=10)\n\nresponse = await client.post_json_service(\n    service_group=\"SysSqlDiagnosticService\",\n    service_name=\"SysSqlDiagnosticServiceOperations\",\n    operation_name=\"GetAxSqlResourceStats\",\n    parameters={\n        \"start\": start_time.isoformat(),\n        \"end\": end_time.isoformat()\n    }\n)\n\n# Using JsonServiceRequest object for better structure\nfrom d365fo_client.models import JsonServiceRequest\n\nrequest = JsonServiceRequest(\n    service_group=\"SysSqlDiagnosticService\",\n    service_name=\"SysSqlDiagnosticServiceOperations\",\n    operation_name=\"GetAxSqlBlocking\"\n)\n\nresponse = await client.call_json_service(request)\nprint(f\"Service endpoint: {request.get_endpoint_path()}\")\n\n# Multiple SQL diagnostic operations\noperations = [\"GetAxSqlExecuting\", \"GetAxSqlBlocking\", \"GetAxSqlLockInfo\"]\nfor operation in operations:\n    response = await client.post_json_service(\n        service_group=\"SysSqlDiagnosticService\",\n        service_name=\"SysSqlDiagnosticServiceOperations\",\n        operation_name=operation\n    )\n    \n    if response.success:\n        count = len(response.data) if isinstance(response.data, list) else 1\n        print(f\"{operation}: {count} records\")\n\n# Custom service call template\nresponse = await client.post_json_service(\n    service_group=\"YourServiceGroup\",\n    service_name=\"YourServiceName\",\n    operation_name=\"YourOperation\",\n    parameters={\n        \"parameter1\": \"value1\",\n        \"parameter2\": 123,\n        \"parameter3\": True\n    }\n)\n```\n\n### Metadata Operations\n\n```python\n# Intelligent metadata synchronization (v2 system)\nsync_manager = await client.get_sync_manager()\nawait sync_manager.smart_sync()\n\n# Search entities with enhanced filtering\nsales_entities = await client.search_entities(\"sales\")\nprint(\"Sales-related entities:\", [e.name for e in sales_entities])\n\n# Get detailed entity information with labels\nentity_info = await client.get_public_entity_info(\"CustomersV3\")\nif entity_info:\n    print(f\"Entity: {entity_info.name}\")\n    print(f\"Label: {entity_info.label_text}\")\n    print(f\"Data Service Enabled: {entity_info.data_service_enabled}\")\n\n# Search actions with caching\ncalc_actions = await client.search_actions(\"calculate\")\nprint(\"Calculation actions:\", [a.name for a in calc_actions])\n\n# Get enumeration information\nenum_info = await client.get_public_enumeration_info(\"NoYes\")\nif enum_info:\n    print(f\"Enum: {enum_info.name}\")\n    for member in enum_info.members:\n        print(f\"  {member.name} = {member.value}\")\n```\n\n### Label Operations\n\n```python\n# Get specific label (v2 caching system)\nlabel_text = await client.get_label_text(\"@SYS13342\")\nprint(f\"Label text: {label_text}\")\n\n# Get multiple labels efficiently\nlabels = await client.get_labels_batch([\n    \"@SYS13342\", \"@SYS9490\", \"@GLS63332\"\n])\nfor label_id, text in labels.items():\n    print(f\"{label_id}: {text}\")\n\n# Enhanced entity info with resolved labels\nentity_info = await client.get_public_entity_info_with_labels(\"CustomersV3\")\nif entity_info.label_text:\n    print(f\"Entity display name: {entity_info.label_text}\")\n\n# Access enhanced properties with labels\nfor prop in entity_info.enhanced_properties[:5]:\n    if hasattr(prop, 'label_text') and prop.label_text:\n        print(f\"{prop.name}: {prop.label_text}\")\n```\n\n## Error Handling\n\n```python\nfrom d365fo_client import D365FOClientError, AuthenticationError, ConnectionError\n\ntry:\n    async with D365FOClient(config) as client:\n        customer = await client.get_data(\"/data/CustomersV3('NON-EXISTENT')\")\nexcept ConnectionError as e:\n    print(f\"Connection failed: {e}\")\nexcept AuthenticationError as e:\n    print(f\"Authentication failed: {e}\")\nexcept D365FOClientError as e:\n    print(f\"Client operation failed: {e}\")\n    print(f\"Status code: {e.status_code}\")\n    print(f\"Response: {e.response_text}\")\n```\n\n## Development\n\n### Setting up Development Environment\n\n```bash\n# Clone the repository\ngit clone https://github.com/mafzaal/d365fo-client.git\ncd d365fo-client\n\n# Install with development dependencies using uv\nuv sync --dev\n\n# Run tests\nuv run pytest\n\n# Run integration tests\n.\\tests\\integration\\integration-test-simple.ps1 test-sandbox\n\n# Format code\nuv run black .\nuv run isort .\n\n# Type checking\nuv run mypy src/\n\n# Quality checks\n.\\make.ps1 quality-check  # Windows PowerShell\n# or\nmake quality-check       # Unix/Linux/macOS\n```\n\n### Project Structure\n\n```\nd365fo-client/\n├── src/\n│   └── d365fo_client/\n│       ├── __init__.py          # Public API exports\n│       ├── main.py              # CLI entry point  \n│       ├── cli.py               # CLI command handlers\n│       ├── client.py            # Enhanced D365FOClient class\n│       ├── config.py            # Configuration management\n│       ├── auth.py              # Authentication management\n│       ├── session.py           # HTTP session management\n│       ├── crud.py              # CRUD operations\n│       ├── query.py             # OData query utilities\n│       ├── metadata.py          # Legacy metadata operations\n│       ├── metadata_api.py      # Metadata API client\n│       ├── metadata_cache.py    # Metadata caching layer V2\n│       ├── metadata_sync.py     # Metadata synchronization V2 with session management\n│       ├── sync_session.py      # Enhanced sync session management (New in v0.2.3)\n│       ├── credential_manager.py # Credential source management (New in v0.2.3)\n│       ├── labels.py            # Label operations V2\n│       ├── profiles.py          # Profile data models\n│       ├── profile_manager.py   # Profile management\n│       ├── models.py            # Data models and configurations\n│       ├── output.py            # Output formatting\n│       ├── utils.py             # Utility functions\n│       ├── exceptions.py        # Custom exceptions\n│       └── mcp/                 # Model Context Protocol server\n│           ├── __init__.py      # MCP server exports\n│           ├── main.py          # MCP server entry point\n│           ├── server.py        # Core MCP server implementation\n│           ├── client_manager.py# D365FO client connection pooling\n│           ├── models.py        # MCP-specific data models\n│           ├── mixins/          # FastMCP tool mixins (49 tools)\n│           ├── tools/           # Legacy MCP tools (deprecated)\n│           │   ├── connection_tools.py\n│           │   ├── crud_tools.py\n│           │   ├── metadata_tools.py\n│           │   └── label_tools.py\n│           ├── resources/       # MCP resource handlers (4 types)\n│           │   ├── entity_handler.py\n│           │   ├── metadata_handler.py\n│           │   ├── environment_handler.py\n│           │   └── query_handler.py\n│           └── prompts/         # MCP prompt templates\n├── tests/                       # Comprehensive test suite\n│   ├── unit/                    # Unit tests (pytest-based)\n│   ├── integration/             # Multi-tier integration testing\n│   │   ├── mock_server/         # Mock D365 F&O API server\n│   │   ├── test_mock_server.py  # Mock server tests\n│   │   ├── test_sandbox.py      # Sandbox environment tests ✅\n│   │   ├── test_live.py         # Live environment tests\n│   │   ├── conftest.py          # Shared pytest fixtures\n│   │   ├── test_runner.py       # Python test execution engine\n│   │   └── integration-test-simple.ps1 # PowerShell automation\n│   └── test_mcp_server.py       # MCP server unit tests ✅\n├── scripts/                     # Metadata discovery scripts\n│   ├── search_data_entities.ps1 # PowerShell entity search\n│   ├── get_data_entity_schema.ps1 # PowerShell schema retrieval\n│   ├── search_enums.py          # Python enumeration search\n│   ├── get_enumeration_info.py  # Python enumeration info\n│   ├── search_actions.ps1       # PowerShell action search\n│   └── get_action_info.py       # Python action information\n├── docs/                        # Comprehensive documentation\n├── pyproject.toml               # Project configuration\n└── README.md                    # This file\n```\n\n## Configuration Options\n\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| `base_url` | str | Required | D365 F&O base URL |\n| `client_id` | str | None | Azure AD client ID |\n| `client_secret` | str | None | Azure AD client secret |\n| `tenant_id` | str | None | Azure AD tenant ID |\n| `use_default_credentials` | bool | True | Use Azure Default Credential |\n| `credential_source` | str | \"environment\" | Credential source: \"environment\", \"keyvault\" |\n| `keyvault_url` | str | None | Azure Key Vault URL for credential storage |\n| `verify_ssl` | bool | False | Verify SSL certificates |\n| `timeout` | int | 30 | Request timeout in seconds |\n| `metadata_cache_dir` | str | Platform-specific user cache | Metadata cache directory |\n| `use_label_cache` | bool | True | Enable label caching V2 |\n| `label_cache_expiry_minutes` | int | 60 | Label cache expiry time |\n| `use_cache_first` | bool | False | Enable cache-first mode with background sync |\n\n### Cache Directory Behavior\n\nBy default, the client uses platform-appropriate user cache directories:\n\n- **Windows**: `%LOCALAPPDATA%\\d365fo-client` (e.g., `C:\\Users\\username\\AppData\\Local\\d365fo-client`)\n- **macOS**: `~/Library/Caches/d365fo-client` (e.g., `/Users/username/Library/Caches/d365fo-client`)\n- **Linux**: `~/.cache/d365fo-client` (e.g., `/home/username/.cache/d365fo-client`)\n\nYou can override this by explicitly setting `metadata_cache_dir`:\n\n```python\nfrom d365fo_client import FOClientConfig\n\n# Use custom cache directory\nconfig = FOClientConfig(\n    base_url=\"https://your-fo-environment.dynamics.com\",\n    metadata_cache_dir=\"/custom/cache/path\"\n)\n\n# Or get the default cache directory programmatically\nfrom d365fo_client import get_user_cache_dir\n\ncache_dir = get_user_cache_dir(\"my-app\")  # Platform-appropriate cache dir\nconfig = FOClientConfig(\n    base_url=\"https://your-fo-environment.dynamics.com\", \n    metadata_cache_dir=str(cache_dir)\n)\n```\n\n## Testing\n\nThis project includes comprehensive testing at multiple levels to ensure reliability and quality.\n\n### Unit Tests\n\nRun standard unit tests for core functionality:\n\n```bash\n# Run all unit tests\nuv run pytest\n\n# Run with coverage\nuv run pytest --cov=d365fo_client --cov-report=html\n\n# Run specific test file\nuv run pytest tests/test_client.py -v\n```\n\n### Integration Tests\n\nThe project includes a sophisticated multi-tier integration testing framework:\n\n#### Quick Start\n\n```bash\n# Run sandbox integration tests (recommended)\n.\\tests\\integration\\integration-test-simple.ps1 test-sandbox\n\n# Run mock server tests (no external dependencies)\n.\\tests\\integration\\integration-test-simple.ps1 test-mock\n\n# Run with verbose output\n.\\tests\\integration\\integration-test-simple.ps1 test-sandbox -VerboseOutput\n```\n\n#### Test Levels\n\n1. **Mock Server Tests** - Fast, isolated tests against a simulated D365 F&O API\n   - No external dependencies\n   - Complete API simulation\n   - Ideal for CI/CD pipelines\n\n2. **Sandbox Tests** ⭐ *(Default)* - Tests against real D365 F&O test environments\n   - Validates authentication\n   - Tests real API behavior\n   - Requires test environment access\n\n3. **Live Tests** - Optional tests against production environments\n   - Final validation\n   - Performance benchmarking\n   - Use with caution\n\n#### Configuration\n\nSet up integration testing with environment variables:\n\n```bash\n# Copy the template and configure\ncp tests/integration/.env.template tests/integration/.env\n\n# Edit .env file with your settings:\nINTEGRATION_TEST_LEVEL=sandbox\nD365FO_SANDBOX_BASE_URL=https://your-test.dynamics.com\nD365FO_CLIENT_ID=your-client-id\nD365FO_CLIENT_SECRET=your-client-secret\nD365FO_TENANT_ID=your-tenant-id\n```\n\n#### Available Commands\n\n```bash\n# Test environment setup\n.\\tests\\integration\\integration-test-simple.ps1 setup\n\n# Dependency checking\n.\\tests\\integration\\integration-test-simple.ps1 deps-check\n\n# Run specific test levels\n.\\tests\\integration\\integration-test-simple.ps1 test-mock\n.\\tests\\integration\\integration-test-simple.ps1 test-sandbox\n.\\tests\\integration\\integration-test-simple.ps1 test-live\n\n# Coverage and reporting\n.\\tests\\integration\\integration-test-simple.ps1 coverage\n\n# Clean up test artifacts\n.\\tests\\integration\\integration-test-simple.ps1 clean\n```\n\n#### Test Coverage\n\nIntegration tests cover:\n\n- ✅ **Connection & Authentication** - Azure AD integration, SSL/TLS validation\n- ✅ **Version Methods** - Application, platform, and build version retrieval\n- ✅ **Metadata Operations** - Entity discovery, metadata API validation\n- ✅ **Data Operations** - CRUD operations, OData query validation\n- ✅ **Error Han",
  "bytes": 60000,
  "sha": "53386fe0b0853689df08aa92a40da75ec8e25adc5188e0d7bbeb8db13b4c3bd6",
  "repo_slug": "mafzaal/d365fo-client",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_mafzaal_d365fo_client_59c856f8/readme"
}