Skip to main content
Glama

generate_object

Generates X++/AOT code for Dynamics 365 F&O by mode: pattern skeletons, whole-object scaffolds, find methods, relation queries, field XML, or table-relation XML.

Instructions

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.

Input Schema

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

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed4 schema fields changedv1.16.2
    • 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"
      +]
  2. Changed36 schema fields changedv1.9.0
    • 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"
      -}
  3. First observedv1.8.0

TDQS

A4.8/5.0
Behavior4/5

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

The description adds meaningful behavior beyond annotations: pattern mode is explicitly 'text only, no write', other modes are labeled as producing text or XML, and dependencies between calls are spelled out. The destructiveHint=false annotation already covers the safety profile; the only minor gap is that non-pattern modes are not all explicitly confirmed as output-only with no 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 long because the tool genuinely has six modes, but it is tightly structured with a lead sentence, scannable bullets, and clear routing instructions. Every sentence carries operational value; there is 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 complex multi-mode tool with no output schema, the description covers all mode categories, output forms, required inputs, workflow prerequisites, and a pointer to get_knowledge(op-spec) for exact contracts. That is sufficient for an agent to select, call, and verify the tool correctly in context.

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 schema coverage is already 83%, the description adds substantial semantics: it explains how `name` is interpreted differently per mode, how `params` must be passed as one nested object, what kinds of keys it may contain, and that a missing required parameter triggers the return of the complete spec. It also clarifies pattern-specific enum values like 'ssrs-report-full' and the 'report-*' recipes.

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 then enumerates six concrete modes, each with a distinct output type such as skeleton, XML, or method text. It also distinguishes itself from d365fo_file by pointing out that generating XML for an existing object belongs there, so an agent can clearly tell this tool apart from siblings.

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 explicit when-to-use and when-not-to-use guidance: for the pattern mode it prescribes the exact workflow 'analyze_code → generate_object → d365fo_file(create)', and for existing object XML it directs to d365fo_file(action='generate'). It also tells the agent to fetch missing mode contracts via get_knowledge instead of guessing.

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