Skip to main content
Glama

Fabrement

Save options page

fabrement-save-options-page

Create or change an options page — site-wide settings such as contacts, social links, a header announcement or the footer, shown in wp-admin under "Site General Settings": its page settings, its fields and its tabs (a section you leave out stays as it is). Read get-options-page first and send its revision as expectedRevision; 0 with a new slug creates the page and needs page.title. "fields" is the complete active list, as in save-fields. Values are filled on the page, or with set-field-values {options: slug}. Everything is checked before writing; an error names the input to fix. Rules: get-skill-doc {id:"options-contract"} — read it before the first call.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
pageNoHow the page shows in wp-admin. {title (required for a new page), menuTitle? (tab label, "" = title), description? (a line above the form), position? (0–1000, lower first among the tabs of Fabrement → Site General Settings; default 100), autoload? (true, the default: its values load with every request — right for what the header, footer or most pages show; false for a big page read on a few screens only)}. A property left out keeps its value.
slugYesThe options page slug, e.g. "site", "header", "footer" (list-options-pages); a-z, 0-9, _ and -, no "__", at most 32.
fieldsNoThe COMPLETE list of active fields, as a whole. A field you leave out is retired (hidden, values kept), never deleted. get-fields lists retired ones with "retired": true: leave them out (they stay retired), or send one without "retired" to restore it. "key" may be left out. A field IS its name: a new name is a new, EMPTY field (there is no rename: to rename what editors see, change the label; a real name change is a migration, see fields-contract RENAMING). Each field, sub-fields included: {name, label (required, non-empty, ≤200: what editors see), description (required, non-empty, ≤2000: the hint editors see under the field), type (text|textarea|wysiwyg|number|true_false|select|icon|date_picker|date_time_picker|image|gallery|file|link|post_object|relationship|group|repeater), translation? (translate|copy|copy_once|ignore; what a language version gets: translate = its own words, seeded from the original and sent to translators (text/textarea/wysiwyg/link only); copy = one value for every language, locked in translations; copy_once = seeded once, then each language has its own (a price, a date or a picked record that differs per language); ignore = never touched. A repeater under copy takes its ROW LIST from the original, each sub-field following its own policy; a group under copy is one set whose sub-fields each follow their own policy (clearing it on the original clears only its copy sub-fields in translations). Omitted: translate for text/textarea/wysiwyg/link, copy for everything else; an existing field keeps its policy. It only matters once the site has several languages), required?, default?, format? (number: integer|decimal), min?/max? (number bounds; repeater/relationship/gallery item counts: max enforced, min only a hint shown in the form), choices? (select: [{value,label}]; icon: [{value: a library icon id from list-icons, e.g. "social/facebook", label}] — the editor picks one or uploads an image instead), postTypes? (post_object/relationship: the post type slugs that may be picked, e.g. ["project"]; omitted = any public type; see list-post-types), sub_fields? (group/repeater)}. name: a-z, digits, single underscores, starts with a letter, not with "fab_", at most 24 characters, no part only digits (step_2 is refused, step2 is fine); unique among siblings; templates read it with fabrement_get_field('name', $id). The type and number format of a name never change (a retired field keeps its name too): add a new field instead. The same top-level name on another post type is the same meta key, so it must have the same type and number format there.
layoutNoForm layout only; never affects stored values. {tabs: [{label, items: [{field: <name or key of an active top-level field>, width?: 1/4|1/3|1/2|2/3|3/4|1, display?: block|row|table (repeater only)}]}]}. Fields not placed are shown after the tabs. Short numbers, dates and switches: 1/2 or 1/3; long text, wysiwyg and repeaters: 1. Omit layout for an automatic grid.
expectedRevisionYesrevision from get-options-page; 0 creates a new page.

Schema Changelog

Changes observed during successful MCP inspections.

  1. First observed

TDQS

A4.5/5.0
Behavior5/5

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

Goes well beyond the annotations: optimistic concurrency via expectedRevision, partial-update semantics ('a property left out keeps its value'), non-destructive omission behavior (fields are retired, never deleted), pre-write validation with errors naming the offending input, and the requirement to complete a contract skill-doc step first. The annotations (readOnlyHint=false, destructiveHint=false, idempotentHint=false) are consistent with this and the description adds substantial operational context.

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?

Purpose is front-loaded in the first sentence, followed by prerequisites, cross-references, and validation behavior in a compact progression. A few clauses duplicate schema content (e.g. 'fields is the complete active list'), but no sentence is fully 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 complex, nested, five-parameter mutation tool with no output schema, the description covers prerequisites, create-vs-update discrimination, validation behavior, and sibling delegation. It does not describe the success return shape, but the annotation and the contract-doc pointer cover most of what an agent needs.

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% and the schema already documents every parameter in depth (page, slug, fields, layout, expectedRevision). The description largely restates schema content and adds only cross-references (save-fields, set-field-values, fields-contract), which is the expected baseline when the schema carries the detail.

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 pair (create or change) and resource (an options page), scoped to site-wide settings shown under 'Site General Settings', with concrete examples (contacts, social links, header announcement, footer). It also enumerates the sub-parts it manages (page settings, fields, tabs), making it easy to distinguish from save-fields, save-content, or set-field-values.

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?

Gives explicit prerequisites and channels: read get-options-page first and pass its revision as expectedRevision; use 0 with a new slug to create (requiring page.title); read the options-contract skill doc before the first call. It also routes value entry to set-field-values {options: slug} and the field list convention to save-fields, so the agent knows when this tool applies versus its neighbors.

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

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources