Skip to main content
Glama

redo_revert

Revert is non-destructive: this restores the session FORWARD to the pre-revert state (returned by the revert as redo_checkpoint_id), restores the document to that state while still merging any concurrent edits from other sessions (keeping both where they conflict), and un-archives exactly the chat turns the revert hid. Intended for use immediately after a revert; once a new message is sent the timeline diverges and the web app stops offering it.

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": {
      "session_id": "<session_id>",
      "turn_index": "<turn_index>",
      "redo_checkpoint_id": "<redo_checkpoint_id>"
    },
    "name": "redo_revert"
  }
}

Input Schema

NameRequiredDescriptionDefault
session_idYes
turn_indexYesThe turn the revert rewound to (rows at/after this were archived); redo un-archives exactly those.
response_modeNo'full' (default): the whole restored document HTML, as the web editor needs. 'summary' (agents): no HTML; the restored row count and what did not land. Its size does not grow with the document.full
redo_checkpoint_idYesThe identifier of the pre-revert state, returned by the revert response.

Output Schema

NameRequiredDescriptionDefault
dry_runNoEchoes the request's dry_run: when true nothing was committed/archived — this is a preview only.
session_idYesSession identifier.
compose_textYesThe text of the user message that was reverted. Clients should pre-fill the compose box with this so the user can edit and resend.
change_countsNoresponse_mode 'summary' only (absent otherwise): per document (slug), how many sections the revert restores, by operation (edit, create, delete). Summary carries this in place of revert_changes, which is null there.
editor_actionNoClient instruction: 'update' to load the restored document, or 'clear' to reset the editor to empty.update
document_stateNoRestored document state. Null when the session is reset to empty.
revert_changesNoPer-document (slug -> change-set) revert diff. Applying these merges the revert onto any concurrent live edits — a conflicting section is surfaced for you to resolve rather than replacing the whole document. On dry_run this is the preview; on a real revert it is what was committed.
revert_conflictsNoPer-document (slug -> entries) sections whose restore did NOT fully land. TWO classes, told apart by the 'displaced' flag. (1) NOT LANDED ('displaced' absent/false): content another writer committed was preserved instead (reason 'concurrent_edit_preserved' / 'lineage_unknown'), or a removal could not be resolved against the live document; the matching revert_changes entry is annotated 'conflict': true and carries the preserved bytes as new_html (the honest committed state) plus the un-landed restore as restore_html. (2) LANDED IN THE WRONG PLACE ('displaced': true): the content WAS restored but not at its original position — reason 'restored_elsewhere' (it was added at the end of the document because the section it anchors to is gone) or 'position_not_restored' (a concurrent writer's placement won). These carry an empty their_html (nothing of another writer's was preserved, so there is nothing to adopt) plus the raw 'resolution' token, and the matching revert_changes entry is annotated 'displaced': true — never 'conflict', because new_html is still the restored content. (3) NOT SAVED AT ALL ('write_failed': true, operation 'write', chunk_id null): the document's recovery write did not commit — reason 'document_deleted' (archived mid-revert), 'storage_paused' (durable saving paused for this account) or 'write_failed'. Document-level, so there is no matching revert_changes entry; storage still holds the pre-revert content while document_state shows the reverted document, so a client MUST re-read the document before saving again. Null/absent when the revert landed cleanly everywhere.
reverted_to_turnYesTurn index that the active conversation now ends at (the AI reply preceding the reverted user message). -1 when the session is reset to its initial empty state (revert from the very first user message).
redo_checkpoint_idNoThe identifier of the pre-revert state. Revert is non-destructive — passing this back to POST /sessions/{id}/redo (with the same turn_index) restores it and un-archives the rolled-back turns, undoing the revert. Null on a dry-run, and null when the pre-revert state could not be captured — in that case redo_unavailable_reason says which, so absence by design and absence by failure are never the same value.
archived_turn_countYesNumber of chat rows soft-archived by this revert (turns hidden from the UI but retained for audit).
redo_unavailable_reasonNoPresent ONLY when redo_checkpoint_id is null because the pre-revert state could not be captured (never on a dry-run, where null is by design). The revert itself succeeded and is durable; what is unavailable is the one-step undo of it. Treat a non-null value as: do not attempt redo_revert for this revert — it has no argument to pass.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed4 schema fields changed
    • removedInput schema / properties / authorization
      Removed value: -{
      -  "anyOf": [
      -    {
      -      "type": "string"
      -    },
      -    {
      -      "type": "null"
      -    }
      -  ],
      -  "title": "Authorization"
      -}
    • addedInput schema / properties / response_mode
      Added value: +{
      +  "default": "full",
      +  "description": "'full' (default): the whole restored document HTML, as the web editor needs. 'summary' (agents): no HTML; the restored row count and what did not land. Its size does not grow with the document.",
      +  "enum": [
      +    "full",
      +    "summary"
      +  ],
      +  "title": "Response Mode",
      +  "type": "string"
      +}
    • removedInput schema / properties / window_id
      Removed value: -{
      -  "anyOf": [
      -    {
      -      "type": "string"
      -    },
      -    {
      -      "type": "null"
      -    }
      -  ],
      -  "description": "Optional identifier for the client window issuing the request, used to coordinate concurrent reverts from multiple browser tabs.",
      -  "title": "Window Id"
      -}
    • addedOutput schema / properties / change_counts
      Added value: +{
      +  "anyOf": [
      +    {
      +      "additionalProperties": {
      +        "additionalProperties": {
      +          "type": "integer"
      +        },
      +        "type": "object"
      +      },
      +      "type": "object"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "description": "response_mode 'summary' only (absent otherwise): per document (slug), how many sections the revert restores, by operation (edit, create, delete). Summary carries this in place of revert_changes, which is null there.",
      +  "title": "Change Counts"
      +}
  2. First observed

TDQS

A4.4/5.0
Behavior5/5

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

With no annotations, the description carries the full burden and does so: it declares the operation non-destructive, describes concurrency behavior ('still merging any concurrent edits from other sessions, keeping both where they conflict'), and pins the extent of chat un-archiving to exactly what the revert hid. These are material side-effect disclosures an agent would otherwise have to guess.

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?

Two sentences with no filler, and the key safety trait is front-loaded. The first sentence is a long run-on with three stacked clauses, which slightly hurts scanability but not content density.

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 4-param state-mutating tool with an output schema and no annotations, the description covers purpose, timing, concurrency semantics and redo checkpoint provenance. It does not mention auth/permission requirements or error behavior on stale checkpoints, which would round it out.

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 75%, so the baseline is 3; the description adds value by explaining that redo_checkpoint_id is 'returned by the revert' and that turn_index governs which turns get un-archived. session_id is never explained in either description or schema, which caps it at 4.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description gives a concrete verb and scope: 'restores the session FORWARD to the pre-revert state' and un-archives the hidden turns. The opening clause 'Revert is non-destructive: this restores...' briefly muddles the subject (it reads like it is describing revert rather than redo), which keeps it from a clean 5. The tie to 'a revert' still makes it distinguishable from revert_session_to_message.

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 exactly when to use it ('immediately after a revert') and the condition under which it stops being valid ('once a new message is sent the timeline diverges and the web app stops offering it'). That is an explicit when/when-not pair with the alternative (sending a message / diverging timeline) named.

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.