D365 F&O MCP Server
It is a D365FO MCP server that grounds AI coding against your indexed X++ metadata and supports the full development workflow.
Search and inspect the indexed D365FO codebase: classes, tables, forms, EDTs, enums, labels, security artifacts, and references.
Generate X++/AOT code from patterns, scaffolds, table methods, relations, and field definitions.
Analyze existing implementations, pattern usage, API usage, and class completeness.
Validate generated X++ and XML for syntax, best practices, and real symbol references before writing.
Create, modify, delete, undo, and project-register D365FO AOT objects safely.
Build forms with pattern recommendations, specs, cloning, validation, and auto-repair.
Manage labels: search, inspect translations, create, update, and rename.
Analyze security hierarchies and extensibility: CoC, events, extension points, table merges, and strategy recommendations.
Validate object naming, workspace configuration, and project/object existence.
Build models, run DB sync, best-practice checks, and SysTest unit tests.
Provide X++ knowledge, error diagnosis, operation specs, and BP moniker help.
Aggregate grounded context with
preparetokens for safer writes.Optionally support read-only AxDB SQL queries and performance tracing when configured.
Provides 54 specialized tools for GitHub Copilot to interact with a D365FO codebase, enabling instant lookup of class signatures, table relations, EDT definitions, CoC extensions, menu items, security coverage, labels, and more, directly within Copilot's agent mode in Visual Studio.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@D365 F&O MCP Server Find CoC extensions for CustTable.insert()"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
D365 F&O MCP Server
22 AI tools that know every X++ class, table, form, and EDT in your D365FO codebase
Grounded AI development for Dynamics 365 Finance & Operations — works with GitHub Copilot and Claude Code
These connect an editor to a server that is already deployed — see Quick Start if you still need to set one up.
Why
AI assistants excel at C#, Python, and JavaScript. X++ is different: your D365FO codebase is private, deeply customized, and invisible to every model — so AI confidently generates code that doesn't compile.
This server pre-indexes your entire D365FO installation (580 000+ symbols across standard, ISV, and custom models) and exposes it as 22 specialized MCP tools (axdb_sql and trace_d365fo only once configured). Every signature, every CoC wrapper, every label, every form pattern — verified against your real metadata before the AI writes a single line.
Task | Without this server | With this server |
Method signatures | Guessed → compile errors | Exact, from your codebase |
Existing CoC wrappers | Manual AOT search |
|
New forms | Hand-written XML, broken patterns | Cloned from reference forms, validated against the pattern catalog |
Labels | Hardcoded strings | Right |
Security chains | Hours of manual tracing | Role → Duty → Privilege → Entry Point in one call |
Generated code | Hallucinated fields and types | Every reference proven against the index, gated before write |
Related MCP server: Dynamics 365 Finance & Operations MCP Server
Capabilities
Feature | Description |
🔍 Full-codebase intelligence | 580K+ symbols indexed: classes, tables, forms, EDTs, enums, labels (20M+ rows), security artifacts — FTS5 search in < 10 ms |
🛡️ Grounded generation | Fail-closed gates: |
🧩 Form pattern engine | Complete catalog of Microsoft form patterns and sub-patterns: recommends the right pattern, clones reference forms with datasource re-binding, deterministically expands patterns that have no reference form, auto-repairs a form's missing required controls, validates structure and blocks invalid writes |
✍️ Safe metadata writes | C# bridge uses Microsoft's own |
🏗️ SDLC integration | MSBuild compilation with structured diagnostics, DB sync, xppbp best practices, SysTestRunner — all from chat. Optional |
🗄️ Optional AxDB SQL | Off by default and not even published until configured: |
⏱️ Optional performance trace | Off by default and not published until enabled: |
📐 X++ knowledge base | Queryable rules: select grammar, CoC authoring, financial dimensions, the posting engine ( |
Pattern-grounded form development
Forms are the hardest artifact to generate correctly — each pattern dictates required containers, ordering, and allowed sub-patterns. The form pattern engine makes it a guided pipeline:
flowchart LR
A["object_patterns<br/>(domain=form, action=analyze)"] --> B["object_patterns<br/>(domain=form, action=spec)"]
B --> C["generate_object<br/>objectType=form, cloneFrom"]
C --> D["object_patterns<br/>(domain=form, action=validate) FP001–FP011"]
D -->|clean| E["d365fo_file<br/>(action=create) write + project"]
D -->|errors| CStructural violations (wrong order, missing container, disallowed control) block the write — recommendations only warn. Mined pattern statistics from your own environment ground every suggestion in reality.
Quick Start
From D365FO platform update 10.0.49 (PU74), Visual Studio 2026 is the supported IDE for X++ development — Microsoft no longer supports VS 2022. Earlier platform versions still use VS 2022 ≥ 17.14. Details
Installing on your own D365FO VM — the usual case. One line in PowerShell installs Node.js if it is missing, installs the server from npm, and runs the setup wizard, which asks where the index should live and builds the C# bridge for you:
irm https://raw.githubusercontent.com/dynamics365ninja/d365fo-mcp-server/main/install.ps1 | iexAlready have Node.js 24+? Then the one-liner has nothing to bootstrap and you can skip it:
npm install -g d365fo-mcp
d365fo-mcp setupRe-running either is safe. An installation made before the npm package existed is a git checkout, and both are left exactly where they are and updated in place.
Your team already runs a shared server? Then you install nothing — point your editor at it:
npx d365fo-mcp connect https://your-server.azurewebsites.netBoth paths in full — prerequisites, editor configuration for every scenario, the required instruction file, and how to verify grounding actually works: docs/QUICK_START.md
Azure Deployment
One shared instance for the whole team — the metadata index lives in Blob Storage and downloads automatically on startup.
Deployment guide: docs/SETUP_AZURE.md — includes CI/CD pipeline automation
Documentation
Getting started | Reference | Operations |
Quick Start — connect or install | ||
Usage examples — real tool chains | ||
Coverage — what the badge counts | ||
Backlog — deferred work | Eval loop — the self-improvement harness |
License
MIT
Available Tools
20 toolsanalyze_codeARead-only
Learn from the existing codebase. Choose a mode:
• patterns → common classes/methods/dependencies for a scenario (call BEFORE generate_object(mode="pattern")).
• implementations → real implementation examples of a similar method (actual code).
• completeness → missing standard methods on a class (find/exist/validate gaps).
• api-usage → how an API/class is initialized and called in practice.
Inputs: mode (required), limit, apiName, context, +6 more.
build_d365fo_projectAIdempotent
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.
Inputs: wait, force, aosUrl, dbSync, +6 more.
d365fo_fileADestructive
D365FO AOT object files and VS projects. Choose an action:
• create → write a NEW object file into PackagesLocalDirectory (auto-added to .rnrproj). THE WRITE STEP — incomplete until isError=false; ⚠️/❌ = failure. Extensions: objectName="Base.PrefixExtension".
• project → VS project + .sln ops via params.operation: create|delete (confirm first)|add-object|remove-object.
• modify → edit an EXISTING object. APPLIES IMMEDIATELY, no dry-run — confirm with the user first; revert with action="undo". Needs operation.
• delete → remove an object's XML from disk AND un-register it from every .rnrproj listing it. IRREVERSIBLE — confirm with the user first.
• undo → roll back filePath: git-tracked → git checkout HEAD, which discards ALL uncommitted changes to that file, not just the last edit; untracked/outside git → deleted only if created this session.
• generate → XML as TEXT only, no write (Azure/Linux fallback). Try create first. The rest need Windows.
📖 Parameters are NOT inlined here: get_knowledge(kind="op-spec", topic=""|"") returns its contract — pass its values nested in params (modify) / properties (create), along with any packageName/packagePath/solutionPath/workspacePath override.
Model + prefix auto-applied.
Inputs: action (required), params, filePath, modelName, +12 more.
extension_infoARead-only
D365FO extensibility analyzer. Choose a mode:
• coc → Chain of Command extensions + event subscriptions for a class/table. Use before writing a CoC extension to check for conflicts.
• events → event handler subscriptions (SubscribesTo, delegate +=) for a class/table. Use before adding handlers to check for duplicates.
• table-merge → all extensions of a table across models + effective merged schema (base + extension fields/indexes/methods).
• points → available extension points (CoC-eligible/replaceable methods, delegates, blocked methods) and which are already extended.
• strategy → recommends the best extensibility mechanism for a goal (CoC, event handler, business event, data entity, …) with reasoning, risks, alternatives, next steps.
Inputs: mode (required), goal, method, target, +6 more.
find_referencesARead-only
Find all references (where-used) to a class, method, field, table, enum, EDT, or LABEL. 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).
Inputs: targetName (required), limit, ownerName, targetType.
generate_objectA
Generate X++/AOT code. Choose a mode:
• pattern → a named X++ skeleton from the pattern enum (text only, no write). Call analyze_code(mode="patterns") first, then generate_object(mode="pattern"), then d365fo_file(action="create").
• scaffold → pattern-aware whole-object generation (table/form/report) with intelligent field/index/relation or form-pattern suggestions; set objectType.
• find-methods → find()/findRecId()/exists() for a table (text), keyed on its primary/unique index.
• relation-xpp → a table's relation(s) → X++ select + QueryBuildRange (text).
• fields → field names → AxTableField XML with auto-resolved EDTs + optional field group.
• table-relation → EDT-referencing fields → AxTableRelation XML (inverse of relation-xpp).
📖 Mode parameters are NOT inlined here: get_knowledge(kind="op-spec", topic="") — "scaffold:table"/"scaffold:form"/"scaffold:report" for the scaffolds — returns the contract; pass its values nested in params.
For a single existing object definition's XML use d365fo_file(action="generate") instead.
Inputs: mode (required), name, params, pattern, +2 more.
get_knowledgeARead-only
X++ knowledge lookup. Choose a kind:
• knowledge → queryable X++ rulebook: verified patterns, BP rules, AX2012→D365FO migration. Use BEFORE generating code. Topics incl.: select-statement, coc-authoring, bp-rules, sysoperation, event-handlers, workflow, number-sequences, security, sysda, form patterns.
• error → diagnose a D365FO/X++ compiler or runtime error: structured root cause + step-by-step fix + corrected X++ example (TTS mismatch, UpdateConflict, CSUV1, SYS10028 missing next, overlayering, BP errors, …). Call this instead of guessing — X++ error semantics differ from C#/.NET.
• op-spec → the parameter contract for ONE d365fo_file operation/objectType or ONE generate_object mode (topic = "add-index", "table", "scaffold:form", …). Those two tools deliberately do not ship their parameters inline; call this after picking the operation, before the call. Omit topic for the index of available topics.
• bp-moniker → validate an exact BP-check moniker, search by scenario when you have no moniker yet, or render a _BPSuppressions.xml block. Backed by names/text extracted from a real D365FO install — never invents a moniker.
Inputs: kind, path, topic, action, +6 more.
get_object_infoARead-only
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, menu, service, map, config-key, security-policy, macro. The *-extension types 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.
Inputs: name, objects, options, objectType.
get_workspace_infoARead-only
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. Pass projectName/projectPath when you have the project's name or path. Authoritative source for target model — not search results.
Inputs: changes, diagnostics, projectName, projectPath.
labelsADestructive
Unified label operations — read and write. Writing an object? d365fo_file create/modify already turn a raw-text label/fieldLabel into a real @Ref by themselves; no call here is needed. Choose an action:
• search → full-text query across indexed label files. Never needed before a create.
• info → all translations for a labelId; without labelId lists label files (with labelFileId: physical .label.txt path per language).
• create → add a label to an AxLabelFile across every language .label.txt (write). ALWAYS pass createIfMissing=true: it creates when absent and reuses when present, so this ONE call replaces search-then-create. Bulk: labels:[{labelId, translations}, …] with shared labelFileId/model at top level does a whole object in one call. Label IDs describe MEANING — never a model prefix; target the model's ORIGINAL label file, never an …_Extension… one.
• update → overwrite the text of an EXISTING label; same args as create with corrected translations[] (write).
• rename → rename a label ID across .label.txt + X++ + XML + index. Use dryRun=true first (write).
Write plumbing (paths, languages, sortLabels, allowExtensionLabelFile…) is auto-resolved; override it via get_knowledge(kind="op-spec", topic="labels").
Inputs: action (required), model, query, dryRun, +10 more.
object_patternsARead-only
Pattern toolkit. Choose a domain:
• table → field/index/relation patterns for D365FO tables. Filter by tableGroup or similarTo a given table.
• form → form-pattern toolkit; pick an action:
analyze → pattern advisor + usage analysis. For a NEW form pass
recommend(preferred): the Microsoft decision tree picks the pattern and names reference forms to clone. Or filter by formPattern / dataSource / similarTo.spec → structure spec of a pattern/sub-pattern: hierarchy, ordering, allowed children, reference forms, lifecycle.
validate → AxForm XML validator (hierarchy/order, sub-patterns, PatternVersion) → FP001-FP011. Call before d365fo_file action=create. • report → SSRS implementation recipes: object roster, scaffold call, checks. Optional pattern=. • mobile-app → warehouse-app screen recipes, led by the choice between the two frameworks that build them (ProcessGuide vs WHSWorkExecuteDisplay): create a flow, add or replace one screen, step icon/title, GS1 scan input. Optional pattern=.
Inputs: xml, limit, action, domain, +8 more.
prepareARead-only
ONE-call context aggregator + groundingToken (30-min TTL, required for extension/new-object writes when GROUNDING_ENFORCE=true). Choose a mode:
• change → extending/modifying an EXISTING object: exact signature, existing CoC wrappers, eligibility, recommended strategy, naming, patterns. Replaces the analyze→search→info→generate loop.
• create → a NEW object: collision check, naming with auto-prefix, similar objects, EDT suggestions, reusable labels, mined property defaults.
• test → writing a SysTest for an existing class: methods worth covering, tests that already exist, whether the model references TestEssentials, and the red-first cycle.
Inputs: goal (required), mode (required), objectName (required), operation, +4 more.
run_bp_checkARead-only
Run Microsoft Best Practices checker (xppbp.exe) on a D365FO project. Returns BP warnings and errors with rule codes (e.g. BPErrorLabelIsText, BPXmlDocNoDocumentationComments). Runs AFTER a build, not after a write — and build_d365fo_project(bpCheck:true) already folds this check into the build, so a separate call is rarely needed.
Inputs: objects, modelName, packagePath, projectPath.
run_systest_classB
Run a D365FO unit test class (SysTestConsole; UDE: cloud runtime), returning per-method results.
Inputs: className (required), modelName, testMethod, packagePath.
searchARead-only
Search pre-indexed D365FO objects by name or keyword. Three modes in ONE tool:
• single (default) → pass query; returns name, type, model.
• batch → pass queries[] (max 10) to run searches in parallel (3× faster, with dedup + cross-reference).
• extensions → set scope:"extensions" to restrict to custom/ISV models only (filters out Microsoft standard code). Model names in those results are SOURCE models — never use them as create/modify targets.
Use get_object_info(objectType, name) when you already know the exact name and need full details.
Inputs: type, limit, query, scope, +3 more.
security_infoARead-only
D365FO security lookup. Choose a mode:
• artifact → details + full hierarchy of a named privilege/duty/role (Role → Duties → Privileges → Entry Points).
• coverage → reverse chain for an object: which privileges/duties/roles grant access (object → menu items → privileges → duties → roles).
Inputs: mode (required), name, objectName, objectType, +2 more.
update_symbol_indexAIdempotent
Index D365FO XML changed OUTSIDE this server (VS, hand edit, git pull). Do NOT call after d365fo_file create/modify — they re-index already. No args = bridge/cache refresh only.
Inputs: model, filePath.
validate_codeARead-only
Static validator for generated X++/XML (paste the text). Choose a mode:
• syntax → offline best-practice/BP validator (no xppbp.exe). Structured violations {rule, severity, line, excerpt, fix}. Covers select, CoC, BP and table-XML rules mined from standard models.
• references → semantic reference resolver (index-only): verifies every type, field, method (incl. arity), enum, label and intrinsic (tableStr/fieldStr/…) EXISTS in the indexed codebase. codeType="xml-table" checks XML refs instead: EDT/enum/relation/extends/label.
Call mode="both" AFTER generating, BEFORE writes; fix errors in the same turn. Write tools run references internally when GROUNDING_ENFORCE=true.
Inputs: code (required), mode (required), context, codeType.
validate_object_namingARead-only
Validate a proposed D365FO object name: extension naming/formats, ISV prefix, type suffixes, conflicts in the symbol index.
Inputs: objectType (required), proposedName (required), modelPrefix, baseObjectName, +1 more.
verify_d365fo_projectARead-only
Verify that D365FO objects exist on disk at the correct AOT path and are referenced in the .rnrproj project file. Use instead of PowerShell. Runs AFTER a build, not after a write: d365fo_file already verifies its own write inline (on disk + .rnrproj reference) and says so in its response. Omit objects to verify the ENTIRE project: every object referenced in the .rnrproj is checked on disk (requires projectPath, or an auto-detected/configured project).
Inputs: objects, modelName, projectPath.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 20 tools
Most tools target distinct lifecycle stages, but generation/pattern/knowledge/validation capabilities overlap heavily across generate_object, d365fo_file, object_patterns, analyze_code, get_knowledge, validate_code, and prepare. The very detailed descriptions provide routing guidance, but an agent still has multiple plausible entry points for common tasks such as generating or validating an object.
Names are consistently snake_case and readable, but the set mixes verb_noun names (generate_object, get_object_info) with bare nouns/actions (search, labels, prepare, d365fo_file) and noun_info names (security_info, extension_info). The convention is recognizable but not uniform.
Twenty tools is plausible for a broad D365FO development lifecycle, but it sits at the heavy end and includes several mode-heavy tools whose responsibilities overlap. Some consolidation, especially around generation, knowledge lookup, and preparation, could reduce surface area without losing capability.
The surface covers workspace discovery, search, object inspection, generation, file/project operations, labels, extensibility, security, validation, build, BP checks, verification, and unit tests. Minor gaps remain around packaging/deployment or environment lifecycle operations, but core development workflows are well represented.
Maintenance
Related MCP Connectors
D365 F&O: 90 AI tools over 200K+ objects, 25M+ cross-refs, 24M+ label translations.
Governance copilot for AI-assisted coding. 72 packs, 532 rules, proof bundles.
Read-only AI coding tools for change verification, release readiness, capacity, and guidance.
Code intelligence platform for AI agents. 20 tools for architecture, security & impact analysis.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables AI assistants to explore metadata, query data, and perform write operations across multiple Microsoft Dynamics 365 Finance & Operations environments. It features specialized tools for OData execution and data analysis with built-in read-only safety for production environments.44 npm10MIT
- AlicenseAqualityBmaintenanceExposes the full capabilities of Microsoft Dynamics 365 Finance & Operations to AI assistants through 49 comprehensive tools and standardized protocol interactions. It enables sophisticated workflows including OData operations, metadata discovery, and secure database analysis.49118 PyPI41MIT
- AlicenseNot gradedqualityDmaintenanceEnables D365 F\&O development including object creation, modification, deletion, and analysis through the MCP standard.42MIT
- FlicenseNot gradedqualityBmaintenanceEnables AI assistants to search and analyze Microsoft Dynamics 365 Finance & Operations artifacts, read local source code, and generate context-aware solutions through natural language.118 npm12-