create_metadata
September 25, 2026 · View on GitHub
Add a new metadata object or member to a configuration. Parameters and examples: get_tool_guide('create_metadata').
Parameters
| Parameter | Required | Type | Description |
|---|---|---|---|
| projectName | yes | string | EDT project name (required). |
| fqn | yes | string | Full-name FQN of the node to create (required). Top object: 'Type.Name' (e.g. 'Catalog.Products'). Member: 'Type.Name.Kind.Name' (e.g. 'Catalog.Products.Attribute.Weight'). Nested subsystem: 'Subsystem. |
| properties | — | array | Optional properties to apply at creation, as [{name, value, language?}]. For most kinds this applies 'synonym' (with optional 'language' code) and 'comment'; other property names are rejected (set them via modify_metadata). A FORM CONTENT member ('...Form. |
| expectedNotExists | — | boolean | Optional stale-intent guard (default false): assert the node does not yet exist for a sharper precondition error. A real duplicate is always rejected anyway. |
| normalizeYo | — | boolean | Normalize the Russian letter 'ё'->'е' / 'Ё'->'Е' in the new node's NAME (the trailing FQN segment) and in any synonym / comment / predefined-item description value (default true). 'ё' in a Name is flagged by the 1C standard mdo-ru-name-unallowed-letter, so normalizing on input stores a compliant name. Set false to keep 'ё' exactly as supplied. |
| setAsDefault | — | boolean | Form OBJECT create only (FQN 'Type.Object.Form.FormName'). When true, registers the new form as the owner's default object form (default: false). Ignored for other create kinds. |
| generateContent | — | boolean | Form OBJECT create only (FQN 'Type.Object.Form.FormName'), and only for an OBJECT-form owner: Catalog / Document / ChartOfCharacteristicTypes / ChartOfAccounts / ChartOfCalculationTypes / ExchangePlan / BusinessProcess / Task / Report / DataProcessor. When true, seeds the new form with the main Object attribute (type ' |
| objectFields | — | array | Form OBJECT create only, and only with generateContent=true: the owner attribute names to render as bound input fields (dataPath 'Object. |
| callType | — | string (one of: Before, After, Instead) | Form event handler ONLY (item-level '...Form.F. |
| commonModuleKind | — | string (one of: Server, ServerCall, ClientManaged, ClientOrdinary, ClientServer, Global) | CommonModule top-object only. Selects a standards-compliant flag combination the common-module-type validator accepts (no warning), instead of a bare module: 'Server', 'ServerCall', 'ClientManaged', 'ClientOrdinary', 'ClientServer', 'Global'. Defaults to 'Server'. Ignored for other types. Combine with 'serverCall' / 'privileged' / 'returnValuesReuse'. These are create-time-only (the flag set cannot be re-derived post-hoc). |
| serverCall | — | boolean | CommonModule top-object only. When true, the server module is callable from the client (server call). Valid only with a server kind and incompatible with 'Global'. Ignored for other types. |
| privileged | — | boolean | CommonModule top-object only. When true, the module runs with full (privileged) access. Valid only with the 'Server' kind (not a server call). Ignored for other types. |
| returnValuesReuse | — | string (one of: DontUse, DuringRequest, DuringSession) | CommonModule top-object only. Reuse of return values: 'DontUse' (default), 'DuringRequest' or 'DuringSession'. 'DuringSession' yields a cached module accepted by the common-module-type validator. Ignored for other types. |
| targetNamespace | — | string | XDTOPackage top-object only. URI namespace for the new package; a non-empty namespace is required for the package to be valid. Defaults to 'http://example.org/ |
Guide
Creates one metadata node addressed by a 1C full-name FQN, then force-exports the affected top object to its .mdo on disk so the change survives a refresh / clean_project / EDT restart. Replaces the former create_metadata_object (top-level) and add_metadata_attribute (member) tools.
Addressing (the FQN tells the tool what to create)
- Top object:
Type.Name, e.g.Catalog.Products. - Member:
Type.Name.Kind.Name, e.g.Catalog.Products.Attribute.Weight,InformationRegister.Prices.Dimension.Product,InformationRegister.Prices.Resource.Sum,Catalog.Products.TabularSection.Lines,Enum.Colors.EnumValue.Red. - Nested subsystem:
Subsystem.<Parent>.Subsystem.<Child>, repeated to any depth (Subsystem.Sales.Subsystem.Orders.Subsystem.Backlog) - the same chainlist_subsystems,get_subsystem_contentandmodify_metadataalready address. - The leading TYPE token and the KIND token may be English or Russian; the Name parts are the programmatic Names, never the synonym.
Supported kinds
- Top-level types: any configuration object type (Catalog, Document, Information/Accumulation/Accounting/CalculationRegister, Enum, ChartOfAccounts / ChartOfCharacteristicTypes / ChartOfCalculationTypes, ExchangePlan, BusinessProcess, Task, Subsystem, HTTPService, WebService, Constant, CommonForm, CommonCommand, Report, DataProcessor, CommonModule, ...). A type the EDT factory cannot instantiate is rejected with a clear error.
- Member kinds: Attribute, TabularSection, Dimension, Resource, EnumValue, Command, plus the type-specific children AccountingFlag / ExtDimensionAccountingFlag (ChartOfAccounts), AddressingAttribute (Task) and Column (DocumentJournal) - each on the owner types that declare them.
- Template (
Catalog.X.Template.T) and Recalculation (CalculationRegister.R.Recalculation.Rc) are created with their default content wired (a Recalculation's produced types; a Template defaults to the SpreadsheetDocument type). - Service children: an HTTPService URLTemplate and its Method (
HTTPService.S.URLTemplate.T.Method.M), and a WebService Operation and its Parameter (WebService.S.Operation.O.Parameter.P). - Members of a NESTED object are supported too, e.g. a tabular-section attribute
Catalog.X.TabularSection.T.Attribute.A(the owner is re-navigated by name inside the write transaction). - NESTED SUBSYSTEM (
Subsystem.Parent.Subsystem.Child, any depth; every type token bilingual and independently spellable, e.g.Подсистема.Продажи.Subsystem.Orders). The whole PARENT chain must already exist - a missing parent is refused naming the chain that is missing, never auto-created. Despite the member-shaped address a nested subsystem is a TOP object of its own: EDT stores it inSubsystems/<Parent>/Subsystems/<Child>/<Child>.mdowith aparentSubsystemback-reference, and the parent registers it in its<subsystems>list - so BOTH.mdofiles are force-exported, and theConfiguration.mdo(which lists only top-level subsystems) is untouched. Takes the usualsynonym(withlanguage) andcomment. The result reports the CANONICAL FQN, built from the parent's own stored spelling - so a request typed with Russian tokens or a differently-cased parent comes back asSubsystem.<Parent>.Subsystem.<Child>. - Form OBJECT: a managed form on a metadata object (
Catalog.X.Form.FormName, 4 parts, form token at position 2; the form token may beForm/Forms/Форма/Формы). Creates the MD-form (aBasicFormon the owner'sforms) AND a renderable, empty contentForm(itsForm.form), linked both ways and attached under the canonical FQN so its structure re-resolves. The form gets the render-criticalautoCommandBar+ the standard form defaults, so it opens/renders in the EDT editor. Add structure afterwards with the form-member FQNs below, or pass the top-levelgenerateContentflag to seed the mainObjectattribute (type<Type>Object.<Name>, main + savedData) like the designer's "New form" wizard. WithgenerateContent=truethe optionalobjectFieldsarray also seeds bound input fields for the listed owner attributes (dataPathObject.<name>) - omitted it falls back to the kind defaults (documents:Number,Date; catalogs:Code,Description), an empty array[]seeds the mainObjectattribute only. Optionalsynonym(withlanguage) and the top-levelsetAsDefaultflag (register the form as the owner's default object form). ACommonFormis a top object - create it asCommonForm.Name(2 parts) via the normal top-level path; it gets the same renderable contentForm(itsForm.form), so form members can be added to it straight away. - Form content: a member of a form (
Catalog.X.Form.F.<Kind>.NameorCommonForm.F.<Kind>.Name) where Kind is Attribute, Command, Parameter, Group, Decoration, Field, Button or Table. A form PARAMETER (...Form.F.Parameter.Filter, bilingualПараметр) is created BARE: the platform type carries name / valueType / keyParameter / comment only, so it takes no create-time property at all (atitleorparentis refused rather than dropped) - set its three real properties afterwards with modify_metadata. A COLLECTION attribute (type ValueTable / ValueTree) additionally owns COLUMNS, addressed one level deeper as...Form.F.Attribute.AttrName.Column.ColName(bilingual:Column/Колонка); the owning attribute must already carry its collection type, and each column's own type is set afterwards with modify_metadata, exactly like an attribute's. Optional properties:title(withlanguage);parentto nest under an item; a Field binds to a form attribute viadataPath(e.g. {name:'dataPath', value:'Price'}); a Field can also bind to an object sub-attribute with a dotteddataPathObject.<attr>(e.g. {name:'dataPath', value:'Object.Number'}) whereObjectis the form's main object attribute and<attr>is one of the object's attributes; a Field can also output a dynamic-list column with a dotteddataPathList.<field>(e.g. {name:'dataPath', value:'List.Number'}) whereListis a dynamic-list attribute and<field>is one of its query select fields; a Field can also show a collection attribute's column with a dotteddataPath<Attr>.<Column>(e.g. {name:'dataPath', value:'Rows.Price'}) whereRowsis a ValueTable / ValueTree form attribute andPriceone of its columns (create the column first, otherwise the field is refused by name); a Button binds to a form command viacommand(the target must exist first); a Group takes an optionaltype(UsualGroup/Popup/Pages/Page/CommandBar/ButtonGroup/ColumnGroup; defaults by container, e.g. Popup inside a command bar); a Table binds to a tabular section viadataPathnaming that section (e.g. {name:'dataPath', value:'Object.Goods'} for the form object'sGoodstabular section) and is generated with the full designer defaults — aLineNumbercolumn plus one input column per attribute of the tabular section, the auto command bar, and the search-string / view-status / search-control additions — byte-identical to a designer-created table (the columns are auto-generated; you do not list them); a Table can equally show a collection form attribute by naming it alone (e.g. {name:'dataPath', value:'Rows'} for a ValueTable / ValueTree attribute), and then its columns come from that ATTRIBUTE's own columns and it gets NOLineNumbercolumn - an in-memory collection has no such field. Visual items are created with the full designer defaults: enabled + visible, the field's header/footer/edit-mode and input extInfo flags, and the designer auto-children (extended tooltip; context menu for fields and decorations) named<Item><Suffix>per the configuration script variant. - Button/item parent:
parentnames an existing item ({name:'parent', value:'MainGroup'}); the special valueAutoCommandBarplaces the item in the form's command bar (MyTable.AutoCommandBarfor a table's bar). Buttons inside a command bar / context menu / popup automatically get the CommandBarButton type the platform requires there. Placements the designer forbids are rejected (a button in a table / pages / column group; a decoration in a command bar, context menu or popup/pages/button/column group). - Form event handler:
Catalog.X.Form.F.Handler.EventNamebinds a BSL handler to a form event (the leaf is the event name, e.g. OnOpen); an ITEM-level handler usesCatalog.X.Form.F.Field.Price.Handler.OnChange(the item's events include its kind, e.g. an input field's OnChange, or a Pages group's OnCurrentPageChange atCatalog.X.Form.F.Group.Tabs.Handler.OnCurrentPageChange). The OWNER's kind segment is part of that address, not a hint: naming another kind (...Button.Price...for a FIELD) or misspelling it (...Fielld.Price...) is refused with the kind the same-named item actually has, so a handler can never be bound to the element that merely bears the name. An unknown event is rejected WITH the list of available events (in the configuration language). The BSL procedure name is theprocedureproperty (defaults to the event name). The event name resolves in BOTH script variants regardless of the configuration's language: supply it in English (OnOpen/OnChange) or Russian (ПриОткрытии/ПриИзменении) - the tool matches the platform event by either name (only the "Available events" advisory is listed in the configuration language). In a configuration EXTENSION, passcallType(Before/After/Instead) to intercept the base element's event instead of binding a plain handler - see "Extension event interception" below. - Form command action:
Catalog.X.Form.F.Command.C.Handler.Actionbinds the command's action to a BSL procedure (the designer's "Action" property).proceduredefaults to the COMMAND name here. Typical flow: create the Command, create this Action handler, create a Button bound to the command, then write the BSL procedure with write_module_source.
Predefined items (Catalog / ChartOfCharacteristicTypes / ChartOfCalculationTypes / ChartOfAccounts)
Address a predefined item as Catalog.X.Predefined.ItemName, ChartOfCharacteristicTypes.X.Predefined.ItemName, ChartOfCalculationTypes.X.Predefined.ItemName or ChartOfAccounts.X.Predefined.AccountName (4 parts, Predefined token at position 2; the owner TYPE token may be English or Russian, and the Predefined token itself may be its Russian equivalent too). The predefined content is a plain containment on the owner (not a separate top object) - the tool force-exports only the OWNER's .mdo. Properties (all optional, in properties):
description(string, strict - a JSON string value is required when the property is present; an explicitly EMPTY string is stored as-is) - defaults to the item's Name only when the property is OMITTED. Like a synonym/comment, it is covered by this tool'snormalizeYonormalization. Validated against the owner'sdescriptionLength(0 = unlimited; an over-long description is REJECTED with an actionable error, never silently truncated).code- matched to the owner's code type: on a Catalog withcodeType=Stringgive a JSON string, withcodeType=Numbera JSON number (a mismatched JSON type, e.g. a string for a Number-coded catalog, is rejected); on aChartOfCharacteristicTypesthe code is always a plain string. Validated against the owner'scodeLength(0 = unlimited up to the platform's numeric precision cap; an over-long code is rejected); a numeric code must be a non-negative integer. Omitted -> left UNSET - there is no autonumbering, nothing is invented or padded. Acodeentry MISSING itsvalueis rejected at create (nothing to clear); clearing a code is a modify_metadata operation (pass null or omit the value there). On aChartOfCalculationTypesthe code is matched to the chart'scodeTypeexactly like a Catalog (a JSON number whenNumber, a JSON string whenString); on aChartOfAccountsthe code is a plain string paired with a separateorderstring - see the owner-specific sections below.isFolder(boolean) - marks the new item as a FOLDER that can hold children.parent(string, create-time only) - the NAME of an existing predefined item on the SAME owner to nest the new one under; omitted -> a top-level item. On a Catalog / ChartOfCharacteristicTypes the parent must be a FOLDER (isFolder), and a parent that is not one is rejected with an actionable error; a ChartOfAccounts has no folders - the parent is the ACCOUNT the new one becomes a child of (see its section below). A ChartOfCalculationTypes takes neitherisFoldernorparent. A missing parent is always an actionable error.valueType(aliastype) -ChartOfCharacteristicTypesitems only (rejected for a Catalog item with an actionable error): the item's VALUE TYPE, built from the SAME{types:[{kind, ...}]}payload shape an mdclass attribute'stypeproperty uses (see modify_metadata's type-building notes / get_metadata_details(assignable:true) on any attribute for the shape). Omitted -> left UNSET. A JSONnullat CREATE is rejected (nothing to clear yet) - omit the property instead; use modify_metadata'snullto clear an existing value type later.
A name that already resolves (EXACT, case-insensitive match, recursively over top-level items and the content of every container - a folder, or a ChartOfAccounts parent account) is rejected as a duplicate; uniqueness beyond that is NOT enforced here (EDT's own validation flags a real duplicate on save/build). The item Name and the parent reference are ё->е normalized on create (like every other name, unless normalizeYo: false), so the stored Name is standard-compliant; get_metadata_details / modify_metadata / delete_metadata then resolve it by EITHER the normalized or the original ё spelling (exact-first, then a yo-normalized retry).
Owner-specific properties are OWNER-GATED like valueType: a property that does not apply to the addressed owner is REJECTED with an actionable error (never silently ignored). valueType is ChartOfCharacteristicTypes only; actionPeriodIsBase / base / displaced / leading are ChartOfCalculationTypes only; accountType / offBalance / order / accountingFlags / extDimensionTypes are ChartOfAccounts only. Every referenced sibling item / flag / linked-chart item is resolved to a live in-model object inside the SAME write transaction (by Name, never a proxy or a bare FQN string), and an unresolved name is a hard, actionable error naming the bad value - nothing is invented.
ChartOfCalculationTypes items (calculation types / ПланВидовРасчета)
A calculation-type chart is FLAT: its predefined items have NO folders and NO nesting, so isFolder and parent are REJECTED with an owner-scoped error. Besides description these items accept:
code- matched to the chart'scodeTypeexactly like a Catalog: a JSON number whencodeType=Number(stored via the same non-negative-integer, precision/scale/codeLength-validated path - an over-length / fractional / negative code is REJECTED, never truncated), a JSON string whencodeType=String. Omitted -> unset.actionPeriodIsBase(boolean) - the calc type's "action period is base" flag (ПериодДействияБазовый).base/displaced/leading(arrays of strings) - the calc type's dependency lists (base = Базовые, displaced = Вытесняющие, leading = Ведущие). Each entry is the NAME of another (SIBLING) predefined calc type in the SAME chart; it is resolved to that sibling item and the reference is set. A name that does not resolve to an existing sibling is REJECTED with an actionable error naming the bad value. These are plain REFERENCES, not containment - they never nest.
ChartOfAccounts accounts (chart of accounts / ПланСчетов)
An account chart nests accounts through an account HIERARCHY. There is NO folder flag, so isFolder is REJECTED; nest an account under an existing parent account with the create-time parent property (naming an existing predefined account on the same chart) - any account can hold child accounts. Besides description these accounts accept:
code(string) - the account code, validated against the chart'scodeLength(0 = unlimited; an over-long code is REJECTED, never truncated). Omitted -> unset.order(string) - the account order string (Порядок), validated the same way against the chart's order-length limit (never truncated). Omitted -> unset.accountType- the account type, one ofActive/Passive/ActivePassive(bilingual aliasesАктивный/Пассивный/Активный/Пассивный); matched by EXACT token (not as a substring). An unknown value is REJECTED with the allowed tokens.offBalance(boolean) - the off-balance flag (Забалансовый).accountingFlags(array of strings) - the account's accounting flags, each the NAME of anAccountingFlagdeclared on THIS chart (create the flags first withcreate_metadata fqn:'ChartOfAccounts.X.AccountingFlag.<Name>'). A name that does not resolve to one of the chart's own accounting flags is REJECTED (no flag is invented).extDimensionTypes(array of objects) - the account's ext-dimension (subconto) rows, each{characteristicType, turnover?, extDimensionAccountingFlags?}:characteristicType(required) - the NAME of a predefined item of the chart's LINKEDChartOfCharacteristicTypes; the chart's ext-dimension-types (Виды субконто) property must already point at that characteristic-types chart. Resolved to that item and set as the row's characteristic type; a name that does not resolve is REJECTED.turnover(boolean, optional) - the row's "turnover only" flag (ТолькоОбороты).extDimensionAccountingFlags(array of strings, optional) - each the NAME of anExtDimensionAccountingFlagdeclared on THIS chart; resolved and set. A name that does not resolve is REJECTED.
ChartOfCalculationTypes / ChartOfAccounts predefined items are addressed and created by the same ...Predefined.<Item> grammar as a Catalog item; only the property set above differs.
Parameter details
projectName(required) - EDT project name.fqn(required) - full-name FQN of the node to create.properties(optional) - array of{name, value, language?}applied at creation. For a metadata node this version appliessynonym(with optionallanguageCODE, e.g. 'en'/'ru'; defaults to the configuration default language) andcomment; any other property name is rejected - set those via modify_metadata. For a PREDEFINED item the supported names aredescription/code/isFolder/parent/valueType(ChartOfCharacteristicTypesonly) /actionPeriodIsBase+base/displaced/leading(ChartOfCalculationTypesonly) /accountType+offBalance+order+accountingFlags+extDimensionTypes(ChartOfAccountsonly) instead - each owner-gated (see the predefined-items section above).expectedNotExists(optional, default false) - assert the node does not yet exist, for a sharper precondition error. A real duplicate is rejected regardless.normalizeYo(optional, default true) - normalize the Russian letterё->е/Ё->Еin the NAME (the trailing FQN segment) and in anysynonym/comment/ predefined-itemdescriptionvalue, applied at the parse step before identifier validation.ёin a Name is flagged by the 1C standardmdo-ru-name-unallowed-letter, so this stores a compliant Name; setfalseto keepёexactly as supplied. The result lists the rewritten fields undernormalized.setAsDefault(optional, default false) - FORM OBJECT create only (Type.Object.Form.FormName). When true, registers the new form as the owner's default object form. Works for every object-form owner kind, includingDataProcessor/Report/Task(these exposesetDefaultFormrather thansetDefaultObjectForm; the reflective lookup tries both setter names). Ignored for other create kinds.generateContent(optional, default false) - FORM OBJECT create only (Type.Object.Form.FormName). When true, seeds the new form with the mainObjectattribute (type<Type>Object.<Name>, e.g.DocumentObject.Invoice, withmain+savedData), like the designer's "New form" wizard - so you never need to edit the.formoutside MCP. This also applies to an owner object CREATED IN A CONFIGURATION EXTENSION - the value type is resolved by name through the platform type provider when the owner's produced-types data has not materialized yet (as happens for an extension-own object), so the attribute is typed either way; only if the platform genuinely has no such type is the attribute left untyped, with a logged warning naming the owner. Default is an empty form. Ignored for other create kinds.objectFields(optional, array of strings) - FORM OBJECT create only, and only withgenerateContent=true. The owner attribute names to render as bound input fields (dataPathObject.<name>), like the designer's checked-attribute list. Omitted -> the kind defaults (documents:Number,Date; catalogs:Code,Description; other object kinds: none). An explicit non-empty list -> exactly those names. An empty array[]-> only the mainObjectattribute (no fields). Ignored for other create kinds.callType(optional) - FORM EVENT HANDLER only, in a configuration EXTENSION (Before/After/Instead). Selects extension event interception (see below). Omit for a plain base handler; rejected on a base configuration or a non-handler FQN.
Extension event interception (configuration extensions)
In a configuration EXTENSION you intercept a base form element's event rather than replacing its handler. Address the item handler FQN and pass callType:
Before- the extension procedure runs BEFORE the base handler.After- the extension procedure runs AFTER the base handler (the common case).Instead- the extension procedure runs INSTEAD of the base handler (1C "Вместо"; serialized as theOverridecall type on disk).
This writes a form:EventHandlerExtension (<event>, <name>, <callType>) onto the adopted form item. It COEXISTS with the base element's own handler (that is the whole point) and works even when the base element has no handler of its own. ChangeAndValidate is a METHOD-only call type and is rejected for an event.
Preconditions and flow:
- The form must already be ADOPTED into the extension (
adopt_metadata_object); otherwise the form does not resolve. create_metadatawithfqn='Document.X.Form.F.Field.Date.Handler.OnChange',callType='After',properties:[{name:'procedure', value:'ext_DateOnChangeAfter'}]writes only the.formhandler.- Add the matching BSL procedure to the extension form module with
write_module_source(e.g.&AtClient Procedure ext_DateOnChangeAfter(Item) ... EndProcedure). For METHOD interception (annotations like&After("BaseMethod")) usewrite_module_sourcedirectly - see its guide.
CommonModule presets (top-object CommonModule only; create-time-only)
A bare CommonModule has no flags set, which the platform common-module-type validator flags. Pass commonModuleKind to get a standards-compliant flag combination it accepts:
commonModuleKind:'Server'(default),'ServerCall','ClientManaged','ClientOrdinary','ClientServer','Global'.serverCall(boolean): make a server module callable from the client. Valid only with a server kind; incompatible withGlobal.privileged(boolean): run with full access. Valid only with theServerkind (not a server call).returnValuesReuse:'DontUse'(default),'DuringRequest','DuringSession'.DuringSessionyields a cached module onServer/ServerCall/ClientManaged/ClientOrdinary;DuringRequesthas no validator-accepted combo.
The kind + modifiers map to ONE canonical 8-flag combination; an illegal mix (e.g. serverCall on a client kind, privileged with Global) is rejected up front with an actionable error. These flags cannot be re-derived post-hoc, so they are create-time args (not properties). The success payload echoes the resolved commonModuleKind.
XDTOPackage namespace (top-object XDTOPackage only; create-time-only)
targetNamespace: the package URI namespace. A non-empty namespace is required for the package to be valid; defaults tohttp://example.org/<Name>when omitted. The success payload echoes the writtentargetNamespace.
Edition-gated top types
Bot, WebSocketClient and IntegrationService are created only when the loaded platform version exposes their Configuration collection. On a build that lacks the collection feature the create returns a clear "Could not resolve configuration collection" error rather than crashing (the feature is probed on the live Configuration EClass, never assumed). On the 2026.1 target platform all three resolve and create.
Bilingual (ru/en)
The synonym EMap is keyed by the language CODE (ru/en), never the language name. Objects are resolved by programmatic Name; only the type / kind tokens are dialect-aware.
A language CODE must be one the configuration DECLARES (get_configuration_properties lists them all under languages). An undeclared code is REJECTED with the declared list: the platform has no fallback between locale codes, so a value stored under a code nothing declares is simply never displayed - a blank label whose cause is invisible until someone opens the form. A declared code given in a different case is accepted and stored under the configuration's own spelling. After a localized write the result echoes the language used and localesMissing - the languages the configuration USES that still have no translation. A language is "in use" when the configuration's OWN synonym is filled in for it: a multilingual configuration worked on in a single-language branch declares the others but is not translated into them, and nobody wants to be nagged about those. Writing a value UNDER such a language is legal (it is declared, so it will display) but comes back with localeUnusedInConfiguration: true - ASK the user whether translating into it is really wanted before filling in more: it may be a single-language build, or a language this configuration does not support yet.
External-objects projects
Members of an external data processor / report are created the same way as a configuration
object's - ExternalDataProcessor.<Name>.Attribute.<Attr>, ....Form.<F>, and the
form content under it. Two limits are structural, not gaps in addressing:
- the ROOT object itself cannot be created here (it is created with its project, in EDT or by
importing an .epf/.erf;
create_projectwithprojectKind=externalObjectsmakes the empty project only); - an external data processor / report has no
Commandcollection in the platform model, so....Command.<Name>is refused with the list of kinds the object does accept.
Examples
- Top object:
{projectName: 'P', fqn: 'Catalog.Products'} - With synonym:
{projectName: 'P', fqn: 'Document.Invoice', properties: [{name: 'synonym', value: 'Invoice', language: 'en'}]} - Attribute:
{projectName: 'P', fqn: 'Catalog.Products.Attribute.Weight'} - Register resource:
{projectName: 'P', fqn: 'InformationRegister.Prices.Resource.Sum'} - Extension event interception (After):
{projectName: 'Ext', fqn: 'Document.Order.Form.DocumentForm.Field.Date.Handler.OnChange', callType: 'After', properties: [{name: 'procedure', value: 'ext_DateOnChangeAfter'}]} - Predefined calc type with a base list:
{projectName: 'P', fqn: 'ChartOfCalculationTypes.Accruals.Predefined.Bonus', properties: [{name: 'code', value: 5}, {name: 'base', value: ['Salary']}, {name: 'actionPeriodIsBase', value: true}]} - Predefined account (active, with an accounting flag):
{projectName: 'P', fqn: 'ChartOfAccounts.Main.Predefined.Cash', properties: [{name: 'code', value: '50'}, {name: 'accountType', value: 'Active'}, {name: 'accountingFlags', value: ['Currency']}]} - Predefined account with an ext-dimension row:
{projectName: 'P', fqn: 'ChartOfAccounts.Main.Predefined.Settlements', properties: [{name: 'code', value: '60'}, {name: 'accountType', value: 'ActivePassive'}, {name: 'extDimensionTypes', value: [{characteristicType: 'Counterparties', turnover: false, extDimensionAccountingFlags: ['Sum']}]}]} - Nest a child account under a parent account:
{projectName: 'P', fqn: 'ChartOfAccounts.Main.Predefined.CashInHand', properties: [{name: 'code', value: '50.01'}, {name: 'accountType', value: 'Active'}, {name: 'parent', value: 'Cash'}]} - Nested subsystem:
{projectName: 'P', fqn: 'Subsystem.Sales.Subsystem.Orders', properties: [{name: 'synonym', value: 'Orders', language: 'en'}]}
Result
JSON with action='created', the normalized fqn, kind (the EClass - EventHandlerExtension for an extension event handler), name, persisted, and (when a synonym was written) the echoed synonym + resolved language. An extension event handler also echoes the written callType. After a create run get_project_errors to verify.
Gotchas
- A node whose FQN already resolves is rejected as a duplicate.
- An unknown type / kind token or a malformed FQN (odd trailing token) is rejected with guidance; a recognized top-type the EDT factory cannot instantiate fails with a clear error (no static allow-list).
- Members are created with DEFAULT properties (e.g. a default type); adjust with modify_metadata.
persisted=falsemeans the in-memory change committed but the.mdoexport did not confirm - re-check before relying on it on disk.- No automatic undo: to revert a create, delete the node with delete_metadata (same FQN). create_metadata is intentionally NOT confirm-gated because it is reversible that way; only the destructive / high-blast-radius writes (delete_metadata, rename_metadata_object, update_database, delete_project) are gated with a confirm-preview.
- A NESTED SUBSYSTEM is the one exception to that undo route: delete_metadata does not address a nested-subsystem chain yet, so it cannot remove one. Remove it in the EDT UI (or drop the parent) until delete_metadata learns the chain.
ObjectType members
ObjectType is an XDTO segment only — it addresses a type inside an XDTO package, as
XDTOPackage.<Package>.ObjectType.<Name>. There is no ObjectType child kind on an
mdclass object: an FQN like ChartOfCharacteristicTypes.Properties.ObjectType.Products
falls through to MetadataNodeResolver, whose child-kind map has no such token, and the
call fails with "Cannot resolve a create target".
Nested XDTO member addresses
A nested XDTO property is addressed through the full member chain:
XDTOPackage.<Package>.ObjectType.<Type>.Property.<Name>.
Generated from the live MCP server (get_tool_guide) by docs/generate_tool_docs.py. Do not edit this file. Edit the tool's description/schema in its Java source and its guide body in mcp/bundles/com.ditrix.edt.mcp.server/guides/<tool>.md.