Skip to content

Configuration

The configuration plane: page layouts, and configuration changes. Config actions name the slugs and ids the meta-model brief returns, so pair these with get_schema. Proposed configuration lands in a change request a project administrator reviews and promotes.

get_layout

Scope: read

Read the project's page layouts — how an item type's page and a hub are arranged. With no arguments: every stored layout, summarised (an item type with none renders a derived default: one fields section in display order). With subjectKind + subjectSlug: the layout that page renders — the stored one the selection picks (by context, the caller's roles and the item's state), else the derived default marked derived:true — with its full document, the attributes it leaves unplaced (they render after the layout), and every stored layout for the subject. With layoutId: one stored layout's full document. A layout comes back in the exact shape FORM_LAYOUT_CREATE / FORM_LAYOUT_EDIT take, so edit by changing the document you read and proposing it. Also returns the widget ids a WIDGET section may name.

Input schema
{
  "type": "object",
  "properties": {
    "subjectKind": {
      "type": "string",
      "enum": [
        "ITEM_TYPE",
        "HUB"
      ],
      "description": "ITEM_TYPE for an item type's page, HUB for a hub. Needs subjectSlug."
    },
    "subjectSlug": {
      "type": "string",
      "description": "The item type slug, or the hub key."
    },
    "context": {
      "type": "string",
      "enum": [
        "create",
        "edit",
        "view"
      ],
      "description": "ITEM_TYPE only: the page context to select for. Omit for the fallback."
    },
    "state": {
      "type": "string",
      "description": "ITEM_TYPE only: the lifecycle state slug of the item shown, when layouts differ by state."
    },
    "layoutId": {
      "type": "string",
      "description": "A stored layout's id, from the list."
    }
  },
  "required": []
}

propose_config_actions

Scope: propose

Propose typed CONFIGURATION changes — item types, attributes, attribute assignments, relationship types, categories, lifecycles, role definitions, permission rules, page layouts — as one reviewable batch anchored to an OPEN configuration change request. This changes the project's meta-model, not its content: for items, relationships or documents use propose_item_actions instead. You must pass the id of an open configuration change request — call list_config_change_requests first; if none is open, tell the user a project administrator must open one (you cannot). Nothing is applied by this tool, ever: the batch lands PENDING, a human reviews each proposal with its impact preview in the Changes panel and accepts it (which only stages the change into the change request), and the change request's own promotion remains the gate to live configuration. One call = one reviewable batch, so put everything that belongs together into a single call, in dependency order — a later action may reference a slug an earlier action in the same batch creates. Editing something created earlier in the same change request is fine: the edit folds into the staged create. Returns {batchId, stagedCount, changeRequestId}. The user reviews the proposals in the Changes panel. In the Avera app the review button on this tool call's card opens it — tell the user to review there and do NOT invent a review URL. When the result carries a reviewLink (external clients only), include it in your reply as a markdown link instead. Lifecycle, state and transition ids are slugs the server minted (e.g. "wf-standard:<projectId>:submit"): read them with get_schema scope "lifecycles" before naming one in a LIFECYCLE_EDIT or a state- or transition-scoped PERMISSION_RULE — never guess them, a guessed slug is refused or names nothing. Action types and payloads (slugs are kebab-case — except role ids, which the server mints from the name with underscores; absent optional fields keep their current value on edits): - ITEM_TYPE_CREATE {id, name, prefix, documentType: "NO"|"FILE"|"LIVEDOC", description?, icon?, color?, categoryId?, revisionable?, guestPolicy?: "ALLOWED"|"MARKED"|"REFUSED", folderMembershipTypeId?} - ITEM_TYPE_EDIT {id, name?, prefix?, documentType?, description?, icon?, color?, categoryId?, revisionable?, lifecycleId?, guestPolicy?, folderMembershipTypeId?} folderMembershipTypeId names the relationship type a folder of this type holds its children through (the type is then a folder; a child is the downstream of such a link whose upstream is the folder); an explicit null on an edit makes the type no longer a folder - ITEM_TYPE_RETIRE {id} - ITEM_TYPE_CATEGORY_CREATE / _EDIT {id, name, icon}; ITEM_TYPE_CATEGORY_DELETE {id} - ATTRIBUTE_DEFINITION_CREATE / _EDIT {id, name, label, dataType (e.g. "TEXT"), description?, unique?, validation?, enumValues?, enumNumericValues?, formulaExpression?}; ATTRIBUTE_DEFINITION_RETIRE {id} - ATTRIBUTE_ASSIGNMENT_ADD / _EDIT {itemTypeId, attributeDefinitionId, required?, displayOrder?, defaultValue?, readOnly?, restricted? (editing the field then takes an attribute.edit PERMISSION_RULE naming it)}; ATTRIBUTE_ASSIGNMENT_REMOVE {itemTypeId, attributeDefinitionId} - RELATIONSHIP_TYPE_CREATE / _EDIT {id, name, forwardLabel, reverseLabel, allowedPairs: ["upstreamSlug>downstreamSlug", …], propagateSuspect?, ordered? (the owner's links carry a position), membership? ("TAB" — the default — or "DOCUMENT": the downstream container's document writes the order and the membership; requires ordered and a document-bearing downstream type), description?}; RELATIONSHIP_TYPE_RETIRE {id} - LIFECYCLE_CREATE {name, cloneFromLifecycleId} (a new lifecycle is always cloned from an existing one, permission rules included) - LIFECYCLE_EDIT {kind: "transitionPolicy", transitionId, requiresSignature?, separationOfDuties?, requiredEndorsements?: [{principal: "ROLE:<id>"|"USER:<uuid>"|"ATTRIBUTE:<slug>", signatureRequired?}], distinctUsers?, buttonLabel?, buttonColor?, buttonIcon?, sortOrder?, requiresComment?, commentMinLength?, confirmationRequired?, confirmationMessage?} (obligations and presentation only — who may act is PERMISSION_RULE_*; the current values are in get_schema scope "lifecycles") - LIFECYCLE_EDIT shape kinds — {kind: "stateCreate", lifecycleId, name, lifecycleStatus: "DRAFT"|"REVIEW"|"RELEASED"|"OBSOLETE", type: "INITIAL"|"INTERMEDIATE"|"APPROVAL"|"FINAL"|"TERMINAL", description?, color?, displayOrder?} (the slug is server-minted; a new state is born with no permission cells — add PERMISSION_RULE_* for it; wire it with transitions in the same batch or promotion blocks on reachability); {kind: "stateEdit", stateId, name?, description?, color?, type?, lifecycleStatus?, displayOrder?}; {kind: "stateDelete", stateId} (its cells are staged as deletes; refused while items occupy it at promotion); {kind: "transitionCreate", lifecycleId, name, fromStateId, toStateId, description?} (policy via transitionPolicy afterwards); {kind: "transitionDelete", transitionId}; {kind: "initialState", lifecycleId, stateId} - LIFECYCLE_DELETE {lifecycleId} (refused for the project default and while any item type is bound to it) - ROLE_DEFINITION_CREATE {name, description?}; ROLE_DEFINITION_EDIT {roleId, name?, description?}; ROLE_DEFINITION_DELETE {roleId} (a role is a named principal — what it may do is PERMISSION_RULE_*). The role's id is minted from its name: lowercased, every run of non-alphanumerics an underscore — "Quality Manager" → quality_manager (a taken id gets _2). Existing ids: get_schema scope "roles"; ids staged but not yet promoted: list_config_change_requests. - PERMISSION_RULE_CREATE {principal: "ROLE:<id>"|"USER:<uuid>"|"ATTRIBUTE:<slug>", verb (e.g. "item.edit", "transition.fire", "comment.create"), itemTypes?, states?, fields?, relationshipTypes?, transitionIds?} — one principal, one verb per rule; omitted scope list = unscoped; every scope entry is an exact slug (no wildcards). A ROLE: principal is the role's ID, never its name — a role created earlier in this batch is ROLE:<the id its name mints>, e.g. ROLE:quality_manager - PERMISSION_RULE_EDIT {ruleId, principal, verb, …same scope fields — the full new content}; PERMISSION_RULE_DELETE {ruleId} — read the live rules and their ruleIds with get_schema scope "permission-rules" (filter by principal, verb, itemType, state or transition) - FORM_LAYOUT_CREATE {id (kebab-case), subjectKind: "ITEM_TYPE"|"HUB", subjectSlug (the item type slug, or a hub key: lowercase letters, digits, single hyphens), name, definition, description?, isDefault?, applicability?: {contexts?: ["create"|"edit"|"view"|"embed"|"print"], roles?: [roleId], states?: [stateSlug], priority?}}; FORM_LAYOUT_EDIT {id, name?, description?, isDefault?, applicability?, definition?} (a present definition or applicability replaces it whole; the subject is fixed); FORM_LAYOUT_DELETE {id}. Read first with get_layout — it returns layouts in exactly this shape; to customise a derived layout, propose a CREATE from the document it returns. Selection: among the subject's layouts whose applicability admits the read (an empty list admits all), the one naming the most of contexts/roles/states wins, then higher priority, then isDefault. Two layouts for one subject with the same applicability are refused. A layout may hide or require a field but never grants or locks one — that is PERMISSION_RULE_*. definition = {sections: [section], tabGroups?: [{id, name, order?, icon?}], icon? (HUB only, a Lucide name)}. Every section: {id (unique), type: "FIELDS"|"GRID"|"WIDGET", title?, order?, tabGroupId? (null = inline under the attributes; a HUB's sections must all be in tab groups), collapsible?, collapsedByDefault?}. A tab group with no section is refused. FIELDS (ITEM_TYPE only): {columns?: 1–3, fields: [{slug, order?, label?, columnSpan?: 1–3, helpText?}]} — each attribute placed at most once; an attribute of the type the layout does not place still renders after it. GRID: {grid, readOnly?}. grid = {levels: [{relationshipTypeId, direction: "upstream"|"downstream", itemTypeId?, recursive?, maxDepth?}] (at least one hop; on an item page the first hop starts at the page's item), columns?: [{kind: "attribute", slug, header, width?, flex?} | {kind: "relationship", key, header, relationshipTypeId, direction, itemTypeId?, arity: "one"|"many"} | {kind: "lookup", key, header, path: [level…], slug} (read-only, walked one hop per path element)], addChild?: {itemTypeId, via: {relationshipTypeId, direction}} (a list on an item page), emptyMessage?, autoHeight?}. On a HUB the grid also names exactly one anchor: anchorItemTypeId, or scope {pickItemTypeIds, relationshipTypeId, direction, defaultDepth, maxDepth, allowAll?: {emptyMessage}}. WIDGET: {widgetId (one of get_layout's widgetIds), widgetParams}. enum-matrix {source, rows: attrSlug, views: [{id, label, columns: attrSlug, partition?: {slug, acceptable: [value]}}]} — rows and columns ranked enums; coverage {source, coveredBy: {relationshipTypeId, direction, label}, verifiedBy?: {…same}, verdict?: {slug, acceptable: [value]}}; kpi-cards {cards: [{id, title, icon?, progress?, source, parts?: [{id, label, having: {attribute: {slug, values}} | {link: {relationshipTypeId, direction}} | {suspect: true}}]}]}. source = {type: "items", itemTypeId} | {type: "related", useCurrentItem: true, levels: [{direction: "incoming"|"outgoing", relationshipTypeId, itemTypeId?}]} | {type: "expression", expression} | {type: "members", relationshipTypeId} — the LiveDoc query-source vocabulary; copy a stored layout's widgetParams when unsure. Retiring or deleting something that was CREATED in the same change request is refused — that staged create is removed by reverting its change on the change request page instead. Proposing configuration requires project-administrator rights; the proposal is refused without them.

Input schema
{
  "type": "object",
  "properties": {
    "changeRequestId": {
      "type": "string",
      "description": "Id of an OPEN configuration change request (from list_config_change_requests)."
    },
    "actions": {
      "type": "array",
      "description": "The typed configuration changes to propose as one batch, in dependency order.",
      "items": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "description": "One of: ITEM_TYPE_CREATE, ITEM_TYPE_EDIT, ITEM_TYPE_RETIRE, ITEM_TYPE_CATEGORY_CREATE, ITEM_TYPE_CATEGORY_EDIT, ITEM_TYPE_CATEGORY_DELETE, ATTRIBUTE_DEFINITION_CREATE, ATTRIBUTE_DEFINITION_EDIT, ATTRIBUTE_DEFINITION_RETIRE, ATTRIBUTE_ASSIGNMENT_ADD, ATTRIBUTE_ASSIGNMENT_EDIT, ATTRIBUTE_ASSIGNMENT_REMOVE, RELATIONSHIP_TYPE_CREATE, RELATIONSHIP_TYPE_EDIT, RELATIONSHIP_TYPE_RETIRE, LIFECYCLE_CREATE, LIFECYCLE_EDIT, LIFECYCLE_DELETE, ROLE_DEFINITION_CREATE, ROLE_DEFINITION_EDIT, ROLE_DEFINITION_DELETE, PERMISSION_RULE_CREATE, PERMISSION_RULE_EDIT, PERMISSION_RULE_DELETE, FORM_LAYOUT_CREATE, FORM_LAYOUT_EDIT, FORM_LAYOUT_DELETE"
          },
          "payload": {
            "type": "object",
            "description": "Fields per the type's payload schema (see tool description)."
          }
        },
        "required": [
          "type",
          "payload"
        ]
      }
    }
  },
  "required": [
    "changeRequestId",
    "actions"
  ]
}

list_config_change_requests

Scope: read

List this project's open CONFIGURATION change requests — the staging containers a configuration proposal (propose_config_actions) must target. These govern the meta-model (item types, attributes, relationship types, categories), lifecycles and role definitions; they are NOT product change requests or ECOs/ECRs (those are items — use the item tools). Returns id, name, owner and staged-change count per open request, plus the ids of what the request has staged for creation (roles, item types, attributes, …) — these are not live until promotion, so get_schema does not list them yet; reference them from here (a staged role as ROLE:<id>), and a count of staged changes per change type. Pass changeRequestId to read that request's staged changes in full — every create, edit and delete with its summary, risk level and breaking flag, optionally narrowed by changeType or targetType, and with each change's before/after state when includeStates is true — and, apart from them, its pendingProposals: configuration proposals awaiting a human's accept, which are not staged until accepted (check them before proposing, so you do not propose a change twice). When the list is empty, configuration cannot be proposed: only a project administrator can open a change request, in Settings → Configuration — say so instead of inventing an id.

Input schema
{
  "type": "object",
  "properties": {
    "changeRequestId": {
      "type": "string",
      "description": "Read this open change request's staged changes in full."
    },
    "changeType": {
      "type": "string",
      "description": "With changeRequestId: keep changes of this type, e.g. MODIFY_ITEM_TYPE or CREATE_PERMISSION_RULE."
    },
    "targetType": {
      "type": "string",
      "description": "With changeRequestId: keep changes to this kind of element, e.g. ItemType, AttributeDefinition, Lifecycle."
    },
    "includeStates": {
      "type": "boolean",
      "description": "With changeRequestId: include each change's before and after state. Default false."
    },
    "limit": {
      "type": "integer",
      "description": "With changeRequestId: at most this many changes. Default 100, max 500."
    }
  },
  "required": []
}