Skip to main content
Glama

D365 F&O MCP Server

20 AI tools that know every X++ class, table, form, and EDT in your D365FO codebase

npm License: MIT Node.js TypeScript Tests

Core coverage Total coverage

Grounded AI development for Dynamics 365 Finance & Operations — works with GitHub Copilot and Claude Code

Install in VS Code Install in VS Code Insiders Add to Cursor

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 20 specialized MCP tools. Every signature, every CoC wrapper, every label, every form pattern — verified against your real metadata before the AI writes a single line.

Solution Architecture

Task

Without this server

With this server

Method signatures

Guessed → compile errors

Exact, from your codebase

Existing CoC wrappers

Manual AOT search

extension_info(mode="coc") in < 50 ms

New forms

Hand-written XML, broken patterns

Cloned from reference forms, validated against the pattern catalog

Labels

Hardcoded strings

Right @SYS/@MODULE key found instantly

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: D365 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: prepare issues grounding tokens, validate_code(mode="references") proves every identifier, validate_code(mode="syntax") enforces best practices — hallucinated code never reaches disk

🧩 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 IMetadataProvider wherever it can express the object; the few types and ops it cannot go through structured XML writers with ambiguity guards — never blind string replacement. Automatic .rnrproj registration, one-call undo

🏗️ SDLC integration

MSBuild compilation with structured diagnostics, DB sync, xppbp best practices, SysTestRunner — all from chat

📐 X++ knowledge base

Queryable rules: select grammar, CoC authoring, financial dimensions, the posting engine (LedgerVoucher), number sequences, SysExtension, Electronic Reporting, AX2012→D365FO migration — prevents deprecated APIs

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–FP010"]
    D -->|clean| E["d365fo_file<br/>(action=create) write + project"]
    D -->|errors| C

Structural 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 | iex

Already have Node.js 24+? Then the one-liner has nothing to bootstrap and you can skip it:

npm install -g d365fo-mcp
d365fo-mcp setup

Re-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.net

Both 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.

Deploy to Azure

Deployment guide: docs/SETUP_AZURE.md — includes CI/CD pipeline automation


Documentation

License

MIT

Available Tools

20 tools
analyze_codeA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
modeYesWhich analysis to run.
limitNo[patterns] Maximum number of pattern examples to return
apiNameNo[api-usage] REQUIRED. Name of the API/class to get usage patterns for.
contextNo[api-usage] Optional context to filter patterns (e.g., "initialization", "validation").
scenarioNo[patterns] REQUIRED. Scenario/functionality to analyze (e.g., "financial dimensions", "inventory transactions").
classNameNo[implementations|completeness] REQUIRED. Class to analyze / containing the method.
methodNameNo[implementations] REQUIRED. Name of the method to implement.
parametersNo[implementations] Method parameters.
returnTypeNo[implementations] Method return type.void
classPatternNo[patterns] Optional class name pattern to filter results (e.g., "Helper", "Service").

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare readOnlyHint=true, so the tool is known to be harmless. The description adds value by explaining what each mode returns (e.g., 'real implementation examples', 'missing standard methods'), offering behavioral context beyond the schema. It doesn't discuss performance or limitations, but the read-only nature is covered by annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with a brief opening and a bulleted list of modes. It is concise enough for a multi-mode tool and front-loads the core action. Every sentence adds information, though the list is somewhat lengthy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Without an output schema, the description compensates by explaining the return type of each mode (patterns, code examples, gaps, usage). Given the tool's complexity (10 params, 4 modes) and the read-only annotation, the description is sufficiently complete for an agent to select and invoke the tool correctly. Minor gaps remain around edge-case behavior, but not critical.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description repeats mode-to-parameter associations (e.g., '[patterns]', '[api-usage]') but does not add substantive meaning beyond what the schema already provides. Each parameter's purpose is already documented in the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's function: 'Learn from the existing codebase' and then enumerates four distinct modes with concrete outcomes (patterns, implementations, completeness, api-usage). It distinguishes itself by naming these modes, though the verb 'learn' is somewhat abstract and it doesn't explicitly contrast with sibling tools like get_method or object_patterns.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It provides an explicit usage directive: 'call BEFORE generate_object(mode="pattern")' for the patterns mode. Other modes are described with their purposes, implying appropriate use cases, but no exclusions or comparisons to alternative tools are given.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

build_d365fo_projectA
Idempotent

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
waitNoWhen true (default) the tool blocks until the build finishes and returns the final result in a single call. The agent should make exactly one call per requested build. Set false for legacy fire-and-forget polling behaviour.
forceNoKill any running build processes for this model and restart.
dbSyncNoOn a SUCCESSFUL build, also run the database sync (SyncEngine.exe) — REQUIRED after any table/view/data-entity change. true = partial sync of the syncable objects in the project, full-model when it has none; an ARRAY syncs exactly those tables/views (much faster).
bpCheckNoOn a SUCCESSFUL build, also run the best-practice checker and append its findings. Prefer this to a follow-up run_bp_check call: one build call instead of two round trips.
fullBuildNoFull recompile of the TARGET model only (deps stay incremental). Use when xppc reports stale symbol errors.
modelNameNoD365FO model name to build (e.g. MyCustomModel). Auto-detected from workspace if omitted.
waitTimeoutMsNoMaximum time (ms) to block when wait:true before returning a "still running" snapshot. Defaults to 30 minutes. The build itself continues in the background.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description clearly discloses that the tool blocks until done and warns against polling, which adds real behavioral context. It also explains the effect of fullBuild on stale-symbol errors. Annotations already cover read-only/destructive hints, so the description builds on them without contradiction.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three dense sentences, each earning its place. The key behavioral constraint (blocks, call once, don't poll) is front-loaded, and the fullBuild fix is stated as a specific conditional. No filler or redundant restating of the tool name.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 7-parameter tool with no output schema, the description plus rich input schema covers the important behavioral caveats: blocking, single-call usage, whole-model compilation, and stale-symbol remediation. It is slightly incomplete in not mentioning the dbSync requirement after schema changes, though the schema handles that thoroughly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description adds some interpretive value by explaining the full-model scope and a concrete use case for fullBuild, but most parameter meaning is already well documented in the schema. It does not materially clarify the other six parameters beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific action (Build), a specific resource (D365FO model via xppc.exe), and explicitly distinguishes scope: compiles the ENTIRE model, not one project. This clearly separates it from project-level or verification tools like verify_d365fo_project.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives strong operational guidance: call exactly once per build, do not poll, and use fullBuild:true for stale-symbol errors. It does not explicitly name sibling alternatives or state when to use an alternative tool, but the blocking semantics and fullBuild trigger provide clear usage context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

d365fo_fileA
Destructive

Create, modify, delete, undo, or generate a D365FO AOT object. Choose an action: • create → write a NEW object file into PackagesLocalDirectory (UTF-8 BOM, auto-added to .rnrproj). THE WRITE STEP — incomplete until isError=false; ⚠️/❌ = failure. Extensions: objectName="Base.PrefixExtension". • 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 of the model that lists 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 → deleted. • generate → XML as TEXT only, no write (Azure/Linux fallback). Try create first. create/modify/delete/undo need Windows. 📖 Parameters are NOT inlined here: get_knowledge(kind="op-spec", topic=""|"") returns the contract for the one you picked — pass its values nested in params (modify) / properties (create), along with any packageName/packagePath/solutionPath/workspacePath override. Model + prefix auto-applied.

ParametersJSON Schema
NameRequiredDescriptionDefault
actionYes
paramsNo[modify] Operation-specific parameters as ONE nested object, per the op-spec lookup above. A missing/wrong one returns that COMPLETE spec — follow it, do not guess.
filePathNo[modify|delete] Absolute XML path — bypasses symbol-DB lookup. Use for objects just created. [undo] REQUIRED: the file to roll back.
modelNameNoTarget model — auto-detected. NEVER take it from search results (those are source models).
operationNo[modify] REQUIRED unless using operations[]. add-method also UPDATES in place; replace-code is the surgical oldCode→newCode path.
overwriteNoAllow overwriting — never rewrite via PowerShell.
objectNameNoBase name WITHOUT model prefix — the tool prepends it. Extension classes: "{Base}_Extension". NEVER hand-build the prefix.
objectTypeNoEach security/menu-item type is its own AOT folder — NEVER use security-privilege for duty or role. [modify]/[generate] cover the core families + their *-extension variants; [delete] takes the same enum as [create].
operationsNo[modify|create] PREFERRED for 2+ edits to the SAME object — ONE call, not one per edit. On create they run against the just-created object, under the name it actually got. Entries are {operation, …op-spec params}; objectType/objectName/modelName stay top-level. Applied in order, stopped at the first failure, per-operation results back.
propertiesNo[create] Per-objectType creation properties (label, fields[], extends, enumValues[], primaryTable, …) — not in this schema; fetch yours with the op-spec lookup above.
sourceCodeNoX++ source. FOR CLASSES auto-split: <Declaration> = class line + member vars; <Methods> = each method after the closing }.
xmlContentNoComplete XML written verbatim (+overwrite=true rewrites an object).
projectPathNoPath to .rnrproj. Set if known, else auto-detected.
addToProjectNoAdd to the ACTIVE .rnrproj — keep the default.
createBackupNo[modify] Back up before modifying.
groundingTokenNoFrom prepare(change/create). Required for *-extension when GROUNDING_ENFORCE=true; object-bound.

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark the tool destructive and non-read-only, but the description adds rich behavioral detail: UTF-8 BOM writes, auto-registration in .rnrproj, IRREVERSIBLE delete semantics, git checkout HEAD behavior for undo, immediate apply with no dry-run for modify, and Windows-only execution. This goes far beyond the annotations and materially changes how an agent should act.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but densely packed and well-structured with per-action bullets, warnings, and navigation hints. Critical safety information is front-loaded and visually emphasized, and no sentence is filler given the tool's genuine complexity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 5-action tool with 16 parameters and no output schema, the description covers most operational context: environment constraints, op-spec lookup, project-file behavior, failure signals via isError, and per-operation results. The only minor gap is that it does not describe the success return shape in more detail beyond these signals.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is high at 94%, but the description adds essential semantic context: which params nest under params vs properties, how op-spec lookups supply operation-specific contracts, when filePath bypasses symbol-DB lookup, and critical anti-guidance like 'NEVER hand-build the prefix' and 'NEVER take modelName from search results.' This meaningfully exceeds the schema alone.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a precise verb and resource: 'Create, modify, delete, undo, or generate a D365FO AOT object.' Each action is explicitly defined and distinguished from the others, making the tool's boundaries clear even without reading the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives actionable when-to-use guidance for each action: modify applies immediately so confirm first, delete is irreversible, undo discards ALL uncommitted changes, generate is the non-Windows fallback with 'Try create first.' It also tells the agent to fetch op-spec contracts via get_knowledge before invoking, which prevents guessing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

extension_infoA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
goalNo[strategy] REQUIRED. What you want to achieve — e.g. "validate that SalesLine quantity is positive".
modeYescoc/events/table-merge/points need `target`; strategy needs `goal`.
methodNo[coc] filter to a specific method name; [events] filter to a specific event name (e.g. onInserted).
targetNoThe base object: [coc] class/table being extended; [events] class/table whose handlers to find; [table-merge] base table; [points] class/table/form; [strategy] optional target object.
scenarioNo[strategy] Scenario category (auto-detected from goal if omitted). field-defaulting = set defaults on NEW records (initValue); field-change-reaction = react when a user/code CHANGES a field (modifiedField).
objectTypeNo[events] set "table" when target is a table (else class is assumed); [points] object type (default: auto-detect).auto
handlerTypeNo[events] Filter by handler type (default: all).all
includeEventHandlersNo[coc] Also find static event subscriptions (SubscribesTo) (default: true).
includeEffectiveSchemaNo[table-merge] Merge base + extension counts (default: true).
showExistingExtensionsNo[points] Also list who already wraps/subscribes each point — opt-in, roughly doubles the response.

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare readOnlyHint=true and openWorldHint=false, so the tool is known to be read-only. The description adds behavioral context by detailing what each mode returns or analyzes (e.g., effective merged schema, available extension points, who already wraps). It also notes that showExistingExtensions 'roughly doubles the response', a practical performance trait. It does not contradict annotations and adds value beyond them, though it doesn't cover potential errors or latency.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a compact bulleted list, front-loaded with a clear one-line purpose. Each mode is described in one or two sentences with no redundancy. The structure is scannable and every sentence earns its place, from the overall analysis purpose to mode-specific guidance.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with 10 parameters and 5 modes, the description covers all modes and their intended use cases, including which parameters are relevant per mode. It explains outputs (e.g., merged schema, extension points, recommendations) sufficiently without an output schema. No missing critical information prevents an agent from calling the tool correctly, making it complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% with detailed per-parameter descriptions (e.g., mode: 'coc/events/table-merge/points need target; strategy needs goal'). The description adds mode-level context but does not introduce new parameter meanings beyond the schema. Since the schema already documents parameters thoroughly, the baseline of 3 is appropriate; the description names which modes use which parameters, slightly aiding selection but not adding substantial semantics.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states 'D365FO extensibility analyzer' and enumerates five distinct modes (coc, events, table-merge, points, strategy) with specific resources and goals. Each mode is tied to a concrete action (e.g., 'Chain of Command extensions + event subscriptions for a class/table'), making it unambiguous what the tool does and how it differs from generic search or analysis tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Every mode includes explicit usage context: 'Use before writing a CoC extension to check for conflicts', 'Use before adding handlers to check for duplicates'. The strategy mode states it 'recommends the best extensibility mechanism for a goal', and the description explains which parameters each mode requires. This provides clear when-to-use guidance for each variation, effectively distinguishing from siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

find_referencesA
Read-only

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).

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMaximum number of references to return
ownerNameNoDeclaring table/class/form that owns the method, when targetName is the bare method name. Scopes the where-used to that single type.
targetNameYesTarget name. Methods: see the scoping rule in the description above. Labels: the id exactly as written — "@WAX2194" or "@LabelFile:LabelId".
targetTypeNoType of the target to search for. Use "label" for label where-used (or just pass an "@…" / "/Labels/@…" targetName).all

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, so a read operation is understood. The description adds meaningful behavioral detail beyond that: the method-name-matches-every-type over-reporting behavior, that label results span every object type (not just code), and the DYNAMICSXREFDB/full-server-mode requirement. This enriches the safety/behavioral profile without contradicting annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but every sentence earns its place — method scoping, label semantics, and prerequisites are all operationally critical for correct invocation. It is front-loaded with the core purpose and scoping rule before edge cases. Slightly dense but no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Comprehensive for a read tool whose annotations already cover safety: all target types, method-scoping edge cases, label behavior, and the xref prerequisite are covered. The only gap is that with no output schema, the return format/pagination behavior (relevant given the limit param) is not described. Otherwise nothing an agent needs to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Despite 100% schema coverage, the description substantially enriches parameter meaning. It explains the targetName scoping rule for methods (Owner.method vs bare name vs AOT path), the exact label id format ('@WAX2194' or '@MyLabelFile:MyLabel'), and how ownerName scopes a bare method name. It also clarifies targetType's 'label' value and the '@…' shortcut. This goes well beyond the schema's one-line parameter descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: 'Find all references (where-used) to a class, method, field, table, enum, or LABEL.' This clearly distinguishes it from siblings like search (general search), get_object_info, and validate_code. The 'Essential for impact analysis before refactoring' line reinforces the distinct role. No tautology.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides strong usage context — 'Essential for impact analysis before refactoring' — plus concrete invocation patterns (Owner.method, ownerName, AOT path) and an explicit over-reporting warning for bare method names. Covers label usage and its xref database prerequisite. It doesn't name which sibling to use instead in specific cases, but the guidance is otherwise explicit and actionable.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
modeYes
nameNoREQUIRED. [pattern] element name (extensions: base element; form-datasource/control-extension: the FORM name). [scaffold] object name WITHOUT model prefix. [other modes] the existing table.
paramsNoMode-specific parameters as ONE nested object (label, fields[], fieldsHint, cloneFrom, tableMapping, formPattern, contractParams[], keyFields[], style, fieldGroup, …). A missing required one is answered with that mode's COMPLETE spec.
patternNo[pattern] REQUIRED. ssrs-report-full = Contract+DP+Controller; service-class-ais = CRUD service + contract; systest = failing SysTestCase (TDD red); report-* extend a STANDARD report (recipes: object_patterns(domain="report")).
modelNameNoModel name (auto-detected). NEVER use placeholders like "MyModel".
objectTypeNo[scaffold] REQUIRED. Kind of object to generate.

TDQS

A4.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description clearly discloses that pattern mode is 'text only, no write', and it labels outputs for most modes (text, XML, X++ snippets). It also reveals that missing required parameters cause the tool to return that mode's complete spec. However, scaffold mode's write-vs-return behavior is not explicitly stated, leaving some ambiguity about side effects beyond what the annotations convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but well-organized with a front-loaded purpose statement and a clear bullet list of modes. Every sentence carries routing, parameter, or behavioral information; no filler or redundant restatement of the schema is present. The length is proportional to the tool's six-mode complexity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with no output schema and six distinct modes, the description is remarkably complete: it explains each mode's intent, output form, required setup, and related tools. It intentionally outsources full mode contracts to get_knowledge, which is a reasonable and explicit completeness mechanism. The only slight gap is scaffold's output behavior, but the overall guidance is sufficient for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Even though the schema covers 83% of parameters, the description adds substantial meaning: it explains what `name` means for each mode, clarifies that `params` is one nested object, decodes pattern enum abbreviations, and notes that modelName is auto-detected. This goes well beyond the raw schema and helps an agent construct valid calls.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource, 'Generate X++/AOT code', and immediately enumerates six distinct modes with their concrete outputs. It also explicitly contrasts this tool with d365fo_file(action="generate") for existing objects, making it easy for an agent to distinguish it from a sibling tool.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives an explicit workflow for pattern mode: call analyze_code(mode="patterns") first, then generate_object(mode="pattern"), then d365fo_file(action="create"). It also directs agents to get_knowledge for mode contracts and identifies d365fo_file(action="generate") as the alternative for existing object XML, providing clear when-to-use guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_knowledgeA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
kindNo
pathNo[bp-moniker suppress] REQUIRED. dynamics:// path, verbatim from the finding.
topicNo[knowledge] REQUIRED. Topic to query — e.g. "ttsbegin", "RunBase vs SysOperation". [op-spec] The operation / objectType / mode to look up.
actionNo[bp-moniker] REQUIRED. validate = confirm an exact moniker is real; search = free-text scenario query; suppress = render a <Diagnostic> block.
formatNo[knowledge] concise = quick reference (default), detailed = full explanation with code examplesconcise
topicsNo[knowledge|op-spec] Look up SEVERAL topics in one call instead of one call each. Replaces topic.
monikerNo[bp-moniker validate/suppress] REQUIRED. Exact moniker, e.g. "BPErrorPrivilegeNotCoveredByDuty".
errorCodeNo[error] Optional error code (e.g. SYS10028, CSUV1, BPUpgradeCodeToday)
errorTextNo[error] REQUIRED. Full error message text as displayed in the X++ compiler or event log
justificationNo[bp-moniker suppress] REQUIRED. Why the warning is ignored; 95% of real entries carry one.

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations cover read-only safety, and the description adds behavioral guarantees beyond that: knowledge is a 'queryable rulebook', error mode promises 'structured root cause + step-by-step fix + corrected X++ example', and bp-moniker is 'backed by names/text extracted from a real D365FO install — never invents a moniker'. No contradiction with readOnlyHint or openWorldHint.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is bulleted and front-loaded with the core instruction ('Choose a kind'), then each mode gets a compact, purposeful sentence with no filler. The length is justified by the four distinct behaviors and the need to route callers correctly.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 10-parameter tool with no output schema, the description covers the input space thoroughly: all four kind values, their intended use, the output shape for error mode, the index behavior for op-spec, and the rendered Diagnostic block for bp-moniker. The remaining details are already captured by the high-coverage input schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is already high (90%) and each parameter has a mode-tagged description, so the baseline is 3. The description earns an extra point by explaining why op-spec exists, by defining what each kind means for parameter selection, and by adding the 'omit topic for index' rule that clarifies an otherwise underspecified optional parameter.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific action ('knowledge lookup') plus four clearly delineated resource kinds, each with its own purpose: rulebook, error diagnostics, op-spec contract, and bp-moniker validation. It explicitly references the sibling tools d365fo_file and generate_object, making it easy for an agent to distinguish this from nearby operations.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Each bullet gives an explicit when-to-use rule: knowledge before generating code, error instead of guessing, op-spec after picking the operation and before the call, bp-moniker for validate/search/suppress. It even explains that d365fo_file and generate_object deliberately omit inline parameters, making this lookup a required prerequisite rather than an optional convenience.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_object_infoA
Read-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, 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.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameNoExact object name (use search first if unsure). REQUIRED unless using objects[].
objectsNoPREFERRED for 2+ objects: read them all in one round trip. Each entry takes the same objectType/options as the single form, with the name in objectName.
optionsNoType-specific reader flags: includeRdl (report), searchControl/maxControls (form), compact/methodOffset (class+table), fieldsOffset/fieldFilter/relations (table), filter (macro), mode (edt), includeFields, includeOperations, modelName. On class/table/view/data-entity, {"method":"validateWrite","include":"signature"} returns ONE method (include: signature | source | both) — required before writing a CoC extension. {"include":"xml"} returns raw AOT XML + its path (page: startLine/endLine) — never shell out to find or read a file. Applies to every objects[] entry.
objectTypeNoKind of object to read. REQUIRED unless using objects[].

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark readOnlyHint=true, and openWorldHint=false, so the read-only safety profile is established. The description adds substantial behavioral context beyond that: batching with max 10, parallel execution, per-object sections, automatic dot-suffix stripping for extensions, the members shortcut for classes, and the method-signature option needed before writing CoC extensions. This richly discloses how the tool behaves.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but dense and appropriately front-loaded with the core purpose. Every sentence carries operational value, and guidance like 'never loop single calls' is a necessary addition. It could be slightly improved with clearer visual separation of the many rules, but no sentence is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with no output schema and high complexity, the description covers the main calling patterns, type taxonomy, extension behavior, and key options. It gives only a high-level picture of return values ('per-object sections back', 'fast IntelliSense-style member-name list'), which is probably sufficient for invocation but leaves some response-shape detail unspecified. Still, the description is complete enough for an agent to select and call the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Although schema coverage is 100%, the description adds significant semantic value beyond the schema: it clarifies that objects[] is the preferred batch form, explains how extension types treat base vs. extension names, lists what each options flag is used for, and gives concrete examples like {"members":"names"} and {"method":"validateWrite","include":"signature"}. This goes well beyond the schema's own descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Read D365FO object metadata.' It also enumerates the supported object types and distinguishes the read-oriented purpose from sibling tools by implication. However, it does not explicitly name or contrast any sibling (e.g., search, find_references), so differentiation is clear but not stated.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives strong operational guidance: use objects[] for 2+ objects, never loop single calls, pass base or full extension names, and use type-specific options. It also includes an explicit 'never shell out' directive. It does not, however, tell the agent when to prefer this tool over specific siblings such as search or find_references, so exclusion guidance is incomplete.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_workspace_infoA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
changesNoReturn the uncommitted X++ changes (`git diff HEAD`) plus per-file rollback hints INSTEAD of the configuration. Review-only — not a way to verify a write.
diagnosticsNoInclude verbose sections (config sources, suffix, project paths, index scan, stdio handshake). Use when debugging config or connectivity.
projectNameNoThe PROJECT file name, e.g. "Contoso - FeatureManagement" — pass it whenever you have one: the USER named it, or an earlier call listed it. NOT a model name, and not a guess from a ticket: one model has many projects, so naming it selects none. Steers WRITES only; reads span every model already.
projectPathNoAbsolute path to a .rnrproj file. Use when projectName is ambiguous, none was auto-selected, or D365FO_SOLUTIONS_PATH is unset. Example: "K:\\repos\\Contoso\\MyProject\\MyProject.rnrproj"

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond readOnlyHint=true, the description reveals useful traits: it flags placeholder model names and missing EXTENSION_PREFIX, is the authoritative source for the target model, and treats the changes parameter as review-only ('not a way to verify a write'). This gives agents expectations about validation and reliability.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact and front-loaded with the most important instruction ('ALWAYS call FIRST at session start'), then lists return values, flags, and source authority in four tight sentences. No filler or repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a no-output-schema tool, it names the key returned fields, flags edge conditions (placeholder model, missing prefix), and tells the agent where the information sits in the session workflow. Combined with the rich parameter schema, nothing essential is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the input schema already fully documents all four parameters. The description adds only a small usage note about passing projectName/projectPath, but does not materially extend the parameter semantics beyond what the schema provides.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb and resource ('get workspace info') and states precisely what it returns: model name, package path, framework directory, project path, environment type, and EXTENSION_PREFIX. It also distinguishes itself from siblings by declaring it the 'Authoritative source for target model — not search results,' and by being the mandated first call.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives an explicit invocation rule ('ALWAYS call FIRST at session start'), tells when to pass projectName/projectPath ('when you have the project's name or path'), and warns against using search results for the target model. The schema's diagnostics and changes parameters further state when to use them (debugging vs review-only), so an agent knows when to call this vs alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

labelsA
Destructive

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").

ParametersJSON Schema
NameRequiredDescriptionDefault
modelNo[search|info|create|update|rename] Model that owns the label file (e.g. ContosoExt).
queryNo[search] REQUIRED. Search text — matches label ID, text and developer comment. ARRAY = try several phrasings in ONE call.
actionYes
dryRunNo[rename] Preview changes without writing anything.
labelsNo[create] Bulk mode — shared fields stay at the top level (top-level labelId/translations are then ignored); a failed entry does not abort the batch.
paramsNoOptional write plumbing — the auto-resolved overrides named at the end of the description above.
labelIdNo[info] Label ID, any spelling: SYS67433, @SYS67433, @ContosoExt:MyLabel (paste search output). labelFileId/model optional. Omit to list label files.
verboseNo[search] Default one line per label; true = full multi-line block.
languageNo[search] Language/locale (default: en-US). Examples: cs, de, sk.
maxResultsNo[search] Max labels listed (default 10); a truncated set reports how many more matched.
newLabelIdNo[rename] REQUIRED. New label ID.
oldLabelIdNo[rename] REQUIRED. Current label ID (e.g. MyOldField).
labelFileIdNo[search|info|create|update|rename] AxLabelFile ID (e.g. ContosoExt, SYS). For a NEW label file this ID is the MODEL name, never the bare EXTENSION_PREFIX.
translationsNo[create] REQUIRED for single-label create (omit when using labels[]). Translations for each language. Provide at least en-US.

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark the tool as destructive and not read-only, and the description adds concrete behavioral details: update overwrites existing labels, rename affects .label.txt + X++ + XML + index, bulk failures do not abort the batch, and write plumbing is auto-resolved unless overridden. This is far beyond what annotations alone provide, and there is no contradiction.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the core purpose and then organized by action in a scannable bullet list. It is long, but the tool has 14 parameters and five distinct action modes; the density is justified. One small deduction because some parameter-level details like 'Default one line per label' could have been left to the schema descriptions.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers all five actions, their key parameters, write plumbing, bulk mode, and even output hints for search truncation. However, there is no return-value explanation for create/update/rename and no output schema, so an agent does not know exactly what those write calls respond with. Given the tool's complexity, that is a minor but real gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 93%, but the description adds substantial extra meaning: array queries mean multiple phrasings, labelId accepts @SYS or @Model:Label spellings, labelFileId semantics differ for new vs existing files, label IDs should describe meaning rather than model prefixes, and bulk mode expects shared fields at the top level. It even explains the required createIfMissing=true behavior despite that parameter not being a direct named schema property.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly presents 'Unified label operations — read and write' and enumerates five distinct actions with specific verbs: search, info, create, update, rename. It also distinguishes itself from sibling d365fo_file by explaining when no label call is needed, so an agent can tell what this tool is for.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit when-to-use guidance: search is 'never needed before a create,' createIfMissing=true replaces search-then-create, write operations are labeled as write, and rename advices dryRun first. It also names alternatives like d365fo_file create/modify and tells the agent when to use get_knowledge for overrides.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

object_patternsA
Read-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-FP010. 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=.

ParametersJSON Schema
NameRequiredDescriptionDefault
xmlNo[validate] Complete AxForm XML to validate. Provide this OR formName/filePath.
limitNo[analyze] Max pattern examples.
actionNo[form] Which form-pattern operation to run. repair = auto-fill missing required controls.
domainNoOptional — inferred from the other params (action/pattern/xml/formName → form; tableGroup → table). A concept like "number-sequence" is not a domain: that is get_knowledge.
patternNo[spec|report|mobile-app] Pattern name (id, xmlName or alias) — e.g. "SimpleList", "FieldsFieldGroups", "PrintMgmtFormLetter", "processguide-flow".
filePathNo[form/validate] Path to an AxForm XML file not yet indexed.
formNameNo[validate] Name of an indexed form — XML is loaded from the metadata store.
recommendNo[analyze] Pattern advisor: describe requirements, get a recommended pattern + reference forms to clone.
similarToNo[table] table / [form-analyze] form name to find similar patterns.
dataSourceNo[form/analyze] Table name - find forms using this table
tableGroupNo[table] Table group type to analyze (choose one).
formPatternNo[analyze] D365FO form pattern to analyze

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The readOnlyHint annotation already covers the non-destructive nature. The description adds useful behavioral context: validation returns FP001-FP010 checks, analyze uses the Microsoft decision tree and names reference forms, and validate is meant to precede d365fo_file creation. It would be stronger if it explained the repair action's in-memory behavior explicitly, but there is no contradiction with the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but well-structured with domain bullets and action sub-bullets. It front-loads the domain decision and avoids repeating parameter-level detail already in the schema. For a 12-parameter, multi-domain tool, this is appropriately sized and scannable.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Considering the complexity and the read-only annotation, the description is nearly complete: it covers all major domains, the main actions, output-like evidence (reference forms, FP codes), and a cross-tool dependency. The one clear gap is the undocumented 'repair' action, which prevents a perfect score.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description adds value by showing how parameters combine by domain and action, e.g. recommend for new forms, tableGroup/similarTo for table patterns, and pattern=<id> for report/mobile-app. It does not discuss repair or limit, but the schema documents those clearly.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description is a detailed pattern toolkit manual: each domain (table, form, report, mobile-app) is tied to concrete operations such as analyze, spec, validate, and recipe generation. It clearly scopes the tool to D365FO pattern concerns and even names the related d365fo_file create action for the validation flow.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives strong usage guidance inside the tool: 'For a NEW form pass recommend (preferred)', 'Call before d365fo_file action=create', and it explains when to filter by formPattern/dataSource/similarTo. However, the schema's action enum also lists 'repair' yet the description completely omits that action, so guidance for one alternative is missing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

prepareA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
goalYesOne-sentence description of the intent. Example (change): "Add CoC on CustTable.validateWrite". Example (create): "Parameter table for the Contoso import feature."
modeYes
operationNo[change] The modify operation(s) you intend to run — comma-separated for several ("add-field,add-index"). Their full parameter contracts come back in THIS response. Defaults to add-method when methodName is given.
fieldsHintNo[create] For tables/views: planned field names — each gets EDT suggestions from the index.
methodNameNo[change] Target method name when the change involves a specific method (CoC or event handlers). Example: "validateWrite".
objectNameYes[change] Name of the object to extend/modify (e.g. "CustTable"). [create] Proposed BASE name WITHOUT model prefix.
objectTypeNo[change] type — auto-detected when omitted. [create] REQUIRED; an extension is Base.Suffix.
proposedNameNo[change] Proposed name for the new extension class/object. When provided, naming validation runs.

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare readOnlyHint=true, so safety is covered. The description adds useful behavioral details beyond the annotations: groundingToken has a 30-minute TTL and is required for extension/new-object writes when GROUNDING_ENFORCE=true. It does not describe the full response shape, but the token and its lifecycle are disclosed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but well-structured: the core value proposition and token requirement are front-loaded, then each mode gets a concise bullet with concrete outputs. Every sentence contributes useful information with no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Despite no output schema, the description enumerates exactly what each mode returns: signatures, wrappers, collision checks, naming advice, EDT suggestions, tests, and the red-first cycle. It also explains parameter behavior such as operation defaults and objectType auto-detection, making it sufficient for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 88%, and the input schema already documents each parameter with mode-specific meanings and examples. The description adds high-level mode context but does not materially improve parameter-level understanding beyond what the schema already provides.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly identifies 'prepare' as a one-call context aggregator that returns a groundingToken, and it defines distinct change/create/test modes with concrete outputs. It also differentiates itself from the sibling loop by explicitly stating it replaces analyze→search→info→generate.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit mode-specific guidance: change for modifying existing objects, create for new objects, and test for writing SysTests. It also names the multi-tool alternative it replaces, making selection straightforward.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

run_bp_checkA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
objectsNoCheck several objects in ONE call — preferred over targetFilter. Shared preamble is printed once and findings are grouped per object.
modelNameNoModel name to check. Auto-detected if omitted.
packagePathNoPackagesLocalDirectory root path. Auto-detected if omitted.
projectPathNoAbsolute path to the .rnrproj file to analyze. Auto-detected if omitted.

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so the read-only nature is covered. The description adds useful behavioral context: the ordering constraint relative to builds, the kind of findings returned, and the relationship to the integrated build check. It does not cover failure modes or permissions, but the read-only annotation lowers the burden.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences deliver purpose, output examples, a usage precondition, and the key alternative in a compact way. There is no filler, and the most important scoping guidance appears early.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, so the description correctly covers what the tool returns: BP warnings and errors with rule codes. It also communicates when to call it and why separate calls are often unnecessary. It could mention result grouping or what happens when all parameters are omitted, but the schema already covers parameter auto-detection and batching.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all four parameters (objects, modelName, packagePath, projectPath) are already documented with meaningful descriptions, including auto-detection and preferred batching of objects. The description does not need to repeat these details, and it adds only output-related context. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the specific action: running Microsoft Best Practices checker (xppbp.exe) on a D365FO project, and what the output is: BP warnings and errors with rule codes. It also distinguishes itself from the sibling build_d365fo_project by noting that build already integrates this check.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly says when the tool should be used — AFTER a build, not after a write — and notes that build_d365fo_project(bpCheck:true) already folds this check in, so a separate call is rarely needed. This gives an agent clear routing guidance toward the preferred alternative.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

run_systest_classA

Execute a D365FO unit test class via SysTestConsole.exe (/unattended), returning per-method results.

ParametersJSON Schema
NameRequiredDescriptionDefault
classNameYesThe name of the SysTest class to run (e.g. "MyModuleTest")
modelNameNoThe model containing the test class. Auto-detected if omitted.
testMethodNoOptional: run only this specific test method within the class (e.g. "testValidation").
packagePathNoPackagesLocalDirectory root path. Auto-detected if omitted.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description adds meaningful behavioral detail beyond the annotations by specifying that execution happens via SysTestConsole.exe in unattended mode and that results are returned per method. This tells the agent what kind of operation this is and what to expect without contradicting the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, well-structured sentence. It front-loads the action and target, then adds the execution mechanism and result format with no unnecessary words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description does need to convey what the caller receives, and it does so by stating 'returning per-method results'. It also covers the core execution context. However, it does not describe the output shape beyond per-method results, which is a minor gap for a test runner with no output schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all four parameters are already documented in the input schema. The description does not add additional parameter-level meaning, but it also does not need to; the baseline of 3 is appropriate when the schema fully carries parameter semantics.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb ('Execute'), a specific resource ('D365FO unit test class'), and a concrete mechanism ('SysTestConsole.exe (/unattended)'). It also states the observable outcome ('returning per-method results'), making the tool's purpose unambiguous and distinct from sibling build/validation tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description makes the usage context clear: it is the tool for executing a D365FO unit test class and getting per-method results. While it does not explicitly name alternatives or exclusions, none of the sibling tools perform unit-test execution, so the context is sufficient without needing an explicit when-not-to-use clause.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

security_infoA
Read-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).

ParametersJSON Schema
NameRequiredDescriptionDefault
modeYes
nameNo[artifact] REQUIRED. Name of the security privilege, duty, or role
objectNameNo[coverage] REQUIRED. Name of the form, table, class, or menu item
objectTypeNo[coverage] Type of the object (default: auto-detect)auto
artifactTypeNo[artifact] REQUIRED. Type of security artifact to look up
includeChainNo[artifact] Walk the full hierarchy (default: true)

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The readOnlyHint annotation already communicates non-destructive behavior, so the description's additional detail is valuable: it discloses the traversal paths (Role → Duties → Privileges → Entry Points and object → menu items → privileges → duties → roles). This exceeds what the annotations alone provide and helps the called tool behave predictably, though it doesn't cover potential errors or edge cases.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact and well structured, using bullet-like mode definitions with clear arrows to show hierarchy. Every sentence and clause contributes practical information, and the most important routing instruction ('Choose a mode') is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Although there is no output schema, the description gives a fairly concrete picture of what the caller can expect: full artifact hierarchies for artifact mode and reverse access chains for coverage mode. Combined with the input schema, this is sufficient for most call intentions, though a few details such as exact response shape or limit behavior are absent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is high (83%), and the schema already explains each parameter, including mode-specific requiredness, defaults, and enums. The description reinforces the conceptual meaning of the modes and their output chains, but doesn't add significant parameter-level detail beyond what the schema already provides. Thus it earns the baseline 3.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly identifies the tool as a D365FO security lookup and breaks down two distinct modes: artifact lookup and coverage analysis. Each mode specifies exactly what is returned, including the full hierarchy and reverse chain, making the tool's purpose unambiguous and differentiating it from generic lookup tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear context about when to use each mode: 'artifact' for hierarchy details on a security artifact, and 'coverage' for reverse access chains on an object. It does not explicitly name alternative tools or exclusions, so it stops short of a perfect 5, but the mode guidance is strong enough to guide correct invocation.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

update_symbol_indexA
Idempotent

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 themselves, so it is a wasted round trip. Omit filePath for a bridge/cache refresh only.

ParametersJSON Schema
NameRequiredDescriptionDefault
filePathNoAbsolute path to the changed XML file, or an ARRAY — batch them, each call costs a bridge refresh.

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already provide idempotentHint=true and destructiveHint=false, and the description adds meaningful behavioral context beyond those: each call triggers a bridge refresh cost, calling it after create/modify is a wasted round trip, and omitting filePath changes the operation to a bridge/cache refresh only. This gives the agent a clear mental model of what the tool actually does and its side effects.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is three sentences, each with a distinct purpose: stating the tool's role, giving an explicit exclusion, and explaining an optional invocation mode. No unnecessary words or redundancy. Information is front-loaded and easy to scan.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a low-complexity tool with one optional parameter, no output schema, and rich annotations, the description covers purpose, usage boundaries, and both invocation modes. There is no missing information that an agent would need to correctly select and invoke this tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema already documents filePath with type, array support, and batching guidance, so the baseline is 3. The description adds critical semantics beyond the schema: omitting filePath performs a bridge/cache refresh only, and the filePath should identify files changed outside this server, which shapes what value the agent should pass. This is valuable supplementary meaning.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb ('Index'), a specific resource ('D365FO XML file(s)'), and a precise scope ('changed OUTSIDE this server'). It also differentiates the tool from sibling d365fo_file create/modify by explaining that those operations already refresh the index. An agent can clearly tell what this tool is for and what it is not for.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly states when to use the tool ('changed OUTSIDE this server') and when not to call it ('Do NOT call after d365fo_file create/modify'), naming the alternative tool. It also documents the special mode where filePath is omitted for a bridge/cache refresh only. This is direct, actionable usage guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

validate_codeA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
codeYesX++ source code or XML metadata to validate. Paste the full generated text.
modeYesboth = run the two checks in ONE call (preferred).
contextNoOptional: owning class/table name, used in diagnostic messages.
codeTypeNo[syntax] "xpp" X++ (default), "xml-table" AxTable, "xml-form" AxForm(+Extension), "xml-report" AxReport, "xml-any" other.xpp

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the readOnlyHint annotation, the description adds rich behavioral context: offline operation, no xppbp.exe, index-only reference resolution, structured violation output, and coverage of specific rule families. This makes the tool's side-effect-free and execution model clear.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with a concise opening line and bullet-separated modes. It front-loads the core purpose, then gives mode-specific detail and final actionable timing guidance. Every sentence contributes useful information without unnecessary repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with no output schema, the description explains the syntax-mode return shape and the overall verification behavior. It is slightly less explicit about the exact return format for references mode, but the usage context, parameter intent, and integration behavior are otherwise well covered.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema already covers all parameters at 100%, so the baseline is 3. The description adds meaningful semantics beyond the schema, especially for mode ('both' preferred), codeType ('xml-table' checks XML refs), and the behavior of references mode. It doesn't enrich the context parameter, but the overall value exceeds baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: a static validator for generated X++/XML. The mode breakdown (syntax vs references) and the 'no xppbp.exe' note clearly distinguish it from related siblings like run_bp_check and find_references.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit timing guidance: call mode='both' AFTER generating and BEFORE writes, and fix errors in the same turn. It also notes that write tools run references internally when GROUNDING_ENFORCE=true. It does not explicitly contrast with sibling alternatives, so it stops short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

validate_object_namingA
Read-only

Validate a proposed D365FO object name against naming conventions: extension naming, ISV prefix, type-specific suffixes, and conflict detection against the symbol index.

ParametersJSON Schema
NameRequiredDescriptionDefault
objectTypeYesType of the D365FO object
modelPrefixNoExpected ISV/model prefix (2-4 uppercase letters, e.g. "WHS"). Auto-detected if omitted.
proposedNameYesThe proposed object name to validate
baseObjectNameNoRequired for extension types: name of the object being extended

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The readOnlyHint annotation already signals safety, and the description adds useful behavioral detail by mentioning conflict detection against the symbol index and the categories of naming rules checked. No contradictions exist between description and annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, tightly worded sentence that front-loads the action and resource, then lists the validation checks. Every phrase adds useful information with no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the moderate complexity, complete parameter schema, and readOnlyHint annotation, the description is largely sufficient for selecting and invoking the tool. It could explicitly mention the return format or that results indicate pass/fail with reasons, but that is a minor gap because the tool's purpose is clear.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all four parameters are already documented. The description reinforces concepts like ISV prefix and extension naming, but does not add significant new parameter-level meaning beyond what the schema provides.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Validate'), a clear resource ('a proposed D365FO object name'), and enumerates the exact validation dimensions (extension naming, ISV prefix, type-specific suffixes, symbol-index conflict detection). This clearly distinguishes it from sibling tools like validate_code or generate_object without ambiguity.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context: this tool is for checking a proposed object name against naming conventions before use. It does not explicitly name alternatives or state when not to use it, but the purpose is specific enough for an agent to infer when it applies.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

verify_d365fo_projectA
Read-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).

ParametersJSON Schema
NameRequiredDescriptionDefault
objectsNoList of objects to verify. OPTIONAL — omit to verify every object referenced in the project (.rnrproj).
modelNameNoModel name. Auto-detected if omitted.
projectPathNoAbsolute path to the .rnrproj file. Required for project-reference check.

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish readOnlyHint=true, and the description adds useful behavioral context: the tool runs after build, is read-only verification, and supports scoped vs whole-project verification. It does not describe result/output or failure behavior, but this is a minor gap given the read-only nature.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but every sentence earns its place: core purpose, alternative tool, timing, and the important omit-objects behavior. It is front-loaded with the primary verification action and keeps all guidance relevant.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only verification tool with three optional parameters and no output schema, the description supplies sufficient context for correct selection and invocation. It covers scope, timing, prerequisites, and the key alternative, so an agent can act without further clarification.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds meaning beyond the schema by clarifying that omitting `objects` verifies every object in the project and that projectPath is needed for project-reference checking or can be auto-detected/configured. This goes beyond the raw schema descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: verify D365FO objects exist on disk at the correct AOT path and are referenced in the .rnrproj project file. It clearly distinguishes this from related tools like d365fo_file by noting it runs after a build rather than after a write.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit when-to-use guidance: after a build, not after a write, and names d365fo_file as the alternative that already verifies its own write inline. It also explains the omit-objects behavior for verifying the entire project and notes the projectPath requirement, leaving little to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. 18 tool updatesv1.16.2
    • Changedbuild_d365fo_project3 fields changed
      • changedInput schema / properties / bpCheck / description
        Previous value: -"On a SUCCESSFUL build, also run the best-practice checker and append its findings — saves the usual follow-up run_bp_check call."New value: +"On a SUCCESSFUL build, also run the best-practice checker and append its findings. Prefer this to a follow-up run_bp_check call: one build call instead of two round trips."
      • addedInput schema / properties / dbSync
        Added value: +{
        +  "description": "On a SUCCESSFUL build, also run the database sync (SyncEngine.exe) — REQUIRED after any table/view/data-entity change. true = partial sync of the syncable objects in the project, full-model when it has none; an ARRAY syncs exactly those tables/views (much faster).",
        +  "items": {
        +    "type": "string"
        +  },
        +  "type": [
        +    "boolean",
        +    "array"
        +  ]
        +}
      • removedInput schema / properties / projectPath
        Removed value: -{
        -  "description": "(Legacy) Absolute path to a .rnrproj file — used only to extract the model name when modelName is not provided.",
        -  "type": "string"
        -}
    • Changedd365fo_file6 fields changed
      • removedInput schema / properties / action / description
        Removed value: -"One of the four modes described above."
      • changedInput schema / properties / action / enum
        Previous value: -[
        -  "create",
        -  "modify",
        -  "delete",
        -  "generate"
        -]New value: +[
        +  "create",
        +  "modify",
        +  "delete",
        +  "undo",
        +  "generate"
        +]
      • changedInput schema / properties / filePath / description
        Previous value: -"[modify|delete] Absolute XML path — bypasses symbol-DB lookup. Use for objects just created."New value: +"[modify|delete] Absolute XML path — bypasses symbol-DB lookup. Use for objects just created. [undo] REQUIRED: the file to roll back."
      • changedInput schema / properties / params / description
        Previous value: -"[modify] Operation-specific parameters as ONE nested object, per get_knowledge(kind=\"op-spec\", topic=\"<operation>\"). A missing/wrong one returns that COMPLETE spec — follow it, do not guess."New value: +"[modify] Operation-specific parameters as ONE nested object, per the op-spec lookup above. A missing/wrong one returns that COMPLETE spec — follow it, do not guess."
      • changedInput schema / properties / projectPath / description
        Previous value: -"Path to .rnrproj (auto-detected)."New value: +"Path to .rnrproj. Set if known, else auto-detected."
      • changedInput schema / properties / properties / description
        Previous value: -"[create] Per-objectType creation properties (label, fields[], extends, enumValues[], primaryTable, …) — NOT in this schema. Fetch yours: get_knowledge(kind=\"op-spec\", topic=\"<objectType>\")."New value: +"[create] Per-objectType creation properties (label, fields[], extends, enumValues[], primaryTable, …) — not in this schema; fetch yours with the op-spec lookup above."
    • Changedgenerate_object4 fields changed
      • removedInput schema / properties / mode / description
        Removed value: -"pattern = X++ skeleton; scaffold = whole table/form/report (set objectType); find-methods/relation-xpp/fields/table-relation = X++/XML helpers for an existing table."
      • changedInput schema / properties / params / description
        Previous value: -"Mode-specific parameters as ONE nested object (label, fields[], fieldsHint, cloneFrom, tableMapping, formPattern, contractParams[], keyFields[], style, fieldGroup, …). Get the contract from get_knowledge(kind=\"op-spec\", topic=\"<mode>\"); a missing required one returns that COMPLETE spec."New value: +"Mode-specific parameters as ONE nested object (label, fields[], fieldsHint, cloneFrom, tableMapping, formPattern, contractParams[], keyFields[], style, fieldGroup, …). A missing required one is answered with that mode's COMPLETE spec."
      • changedInput schema / properties / pattern / description
        Previous value: -"[pattern] REQUIRED. CoC skeletons: class/table-extension, form-handler, form-datasource-extension, form-control-extension, map-extension. ssrs-report-full = Contract+DP+Controller; service-class-ais = CRUD service + contract."New value: +"[pattern] REQUIRED. ssrs-report-full = Contract+DP+Controller; service-class-ais = CRUD service + contract; systest = failing SysTestCase (TDD red); report-* extend a STANDARD report (recipes: object_patterns(domain=\"report\"))."
      • changedInput schema / properties / pattern / enum
        Previous value: -[
        -  "class",
        -  "runnable",
        -  "form-handler",
        -  "data-entity",
        -  "batch-job",
        -  "table-extension",
        -  "sysoperation",
        -  "event-handler",
        -  "security-privilege",
        -  "menu-item",
        -  "class-extension",
        -  "ssrs-report-full",
        -  "lookup-form",
        -  "dialog-box",
        -  "dimension-controller",
        -  "number-seq-handler",
        -  "display-menu-controller",
        -  "data-entity-staging",
        -  "service-class-ais",
        -  "form-datasource-extension",
        -  "form-control-extension",
        -  "map-extension"
        -]New value: +[
        +  "class",
        +  "runnable",
        +  "form-handler",
        +  "data-entity",
        +  "batch-job",
        +  "table-extension",
        +  "sysoperation",
        +  "event-handler",
        +  "security-privilege",
        +  "menu-item",
        +  "class-extension",
        +  "ssrs-report-full",
        +  "lookup-form",
        +  "dialog-box",
        +  "dimension-controller",
        +  "number-seq-handler",
        +  "display-menu-controller",
        +  "data-entity-staging",
        +  "service-class-ais",
        +  "form-datasource-extension",
        +  "form-control-extension",
        +  "map-extension",
        +  "systest",
        +  "report-dataset-extension",
        +  "report-custom-design",
        +  "report-menu-redirect"
        +]
    • Changedget_knowledge2 fields changed
      • removedInput schema / properties / kind / description
        Removed value: -"knowledge = look up an X++ topic/rule; error = diagnose an error message; op-spec = parameter contract for a d365fo_file operation/objectType or generate_object mode; bp-moniker = validate/search a BP-check moniker or render a suppression."
      • changedInput schema / properties / topic / description
        Previous value: -"[knowledge] REQUIRED. Topic to query — e.g. \"batch job\", \"ttsbegin\", \"RunBase vs SysOperation\", \"set-based operations\", \"CoC\", \"data entities\", \"number sequences\", \"security\", \"temp tables\", \"today() deprecated\", \"query patterns\", \"form patterns\". [op-spec] The operation / objectType / mode to look up."New value: +"[knowledge] REQUIRED. Topic to query — e.g. \"ttsbegin\", \"RunBase vs SysOperation\". [op-spec] The operation / objectType / mode to look up."
    • Changedget_object_info3 fields changed
      • changedInput schema / properties / objects / items / properties / objectType / description
        Previous value: -"Kind of object to read"New value: +"Kind of object to read — same values as the top-level `objectType`."
      • removedInput schema / properties / objects / items / properties / objectType / enum
        Removed value: -[
        -  "class",
        -  "table",
        -  "form",
        -  "query",
        -  "view",
        -  "enum",
        -  "edt",
        -  "report",
        -  "data-entity",
        -  "menu-item",
        -  "service",
        -  "map",
        -  "config-key",
        -  "security-policy",
        -  "macro",
        -  "table-extension",
        -  "class-extension",
        -  "form-extension",
        -  "enum-extension",
        -  "edt-extension",
        -  "data-entity-extension"
        -]
      • changedInput schema / properties / options / description
        Previous value: -"Type-specific reader flags: includeRdl (report), searchControl/maxControls (form), compact/methodOffset (class), fieldsOffset/fieldFilter (table), filter (macro), mode (edt), includeFields, includeOperations, modelName. On class/table/view/data-entity, {\"method\":\"validateWrite\",\"include\":\"signature\"} returns ONE method (include: signature | source | both) — required before writing a CoC extension. {\"include\":\"xml\"} returns raw AOT XML + its path (page: startLine/endLine) — never shell out to find or read a file. Applies to every objects[] entry."New value: +"Type-specific reader flags: includeRdl (report), searchControl/maxControls (form), compact/methodOffset (class+table), fieldsOffset/fieldFilter/relations (table), filter (macro), mode (edt), includeFields, includeOperations, modelName. On class/table/view/data-entity, {\"method\":\"validateWrite\",\"include\":\"signature\"} returns ONE method (include: signature | source | both) — required before writing a CoC extension. {\"include\":\"xml\"} returns raw AOT XML + its path (page: startLine/endLine) — never shell out to find or read a file. Applies to every objects[] entry."
    • Changedget_workspace_info3 fields changed
      • addedInput schema / properties / changes
        Added value: +{
        +  "default": false,
        +  "description": "Return the uncommitted X++ changes (`git diff HEAD`) plus per-file rollback hints INSTEAD of the configuration. Review-only — not a way to verify a write.",
        +  "type": "boolean"
        +}
      • changedInput schema / properties / projectName / description
        Previous value: -"Only when the USER says \"switch to <project>\". The PROJECT file name, e.g. \"Contoso - FeatureManagement\". NOT a model name: one model is built by many projects, so naming it selects none and the call is refused. Reads span every model already."New value: +"The PROJECT file name, e.g. \"Contoso - FeatureManagement\" — pass it whenever you have one: the USER named it, or an earlier call listed it. NOT a model name, and not a guess from a ticket: one model has many projects, so naming it selects none. Steers WRITES only; reads span every model already."
      • changedInput schema / properties / projectPath / description
        Previous value: -"Absolute path to a .rnrproj file. Fallback when projectName is ambiguous or D365FO_SOLUTIONS_PATH is not configured. Example: \"K:\\\\repos\\\\Contoso\\\\MyProject\\\\MyProject.rnrproj\""New value: +"Absolute path to a .rnrproj file. Use when projectName is ambiguous, none was auto-selected, or D365FO_SOLUTIONS_PATH is unset. Example: \"K:\\\\repos\\\\Contoso\\\\MyProject\\\\MyProject.rnrproj\""
    • Changedlabels8 fields changed
      • removedInput schema / properties / action / description
        Removed value: -"Label operation to perform."
      • changedInput schema / properties / labels / description
        Previous value: -"[create] OPTIONAL bulk mode — create several labels in one call; shared fields (labelFileId, model, languages, paths…) stay at the top level and top-level labelId/translations are ignored. A failed entry does not abort the batch."New value: +"[create] Bulk mode — shared fields stay at the top level (top-level labelId/translations are then ignored); a failed entry does not abort the batch."
      • removedInput schema / properties / labels / items / properties / labelId / description
        Removed value: -"Label ID for this entry — alphanumeric, no model prefix."
      • removedInput schema / properties / labels / items / properties / translations / description
        Removed value: -"Same entries as the top-level translations[]."
      • changedInput schema / properties / newLabelId / description
        Previous value: -"[rename] REQUIRED. New label ID — must be alphanumeric, no spaces."New value: +"[rename] REQUIRED. New label ID."
      • changedInput schema / properties / params / description
        Previous value: -"Optional write plumbing (packagePath, projectPath, languages, sortLabels, allowExtensionLabelFile, …) — all auto-resolved when omitted. Contract: get_knowledge(kind=\"op-spec\", topic=\"labels\")."New value: +"Optional write plumbing — the auto-resolved overrides named at the end of the description above."
      • removedInput schema / properties / translations / items / properties / comment / description
        Removed value: -"Developer comment (optional)"
      • removedInput schema / properties / translations / items / properties / text / description
        Removed value: -"Label text"
    • Changedobject_patterns6 fields changed
      • changedInput schema / properties / domain / description
        Previous value: -"table = table field/index/relation patterns; form = form-pattern toolkit (set action). Optional — inferred from the other params (action/pattern/xml/formName → form; tableGroup → table). ⚠️ This is NOT a free-form \"pattern type\": a concept like \"number-sequence\"/\"SysOperation\" belongs to get_knowledge, not here."New value: +"Optional — inferred from the other params (action/pattern/xml/formName → form; tableGroup → table). A concept like \"number-sequence\" is not a domain: that is get_knowledge."
      • changedInput schema / properties / domain / enum
        Previous value: -[
        -  "table",
        -  "form"
        -]New value: +[
        +  "table",
        +  "form",
        +  "report",
        +  "mobile-app"
        +]
      • changedInput schema / properties / filePath / description
        Previous value: -"[form/validate] Explicit path to an AxForm XML file (e.g. a freshly created form not yet indexed)."New value: +"[form/validate] Path to an AxForm XML file not yet indexed."
      • changedInput schema / properties / limit / description
        Previous value: -"[analyze] Maximum number of pattern examples (default: 10)"New value: +"[analyze] Max pattern examples."
      • changedInput schema / properties / pattern / description
        Previous value: -"[spec] REQUIRED. Pattern name (id, xmlName, or alias) — e.g. \"SimpleList\", \"DetailsMaster\", or a sub-pattern like \"FieldsFieldGroups\"."New value: +"[spec|report|mobile-app] Pattern name (id, xmlName or alias) — e.g. \"SimpleList\", \"FieldsFieldGroups\", \"PrintMgmtFormLetter\", \"processguide-flow\"."
      • changedInput schema / properties / similarTo / description
        Previous value: -"[table] table name to find similar table patterns; [form/analyze] form name to find similar form patterns."New value: +"[table] table / [form-analyze] form name to find similar patterns."
    • Changedprepare6 fields changed
      • removedInput schema / properties / mode / description
        Removed value: -"change = extend/modify an existing object; create = a brand-new object."
      • changedInput schema / properties / mode / enum
        Previous value: -[
        -  "change",
        -  "create"
        -]New value: +[
        +  "change",
        +  "create",
        +  "test"
        +]
      • changedInput schema / properties / objectName / description
        Previous value: -"[change] Name of the object to extend/modify (e.g. \"CustTable\"). [create] Proposed BASE name WITHOUT model prefix (same value you would pass to d365fo_file create)."New value: +"[change] Name of the object to extend/modify (e.g. \"CustTable\"). [create] Proposed BASE name WITHOUT model prefix."
      • changedInput schema / properties / objectType / description
        Previous value: -"[change] D365FO object type — auto-detected when omitted. [create] REQUIRED — type of the new object."New value: +"[change] type — auto-detected when omitted. [create] REQUIRED; an extension is Base.Suffix."
      • changedInput schema / properties / objectType / enum
        Previous value: -[
        -  "class",
        -  "table",
        -  "form",
        -  "enum",
        -  "edt",
        -  "query",
        -  "view",
        -  "data-entity",
        -  "report",
        -  "map",
        -  "menu-item-display",
        -  "menu-item-action",
        -  "menu-item-output",
        -  "menu",
        -  "security-privilege",
        -  "security-duty",
        -  "security-role",
        -  "business-event",
        -  "tile",
        -  "kpi",
        -  "service",
        -  "service-group",
        -  "macro",
        -  "configuration-key",
        -  "security-policy",
        -  "aggregate-measurement",
        -  "license-code"
        -]New value: +[
        +  "class",
        +  "table",
        +  "form",
        +  "enum",
        +  "edt",
        +  "query",
        +  "view",
        +  "data-entity",
        +  "report",
        +  "map",
        +  "menu-item-display",
        +  "menu-item-action",
        +  "menu-item-output",
        +  "menu",
        +  "security-privilege",
        +  "security-duty",
        +  "security-role",
        +  "business-event",
        +  "tile",
        +  "kpi",
        +  "service",
        +  "service-group",
        +  "macro",
        +  "configuration-key",
        +  "security-policy",
        +  "aggregate-measurement",
        +  "license-code",
        +  "table-extension",
        +  "class-extension",
        +  "form-extension",
        +  "enum-extension",
        +  "edt-extension"
        +]
      • changedInput schema / properties / operation / description
        Previous value: -"[change] The modify operation you intend to run; its full parameter contract comes back in THIS response, so no separate op-spec call. Defaults to add-method when methodName is given."New value: +"[change] The modify operation(s) you intend to run — comma-separated for several (\"add-field,add-index\"). Their full parameter contracts come back in THIS response. Defaults to add-method when methodName is given."
    • Removedreview_workspace_changes
    • Changedrun_bp_check2 fields changed
      • removedInput schema / properties / targetElementType
        Removed value: -{
        -  "description": "Element type for targetFilter. Looked up in the symbol index if omitted; ambiguous or unknown names error rather than being assumed to be a class.",
        -  "type": "string"
        -}
      • removedInput schema / properties / targetFilter
        Removed value: -{
        -  "description": "Single-object form: object name to check. Use objects[] for more than one.",
        -  "type": "string"
        -}
    • Changedsearch1 field changed
      • changedInput schema / properties / queries / items / properties / query / description
        Previous value: -"Search query (class name, method name, etc.)"New value: +"Search query."
    • Changedsecurity_info1 field changed
      • removedInput schema / properties / mode / description
        Removed value: -"artifact = look up a named privilege/duty/role; coverage = who can access an object."
    • Removedtrigger_db_sync
    • Removedundo_last_modification
    • Changedvalidate_code3 fields changed
      • changedInput schema / properties / codeType / description
        Previous value: -"[syntax] \"xpp\" for X++ source (default), \"xml-table\" for AxTable XML, \"xml-any\" for other XML."New value: +"[syntax] \"xpp\" X++ (default), \"xml-table\" AxTable, \"xml-form\" AxForm(+Extension), \"xml-report\" AxReport, \"xml-any\" other."
      • changedInput schema / properties / codeType / enum
        Previous value: -[
        -  "xpp",
        -  "xml-table",
        -  "xml-any"
        -]New value: +[
        +  "xpp",
        +  "xml-table",
        +  "xml-form",
        +  "xml-any",
        +  "xml-report"
        +]
      • changedInput schema / properties / mode / description
        Previous value: -"both = run the two checks in ONE call (preferred); syntax = BP/best-practice rules only; references = symbol resolution only."New value: +"both = run the two checks in ONE call (preferred)."
    • Changedvalidate_object_naming1 field changed
      • changedInput schema / properties / objectType / enum
        Previous value: -[
        -  "class",
        -  "table",
        -  "form",
        -  "enum",
        -  "edt",
        -  "query",
        -  "view",
        -  "table-extension",
        -  "class-extension",
        -  "form-extension",
        -  "enum-extension",
        -  "edt-extension",
        -  "menu-item",
        -  "security-privilege",
        -  "security-duty",
        -  "security-role",
        -  "data-entity"
        -]New value: +[
        +  "class",
        +  "table",
        +  "form",
        +  "enum",
        +  "edt",
        +  "query",
        +  "view",
        +  "report",
        +  "table-extension",
        +  "class-extension",
        +  "form-extension",
        +  "enum-extension",
        +  "edt-extension",
        +  "menu-item",
        +  "security-privilege",
        +  "security-duty",
        +  "security-role",
        +  "data-entity"
        +]
    • Changedverify_d365fo_project2 fields changed
      • removedInput schema / properties / packageName
        Removed value: -{
        -  "description": "Package name. Auto-resolved from model name if omitted.",
        -  "type": "string"
        -}
      • removedInput schema / properties / packagePath
        Removed value: -{
        -  "description": "Base package path (default: auto-detected PackagesLocalDirectory)",
        -  "type": "string"
        -}
  2. 14 tool updatesv1.14.0
    • Changedbuild_d365fo_project2 fields changed
      • addedInput schema / properties / bpCheck
        Added value: +{
        +  "description": "On a SUCCESSFUL build, also run the best-practice checker and append its findings — saves the usual follow-up run_bp_check call.",
        +  "type": "boolean"
        +}
      • removedInput schema / properties / buildReferencedModels
        Removed value: -{
        -  "description": "DISABLED — always ignored. Rebuilding dependency models on every build slows the run down and referenced models are expected to already be compiled.",
        -  "type": "boolean"
        -}
    • Changedd365fo_file3 fields changed
      • changedInput schema / properties / operation / description
        Previous value: -"[modify] REQUIRED unless using operations[]. add-method also UPDATES in place; replace-code is the surgical oldCode→newCode path. Parameters: get_knowledge(kind=\"op-spec\", topic=\"<operation>\")."New value: +"[modify] REQUIRED unless using operations[]. add-method also UPDATES in place; replace-code is the surgical oldCode→newCode path."
      • changedInput schema / properties / operation / enum
        Previous value: -[
        -  "add-method",
        -  "remove-method",
        -  "replace-code",
        -  "add-field",
        -  "modify-field",
        -  "rename-field",
        -  "replace-all-fields",
        -  "remove-field",
        -  "add-display-method",
        -  "add-table-method",
        -  "add-index",
        -  "remove-index",
        -  "add-full-text-index",
        -  "remove-full-text-index",
        -  "add-table-mapping",
        -  "remove-table-mapping",
        -  "add-relation",
        -  "remove-relation",
        -  "add-delete-action",
        -  "remove-delete-action",
        -  "add-field-group",
        -  "remove-field-group",
        -  "add-field-to-field-group",
        -  "add-field-modification",
        -  "add-data-source",
        -  "add-control",
        -  "remove-control",
        -  "remove-entry-point",
        -  "remove-diagnostic-suppression",
        -  "add-diagnostic-suppression",
        -  "add-enum-value",
        -  "modify-enum-value",
        -  "remove-enum-value",
        -  "add-menu-item-to-menu",
        -  "modify-property",
        -  "add-query-range",
        -  "remove-query-range"
        -]New value: +[
        +  "add-method",
        +  "remove-method",
        +  "replace-code",
        +  "add-field",
        +  "modify-field",
        +  "rename-field",
        +  "replace-all-fields",
        +  "remove-field",
        +  "add-display-method",
        +  "add-table-method",
        +  "add-index",
        +  "remove-index",
        +  "add-full-text-index",
        +  "remove-full-text-index",
        +  "add-table-mapping",
        +  "remove-table-mapping",
        +  "add-relation",
        +  "remove-relation",
        +  "add-delete-action",
        +  "remove-delete-action",
        +  "add-field-group",
        +  "remove-field-group",
        +  "add-field-to-field-group",
        +  "add-field-modification",
        +  "add-data-source",
        +  "add-control",
        +  "remove-control",
        +  "add-entry-point",
        +  "remove-entry-point",
        +  "remove-diagnostic-suppression",
        +  "add-diagnostic-suppression",
        +  "add-enum-value",
        +  "modify-enum-value",
        +  "remove-enum-value",
        +  "add-menu-item-to-menu",
        +  "modify-property",
        +  "add-query-range",
        +  "remove-query-range"
        +]
      • changedInput schema / properties / operations / description
        Previous value: -"[modify] PREFERRED for 2+ edits to the SAME object — ONE call, not one per edit. Entries are {operation, …op-spec params}; objectType/objectName/modelName stay top-level. Applied in order, stopped at the first failure, per-operation results back. 3 fields + their field groups + an index: 7 calls flat, 1 here."New value: +"[modify|create] PREFERRED for 2+ edits to the SAME object — ONE call, not one per edit. On create they run against the just-created object, under the name it actually got. Entries are {operation, …op-spec params}; objectType/objectName/modelName stay top-level. Applied in order, stopped at the first failure, per-operation results back."
    • Changedextension_info2 fields changed
      • changedInput schema / properties / showExistingExtensions / default
        Previous value: -trueNew value: +false
      • changedInput schema / properties / showExistingExtensions / description
        Previous value: -"[points] Show which extension points are already extended (default: true)."New value: +"[points] Also list who already wraps/subscribes each point — opt-in, roughly doubles the response."
    • Changedfind_references1 field changed
      • changedInput schema / properties / targetName / description
        Previous value: -"Target name. Method where-used: qualify as \"Owner.method\" or pass an AOT path \"/Tables/<Table>/Methods/<method>\" for a result scoped to one declaring type (matches Visual Studio xref). A bare method name is name-only and over-reports. Label where-used: pass the label id exactly as written — old format \"@WAX2194\" or new format \"@LabelFile:LabelId\" (e.g. \"@ApplicationPlatform:AbortButtonText\")."New value: +"Target name. Methods: see the scoping rule in the description above. Labels: the id exactly as written — \"@WAX2194\" or \"@LabelFile:LabelId\"."
    • Changedget_knowledge1 field changed
      • addedInput schema / properties / topics
        Added value: +{
        +  "description": "[knowledge|op-spec] Look up SEVERAL topics in one call instead of one call each. Replaces topic.",
        +  "items": {
        +    "type": "string"
        +  },
        +  "maxItems": 10,
        +  "type": "array"
        +}
    • Changedget_object_info2 fields changed
      • changedInput schema / properties / objectType / description
        Previous value: -"Kind of object to read (incl. *-extension types — pass base object name or full extension name). REQUIRED unless using objects[]."New value: +"Kind of object to read. REQUIRED unless using objects[]."
      • changedInput schema / properties / objects / items / properties / objectName / description
        Previous value: -"Exact object name (use search first if unsure)"New value: +"Exact object name."
    • Changedlabels9 fields changed
      • changedInput schema / properties / action / description
        Previous value: -"Label operation to perform. \"list\"/\"list-files\" are aliases of \"info\" (lists label files)."New value: +"Label operation to perform."
      • changedInput schema / properties / action / enum
        Previous value: -[
        -  "search",
        -  "info",
        -  "create",
        -  "update",
        -  "rename",
        -  "list",
        -  "list-files"
        -]New value: +[
        +  "search",
        +  "info",
        +  "create",
        +  "update",
        +  "rename"
        +]
      • changedInput schema / properties / dryRun / description
        Previous value: -"[rename] Preview changes without writing anything (default: false). Use this first!"New value: +"[rename] Preview changes without writing anything."
      • changedInput schema / properties / labelFileId / description
        Previous value: -"[search|info|create|update|rename] AxLabelFile ID (e.g. ContosoExt, SYS). For action=info with no labelId, returns the physical .label.txt path per language. For create/update/rename use the model's ORIGINAL label file, not an extension (…_Extension…). For a NEW label file this ID is the MODEL name, never the bare EXTENSION_PREFIX."New value: +"[search|info|create|update|rename] AxLabelFile ID (e.g. ContosoExt, SYS). For a NEW label file this ID is the MODEL name, never the bare EXTENSION_PREFIX."
      • addedInput schema / properties / labels / items / properties / translations / description
        Added value: +"Same entries as the top-level translations[]."
      • removedInput schema / properties / labels / items / properties / translations / items / properties
        Removed value: -{
        -  "comment": {
        -    "description": "Developer comment (optional)",
        -    "type": "string"
        -  },
        -  "language": {
        -    "description": "Locale code, e.g. en-US, cs, de, sk",
        -    "type": "string"
        -  },
        -  "text": {
        -    "description": "Label text",
        -    "type": "string"
        -  }
        -}
      • removedInput schema / properties / labels / items / properties / translations / items / required
        Removed value: -[
        -  "language",
        -  "text"
        -]
      • removedInput schema / properties / limit
        Removed value: -{
        -  "description": "[search] Alias of maxResults.",
        -  "type": "number"
        -}
      • changedInput schema / properties / maxResults / description
        Previous value: -"[search] Max labels listed (default 10, alias `limit`); a truncated set reports how many more matched."New value: +"[search] Max labels listed (default 10); a truncated set reports how many more matched."
    • Changedobject_patterns3 fields changed
      • changedInput schema / properties / recommend / properties / entityKind / description
        Previous value: -"Kind of entity: master (customers), transaction (orders+lines), setup (group tables), parameters, inquiry (read-only), lookup, workspace, dialogTask"New value: +"Kind of entity being modelled."
      • changedInput schema / properties / recommend / properties / fieldCount / description
        Previous value: -"Approximate fields users see/edit per record (<10 → SimpleList, ≥10 → SimpleListDetails)"New value: +"Approximate fields users see/edit per record."
      • changedInput schema / properties / recommend / properties / tableName / description
        Previous value: -"Main table — pulls field count and existing-form evidence from the index"New value: +"Main table — pulls field count and existing-form evidence from the index."
    • Changedrun_bp_check3 fields changed
      • changedInput schema / properties / modelName / description
        Previous value: -"Model name to check. Auto-detected from .mcp.json if omitted."New value: +"Model name to check. Auto-detected if omitted."
      • changedInput schema / properties / packagePath / description
        Previous value: -"PackagesLocalDirectory root path. Auto-detected from .mcp.json if omitted."New value: +"PackagesLocalDirectory root path. Auto-detected if omitted."
      • changedInput schema / properties / projectPath / description
        Previous value: -"Absolute path to the .rnrproj file to analyze. Auto-detected from .mcp.json if omitted."New value: +"Absolute path to the .rnrproj file to analyze. Auto-detected if omitted."
    • Changedrun_systest_class2 fields changed
      • changedInput schema / properties / modelName / description
        Previous value: -"The model containing the test class. Auto-detected from .mcp.json if omitted."New value: +"The model containing the test class. Auto-detected if omitted."
      • changedInput schema / properties / packagePath / description
        Previous value: -"PackagesLocalDirectory root path. Auto-detected from .mcp.json if omitted."New value: +"PackagesLocalDirectory root path. Auto-detected if omitted."
    • Changedsearch10 fields changed
      • removedInput schema / properties / crossReference
        Removed value: -{
        -  "default": true,
        -  "description": "[batch] Append a cross-reference summary at the end listing symbols that appeared in multiple queries. Useful for identifying the most relevant / commonly matched objects across all searches.",
        -  "type": "boolean"
        -}
      • removedInput schema / properties / deduplicate
        Removed value: -{
        -  "default": true,
        -  "description": "[batch] When true, symbols appearing in multiple query results are collapsed. Later occurrences are replaced with a reference to the query where they first appeared.",
        -  "type": "boolean"
        -}
      • removedInput schema / properties / globalTypeFilter
        Removed value: -{
        -  "description": "[batch] Default type filter for queries without an explicit per-query type. E.g. [\"class\"] restricts all untyped queries to classes. Multiple values fan out each untyped query into one search per type. Values: same as the top-level `type`, except \"all\" (which means \"no filter\" — omit this instead).",
        -  "items": {
        -    "type": "string"
        -  },
        -  "maxItems": 5,
        -  "type": "array"
        -}
      • removedInput schema / properties / includeWorkspace
        Removed value: -{
        -  "default": false,
        -  "description": "[single] Whether to include workspace files in search results (workspace-aware search)",
        -  "type": "boolean"
        -}
      • removedInput schema / properties / queries / items / properties / includeWorkspace
        Removed value: -{
        -  "default": false,
        -  "description": "Whether to include workspace files in results",
        -  "type": "boolean"
        -}
      • changedInput schema / properties / queries / items / properties / type / description
        Previous value: -"Filter by object type — same values as the top-level `type`. Omit to inherit globalTypeFilter or default to \"all\""New value: +"Filter by object type — same values as the top-level `type`."
      • removedInput schema / properties / queries / items / properties / workspacePath
        Removed value: -{
        -  "description": "Optional workspace path to search local files",
        -  "type": "string"
        -}
      • changedInput schema / properties / scope / description
        Previous value: -"[single] Search the whole index (\"all\", default) or only custom/ISV models (\"extensions\"). Ignored when `queries[]` is provided."New value: +"[single] Whole index, or only custom/ISV models. Ignored when `queries[]` is provided."
      • changedInput schema / properties / verbose / description
        Previous value: -"[single] Include related-searches/patterns/tips sections (off by default to keep responses compact)."New value: +"[single] Include related-searches/patterns/tips sections."
      • removedInput schema / properties / workspacePath
        Removed value: -{
        -  "description": "[single] Optional workspace path to search local project files in addition to external metadata",
        -  "type": "string"
        -}
    • Changedtrigger_db_sync5 fields changed
      • changedInput schema / properties / connectionString / description
        Previous value: -"SQL Server connection string. Default: \"Data Source=localhost;Initial Catalog=AxDB;Integrated Security=True\"."New value: +"SQL Server connection string. Defaults to localhost/AxDB."
      • changedInput schema / properties / modelName / description
        Previous value: -"Model to sync. Auto-detected from .mcp.json if omitted."New value: +"Model to sync. Auto-detected if omitted."
      • changedInput schema / properties / packagePath / description
        Previous value: -"PackagesLocalDirectory root. Auto-detected from .mcp.json if omitted."New value: +"PackagesLocalDirectory root. Auto-detected if omitted."
      • changedInput schema / properties / syncViews / description
        Previous value: -"FULL sync only: use syncmode FullAllAndViews. Not needed for partial sync — name the view in tables[] instead. Default: false."New value: +"FULL sync only: use syncmode FullAllAndViews. For partial sync, name the view in tables[] instead."
      • removedInput schema / properties / tableName
        Removed value: -{
        -  "description": "Single-table shorthand — equivalent to tables=[\"tableName\"]. Kept for backwards compatibility.",
        -  "type": "string"
        -}
    • Changedvalidate_code2 fields changed
      • changedInput schema / properties / mode / description
        Previous value: -"syntax = BP/best-practice rules; references = symbol resolution against the index. Defaults to syntax."New value: +"both = run the two checks in ONE call (preferred); syntax = BP/best-practice rules only; references = symbol resolution only."
      • changedInput schema / properties / mode / enum
        Previous value: -[
        -  "syntax",
        -  "references"
        -]New value: +[
        +  "both",
        +  "syntax",
        +  "references"
        +]
    • Changedverify_d365fo_project1 field changed
      • changedInput schema / properties / modelName / description
        Previous value: -"Model name. Auto-detected from mcp.json if omitted."New value: +"Model name. Auto-detected if omitted."
  3. 1 tool updatev1.13.0
    • Changedd365fo_file1 field changed
      • changedInput schema / properties / operation / enum
        Previous value: -[
        -  "add-method",
        -  "remove-method",
        -  "replace-code",
        -  "add-field",
        -  "modify-field",
        -  "rename-field",
        -  "replace-all-fields",
        -  "remove-field",
        -  "add-display-method",
        -  "add-table-method",
        -  "add-index",
        -  "remove-index",
        -  "add-full-text-index",
        -  "remove-full-text-index",
        -  "add-table-mapping",
        -  "remove-table-mapping",
        -  "add-relation",
        -  "remove-relation",
        -  "add-delete-action",
        -  "remove-delete-action",
        -  "add-field-group",
        -  "remove-field-group",
        -  "add-field-to-field-group",
        -  "add-field-modification",
        -  "add-data-source",
        -  "add-control",
        -  "remove-control",
        -  "remove-entry-point",
        -  "remove-diagnostic-suppression",
        -  "add-diagnostic-suppression",
        -  "add-enum-value",
        -  "modify-enum-value",
        -  "remove-enum-value",
        -  "add-menu-item-to-menu",
        -  "modify-property"
        -]New value: +[
        +  "add-method",
        +  "remove-method",
        +  "replace-code",
        +  "add-field",
        +  "modify-field",
        +  "rename-field",
        +  "replace-all-fields",
        +  "remove-field",
        +  "add-display-method",
        +  "add-table-method",
        +  "add-index",
        +  "remove-index",
        +  "add-full-text-index",
        +  "remove-full-text-index",
        +  "add-table-mapping",
        +  "remove-table-mapping",
        +  "add-relation",
        +  "remove-relation",
        +  "add-delete-action",
        +  "remove-delete-action",
        +  "add-field-group",
        +  "remove-field-group",
        +  "add-field-to-field-group",
        +  "add-field-modification",
        +  "add-data-source",
        +  "add-control",
        +  "remove-control",
        +  "remove-entry-point",
        +  "remove-diagnostic-suppression",
        +  "add-diagnostic-suppression",
        +  "add-enum-value",
        +  "modify-enum-value",
        +  "remove-enum-value",
        +  "add-menu-item-to-menu",
        +  "modify-property",
        +  "add-query-range",
        +  "remove-query-range"
        +]
  4. 3 tool updatesv1.12.0
    • Changedd365fo_file6 fields changed
      • changedInput schema / properties / action / description
        Previous value: -"One of the three modes described above."New value: +"One of the four modes described above."
      • changedInput schema / properties / action / enum
        Previous value: -[
        -  "create",
        -  "modify",
        -  "generate"
        -]New value: +[
        +  "create",
        +  "modify",
        +  "delete",
        +  "generate"
        +]
      • changedInput schema / properties / filePath / description
        Previous value: -"[modify] Absolute XML path — bypasses symbol-DB lookup. Use for objects just created."New value: +"[modify|delete] Absolute XML path — bypasses symbol-DB lookup. Use for objects just created."
      • changedInput schema / properties / objectType / description
        Previous value: -"Each security/menu-item type is its own AOT folder — NEVER use security-privilege for duty or role. [modify]/[generate] cover the core families + their *-extension variants."New value: +"Each security/menu-item type is its own AOT folder — NEVER use security-privilege for duty or role. [modify]/[generate] cover the core families + their *-extension variants; [delete] takes the same enum as [create]."
      • changedInput schema / properties / objectType / enum
        Previous value: -[
        -  "class",
        -  "table",
        -  "enum",
        -  "form",
        -  "query",
        -  "view",
        -  "data-entity",
        -  "report",
        -  "edt",
        -  "table-extension",
        -  "class-extension",
        -  "form-extension",
        -  "enum-extension",
        -  "edt-extension",
        -  "data-entity-extension",
        -  "menu-item-display-extension",
        -  "menu-item-action-extension",
        -  "menu-item-output-extension",
        -  "menu-extension",
        -  "menu-item-display",
        -  "menu-item-action",
        -  "menu-item-output",
        -  "menu",
        -  "security-privilege",
        -  "security-duty",
        -  "security-role",
        -  "security-duty-extension",
        -  "security-role-extension",
        -  "business-event",
        -  "tile",
        -  "kpi",
        -  "map",
        -  "service",
        -  "service-group",
        -  "macro",
        -  "configuration-key",
        -  "security-policy",
        -  "aggregate-measurement",
        -  "license-code"
        -]New value: +[
        +  "class",
        +  "table",
        +  "enum",
        +  "form",
        +  "query",
        +  "view",
        +  "data-entity",
        +  "report",
        +  "edt",
        +  "table-extension",
        +  "class-extension",
        +  "form-extension",
        +  "enum-extension",
        +  "edt-extension",
        +  "data-entity-extension",
        +  "menu-item-display-extension",
        +  "menu-item-action-extension",
        +  "menu-item-output-extension",
        +  "menu-extension",
        +  "menu-item-display",
        +  "menu-item-action",
        +  "menu-item-output",
        +  "menu",
        +  "security-privilege",
        +  "security-duty",
        +  "security-role",
        +  "security-duty-extension",
        +  "security-role-extension",
        +  "ignore-diagnostic-list",
        +  "business-event",
        +  "tile",
        +  "kpi",
        +  "map",
        +  "service",
        +  "service-group",
        +  "macro",
        +  "configuration-key",
        +  "security-policy",
        +  "aggregate-measurement",
        +  "license-code"
        +]
      • changedInput schema / properties / operation / enum
        Previous value: -[
        -  "add-method",
        -  "remove-method",
        -  "replace-code",
        -  "add-field",
        -  "modify-field",
        -  "rename-field",
        -  "replace-all-fields",
        -  "remove-field",
        -  "add-display-method",
        -  "add-table-method",
        -  "add-index",
        -  "remove-index",
        -  "add-full-text-index",
        -  "remove-full-text-index",
        -  "add-table-mapping",
        -  "remove-table-mapping",
        -  "add-relation",
        -  "remove-relation",
        -  "add-delete-action",
        -  "remove-delete-action",
        -  "add-field-group",
        -  "remove-field-group",
        -  "add-field-to-field-group",
        -  "add-field-modification",
        -  "add-data-source",
        -  "add-control",
        -  "add-enum-value",
        -  "modify-enum-value",
        -  "remove-enum-value",
        -  "add-menu-item-to-menu",
        -  "modify-property"
        -]New value: +[
        +  "add-method",
        +  "remove-method",
        +  "replace-code",
        +  "add-field",
        +  "modify-field",
        +  "rename-field",
        +  "replace-all-fields",
        +  "remove-field",
        +  "add-display-method",
        +  "add-table-method",
        +  "add-index",
        +  "remove-index",
        +  "add-full-text-index",
        +  "remove-full-text-index",
        +  "add-table-mapping",
        +  "remove-table-mapping",
        +  "add-relation",
        +  "remove-relation",
        +  "add-delete-action",
        +  "remove-delete-action",
        +  "add-field-group",
        +  "remove-field-group",
        +  "add-field-to-field-group",
        +  "add-field-modification",
        +  "add-data-source",
        +  "add-control",
        +  "remove-control",
        +  "remove-entry-point",
        +  "remove-diagnostic-suppression",
        +  "add-diagnostic-suppression",
        +  "add-enum-value",
        +  "modify-enum-value",
        +  "remove-enum-value",
        +  "add-menu-item-to-menu",
        +  "modify-property"
        +]
    • Changedget_knowledge6 fields changed
      • addedInput schema / properties / action
        Added value: +{
        +  "description": "[bp-moniker] REQUIRED. validate = confirm an exact moniker is real; search = free-text scenario query; suppress = render a <Diagnostic> block.",
        +  "enum": [
        +    "validate",
        +    "search",
        +    "suppress"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / justification
        Added value: +{
        +  "description": "[bp-moniker suppress] REQUIRED. Why the warning is ignored; 95% of real entries carry one.",
        +  "type": "string"
        +}
      • changedInput schema / properties / kind / description
        Previous value: -"knowledge = look up an X++ topic/rule; error = diagnose an error message; op-spec = parameter contract for a d365fo_file operation/objectType or generate_object mode."New value: +"knowledge = look up an X++ topic/rule; error = diagnose an error message; op-spec = parameter contract for a d365fo_file operation/objectType or generate_object mode; bp-moniker = validate/search a BP-check moniker or render a suppression."
      • changedInput schema / properties / kind / enum
        Previous value: -[
        -  "knowledge",
        -  "error",
        -  "op-spec"
        -]New value: +[
        +  "knowledge",
        +  "error",
        +  "op-spec",
        +  "bp-moniker"
        +]
      • addedInput schema / properties / moniker
        Added value: +{
        +  "description": "[bp-moniker validate/suppress] REQUIRED. Exact moniker, e.g. \"BPErrorPrivilegeNotCoveredByDuty\".",
        +  "type": "string"
        +}
      • addedInput schema / properties / path
        Added value: +{
        +  "description": "[bp-moniker suppress] REQUIRED. dynamics:// path, verbatim from the finding.",
        +  "type": "string"
        +}
    • Changedlabels1 field changed
      • changedInput schema / properties / labelId / description
        Previous value: -"[info] Exact label ID. Omit for action=info to list available label files for the model."New value: +"[info] Label ID, any spelling: SYS67433, @SYS67433, @ContosoExt:MyLabel (paste search output). labelFileId/model optional. Omit to list label files."
  5. 4 tool updatesv1.10.0
    • Changedd365fo_file1 field changed
      • changedInput schema / properties / addToProject / description
        Previous value: -"Add to the .rnrproj — keep the default."New value: +"Add to the ACTIVE .rnrproj — keep the default."
    • Changedget_object_info1 field changed
      • changedInput schema / properties / options / description
        Previous value: -"Type-specific flags forwarded to the reader: includeRdl, includeFields, searchControl, compact, includeOperations, filter, mode, modelName. For a CLASS, {\"method\":\"validateWrite\",\"include\":\"signature\"} returns ONE method (include: signature | source | both) — required before writing a CoC extension. Big objects are paged — table fieldsOffset/fieldFilter, form maxControls. Applies to every objects[] entry."New value: +"Type-specific reader flags: includeRdl (report), searchControl/maxControls (form), compact/methodOffset (class), fieldsOffset/fieldFilter (table), filter (macro), mode (edt), includeFields, includeOperations, modelName. On class/table/view/data-entity, {\"method\":\"validateWrite\",\"include\":\"signature\"} returns ONE method (include: signature | source | both) — required before writing a CoC extension. {\"include\":\"xml\"} returns raw AOT XML + its path (page: startLine/endLine) — never shell out to find or read a file. Applies to every objects[] entry."
    • Changedget_workspace_info1 field changed
      • changedInput schema / properties / projectName / description
        Previous value: -"Only when the USER says \"switch to <project>\". Just the model name, e.g. \"ContosoEDS\"; path resolved from D365FO_SOLUTIONS_PATH. NOT a way to reach another model — reads span every model already, writes stay in the workspace model."New value: +"Only when the USER says \"switch to <project>\". The PROJECT file name, e.g. \"Contoso - FeatureManagement\". NOT a model name: one model is built by many projects, so naming it selects none and the call is refused. Reads span every model already."
    • Changedlabels3 fields changed
      • changedInput schema / properties / query / description
        Previous value: -"[search] REQUIRED. Search text — matches label ID, text and developer comment."New value: +"[search] REQUIRED. Search text — matches label ID, text and developer comment. ARRAY = try several phrasings in ONE call."
      • addedInput schema / properties / query / items
        Added value: +{
        +  "type": "string"
        +}
      • changedInput schema / properties / query / type
        Previous value: -"string"New value: +[
        +  "string",
        +  "array"
        +]
  6. 14 tool updatesv1.9.0
    • Removedbatch_get_info
    • Changedbuild_d365fo_project1 field changed
      • changedInput schema / properties / buildReferencedModels / description
        Previous value: -"Also build all custom/ISV models this model depends on before building the target. Skips Microsoft standard models."New value: +"DISABLED — always ignored. Rebuilding dependency models on every build slows the run down and referenced models are expected to already be compiled."
    • Changedd365fo_file20 fields changed
      • changedInput schema / properties / addToProject / description
        Previous value: -"Add the file to the .rnrproj project. Keep the default (true) unless explicitly asked otherwise."New value: +"Add to the .rnrproj — keep the default."
      • changedInput schema / properties / createBackup / description
        Previous value: -"[modify] Create backup before modification (default false)"New value: +"[modify] Back up before modifying."
      • changedInput schema / properties / filePath / description
        Previous value: -"[modify] Absolute path to the XML file — bypasses symbol-DB lookup. Use when the object was just created."New value: +"[modify] Absolute XML path — bypasses symbol-DB lookup. Use for objects just created."
      • changedInput schema / properties / groundingToken / description
        Previous value: -"Provenance token from prepare(change/create). Required for *-extension objectTypes when GROUNDING_ENFORCE=true; object-bound — only valid for the object it was issued for."New value: +"From prepare(change/create). Required for *-extension when GROUNDING_ENFORCE=true; object-bound."
      • changedInput schema / properties / modelName / description
        Previous value: -"Target model name — auto-detected from .mcp.json if omitted. NEVER guess or take model names from search results (source models)."New value: +"Target model — auto-detected. NEVER take it from search results (those are source models)."
      • changedInput schema / properties / objectName / description
        Previous value: -"Base name WITHOUT model prefix — the tool prepends EXTENSION_PREFIX (or modelName) and detects an existing prefix. Extension classes: pass \"{Base}_Extension\" with NO prefix infix. NEVER hand-build the prefix."New value: +"Base name WITHOUT model prefix — the tool prepends it. Extension classes: \"{Base}_Extension\". NEVER hand-build the prefix."
      • changedInput schema / properties / objectType / description
        Previous value: -"Each security/menu-item type maps to its own AOT folder — NEVER use security-privilege for duty or role. class-extension = [ExtensionOf] final class skeleton; business-event = BusinessEventsBase + Contract pair. [modify] supports class/table/form/enum/query/view/edt/data-entity/report + *-extension variants. [generate] supports class/table/enum/form/query/view/data-entity/report + table/form/enum/edt/data-entity-extension."New value: +"Each security/menu-item type is its own AOT folder — NEVER use security-privilege for duty or role. [modify]/[generate] cover the core families + their *-extension variants."
      • changedInput schema / properties / operation / description
        Previous value: -"[modify] REQUIRED. Modification to perform. Non-obvious ones:\nadd-method: adds OR updates in place if the name exists (position kept).\nreplace-code: surgical oldCode→newCode; preferred for rewriting a known method. Control overrides: methodName=\"Control.method\".\nrename-field: also fixes index DataField refs and TitleField1/2.\nreplace-all-fields: atomic rewrite of ALL fields.\nadd-display-method: display method with [SysClientCacheDataMethodAttribute].\nadd-table-method: canonical find/exist/findByRecId/validate*/initValue boilerplate.\nadd-field-modification: override base-table field label/mandatory in a table-extension.\nadd-delete-action: DeleteActions entry — deleteActionName + optional deleteActionTable/deleteActionType.\nadd-full-text-index/add-table-mapping: the <FullTextIndexes>/<Mappings> collections.\nmodify-property: any object-level property (TableGroup, TitleField1, Extends…) — see propertyPath; on an *-extension it becomes a PropertyModification."New value: +"[modify] REQUIRED unless using operations[]. add-method also UPDATES in place; replace-code is the surgical oldCode→newCode path. Parameters: get_knowledge(kind=\"op-spec\", topic=\"<operation>\")."
      • addedInput schema / properties / operations
        Added value: +{
        +  "description": "[modify] PREFERRED for 2+ edits to the SAME object — ONE call, not one per edit. Entries are {operation, …op-spec params}; objectType/objectName/modelName stay top-level. Applied in order, stopped at the first failure, per-operation results back. 3 fields + their field groups + an index: 7 calls flat, 1 here.",
        +  "items": {
        +    "additionalProperties": true,
        +    "type": "object"
        +  },
        +  "maxItems": 20,
        +  "type": "array"
        +}
      • changedInput schema / properties / overwrite / description
        Previous value: -"Allow overwriting an existing file (use with xmlContent to rewrite an object — never via PowerShell/create_file)."New value: +"Allow overwriting — never rewrite via PowerShell."
      • removedInput schema / properties / packageName
        Removed value: -{
        -  "description": "Package name — auto-resolved from model name; pass only if they differ.",
        -  "type": "string"
        -}
      • removedInput schema / properties / packagePath
        Removed value: -{
        -  "description": "Base package path (default: auto-detected PackagesLocalDirectory). [modify] also locates objects outside the default dir; for models outside bridge startup roots set D365FO_CUSTOM_PACKAGES_PATH or pass filePath.",
        -  "type": "string"
        -}
      • changedInput schema / properties / params / description
        Previous value: -"[modify] Operation-specific parameters as ONE object — NEST them here. Common shapes: add-method {methodName, sourceCode} · replace-code {oldCode, newCode, methodName?} · add-field {fieldName, fieldType(EDT), fieldBaseType?}; data-entity-ext {fieldName, dataField, dataSource} · rename-field {fieldName, fieldNewName} · add-index {indexName, indexFields[{fieldName}]} · add-relation {relationName, relatedTable, relationConstraints?} · add-field-group {fieldGroupName, fieldGroupFields?} · add-data-source {dataSourceName, dataSourceTable} · add-control {controlName, parentControl, controlDataSource?, controlDataField?} · enum ops {enumValueName, enumValueNewName?(modify-enum-value rename), enumValueLabel?, enumValueInt?} · add-menu-item-to-menu {menuItemToAdd} · modify-property {propertyPath, propertyValue} · add-table-method {tableMethodType, tableKeyField?} · add-display-method {methodName, displayMethodReturnEdt}. A missing/wrong parameter returns the COMPLETE spec for that operation — follow it instead of guessing."New value: +"[modify] Operation-specific parameters as ONE nested object, per get_knowledge(kind=\"op-spec\", topic=\"<operation>\"). A missing/wrong one returns that COMPLETE spec — follow it, do not guess."
      • changedInput schema / properties / projectPath / description
        Previous value: -"Path to .rnrproj file (needed for addToProject). Auto-detected from .mcp.json or workspace if omitted."New value: +"Path to .rnrproj (auto-detected)."
      • addedInput schema / properties / properties / additionalProperties
        Added value: +true
      • changedInput schema / properties / properties / description
        Previous value: -"Additional properties by objectType:\n• class: extends, implements, isFinal, isAbstract\n• table: label, tableGroup, tableType, titleField1/2, cacheLookup?, primaryIndex?, allowRowVersionChangeTracking? (dual-write), created/modifiedBy/DateTime?, fields[{name,type?|edt?|fieldType?,enumType?,label?,mandatory?}] — enum fields need enumType (+ optionally fieldType:\"AxTableFieldEnum\")\n• enum: label, useEnumValue, configurationKey, isExtensible, enumValues[{name,value?,label?,helpText?}]\n• enum-extension: enumValues[{name,label?,value?,countryRegionCodes?}]\n• table-extension: fields[{name,edt?,enumType?,label?,mandatory?,fieldType?}] — enum fields need fieldType:\"AxTableFieldEnum\" + enumType\n• edt: label, extends, edtType, stringSize\n• edt-extension: label?, helpText?, stringSize?, extends?, formHelp?, propertyModifications?[{name,value}] = the change\n• form: caption, formTemplate, dataSource\n• security-privilege: label, targetObject, objectType (MenuItemDisplay|Action|Output), accessLevel (view|maintain), dataEntity (grants perms)\n• security-duty: label, privileges[]\n• security-role: label, duties[], privileges[]\n• menu-item-*: label, object, objectType\n• data-entity: primaryTable, fields[{name,dataField?}], primaryKey?, primaryKeyFields?[], isPublic?, entityCategory?, dynamicFields?, allowRowVersionChangeTracking? (dual-write: set on the source TABLES too), dataManagementEnabled? (needs staging table)\n• map: label?, developerDocumentation?, fields[{name,type?,edt?,enumType?,stringSize?}], mappingTable?, mappings?[{mapField,mapFieldTo}] (one connection/field by default)\n• query: title?, dataSource (root table; table also works), dataSourceName?, fields?[{name,field?}]\n• view: query (existing AxQuery), fields[{name,dataField?}] — dataSource defaults to query\n• service: serviceClass (defaults to the service name), externalName?, namespace?, description?, operations[\"opName\"] or [{name?,method?,enableIdempotence?,subscriberAccessLevelRead?}]\n• service-group: autoDeploy? (Yes publishes at /api/services), description?, services[\"MyService\"] or [{name?,service?}]\n  ⚠ service/service-group CROSS-REFS (serviceClass, services[].service) are written VERBATIM — only objectName is prefixed. Pass the FINAL name (e.g. \"ContosoDemoNoteService\", not \"DemoNoteService\") or the group resolves to nothing; verbatim also lets it reference an unprefixed MS service."New value: +"[create] Per-objectType creation properties (label, fields[], extends, enumValues[], primaryTable, …) — NOT in this schema. Fetch yours: get_knowledge(kind=\"op-spec\", topic=\"<objectType>\")."
      • removedInput schema / properties / solutionPath
        Removed value: -{
        -  "description": "VS solution directory — used to find .rnrproj when projectPath unset.",
        -  "type": "string"
        -}
      • changedInput schema / properties / sourceCode / description
        Previous value: -"X++ source for the object. FOR CLASSES the content is auto-split: <Declaration> = the class line + ALL member variables inside the outer { }; <Methods> = each method AFTER the closing }."New value: +"X++ source. FOR CLASSES auto-split: <Declaration> = class line + member vars; <Methods> = each method after the closing }."
      • removedInput schema / properties / workspacePath
        Removed value: -{
        -  "description": "[modify] Workspace path for finding file",
        -  "type": "string"
        -}
      • changedInput schema / properties / xmlContent / description
        Previous value: -"Complete XML to write verbatim (with overwrite=true rewrites an existing object; Azure/Linux: pass XML from action=generate)."New value: +"Complete XML written verbatim (+overwrite=true rewrites an object)."
    • Changedgenerate_object36 fields changed
      • removedInput schema / properties / additionalDatasets
        Removed value: -{
        -  "description": "[scaffold:report] Multi-dataset report: each entry adds a TempDB TmpTable + a get<Table>() DP method. name = suffix (\"Header\" → <Report>HeaderTmp).",
        -  "items": {
        -    "properties": {
        -      "fields": {
        -        "items": {
        -          "properties": {
        -            "name": {
        -              "type": "string"
        -            }
        -          },
        -          "required": [
        -            "name"
        -          ],
        -          "type": "object"
        -        },
        -        "type": "array"
        -      },
        -      "fieldsHint": {
        -        "type": "string"
        -      },
        -      "name": {
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "name"
        -    ],
        -    "type": "object"
        -  },
        -  "type": "array"
        -}
      • removedInput schema / properties / baseName
        Removed value: -{
        -  "description": "[pattern] event-handler: base class/table. form-datasource-extension: data source name (defaults to form name). form-control-extension: exact control name (find via get_object_info(objectType=\"form\")).",
        -  "type": "string"
        -}
      • removedInput schema / properties / caption
        Removed value: -{
        -  "description": "[scaffold:form|report] Optional caption/title (form: window title; report: human-readable report title).",
        -  "type": "string"
        -}
      • removedInput schema / properties / cloneFrom
        Removed value: -{
        -  "description": "[scaffold:form] PREFERRED: clone a reference form's XML re-bound via tableMapping (methods stripped; fields missing on target tables dropped and reported).",
        -  "type": "string"
        -}
      • removedInput schema / properties / contractParams
        Removed value: -{
        -  "description": "[scaffold:report] Dialog parameters for the Contract class.",
        -  "items": {
        -    "properties": {
        -      "label": {
        -        "type": "string"
        -      },
        -      "mandatory": {
        -        "type": "boolean"
        -      },
        -      "name": {
        -        "type": "string"
        -      },
        -      "type": {
        -        "description": "X++ type — EDT or primitive (e.g. \"TransDate\", \"CustAccount\")",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "name"
        -    ],
        -    "type": "object"
        -  },
        -  "type": "array"
        -}
      • removedInput schema / properties / copyFrom
        Removed value: -{
        -  "description": "[scaffold] Copy structure from an existing object (forms: prefer cloneFrom).",
        -  "type": "string"
        -}
      • removedInput schema / properties / dataSource
        Removed value: -{
        -  "description": "[scaffold:form] Optional: Table name for primary datasource.",
        -  "type": "string"
        -}
      • removedInput schema / properties / designStyle
        Removed value: -{
        -  "description": "[scaffold:report] RDL design pattern: \"SimpleList\" (default) or \"GroupedWithTotals\".",
        -  "type": "string"
        -}
      • removedInput schema / properties / fieldGroup
        Removed value: -{
        -  "description": "[fields] Field-group name — emits an AxTableFieldGroup listing the new fields.",
        -  "type": "string"
        -}
      • removedInput schema / properties / fields
        Removed value: -{
        -  "description": "[scaffold:table|report | fields] Structured field specs; takes priority over fieldsHint. PREFER for enum-backed fields or an explicit EDT — a bare name cannot express either. name + optional edt/enumType/type/label/mandatory (EDT auto-resolved when omitted).",
        -  "items": {
        -    "properties": {
        -      "dataType": {
        -        "description": "[scaffold:report] .NET type, e.g. \"System.Double\"",
        -        "type": "string"
        -      },
        -      "edt": {
        -        "description": "Explicit EDT — for mode=\"fields\", omit to auto-resolve from the field name.",
        -        "type": "string"
        -      },
        -      "enumType": {
        -        "description": "[fields] Enum name for an enum-backed field (AxTableFieldEnum).",
        -        "type": "string"
        -      },
        -      "label": {
        -        "type": "string"
        -      },
        -      "mandatory": {
        -        "description": "[fields] Mark the field Mandatory=Yes.",
        -        "type": "boolean"
        -      },
        -      "name": {
        -        "type": "string"
        -      },
        -      "type": {
        -        "description": "[fields] Explicit base type (String/Integer/Int64/Real/Date/UtcDateTime/Guid).",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "name"
        -    ],
        -    "type": "object"
        -  },
        -  "type": "array"
        -}
      • removedInput schema / properties / fieldsHint
        Removed value: -{
        -  "description": "[scaffold:table|report] Comma-separated field names; EDTs auto-suggested from the index. ⚠️ EDTs/enums created this session are not yet indexed — call update_symbol_index first, else those fields default to String255.",
        -  "type": "string"
        -}
      • removedInput schema / properties / formPattern
        Removed value: -{
        -  "description": "[scaffold:form] Optional: Form pattern (SimpleList, SimpleListDetails, DetailsMaster, DetailsTransaction, Dialog, DropDialog, TableOfContents, Lookup, ListPage, Workspace).",
        -  "type": "string"
        -}
      • removedInput schema / properties / generateCommonFields
        Removed value: -{
        -  "description": "[scaffold:table] Auto-generate common fields based on table group patterns.",
        -  "type": "boolean"
        -}
      • removedInput schema / properties / generateController
        Removed value: -{
        -  "description": "[scaffold:report] Generate Controller class (default: true).",
        -  "type": "boolean"
        -}
      • removedInput schema / properties / generateControls
        Removed value: -{
        -  "description": "[scaffold:form] Auto-generate grid controls for datasource.",
        -  "type": "boolean"
        -}
      • removedInput schema / properties / includeExists
        Removed value: -{
        -  "description": "[find-methods] Emit exists() (default true).",
        -  "type": "boolean"
        -}
      • removedInput schema / properties / includeFindRecId
        Removed value: -{
        -  "description": "[find-methods] Emit findRecId() (default true).",
        -  "type": "boolean"
        -}
      • removedInput schema / properties / includeMethodStubs
        Removed value: -{
        -  "description": "[scaffold:form] Inject pattern-appropriate lifecycle method stubs with TODO markers.",
        -  "type": "boolean"
        -}
      • removedInput schema / properties / keyFields
        Removed value: -{
        -  "description": "[find-methods] Explicit key field names (order matters); overrides index detection.",
        -  "items": {
        -    "type": "string"
        -  },
        -  "type": "array"
        -}
      • removedInput schema / properties / label
        Removed value: -{
        -  "description": "[scaffold:table|form] Optional label for the generated object.",
        -  "type": "string"
        -}
      • removedInput schema / properties / menuItemType
        Removed value: -{
        -  "description": "[pattern] For menu-item pattern: type of menu item (display=form, action=class, output=report)",
        -  "enum": [
        -    "display",
        -    "action",
        -    "output"
        -  ],
        -  "type": "string"
        -}
      • changedInput schema / properties / modelName / description
        Previous value: -"Model name from .mcp.json (auto-detected if omitted). NEVER use placeholders like \"MyModel\"."New value: +"Model name (auto-detected). NEVER use placeholders like \"MyModel\"."
      • changedInput schema / properties / name / description
        Previous value: -"REQUIRED. [pattern] element name (extensions: base element; form-datasource/control-extension: the FORM name). [scaffold] object name WITHOUT model prefix."New value: +"REQUIRED. [pattern] element name (extensions: base element; form-datasource/control-extension: the FORM name). [scaffold] object name WITHOUT model prefix. [other modes] the existing table."
      • removedInput schema / properties / packagePath
        Removed value: -{
        -  "description": "[scaffold:report] Base packages directory path.",
        -  "type": "string"
        -}
      • addedInput schema / properties / params
        Added value: +{
        +  "additionalProperties": true,
        +  "description": "Mode-specific parameters as ONE nested object (label, fields[], fieldsHint, cloneFrom, tableMapping, formPattern, contractParams[], keyFields[], style, fieldGroup, …). Get the contract from get_knowledge(kind=\"op-spec\", topic=\"<mode>\"); a missing required one returns that COMPLETE spec.",
        +  "type": "object"
        +}
      • changedInput schema / properties / pattern / description
        Previous value: -"[pattern] REQUIRED. CoC skeletons: class/table-extension, form-handler, form-datasource-extension (name=FormName, baseName=DataSourceName), form-control-extension (name=FormName, baseName=ControlName), map-extension. ssrs-report-full = Contract+DP+Controller; service-class-ais = CRUD service + contract."New value: +"[pattern] REQUIRED. CoC skeletons: class/table-extension, form-handler, form-datasource-extension, form-control-extension, map-extension. ssrs-report-full = Contract+DP+Controller; service-class-ais = CRUD service + contract."
      • removedInput schema / properties / preview
        Removed value: -{
        -  "description": "[scaffold:table] Return the XML without writing to disk.",
        -  "type": "boolean"
        -}
      • removedInput schema / properties / projectPath
        Removed value: -{
        -  "description": "[scaffold] Path to .rnrproj file for model extraction.",
        -  "type": "string"
        -}
      • removedInput schema / properties / relationName
        Removed value: -{
        -  "description": "[relation-xpp] One relation to convert. Omit = all relations.",
        -  "type": "string"
        -}
      • removedInput schema / properties / serviceMethod
        Removed value: -{
        -  "description": "[pattern] sysoperation: Service method the Controller calls (default \"process\").",
        -  "type": "string"
        -}
      • removedInput schema / properties / solutionPath
        Removed value: -{
        -  "description": "[scaffold] Path to solution directory (alternative to projectPath).",
        -  "type": "string"
        -}
      • removedInput schema / properties / style
        Removed value: -{
        -  "description": "[relation-xpp] select | query | both (default).",
        -  "enum": [
        -    "select",
        -    "query",
        -    "both"
        -  ],
        -  "type": "string"
        -}
      • removedInput schema / properties / tableGroup
        Removed value: -{
        -  "description": "[scaffold:table] Business role (TableGroup enum): Main, Transaction, Parameter, Group, WorksheetHeader/WorksheetLine, Reference, Miscellaneous, Framework. ⛔ NEVER pass \"TempDB\"/\"InMemory\" here — that is tableType.",
        -  "type": "string"
        -}
      • removedInput schema / properties / tableMapping
        Removed value: -{
        -  "additionalProperties": {
        -    "type": "string"
        -  },
        -  "description": "[scaffold:form] With cloneFrom: sourceTable → targetTable map, e.g. {\"CustGroup\": \"MyRentalGroup\"}.",
        -  "type": "object"
        -}
      • removedInput schema / properties / tableType
        Removed value: -{
        -  "description": "[scaffold:table] Storage type: Regular (default, omit), TempDB, InMemory. ⛔ NEVER pass as tableGroup.",
        -  "type": "string"
        -}
      • removedInput schema / properties / targetObject
        Removed value: -{
        -  "description": "[pattern] For menu-item and security-privilege patterns: target form/class/report name",
        -  "type": "string"
        -}
    • Changedget_knowledge3 fields changed
      • changedInput schema / properties / kind / description
        Previous value: -"knowledge = look up an X++ topic/rule; error = diagnose an error message."New value: +"knowledge = look up an X++ topic/rule; error = diagnose an error message; op-spec = parameter contract for a d365fo_file operation/objectType or generate_object mode."
      • changedInput schema / properties / kind / enum
        Previous value: -[
        -  "knowledge",
        -  "error"
        -]New value: +[
        +  "knowledge",
        +  "error",
        +  "op-spec"
        +]
      • changedInput schema / properties / topic / description
        Previous value: -"[knowledge] REQUIRED. Topic to query — e.g. \"batch job\", \"ttsbegin\", \"RunBase vs SysOperation\", \"set-based operations\", \"CoC\", \"data entities\", \"number sequences\", \"security\", \"temp tables\", \"today() deprecated\", \"query patterns\", \"form patterns\""New value: +"[knowledge] REQUIRED. Topic to query — e.g. \"batch job\", \"ttsbegin\", \"RunBase vs SysOperation\", \"set-based operations\", \"CoC\", \"data entities\", \"number sequences\", \"security\", \"temp tables\", \"today() deprecated\", \"query patterns\", \"form patterns\". [op-spec] The operation / objectType / mode to look up."
    • Removedget_method
    • Changedget_object_info5 fields changed
      • changedInput schema / properties / name / description
        Previous value: -"Exact object name (use search first if unsure)"New value: +"Exact object name (use search first if unsure). REQUIRED unless using objects[]."
      • changedInput schema / properties / objectType / description
        Previous value: -"Kind of object to read (incl. *-extension types — pass base object name or full extension name)"New value: +"Kind of object to read (incl. *-extension types — pass base object name or full extension name). REQUIRED unless using objects[]."
      • addedInput schema / properties / objects
        Added value: +{
        +  "description": "PREFERRED for 2+ objects: read them all in one round trip. Each entry takes the same objectType/options as the single form, with the name in objectName.",
        +  "items": {
        +    "properties": {
        +      "objectName": {
        +        "description": "Exact object name (use search first if unsure)",
        +        "type": "string"
        +      },
        +      "objectType": {
        +        "description": "Kind of object to read",
        +        "enum": [
        +          "class",
        +          "table",
        +          "form",
        +          "query",
        +          "view",
        +          "enum",
        +          "edt",
        +          "report",
        +          "data-entity",
        +          "menu-item",
        +          "service",
        +          "map",
        +          "config-key",
        +          "security-policy",
        +          "macro",
        +          "table-extension",
        +          "class-extension",
        +          "form-extension",
        +          "enum-extension",
        +          "edt-extension",
        +          "data-entity-extension"
        +        ],
        +        "type": "string"
        +      },
        +      "options": {
        +        "description": "Optional type-specific flags for this object; overrides the top-level options.",
        +        "type": "object"
        +      }
        +    },
        +    "required": [
        +      "objectType",
        +      "objectName"
        +    ],
        +    "type": "object"
        +  },
        +  "maxItems": 10,
        +  "minItems": 1,
        +  "type": "array"
        +}
      • changedInput schema / properties / options / description
        Previous value: -"Optional type-specific flags forwarded to the reader (e.g. includeRdl, includeFields, searchControl, compact, includeOperations, filter, mode, modelName)."New value: +"Type-specific flags forwarded to the reader: includeRdl, includeFields, searchControl, compact, includeOperations, filter, mode, modelName. For a CLASS, {\"method\":\"validateWrite\",\"include\":\"signature\"} returns ONE method (include: signature | source | both) — required before writing a CoC extension. Big objects are paged — table fieldsOffset/fieldFilter, form maxControls. Applies to every objects[] entry."
      • removedInput schema / required
        Removed value: -[
        -  "objectType",
        -  "name"
        -]
    • Changedget_workspace_info1 field changed
      • changedInput schema / properties / diagnostics / description
        Previous value: -"Include verbose diagnostic sections (suffix breakdown, stdio session/handshake dump). Use when debugging client-server connectivity."New value: +"Include verbose sections (config sources, suffix, project paths, index scan, stdio handshake). Use when debugging config or connectivity."
    • Changedlabels17 fields changed
      • removedInput schema / properties / addToProject
        Removed value: -{
        -  "description": "[create] Add label file XML descriptors to the VS project (default: true).",
        -  "type": "boolean"
        -}
      • removedInput schema / properties / allowExtensionLabelFile
        Removed value: -{
        -  "description": "[create|rename] Allow writing to a label file EXTENSION (\"_Extension\" marker). Default false — new labels belong in the model's ORIGINAL label file.",
        -  "type": "boolean"
        -}
      • removedInput schema / properties / createLabelFileIfMissing
        Removed value: -{
        -  "description": "[create] Create the AxLabelFile structure if missing (default: true). A wrong-path guard still fails loudly when the model directory is not found, so no phantom file is produced. Set false to fail fast instead.",
        -  "type": "boolean"
        -}
      • removedInput schema / properties / defaultComment
        Removed value: -{
        -  "description": "[create] Developer comment for languages without explicit comment.",
        -  "type": "string"
        -}
      • removedInput schema / properties / description
        Removed value: -{
        -  "description": "[create] Label description (comment line in .label.txt). Defaults to VS project name from .rnrproj when omitted, then falls back to labelFileId. Per-translation comment and defaultComment take priority.",
        -  "type": "string"
        -}
      • removedInput schema / properties / languages
        Removed value: -{
        -  "description": "[create] Restrict which language .label.txt files are written (e.g. [\"en-US\"]). Omitted = every language folder present in the model.",
        -  "items": {
        -    "type": "string"
        -  },
        -  "type": "array"
        -}
      • changedInput schema / properties / limit / description
        Previous value: -"[search] Maximum number of results (default 30)."New value: +"[search] Alias of maxResults."
      • addedInput schema / properties / maxResults
        Added value: +{
        +  "description": "[search] Max labels listed (default 10, alias `limit`); a truncated set reports how many more matched.",
        +  "type": "number"
        +}
      • removedInput schema / properties / packageName
        Removed value: -{
        -  "description": "[create|rename] Package name for the model. Auto-resolved if omitted.",
        -  "type": "string"
        -}
      • removedInput schema / properties / packagePath
        Removed value: -{
        -  "description": "[create|rename] Root packages path. Auto-detected from environment config if omitted.",
        -  "type": "string"
        -}
      • addedInput schema / properties / params
        Added value: +{
        +  "additionalProperties": true,
        +  "description": "Optional write plumbing (packagePath, projectPath, languages, sortLabels, allowExtensionLabelFile, …) — all auto-resolved when omitted. Contract: get_knowledge(kind=\"op-spec\", topic=\"labels\").",
        +  "type": "object"
        +}
      • removedInput schema / properties / projectPath
        Removed value: -{
        -  "description": "[create] Path to the .rnrproj project file. Auto-detected from .mcp.json if omitted.",
        -  "type": "string"
        -}
      • removedInput schema / properties / searchPaths
        Removed value: -{
        -  "description": "[rename] Additional absolute directory paths to scan for X++ / XML references.",
        -  "items": {
        -    "type": "string"
        -  },
        -  "type": "array"
        -}
      • removedInput schema / properties / solutionPath
        Removed value: -{
        -  "description": "[create] Path to the .sln solution directory. Fallback to find .rnrproj if projectPath is not set.",
        -  "type": "string"
        -}
      • removedInput schema / properties / sortLabels
        Removed value: -{
        -  "description": "[create] Sort labels alphabetically in .label.txt (default true, from LABEL_SORT_ORDER env; false = append at end).",
        -  "type": "boolean"
        -}
      • removedInput schema / properties / updateIndex
        Removed value: -{
        -  "description": "[create|rename] Update the MCP label index after writing (default: true).",
        -  "type": "boolean"
        -}
      • addedInput schema / properties / verbose
        Added value: +{
        +  "description": "[search] Default one line per label; true = full multi-line block.",
        +  "type": "boolean"
        +}
    • Changedprepare1 field changed
      • addedInput schema / properties / operation
        Added value: +{
        +  "description": "[change] The modify operation you intend to run; its full parameter contract comes back in THIS response, so no separate op-spec call. Defaults to add-method when methodName is given.",
        +  "type": "string"
        +}
    • Changedrun_bp_check3 fields changed
      • addedInput schema / properties / objects
        Added value: +{
        +  "description": "Check several objects in ONE call — preferred over targetFilter. Shared preamble is printed once and findings are grouped per object.",
        +  "items": {
        +    "properties": {
        +      "objectName": {
        +        "description": "Object name.",
        +        "type": "string"
        +      },
        +      "objectType": {
        +        "description": "class, table, form, enum, view, query, edt, ... Looked up in the symbol index if omitted.",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "objectName"
        +    ],
        +    "type": "object"
        +  },
        +  "type": "array"
        +}
      • changedInput schema / properties / targetElementType / description
        Previous value: -"Element type for the filter when using xppbp 10.0.24+ (equals-style CLI). Common values: class, table, form, enum, view, query. Defaults to \"class\" when targetFilter is set but this is omitted."New value: +"Element type for targetFilter. Looked up in the symbol index if omitted; ambiguous or unknown names error rather than being assumed to be a class."
      • changedInput schema / properties / targetFilter / description
        Previous value: -"Optional: filter results to a specific object name (class, table, form, enum, ...)."New value: +"Single-object form: object name to check. Use objects[] for more than one."
    • Changedsearch4 fields changed
      • changedInput schema / properties / globalTypeFilter / description
        Previous value: -"[batch] Default type filter for queries without an explicit per-query type. E.g. [\"class\"] restricts all untyped queries to classes. Multiple values fan out each untyped query into one search per type."New value: +"[batch] Default type filter for queries without an explicit per-query type. E.g. [\"class\"] restricts all untyped queries to classes. Multiple values fan out each untyped query into one search per type. Values: same as the top-level `type`, except \"all\" (which means \"no filter\" — omit this instead)."
      • removedInput schema / properties / globalTypeFilter / items / enum
        Removed value: -[
        -  "class",
        -  "table",
        -  "form",
        -  "field",
        -  "method",
        -  "enum",
        -  "edt",
        -  "query",
        -  "view",
        -  "report",
        -  "security-privilege",
        -  "security-duty",
        -  "security-role",
        -  "menu-item-display",
        -  "menu-item-action",
        -  "menu-item-output",
        -  "table-extension",
        -  "class-extension",
        -  "form-extension",
        -  "enum-extension",
        -  "edt-extension",
        -  "data-entity-extension"
        -]
      • changedInput schema / properties / queries / items / properties / type / description
        Previous value: -"Filter by object type. Omit to inherit globalTypeFilter or default to \"all\""New value: +"Filter by object type — same values as the top-level `type`. Omit to inherit globalTypeFilter or default to \"all\""
      • removedInput schema / properties / queries / items / properties / type / enum
        Removed value: -[
        -  "class",
        -  "table",
        -  "field",
        -  "method",
        -  "enum",
        -  "edt",
        -  "form",
        -  "query",
        -  "view",
        -  "report",
        -  "security-privilege",
        -  "security-duty",
        -  "security-role",
        -  "menu-item-display",
        -  "menu-item-action",
        -  "menu-item-output",
        -  "table-extension",
        -  "class-extension",
        -  "form-extension",
        -  "enum-extension",
        -  "edt-extension",
        -  "data-entity-extension",
        -  "all"
        -]
    • Removedsuggest_edt
    • Changedupdate_symbol_index1 field changed
      • changedInput schema / properties / filePath / description
        Previous value: -"Absolute path to the modified or created XML file (e.g. K:\\\\AosService\\\\PackagesLocalDirectory\\\\MyModel\\\\MyModel\\\\AxClass\\\\MyClass.xml), or an ARRAY — batch them, each call costs a bridge refresh."New value: +"Absolute path to the changed XML file, or an ARRAY — batch them, each call costs a bridge refresh."
  7. 2 tool updatesv1.8.5
    • Changedget_workspace_info1 field changed
      • changedInput schema / properties / projectName / description
        Previous value: -"Preferred way to switch projects. Just the model name, e.g. \"ContosoEDS\" or \"ContosoBank\". The server resolves the full path from D365FO_SOLUTIONS_PATH automatically. Use this when the user says \"switch to <project>\" or opens a different solution."New value: +"Only when the USER says \"switch to <project>\". Just the model name, e.g. \"ContosoEDS\"; path resolved from D365FO_SOLUTIONS_PATH. NOT a way to reach another model — reads span every model already, writes stay in the workspace model."
    • Changedupdate_symbol_index3 fields changed
      • changedInput schema / properties / filePath / description
        Previous value: -"Absolute path to the modified or created XML file (e.g. K:\\\\AosService\\\\PackagesLocalDirectory\\\\MyModel\\\\MyModel\\\\AxClass\\\\MyClass.xml). Omit to run a lightweight bridge/workspace refresh instead of indexing a specific file."New value: +"Absolute path to the modified or created XML file (e.g. K:\\\\AosService\\\\PackagesLocalDirectory\\\\MyModel\\\\MyModel\\\\AxClass\\\\MyClass.xml), or an ARRAY — batch them, each call costs a bridge refresh."
      • addedInput schema / properties / filePath / items
        Added value: +{
        +  "type": "string"
        +}
      • changedInput schema / properties / filePath / type
        Previous value: -"string"New value: +[
        +  "string",
        +  "array"
        +]
  8. 26 tool updatesv1.8.0
    • First observedanalyze_code
    • First observedbatch_get_info
    • First observedbuild_d365fo_project
    • First observedd365fo_file
    • First observedextension_info
    • First observedfind_references
    • First observedgenerate_object
    • First observedget_knowledge
    • First observedget_method
    • First observedget_object_info
    • First observedget_workspace_info
    • First observedlabels
    • First observedobject_patterns
    • First observedprepare
    • First observedreview_workspace_changes
    • First observedrun_bp_check
    • First observedrun_systest_class
    • First observedsearch
    • First observedsecurity_info
    • First observedsuggest_edt
    • First observedtrigger_db_sync
    • First observedundo_last_modification
    • First observedupdate_symbol_index
    • First observedvalidate_code
    • First observedvalidate_object_naming
    • First observedverify_d365fo_project

TDQS

A4.2/5.0
Disambiguation4/5

Most tools map cleanly to distinct operations (search vs exact-info vs references vs knowledge), and the descriptions explicitly manage the few shared boundaries—e.g. analyze_code vs object_patterns vs prepare, or d365fo_file generate vs generate_object. A couple of analysis/context tools could be confused when choosing how to start, but the mode/scenario guidance makes selection reliable.

Naming Consistency3/5

Thirteen of the twenty tools use clear verb_object names (validate_code, build_d365fo_project, get_object_info), but the set also mixes in bare nouns (labels, object_patterns, security_info, extension_info) and bare verbs (search, prepare), plus the odd d365fo_file. The convention is mostly readable but not consistently applied.

Tool Count4/5

20 tools for a D365FO development MCP is on the heavy side, but the domain is broad and several tools are multi-mode bundles (d365fo_file, get_knowledge, object_patterns, prepare), so the count is defensible. It exceeds the typical 3–15 range, but none of the tools feel truly redundant; it is slightly over-scoped rather than bloated.

Completeness5/5

The surface covers the full object lifecycle—search/info/references, generate/validate, create/modify/delete/undo, build, BP check, and unit tests—plus security, extensibility, labels, naming, and knowledge lookup. There are no glaring dead ends for an agent building and maintaining D365FO code.

Maintenance

ActivityActive
ResponsivenessResponsive

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    An MCP server for Microsoft Dynamics 365 Finance & Operations that enables the creation, modification, and analysis of D365 objects like classes, tables, and forms. It integrates with Visual Studio 2022 to provide tools for X++ code extraction, codebase search, and safe object deletion with dependency validation.
    -
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables 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.
    47
    10
    MIT
  • A
    license
    A
    quality
    A
    maintenance
    Exposes 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.
    49
    38
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables D365 F\&O development including object creation, modification, deletion, and analysis through the MCP standard.
    40
    MIT

Latest Blog Posts

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