Skip to main content
Glama

Edit or roll back collaborative Markdown document

chat_save_doc
Idempotent

WRITE OR ROLL BACK THE SHARED SCRATCHPAD. Replaces the Markdown document (<=50,000 chars) OR restores a previous revision via 'rollback_to_version' / 'rollback_to_ts' as a new non-destructive edit action, computes GitHub-style '+' (additions) and '-' (deletions) line diffs, stores the full snapshot in 'history', and broadcasts 'md_update' to every participant. OPTIMISTIC CONCURRENCY: pass 'base_updated_at' from your latest chat_get_doc (or 0 for a brand-new room). If the document changed since, the server rejects the write with 'conflict: true' and returns 'current_content' and 'current_updated_at'. On conflict: re-read, MERGE your change into 'current_content', and retry. ROLLBACK MODE: pass 'rollback_to_version' (e.g. 1, 2) or 'rollback_to_ts' instead of 'content' to restore that revision's Markdown as a new version without losing any history. EXPORT MODE: pass 'export_fourwords_link: true' to also publish a 24h 4-word .md download link (documento-colaborativo.md) and attach its URL to the revision entry in history. USE WHEN: recording specs, checklists, decisions, initial room documentation requested by the user, or rolling back to a prior Markdown version.

Tool call template

Replace each placeholder with a value matching the input schema. Only required parameters are included; add optional parameters as needed.

{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "arguments": {
      "url": "<url>"
    },
    "name": "chat_save_doc"
  }
}

Input Schema

NameRequiredDescriptionDefault
urlYesFull chat room URL (https://host/chat/<sha512>, 4-word room URL https://host/w1-w2-w3-w4-123456789, or 4-word combo).
nickNoOptional: author nickname (if omitted, uses IP-bound or LLM nickname).
contentNoComplete new Markdown document content (up to 50,000 characters). Optional when rollback_to_version or rollback_to_ts is provided.
llm_keyNoOptional: room LLM key (fwllm_<48hex>) shared by the room creator to authenticate as an 🤖 LLM participant (forwarded as x-llm-key).
llm_nameNoOptional: short LLM agent identifier (2-16 lowercase alphanumeric chars, e.g., 'claude', 'gemini', 'cursor') forwarded as x-llm-name.
notify_keyNoOptional NotificationKeyHub MD5 hash to push real-time alerts to all subscribed user devices when this action completes
download_urlNoOptional: public 4-word download URL of the document archive.
rollback_to_tsNoOptional: timestamp (ts) of a history entry to restore as the current Markdown document.
base_updated_atNoOptional (recommended): updated_at returned by your latest chat_get_doc (0 if document was untouched). If it differs from the current timestamp, the write is rejected with conflict=true.
rollback_to_versionNoOptional: version number from history (e.g. 1, 2) to restore as the current Markdown document (creates a new non-destructive edit entry).
export_fourwords_linkNoOptional: if true, automatically publishes this Markdown revision as a 24h 4-word .md file link and attaches its URL to the revision history entry.

Output Schema

NameRequiredDescriptionDefault
okYes
editorNo
contentNo
historyNo
versionNo
conflictNo
additionsNo
deletionsNo
delete_urlNo
updated_atNo
download_urlNo
export_comboNo
rollback_fromNo
current_contentNo
current_updated_atNo

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changed
    • addedInput schema / properties / notify_key
      Added value: +{
      +  "description": "Optional NotificationKeyHub MD5 hash to push real-time alerts to all subscribed user devices when this action completes",
      +  "pattern": "^[a-f0-9]{32}$",
      +  "type": "string"
      +}
  2. Changed14 schema fields changed
    • changedInput schema / properties / base_updated_at / description
      Previous value: -"updated_at returned by your latest chat_get_doc (0 if document was empty). If it differs from the current timestamp, the write is rejected with a conflict."New value: +"Optional (recommended): updated_at returned by your latest chat_get_doc (0 if document was untouched). If it differs from the current timestamp, the write is rejected with conflict=true."
    • changedInput schema / properties / content / description
      Previous value: -"Complete new Markdown document content (up to 50,000 characters)."New value: +"Complete new Markdown document content (up to 50,000 characters). Optional when rollback_to_version or rollback_to_ts is provided."
    • addedInput schema / properties / export_fourwords_link
      Added value: +{
      +  "description": "Optional: if true, automatically publishes this Markdown revision as a 24h 4-word .md file link and attaches its URL to the revision history entry.",
      +  "type": "boolean"
      +}
    • addedInput schema / properties / rollback_to_ts
      Added value: +{
      +  "description": "Optional: timestamp (ts) of a history entry to restore as the current Markdown document.",
      +  "type": "number"
      +}
    • addedInput schema / properties / rollback_to_version
      Added value: +{
      +  "description": "Optional: version number from history (e.g. 1, 2) to restore as the current Markdown document (creates a new non-destructive edit entry).",
      +  "type": "number"
      +}
    • changedInput schema / properties / url / description
      Previous value: -"Full chat room URL (https://host/chat/<sha512>)."New value: +"Full chat room URL (https://host/chat/<sha512>, 4-word room URL https://host/w1-w2-w3-w4-123456789, or 4-word combo)."
    • changedInput schema / required
      Previous value: -[
      -  "url",
      -  "content",
      -  "base_updated_at"
      -]New value: +[
      +  "url"
      +]
    • addedOutput schema / properties / additions
      Added value: +{
      +  "type": "number"
      +}
    • addedOutput schema / properties / delete_url
      Added value: +{
      +  "type": "string"
      +}
    • addedOutput schema / properties / deletions
      Added value: +{
      +  "type": "number"
      +}
    • addedOutput schema / properties / download_url
      Added value: +{
      +  "type": "string"
      +}
    • addedOutput schema / properties / export_combo
      Added value: +{
      +  "type": "string"
      +}
    • addedOutput schema / properties / rollback_from
      Added value: +{
      +  "type": [
      +    "number",
      +    "string"
      +  ]
      +}
    • addedOutput schema / properties / version
      Added value: +{
      +  "type": "number"
      +}
  3. Changed6 schema fields changed
    • addedInput schema / properties / llm_key
      Added value: +{
      +  "description": "Optional: room LLM key (fwllm_<48hex>) shared by the room creator to authenticate as an 🤖 LLM participant (forwarded as x-llm-key).",
      +  "type": "string"
      +}
    • addedInput schema / properties / llm_name
      Added value: +{
      +  "description": "Optional: short LLM agent identifier (2-16 lowercase alphanumeric chars, e.g., 'claude', 'gemini', 'cursor') forwarded as x-llm-name.",
      +  "type": "string"
      +}
    • changedInput schema / properties / nick / description
      Previous value: -"Optional: author nickname (if omitted, uses IP-bound nickname)."New value: +"Optional: author nickname (if omitted, uses IP-bound or LLM nickname)."
    • addedOutput schema / properties / conflict
      Added value: +{
      +  "type": "boolean"
      +}
    • addedOutput schema / properties / current_content
      Added value: +{
      +  "type": "string"
      +}
    • addedOutput schema / properties / current_updated_at
      Added value: +{
      +  "type": "number"
      +}
  4. First observed

TDQS

A4.5/5.0
Behavior5/5

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

Goes well past the annotations: it discloses the 50,000-char limit, that rollback creates a new non-destructive revision rather than erasing history, that diffs are computed, that snapshots are stored in 'history', that 'md_update' is broadcast to all participants, and that export links expire in 24h. The conflict contract (rejection with conflict=true plus current_content/current_updated_at, and the merge-and-retry remedy) is exactly the kind of failure behavior an agent cannot infer from readOnlyHint/destructiveHint.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the core action and keeps related facts in labeled blocks, but the all-caps shouting and repeated rollback explanation (once in the opening sentence, again in ROLLBACK MODE) cost space. Several clauses restate what the parameter descriptions already say verbatim, so the block is denser than it needs to be.

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 an 11-parameter mutation tool with an output schema, the description covers everything an agent needs to call it correctly: the read-before-write prerequisite, the conflict recovery loop, mutually exclusive modes, size limits, and side effects. Return payload details 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 already 100%, so the baseline is 3, but the description adds real usage meaning: base_updated_at should come from the latest chat_get_doc (or 0 for a new room), rollback_to_version/rollback_to_ts substitute for 'content' rather than accompany it, and export_fourwords_link has a side effect (publishing a 24h link attached to the revision entry). The nickname/llm_key/notify_key parameters are left entirely to the schema, which keeps it from a 5.

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?

Opens with a specific verb+resource ("WRITE OR ROLL BACK THE SHARED SCRATCHPAD") and enumerates the three operating modes (replace content, rollback, export). An agent can distinguish this write tool from the read-side sibling chat_get_doc without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The closing "USE WHEN" clause gives concrete triggers (specs, checklists, decisions, initial room documentation, rollbacks) and the optimistic-concurrency paragraph prescribes the read-then-write sequence with chat_get_doc. It stops short of stating when NOT to use it (e.g. small one-off messages that belong in chat_send), so it is strong but not fully exclusionary.

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