Skip to main content
Glama

term_rename

Rename a term or character name across a Word document as one tracked batch, preserving case and optional inflections; dry-run to preview changes.

Instructions

Rename a term or a character's name everywhere (Lucía to Elena) as one tracked batch: whole words by default, case-insensitive with case preserved (LUCÍA becomes ELENA), with optional inflections (["s"] also renames Lucías) and ignore_accents. match_level default/loose folds case, accents and punctuation. Matches inside fields or links are left and counted. Run dry_run first to check counts and the preview, then the same request without it. Use it instead of many text.replace edits. Backed up, undoable; tracked: false writes plainly.

Input Schema

NameRequiredDescriptionDefault
toYesNew term.
docYesPath to the .docx.
tagNoAppended to the author.
fromYesTerm to rename.
authorNoRevision author.
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_runNoPlan and preview only; write nothing.
trackedNofalse: a plain write for a change the writer already approved: the same edits, with this call's own revisions accepted in the same verified write (no revision marks; undo works). Refused (UNSUPPORTED_CONTENT) when a paragraph it rewrites holds another unresolved tracked change.
whole_wordNoWhole words only.
inflectionsNoSuffixes that follow the term: "s" renames Lucías to Elenas; {"from": "o", "to": "a"} renames Lucíao to Elenaa.
match_levelNoFold the search as `text.find` does: `default` ignores case, accents and punctuation (symbols such as `$` still count), `loose` drops symbols too; `exact` is the rename as without it. When passed, Word's Find codes in `from` are read as their characters, each `preview` change and `skipped` row gains `match_level` (the strictest level it meets) and the reply gains `matches_by_level`, adding up to `counts.matches`. No retry at a looser level. Two meanings of exact: without `match_level` the rename is today's, with ^ codes literal and no levels; `match_level: "exact"` keeps that rule but reads the ^ codes and tags each change (`exact` there: character for character). Not with `case_sensitive` or `ignore_accents: false` at a folded level.
preserve_caseNoLUCÍA becomes ELENA, lucía becomes elena, Lucía becomes Elena.
preview_limitNoMost changes echoed back in `preview`.
case_sensitiveNoExact spelling only; `to` is used as written.
ignore_accentsNo`Lucia` also matches `Lucía`.

Output 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"
      +        },
      +        "author": {
      +          "description": "Revision author stamped on the changes.",
      +          "type": "string"
      +        },
      +        "backup": {
      +          "description": "Path of the backup taken before the write.",
      +          "type": [
      +            "string",
      +            "null"
      +          ]
      +        },
      +        "counts": {
      +          "description": "Counts.",
      +          "properties": {
      +            "matches": {
      +              "description": "Matches found.",
      +              "type": "integer"
      +            },
      +            "paragraphs": {
      +              "description": "Paragraphs changed.",
      +              "type": "integer"
      +            },
      +            "replaced": {
      +              "description": "Replaced (or would be).",
      +              "type": "integer"
      +            },
      +            "skipped_boundary": {
      +              "description": "Left alone: would split a character from its marks.",
      +              "type": "integer"
      +            },
      +            "skipped_unsupported": {
      +              "description": "Left alone inside a field, link or other structure.",
      +              "type": "integer"
      +            },
      +            "unchanged": {
      +              "description": "Matches already right.",
      +              "type": "integer"
      +            }
      +          },
      +          "type": "object"
      +        },
      +        "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 name replaced.",
      +          "type": "string"
      +        },
      +        "matches_by_level": {
      +          "description": "With match_level: matches per level.",
      +          "type": "object"
      +        },
      +        "preview": {
      +          "description": "The changes (capped).",
      +          "items": {
      +            "description": "A change.",
      +            "properties": {
      +              "after": {
      +                "description": "Text after (case kept).",
      +                "type": "string"
      +              },
      +              "at": {
      +                "description": "Range address, p<n>#<fp>:<start>-<end> (code points).",
      +                "type": "string"
      +              },
      +              "before": {
      +                "description": "Text before.",
      +                "type": "string"
      +              },
      +              "context": {
      +                "description": "The text around it.",
      +                "type": "string"
      +              },
      +              "match_level": {
      +                "description": "Level it matched at.",
      +                "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"
      +          ]
      +        },
      +        "skipped": {
      +          "description": "Matches left alone (capped).",
      +          "items": {
      +            "description": "A skipped match.",
      +            "properties": {
      +              "at": {
      +                "description": "Range address, p<n>#<fp>:<start>-<end> (code points).",
      +                "type": "string"
      +              },
      +              "match_level": {
      +                "description": "Level it matched at.",
      +                "type": "string"
      +              },
      +              "reason": {
      +                "description": "Why.",
      +                "type": "string"
      +              },
      +              "text": {
      +                "description": "The text.",
      +                "type": "string"
      +              }
      +            },
      +            "type": "object"
      +          },
      +          "type": "array"
      +        },
      +        "to": {
      +          "description": "The new name.",
      +          "type": "string"
      +        },
      +        "tracked": {
      +          "description": "False for a plain (untracked) write.",
      +          "type": "boolean"
      +        }
      +      },
      +      "required": [
      +        "from",
      +        "to",
      +        "dry_run",
      +        "counts",
      +        "skipped",
      +        "preview"
      +      ],
      +      "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. Changed2 schema fields changedv0.1.3
    • changedInput schema / properties / match_level / description
      Previous value: -"Fold the search as `find` does: `default` ignores case, accents and punctuation (symbols such as `$` still count), `loose` drops symbols too; `exact` is the rename as without it. When passed, Word's Find codes in `from` are read as their characters, each `preview` change and `skipped` row gains `match_level` (the strictest level it meets) and the reply gains `matches_by_level`, adding up to `counts.matches`. No retry at a looser level. Two meanings of exact: without `match_level` the rename is today's, with ^ codes literal and no levels; `match_level: \"exact\"` keeps that rule but reads the ^ codes and tags each change (`exact` there: character for character). Not with `case_sensitive` or `ignore_accents: false` at a folded level."New value: +"Fold the search as `text.find` does: `default` ignores case, accents and punctuation (symbols such as `$` still count), `loose` drops symbols too; `exact` is the rename as without it. When passed, Word's Find codes in `from` are read as their characters, each `preview` change and `skipped` row gains `match_level` (the strictest level it meets) and the reply gains `matches_by_level`, adding up to `counts.matches`. No retry at a looser level. Two meanings of exact: without `match_level` the rename is today's, with ^ codes literal and no levels; `match_level: \"exact\"` keeps that rule but reads the ^ codes and tags each change (`exact` there: character for character). Not with `case_sensitive` or `ignore_accents: false` at a folded level."
    • addedInput schema / properties / tracked
      Added value: +{
      +  "default": true,
      +  "description": "false: a plain write for a change the writer already approved: the same edits, with this call's own revisions accepted in the same verified write (no revision marks; undo works). Refused (UNSUPPORTED_CONTENT) when a paragraph it rewrites holds another unresolved tracked change.",
      +  "type": "boolean"
      +}
  3. First observedv0.1.0

TDQS

A4.8/5.0
Behavior5/5

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

Goes well beyond the annotations (destructiveHint=false, readOnlyHint=false): it discloses that the file is backed up and undoable, that matches inside fields/links are left and counted, that a stale file yields DOC_CHANGED_ON_DISK, and that tracked: false is refused with UNSUPPORTED_CONTENT under specific conditions. This is rich mutation-side context the annotations cannot carry.

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-loads the core purpose and example before the modifiers, and every sentence carries operational information. The match_level sentence is long and dense, packing several sub-rules into one run-on, which slightly hurts scanability.

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 15-parameter mutation tool with nested objects and an output schema, the description covers the safety model (backup, undo, tracked revisions), the guard parameter semantics, and the preview/counts return behavior, leaving nothing an agent needs in order to call it correctly.

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 value: an inflection example (["s"] also renames Lucías), the case-preservation rule (LUCÍA becomes ELENA), and the interaction rules for match_level with case_sensitive/ignore_accents. It largely mirrors the schema's own parameter docs rather than exceeding them, keeping it below 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?

States a specific verb and resource ('Rename a term or a character's name everywhere') with a concrete example (Lucía to Elena) and names the operation as one tracked batch. It explicitly distinguishes itself from the sibling text_replace by saying to use it instead of many text.replace edits.

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 an explicit workflow: run dry_run first to check counts and preview, then repeat without it. It also names the alternative (many text.replace edits) and states the condition for tracked: false (a change the writer already approved).

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