Skip to main content
Glama

Embers: Tabletop RPG Toolkit

Update a world page

imagine_update_world_page
Idempotent

PUT updates to one world page by id. Only supplied fields are sent. Caller must have 'edit' on the world page. Imagine REPLACES the content body with whatever you send. To append, fetch the page first with imagine_get_world_page, concatenate, and send the combined body back. REQUIRES baseUpdatedAt: copy updatedAt from a fresh imagine_get_world_page read of this page; a stale or fabricated value is rejected with OUT_OF_SYNC and nothing is written — writing from memory of an earlier read is not possible. Set visibility: 'gm' to make a page GM-only (the world's owner, contributors, and an admin with Admin Mode on only; hidden from and 404 for everyone else), 'masked' to keep it participating in lists/backlinks under maskName with the real identity hidden, or 'public' to reveal it. Hidden pages are stripped from the world menu.

Input Schema

NameRequiredDescriptionDefault
idYesWorld page id.
linkNoURL-safe slug. Lowercase letters, numbers, hyphens, slashes. Choosing a page link needs Premium, VIP, or admin: without it, create ignores the link and derives one from the name, and an update that changes it is refused.
nameNoPage name.
tagsNoTag list. Stored as a comma-separated `keywords` string on the wire.
imageNo
activeNo
aliasesNo
contentNoPage body in markdown. Imagine renders this verbatim. REPLACED wholesale on update.
detailsNo
gmNotesNoGM-only notes attached to the page.
rulesetNo
summaryNoShort page summary; capped at 150 characters by imagine.
maskNameNoWhat everyone who does not edit the world (its owner, a contributor, or an admin with Admin Mode on) sees instead of the page's name while visibility is 'masked'. Empty renders as 'Redacted'.
parentIdNoMongo `_id` of the parent world page (tree structure).
templateNo
eventDateNoOptional in-world event date for chronology-shape pages.
menuLabelNo
menuOrderNo
showInMenuNo
visibilityNoPage visibility. 'gm' pages exist only for the world's owner, its contributors, and an admin with Admin Mode on — every other viewer gets a 404 and the page is absent from lists, search, backlinks, and breadcrumbs. 'masked' pages participate in lists, tags, backlinks, and breadcrumbs but present maskName/maskSummary and an id-based URL to everyone else; the real name, link, content, and aliases stay hidden until the page is flipped to public. Hidden pages are barred from the world menu. Default: 'public'.
maskSummaryNoOptional teaser everyone who does not edit the world sees on the masked page; the real summary and content stay hidden. Max 255 characters.
documentTypeNo
isWorldChildNo
baseUpdatedAtYesREQUIRED proof that you are working from the latest version: copy the `updatedAt` value verbatim from a FRESH read of this exact record (use the matching get tool first). Values from memory, from an earlier conversation, or guessed timestamps are rejected with OUT_OF_SYNC and nothing is written. After a successful update, the response carries the new `updatedAt` — use that for any follow-up write.
outboundLinksNo
relationshipsNo
showBreadcrumbsNo
vaultCharacterIdNoBind this page to a vault character (for character-shape world pages).
playCampaignCharactersNo

Output Schema

NameRequiredDescriptionDefault

No arguments

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed4 schema fields changed
    • changedInput schema / properties / link / description
      Previous value: -"URL-safe slug. Lowercase letters, numbers, hyphens, slashes."New value: +"URL-safe slug. Lowercase letters, numbers, hyphens, slashes. Choosing a page link needs Premium, VIP, or admin: without it, create ignores the link and derives one from the name, and an update that changes it is refused."
    • changedInput schema / properties / maskName / description
      Previous value: -"What non-contributors see instead of the page's name while visibility is 'masked'. Empty renders as 'Redacted'."New value: +"What everyone who does not edit the world (its owner, a contributor, or an admin with Admin Mode on) sees instead of the page's name while visibility is 'masked'. Empty renders as 'Redacted'."
    • changedInput schema / properties / maskSummary / description
      Previous value: -"Optional teaser non-contributors see on the masked page; the real summary and content stay hidden. Max 255 characters."New value: +"Optional teaser everyone who does not edit the world sees on the masked page; the real summary and content stay hidden. Max 255 characters."
    • changedInput schema / properties / visibility / description
      Previous value: -"Page visibility. 'gm' pages exist only for the world's owner and contributors — every other viewer gets a 404 and the page is absent from lists, search, backlinks, and breadcrumbs. 'masked' pages participate in lists, tags, backlinks, and breadcrumbs but present maskName/maskSummary and an id-based URL to non-contributors; the real name, link, content, and aliases stay hidden until the page is flipped to public. Hidden pages are barred from the world menu. Default: 'public'."New value: +"Page visibility. 'gm' pages exist only for the world's owner, its contributors, and an admin with Admin Mode on — every other viewer gets a 404 and the page is absent from lists, search, backlinks, and breadcrumbs. 'masked' pages participate in lists, tags, backlinks, and breadcrumbs but present maskName/maskSummary and an id-based URL to everyone else; the real name, link, content, and aliases stay hidden until the page is flipped to public. Hidden pages are barred from the world menu. Default: 'public'."
  2. Changed32 schema fields changed
    • addedInput schema / $schema
      Added value: +"http://json-schema.org/draft-07/schema#"
    • addedInput schema / additionalProperties
      Added value: +{}
    • addedInput schema / properties / active
      Added value: +{
      +  "type": "boolean"
      +}
    • addedInput schema / properties / aliases
      Added value: +{
      +  "items": {
      +    "type": "string"
      +  },
      +  "type": "array"
      +}
    • addedInput schema / properties / baseUpdatedAt
      Added value: +{
      +  "description": "REQUIRED proof that you are working from the latest version: copy the `updatedAt` value verbatim from a FRESH read of this exact record (use the matching get tool first). Values from memory, from an earlier conversation, or guessed timestamps are rejected with OUT_OF_SYNC and nothing is written. After a successful update, the response carries the new `updatedAt` — use that for any follow-up write.",
      +  "minLength": 1,
      +  "type": "string"
      +}
    • addedInput schema / properties / content
      Added value: +{
      +  "description": "Page body in markdown. Imagine renders this verbatim. REPLACED wholesale on update.",
      +  "type": "string"
      +}
    • addedInput schema / properties / details
      Added value: +{
      +  "items": {
      +    "additionalProperties": {},
      +    "properties": {
      +      "label": {
      +        "type": "string"
      +      },
      +      "value": {
      +        "type": "string"
      +      }
      +    },
      +    "type": "object"
      +  },
      +  "type": "array"
      +}
    • addedInput schema / properties / documentType
      Added value: +{
      +  "enum": [
      +    "generic",
      +    "character",
      +    "location",
      +    "organization",
      +    "event",
      +    "lore",
      +    "religion",
      +    "cosmology"
      +  ],
      +  "type": "string"
      +}
    • addedInput schema / properties / eventDate
      Added value: +{
      +  "additionalProperties": {},
      +  "description": "Optional in-world event date for chronology-shape pages.",
      +  "properties": {
      +    "day": {
      +      "maximum": 9007199254740991,
      +      "minimum": -9007199254740991,
      +      "type": "integer"
      +    },
      +    "eraId": {
      +      "description": "Mongo `_id` reference (24-character hex string).",
      +      "minLength": 1,
      +      "type": "string"
      +    },
      +    "label": {
      +      "type": "string"
      +    },
      +    "monthId": {
      +      "description": "Mongo `_id` reference (24-character hex string).",
      +      "minLength": 1,
      +      "type": "string"
      +    },
      +    "year": {
      +      "maximum": 9007199254740991,
      +      "minimum": -9007199254740991,
      +      "type": "integer"
      +    }
      +  },
      +  "type": "object"
      +}
    • addedInput schema / properties / gmNotes
      Added value: +{
      +  "description": "GM-only notes attached to the page.",
      +  "type": "string"
      +}
    • addedInput schema / properties / id
      Added value: +{
      +  "description": "World page id.",
      +  "minLength": 1,
      +  "type": "string"
      +}
    • addedInput schema / properties / image
      Added value: +{
      +  "type": "string"
      +}
    • addedInput schema / properties / isWorldChild
      Added value: +{
      +  "type": "boolean"
      +}
    • addedInput schema / properties / link
      Added value: +{
      +  "description": "URL-safe slug. Lowercase letters, numbers, hyphens, slashes.",
      +  "type": "string"
      +}
    • addedInput schema / properties / maskName
      Added value: +{
      +  "description": "What non-contributors see instead of the page's name while visibility is 'masked'. Empty renders as 'Redacted'.",
      +  "type": "string"
      +}
    • addedInput schema / properties / maskSummary
      Added value: +{
      +  "description": "Optional teaser non-contributors see on the masked page; the real summary and content stay hidden. Max 255 characters.",
      +  "maxLength": 255,
      +  "type": "string"
      +}
    • addedInput schema / properties / menuLabel
      Added value: +{
      +  "type": "string"
      +}
    • addedInput schema / properties / menuOrder
      Added value: +{
      +  "maximum": 9007199254740991,
      +  "minimum": -9007199254740991,
      +  "type": "integer"
      +}
    • addedInput schema / properties / name
      Added value: +{
      +  "description": "Page name.",
      +  "minLength": 1,
      +  "type": "string"
      +}
    • addedInput schema / properties / outboundLinks
      Added value: +{
      +  "items": {
      +    "description": "Mongo `_id` reference (24-character hex string).",
      +    "minLength": 1,
      +    "type": "string"
      +  },
      +  "type": "array"
      +}
    • addedInput schema / properties / parentId
      Added value: +{
      +  "description": "Mongo `_id` of the parent world page (tree structure).",
      +  "type": "string"
      +}
    • addedInput schema / properties / playCampaignCharacters
      Added value: +{
      +  "items": {
      +    "additionalProperties": {},
      +    "properties": {
      +      "campaignId": {
      +        "type": "string"
      +      },
      +      "playCharacterId": {
      +        "description": "Mongo `_id` reference (24-character hex string).",
      +        "minLength": 1,
      +        "type": "string"
      +      }
      +    },
      +    "type": "object"
      +  },
      +  "type": "array"
      +}
    • addedInput schema / properties / relationships
      Added value: +{
      +  "items": {
      +    "description": "Mongo `_id` reference (24-character hex string).",
      +    "minLength": 1,
      +    "type": "string"
      +  },
      +  "type": "array"
      +}
    • addedInput schema / properties / ruleset
      Added value: +{
      +  "type": "string"
      +}
    • addedInput schema / properties / showBreadcrumbs
      Added value: +{
      +  "type": "boolean"
      +}
    • addedInput schema / properties / showInMenu
      Added value: +{
      +  "type": "boolean"
      +}
    • addedInput schema / properties / summary
      Added value: +{
      +  "description": "Short page summary; capped at 150 characters by imagine.",
      +  "maxLength": 150,
      +  "type": "string"
      +}
    • addedInput schema / properties / tags
      Added value: +{
      +  "description": "Tag list. Stored as a comma-separated `keywords` string on the wire.",
      +  "items": {
      +    "type": "string"
      +  },
      +  "type": "array"
      +}
    • addedInput schema / properties / template
      Added value: +{
      +  "type": "string"
      +}
    • addedInput schema / properties / vaultCharacterId
      Added value: +{
      +  "description": "Bind this page to a vault character (for character-shape world pages).",
      +  "type": "string"
      +}
    • addedInput schema / properties / visibility
      Added value: +{
      +  "description": "Page visibility. 'gm' pages exist only for the world's owner and contributors — every other viewer gets a 404 and the page is absent from lists, search, backlinks, and breadcrumbs. 'masked' pages participate in lists, tags, backlinks, and breadcrumbs but present maskName/maskSummary and an id-based URL to non-contributors; the real name, link, content, and aliases stay hidden until the page is flipped to public. Hidden pages are barred from the world menu. Default: 'public'.",
      +  "enum": [
      +    "public",
      +    "gm",
      +    "masked"
      +  ],
      +  "type": "string"
      +}
    • addedInput schema / required
      Added value: +[
      +  "id",
      +  "baseUpdatedAt"
      +]
  3. First observed

TDQS

A4.8/5.0
Behavior5/5

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

With annotations already declaring readOnlyHint=false, idempotentHint=true, and destructiveHint=false, the description goes well beyond them: it discloses the wholesale content replacement, the OUT_OF_SYNC rejection of stale/memorized tokens with 'nothing is written', the visibility side effects (404s, list/backlink participation, menu stripping), and that follow-up writes must use the updatedAt returned by this call. That is dense, actionable behavioral context for a mutation tool.

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 four paragraphs are front-loaded with the highest-risk facts first (id, replace semantics, permission, sync token) and every sentence is functional. The one cost is redundancy: the baseUpdatedAt and visibility passages restate, nearly verbatim, what the schema's own property descriptions already say, which inflates length without adding new information.

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 29-parameter, nested-object mutation on a permissioned resource with an output schema present, the description covers the workflow (read-then-write), authorization, failure mode with error code, destructive side effect, and visibility semantics. Nothing an agent needs to call this safely is missing, and return values are correctly left to the output 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 only 48% across 29 parameters, so the description is expected to carry weight; it does so for the three riskiest fields (content replacement, baseUpdatedAt freshness/OUT_OF_SYNC, and the three visibility modes), but leaves the majority of parameters (image, active, aliases, ruleset, template, menu ordering, etc.) to the schema alone. Strong on the fields that cause damage, silent on the rest.

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+resource+scope: 'PUT updates to one world page by id', and immediately clarifies partial-update semantics ('Only supplied fields are sent'). This cleanly separates it from imagine_create_world_page, imagine_get_world_page, and imagine_update_adventure_page without the agent needing to open a 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?

It states the permission prerequisite ('edit' on the world page), the mandatory baseUpdatedAt precondition, and gives an explicit alternative path when a different intent is present ('To append, fetch the page first with imagine_get_world_page, concatenate, and send the combined body back'). The replace-vs-append distinction is exactly the when/when-not guidance an agent needs before writing.

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