Claude Code Won’t Take Your Job. An F&O Developer Using Claude Code Might
AI coding assistants are impressive in C#, Python and JavaScript, and often disappointing in X++. The reason is not the model. It is that the model has never seen your Dynamics 365 Finance & Operations metadata. Connect Claude Code to that metadata through an open-source MCP server, and the same model starts producing X++ that compiles, follows best practices and comes with unit tests.
Why Generic AI Struggles with X++
Ask a general-purpose assistant to write a Chain of Command extension on SalesTable and you will get something that reads well. Then the compiler disagrees. A typical first draft looks like this:
[ExtensionOf(tableStr(SalesTable))]
final class SalesTable_Extension
{
public boolean validateWrite()
{
boolean ret = next validateWrite();
CustTable cust = CustTable::findByAccount(this.CustomerId);
if (cust.CreditLimit < this.totalAmount())
ret = checkFailed(“Credit limit exceeded”);
return ret;
}
}
It looks right and it will not compile. CustTable::findByAccount() does not exist, SalesTable has no CustomerId field, CreditLimit is really CreditMax, and totalAmount() is invented. The error text is hard-coded instead of a label, and the class name has no model prefix.
Three things explain this:
- Your codebase is private. Standard, ISV and customer models are not part of any model’s training data.
- X++ is metadata, not just code. Tables, EDTs, forms, labels and security live as XML in the AOT. The code is only part of the story.
- Plausible is not compilable. Guessed signatures and invented fields produce a compile-fix loop that eats the time you hoped to save.
The fix is context, and the Model Context Protocol (MCP) is how you deliver it. MCP is an open standard that lets an AI client such as Claude Code call external tools through one protocol.
Two MCP Servers, Two Jobs
Many people have heard that Microsoft released an MCP server for Finance & Operations and assume it is a developer tool. It is not. There are two servers worth knowing, and they solve different problems.
Microsoft’s Dynamics 365 ERP MCP server is a runtime agent for business processes. It lets an AI agent find and update data, navigate forms and call custom actions in a live environment, under the signed-in user’s security roles.
The community d365fo-mcp-server is a design-time tool for X++ developers. It never touches business data. It reads and writes metadata: classes, tables, forms, EDTs, labels and security objects, and it can build and test from the chat.

One asks the ERP to do things. The other helps you change the ERP. They work well together: build a feature with the developer server, then let an agent on the ERP server create test data and walk the form.
How the Server Keeps the AI Honest
The d365fo-mcp-server indexes your whole installation once: more than 580,000 symbols across standard, ISV and custom models, plus over 20 million label rows. It then exposes that knowledge as 20 specialised tools. Search answers in under 10 milliseconds, according to the project’s documentation.
Behind the tools sit three data sources:
- A symbols database (SQLite with full-text search) for fast lookups of classes, tables, forms, EDTs and enums.
- A labels database, kept separate so symbol searches never scan label rows.
- A C# bridge that runs on the Windows dev VM. It uses Microsoft’s own IMetadataProvider API for live reads and for writes, and the cross-reference database for exact “who calls what” answers.
What makes it different from pointing an AI at a source folder is the chain every change has to pass before it is saved:
- Prepare. The server returns the exact method signature, any existing Chain of Command wrappers and naming rules, and issues a token bound to the object being changed.
- Generate. Claude writes X++ against that real metadata.
- Check references. Every type, field, method and label in the code is proven against the index.
- Check best practices. Offline rules catch deprecated APIs, Chain of Command mistakes and transaction anti-patterns.
- Write. The object is written through the metadata API and registered in your project.
- Build and test. Compile, best-practice check, database sync and SysTest unit tests all run from the chat.
If a check fails, the AI receives a structured error with the fix, instead of you receiving a broken file. The reference check is the heart of it: with enforcement switched on, code that names a field that does not exist is rejected before it reaches disk.
The server also ships a form pattern engine that clones reference forms and validates their structure, and a queryable X++ knowledge base covering select grammar, Chain of Command rules, posting, number sequences and AX 2012 migration patterns.
Getting Set Up
You need a D365 F&O development machine, Node.js 24, the .NET SDK (already on F&O dev VMs) and an AI client. From platform update 10.0.49, Visual Studio 2026 is the supported IDE for X++; earlier versions use Visual Studio 2022 17.14 or later. The project’s quick start puts installation at about 10 minutes, or roughly 25 with a full local index.
- Install on the VM. One PowerShell line installs Node.js if needed and the server from npm:
irm https://raw.githubusercontent.com/dynamics365ninja/d365fo-mcp-server/main/install.ps1 | iex - Run the setup wizard (d365fo-mcp setup). It asks for your scenario, custom models, object prefix and label languages, then builds the C# bridge and the index.
- Register the server in Claude Code with claude mcp add-json. The wizard prints the exact configuration for your paths.
- Add the instruction file. Copy the repository’s .github/copilot-instructions.md to the parent of your solution folders as CLAUDE.md. It is mandatory: it tells the agent which tool to use, to confirm before writing, and never to edit .xml or .xpp files with generic file tools.
- Verify. Run npx d365fo-mcp doctor, then ask Claude to find every table that carries the CustAccount field. A correct setup answers with objects from your own ISV and custom models.
Cloud-hosted VM or UDE
The tools and prompts are the same on both. Only the plumbing differs, and the wizard detects which one you are on.

Local or Azure-hosted
A single developer can run everything locally: Claude Code starts the server itself, with no port and no service. A team can host one shared, read-only index on Azure App Service, refreshed by a pipeline, with a small local companion on each VM for writes, builds and tests. A hosted instance must be protected with an API key; the server refuses to start on a public address without one.
One setting deserves attention. Grounding enforcement, which rejects any write that was not prepared and proven first, is off by default. Switch it on once your workflow reliably starts with the prepare step.
Three Everyday Scenarios
These are the three scenarios we built our internal Learn & Share session around. Each is something an F&O developer does every week. In all three you describe the goal in plain language; you never name a tool.
1. Analysing Existing Functionality
Before touching a feature, you need to understand it. A prompt such as “explain end to end how this feature works: entry points, classes, tables and the standard objects it extends” triggers a chain of lookups. Claude searches the index, reads the objects, lists every Chain of Command wrapper and event handler on the path, and traces security from role to duty to privilege to entry point.
The answer cites real objects and methods, including custom and ISV code no model was trained on. It is the kind of tracing that otherwise means hours in the AOT browser.
2. From FDD to TDD to Working Code
We hand Claude a functional design document in our standard template. The example requirement: sales orders must not be created for customers that credit control has not yet approved. A new Yes/No parameter on the customer controls it, and selecting a non-approved customer on a new sales order raises a warning and rejects the value.
The work runs in two steps:
- FDD to TDD, in plan mode. Claude analyses the standard objects involved and writes a technical design: objects to create or extend with exact names, labels, security, verified method signatures, existing wrappers and a test plan mapped to the acceptance criteria. No X++ yet. This is where the developer’s judgement matters most: is the validation in the right place, and is anything missing?
- TDD to code, test-first. Claude creates the SysTest class first and proves it fails. Then it implements the table and form extensions, the validation, the labels and the privilege, builds with the best-practice check, syncs the database and reruns the tests until they pass.
The failing test comes first on purpose. A test that passes on its first run has proven nothing about its assertion.
3. Root-cause Analysis and Bugfix
The starting point is an incident ticket: new sales orders have no payment terms. Claude traces where the payment terms field is set when a customer is selected and lists every extension on that path. It finds a custom Chain of Command wrapper that restores a value after the call to next, wiping the default the standard code had just set.
Then comes the part that matters for quality. Claude writes a unit test that reproduces the incident, shows it failing, applies the smallest fix that still honours the original requirement, and shows it passing. The incident becomes a permanent regression guard.
What Actually Changes for Developers
The job does not disappear. Its centre of gravity moves.
- From typing to specifying. The quality of the FDD, the TDD and the prompt now drives the quality of the output.
- From searching to reviewing. You read evidence and diffs instead of browsing the AOT.
- From “it compiles” to “it’s proven”. Tests and checks become the default, not a luxury.
- Accountability stays human. You sign the code. The tool does not attend the go-live.
The developers who benefit most are those who know the business and the platform well enough to direct the AI and catch its mistakes. Deep F&O knowledge becomes more valuable, not less.
Guardrails We Recommend

On cost: the server is free, but model usage is not. The project’s own measured runs show a full greenfield module consuming around 411,000 tokens of context, while a single Chain of Command change needs a fraction of that. Its guidance is to discover on a small model, build on a mid-size one and reserve the largest for architecture-heavy work.
On confidentiality: the server runs on your machine, but the context Claude reads is sent to the model provider under your account’s terms. For client code, that means following each client’s policy.
Where to Start
- Install the server on your own dev VM and add the instruction file.
- Run the verification prompts until a search returns your own custom objects.
- Spend the first week on analysis only: explain flows, trace security, investigate tickets.
- Then make one small change, test-first, and have a colleague review it.
AI is changing how software is built, and Dynamics 365 F&O is no longer an exception. If you would like to see how AI-assisted X++ development could work in your project, get in touch with us at axm365.com.
Sources
- d365fo-mcp-server on GitHub — README, architecture, tool reference, setup and usage examples
- Use Model Context Protocol for finance and operations apps — Microsoft Learn
- What’s new in platform update 10.0.49 — Microsoft Learn, Visual Studio 2026 support
