Skip to main content
Glama

history_restore

Restore a paragraph deleted or changed by a logged write, reinserting it as a tracked change. Provide the op_id; preview with dry_run, and undo anytime.

Instructions

Bring back paragraphs a logged write deleted or changed, as a tracked insertion (tracked: false: plainly, for a change the writer approved). Give the op_id (from history.list or history.search); without change, every paragraph that op deleted comes back after the paragraph now holding its old place; change picks one (also an edited one) and after (p12#a1b2c3d4) places it when that place was edited (BATCH_CONFLICT otherwise). Use history.undo to revert a whole write instead. Backed up, logged, undoable; dry_run previews.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
docYesPath to the .docx.
tagNoAppended to the author.
afterNoInsert after this paragraph address instead of the old place (needed when that place was edited, or the history comes from `store`).
op_idYesThe logged op the paragraph was changed by.
storeNoA store folder (see history.orphans) to read instead of the document's own.
authorNoRevision author.
changeNoIndex of one change of the op (history.list shows them).
expectNoWrite guard: the sha256 read earlier (doc.info, or a reply's doc.sha256), e.g. {"sha256": "9f86d081…"}; a file changed since is DOC_CHANGED_ON_DISK.
dry_runNoPreview only; write nothing.
trackedNofalse: a plain write for a change the writer already approved: the paragraph comes back without revision marks (this call's own insertion accepted in the same verified write).

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
okYesAlways true on success.
opYesThe operation that ran.
apiYesAPI version (1.0).
docNoThe document read or written: path, sha256 and paragraph count.
nextYesCursor for the next page (pass as cursor), or null.
resultYesWhat the operation returns.
warningsYesThings to know about the result.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed2 schema fields changedv0.7.2
    • addedInput schema / properties / expect / description
      Added value: +"Write guard: the sha256 read earlier (doc.info, or a reply's doc.sha256), e.g. {\"sha256\": \"9f86d081…\"}; a file changed since is DOC_CHANGED_ON_DISK."
    • changedOutput schema / (root)
      Previous value: -nullNew value: +{
      +  "properties": {
      +    "api": {
      +      "description": "API version (1.0).",
      +      "type": "string"
      +    },
      +    "doc": {
      +      "description": "The document read or written: path, sha256 and paragraph count.",
      +      "properties": {
      +        "characters": {
      +          "description": "text.normalize of a text string: its length.",
      +          "type": "integer"
      +        },
      +        "paragraphs": {
      +          "description": "Body paragraphs.",
      +          "type": "integer"
      +        },
      +        "path": {
      +          "description": "Path of the document.",
      +          "type": "string"
      +        },
      +        "sha256": {
      +          "description": "sha256 of the file (pass as expect.sha256 to a write).",
      +          "type": "string"
      +        },
      +        "source": {
      +          "description": "A .txt/.md/.odt source's format, encoding and split mode; \"text\" for a text string (text.normalize).",
      +          "type": [
      +            "object",
      +            "string"
      +          ]
      +        }
      +      },
      +      "type": "object"
      +    },
      +    "next": {
      +      "description": "Cursor for the next page (pass as cursor), or null.",
      +      "type": [
      +        "string",
      +        "null"
      +      ]
      +    },
      +    "ok": {
      +      "description": "Always true on success.",
      +      "type": "boolean"
      +    },
      +    "op": {
      +      "description": "The operation that ran.",
      +      "type": "string"
      +    },
      +    "result": {
      +      "description": "What the operation returns.",
      +      "properties": {
      +        "address_map": {
      +          "description": "Old address -> new address of every paragraph whose address changed.",
      +          "type": "object"
      +        },
      +        "applied": {
      +          "description": "Edits applied (a count), or for style kinds one entry per style op.",
      +          "type": [
      +            "integer",
      +            "array"
      +          ]
      +        },
      +        "author": {
      +          "description": "Revision author stamped on the changes.",
      +          "type": "string"
      +        },
      +        "backup": {
      +          "description": "Path of the backup taken before the write.",
      +          "type": [
      +            "string",
      +            "null"
      +          ]
      +        },
      +        "comment_ids": {
      +          "description": "Ids of the comments added.",
      +          "items": {
      +            "type": "string"
      +          },
      +          "type": "array"
      +        },
      +        "date": {
      +          "description": "Revision date (UTC, ISO 8601).",
      +          "type": "string"
      +        },
      +        "dry_run": {
      +          "description": "True when nothing was written (a preview).",
      +          "type": "boolean"
      +        },
      +        "footprint": {
      +          "description": "Part name -> the paragraphs or items it touched in that part.",
      +          "type": "object"
      +        },
      +        "from": {
      +          "description": "The logged op restored from.",
      +          "type": "string"
      +        },
      +        "op_id": {
      +          "description": "Undo-log id of this write (history.undo / history.restore).",
      +          "type": [
      +            "string",
      +            "null"
      +          ]
      +        },
      +        "preview": {
      +          "description": "One entry per edit: what changes where.",
      +          "items": {
      +            "description": "A previewed edit.",
      +            "properties": {
      +              "action": {
      +                "description": "accept or reject (revision kinds).",
      +                "type": "string"
      +              },
      +              "after": {
      +                "description": "Text after.",
      +                "type": "string"
      +              },
      +              "at": {
      +                "description": "Where it applies.",
      +                "type": "string"
      +              },
      +              "before": {
      +                "description": "Text before.",
      +                "type": "string"
      +              },
      +              "op": {
      +                "description": "Index of the edit in ops.",
      +                "type": "integer"
      +              },
      +              "revisions": {
      +                "description": "Revisions it resolves (revision kinds).",
      +                "type": "integer"
      +              }
      +            },
      +            "type": "object"
      +          },
      +          "type": "array"
      +        },
      +        "restored": {
      +          "description": "The paragraphs brought back.",
      +          "items": {
      +            "description": "A restored paragraph.",
      +            "properties": {
      +              "after": {
      +                "description": "Address it was inserted after.",
      +                "type": "string"
      +              },
      +              "change": {
      +                "description": "Change number in the logged op.",
      +                "type": "integer"
      +              },
      +              "text": {
      +                "description": "Its text (clipped).",
      +                "type": "string"
      +              }
      +            },
      +            "type": "object"
      +          },
      +          "type": "array"
      +        },
      +        "revision_ids": {
      +          "description": "w:id of every revision this write created.",
      +          "items": {
      +            "type": [
      +              "integer",
      +              "string"
      +            ]
      +          },
      +          "type": "array"
      +        },
      +        "sha256": {
      +          "description": "sha256 of the file after the write (pass as expect.sha256 next).",
      +          "type": [
      +            "string",
      +            "null"
      +          ]
      +        },
      +        "tracked": {
      +          "description": "False for a plain (untracked) write.",
      +          "type": "boolean"
      +        },
      +        "warnings": {
      +          "description": "Notes on what the write could not do as asked.",
      +          "items": {
      +            "type": "string"
      +          },
      +          "type": "array"
      +        }
      +      },
      +      "required": [
      +        "applied",
      +        "dry_run",
      +        "restored",
      +        "from"
      +      ],
      +      "type": "object"
      +    },
      +    "warnings": {
      +      "description": "Things to know about the result.",
      +      "items": {
      +        "type": "string"
      +      },
      +      "type": "array"
      +    }
      +  },
      +  "required": [
      +    "api",
      +    "ok",
      +    "op",
      +    "result",
      +    "warnings",
      +    "next"
      +  ],
      +  "type": "object"
      +}
  2. Addedv0.1.3

TDQS

A4.5/5.0
Behavior4/5

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

Annotations (readOnlyHint=false, destructiveHint=false) already establish this is a non-destructive write, and the description is consistent with that. It goes further by disclosing that changes are backed up, logged and undoable, that dry_run previews, and that a specific BATCH_CONFLICT error arises when a placement was edited. Minor gaps remain (no mention of permission requirements or return behavior, though an output schema exists).

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?

Front-loaded with the core operation and then the routing/parameter rules; almost no wasted words. It is a dense single paragraph with stacked parentheticals (e.g. "tracked: false: plainly, for a change the writer approved") that take effort to parse, keeping it just short of a 5.

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 10-parameter mutation tool with full schema coverage and an output schema, the description covers the operational flow, the main alternative, and the key error conditions. Slightly ambiguous phrasing around tracked:false leaves a small interpretive gap, but nothing essential for a correct call is missing.

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 100%, so the baseline is 3, but the description adds real semantics beyond the schema: the consequence of omitting `change`, the role of `after` as an override of the old place, and the meaning of `tracked: false`. This is meaningfully more than the per-parameter schema text alone.

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 and resource with scope: bring back paragraphs a logged write deleted or changed, and specifies the default form (tracked insertion). It also names a sibling it is not (history.undo reverts a whole write instead), so an agent can distinguish it without opening other schemas.

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?

Explicitly says where op_id comes from (history.list or history.search), what happens without `change` (every deleted paragraph returns after the paragraph now holding its old place), what `change` selects, when `after` is required, and the alternative (history.undo). When-to-use and when-to-use-something-else are both covered.

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