D365 F&O MCP Server
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| MCP_SERVER_MODE | No | Server mode: 'read-write', 'write-only', or 'read-only'. Defaults to 'read-write'. | read-write |
| D365FO_SOLUTIONS_PATH | Yes | Path to the Visual Studio solution directory for D365FO projects. | |
| D365FO_WORKSPACE_PATH | Yes | Path to the D365FO workspace (e.g., AosService\PackagesLocalDirectory\YourPackageName\YourModelName). |
Capabilities
Features and capabilities supported by this server
| Capability | Details |
|---|---|
| tools | {} |
| logging | {} |
| prompts | {} |
| resources | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| searchA | Search pre-indexed D365FO objects by name or keyword. Three modes in ONE tool:
• single (default) → pass |
| generate_objectA | Generate X++/AOT code. Choose a |
| analyze_codeA | Learn from the existing codebase. Choose a |
| d365fo_fileA | Create, modify, or generate a D365FO AOT object. Choose an |
| find_referencesA | Find all references (where-used) to a class, method, field, table, enum, or LABEL. Essential for impact analysis before refactoring. For a method, SCOPE it to its declaring type — pass "Owner.method" (e.g. "SalesTable.initFromSalesQuotationTable"), set ownerName alongside a bare method name, or pass an AOT path ("/Tables/SalesTable/Methods/initFromSalesQuotationTable"). A bare method name (no owner) matches that name on every type and over-reports. For a label, pass the label id as targetName (e.g. "@WAX2194" or "@MyLabelFile:MyLabel"); results span every referencing object type (tables, forms, EDTs, enums, reports, menu items, …), not just code, and require the xref database (DYNAMICSXREFDB, full server mode). |
| get_object_infoA | Read D365FO object metadata. For 2+ objects pass objects:[{objectType,objectName},…] (max 10) — ONE call, run in parallel, per-object sections back; never loop single calls. One object: {objectType, name}. Pick the kind via objectType: class, table, form, query, view, enum, edt, report, data-entity, menu-item, service, map, config-key, security-policy, macro. Extension types (table-extension, form-extension, enum-extension, edt-extension, data-entity-extension) list all extensions of a base object — pass the base object name or a full extension name (the dot suffix is stripped automatically). Type-specific flags go in options. For CLASSES, {"members":"names"} (optional {"prefix":...}) returns a fast IntelliSense-style member-name list instead of full metadata. Replaces the former get__info, code_completion, batch_get_info and get_method tools. |
| labelsA | Unified label operations — read and write. Choose an |
| object_patternsA | Pattern toolkit. Choose a
|
| security_infoA | D365FO security lookup. Choose a |
| extension_infoA | D365FO extensibility analyzer. Choose a |
| validate_object_namingA | Validate a proposed D365FO object name against naming conventions: extension naming, ISV prefix, type-specific suffixes, and conflict detection against the symbol index. |
| get_workspace_infoA | ALWAYS call FIRST at session start. Returns model name, package path, framework directory, project path, environment type, and EXTENSION_PREFIX. Flags placeholder model names and missing prefix. projectName/projectPath ONLY when the USER changed project. This is the authoritative source for target model — not search results. |
| verify_d365fo_projectA | Verify that D365FO objects exist on disk at the correct AOT path and are referenced in the .rnrproj project file. Use instead of PowerShell to check d365fo_file(action="create") results. Omit |
| update_symbol_indexA | Index D365FO XML file(s) changed OUTSIDE this server (hand edit, Visual Studio, git checkout). Do NOT call after d365fo_file create/modify — those refresh the index on their way out, so a follow-up call is a wasted round trip. One genuine same-session case: a brand-new AxEdt/AxEnum you are about to name in a generate_object |
| build_d365fo_projectA | Build a D365FO model with xppc.exe (compiles the ENTIRE model, not one project). Blocks until done — call ONCE per build, do NOT poll (wait:false = legacy polling mode). fullBuild:true fixes "not been successfully compiled since it was last changed" stale-symbol errors. |
| trigger_db_syncA | Run a D365FO database sync (SyncEngine.exe). Supports partial sync of specific tables — much faster than full-model sync. Use partial sync after adding/renaming fields or indexes on known tables. Pass projectPath to auto-extract tables from .rnrproj for smart partial sync. Use full sync only when unsure what changed. |
| run_bp_checkA | Run Microsoft Best Practices checker (xppbp.exe) on a D365FO project. Returns BP warnings and errors with rule codes (e.g. BPErrorLabelIsText, BPXmlDocNoDocumentationComments). |
| run_systest_classA | Execute a D365FO unit test class via SysTestConsole.exe. Needs an interactive console session — fails headless. |
| review_workspace_changesA | Code review of uncommitted X++ changes (git diff HEAD): BP violations, missing labels, CoC patterns. Windows/local mode only. NOT for verifying writes (use verify_d365fo_project + get_object_info instead). If the diff looks truncated, do NOT read .xml/.xpp via built-in tools — proceed with the visible portion or narrow the scope. |
| undo_last_modificationA | Safely roll back incorrectly generated code by restoring a file to its last committed state. If the file is tracked by git, runs git checkout HEAD — this discards ALL uncommitted changes to the file, not just the most recent edit (the "last modification" name is historical). If the file is untracked (newly created), deletes it. Also re-syncs the symbol/label index to the restored content — prefer this over a manual git revert or editor undo, which leave the index stale and (for .xml/.xpp) can desync the VS 2022 in-memory model. ⚠️ Local companion tool: available only in write-only/local mode (Windows VM). |
| get_knowledgeA | X++ knowledge lookup. Choose a |
| validate_codeA | Static validator for generated X++/XML (paste the text). Choose a |
| prepareA | ONE-call context aggregator + groundingToken (30-min TTL, required for extension/new-object writes when GROUNDING_ENFORCE=true). Choose a |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
| xpp_system_instructions | System instructions for AI assistants (GitHub Copilot, Claude Code) when working with D365 Finance & Operations X++ development |
| xpp_create_file | 🔥 USE THIS WHEN CREATING D365FO FILES: Mandatory workflow for creating D365FO classes, tables, forms, enums. ALWAYS use d365fo_file(action="create") tool FIRST. |
| xpp_code_review | Review X++ code for best practices and potential issues |
| xpp_explain_class | Get a detailed explanation of an X++ class |
| xpp_extension_guide | Complete guide for CoC (Chain of Command) extensions and event handlers in D365FO |
| xpp_security_guide | D365FO security model creation guide: privilege, duty, role, and menu item workflow |
| xpp_sysoperation_guide | SysOperation framework reference: DataContract + Controller + Service pattern for batch operations |
| xpp_data_entity_guide | Data entity development guide: OData, DMF, staging tables, computed columns |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
| Workspace Context Snapshot | Curated snapshot of the current work: active model/project, recently edited objects, uncommitted X++ changes and index freshness. Read this first to ground a session. |
| Active Object | The object the developer is most likely working on (most recently modified X++ file) enriched with its indexed metadata. Proxy for editor focus — MCP exposes roots, not the cursor. |
| Workspace Statistics | Symbol-index totals by type, indexed models and workspace file counts. |
| Workspace Files | List of X++ metadata files detected in the workspace (most recent first). |
| Recent Workspace Changes | Uncommitted X++ object files (vs HEAD + untracked). Empty when not a git repo. |
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/dynamics365ninja/d365fo-mcp-server'
If you have feedback or need assistance with the MCP directory API, please join our Discord server