Skip to main content
Glama

comment_add

Add a comment to a specified range in a Word document, with file or live editing, dry-run preview, and hash guard to prevent overwriting changes.

Instructions

Add one comment on a range: at is a paragraph (p3#a1b2c3d4), part of one (p3#a1b2c3d4:10-15) or a span across paragraphs (p3#a1b2c3d4:10..p5#e5f6a7b8:2); a newline in text starts a new comment paragraph. Author defaults to DOC_CONTROL_AUTHOR. File engine: backed up first, dry_run previews, expect.sha256 refuses a file changed since, logged for history.undo. engine live adds it in the open Word/LibreOffice window (after live.open). Use doc.batch to add several, or with comment.reply/comment.resolve, all or nothing. Returns the new comment id.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
atYesRange to comment on: p3#fp, p3#fp:10-15 or across.
docYesPath to the .docx (live: or the file name of one open in a live app).
tagNoAppended to the author.
textYesComment text; a newline starts a new paragraph.
authorNoRevision author.
engineNo`live` edits the document open in Word or LibreOffice (see live.open).
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.

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 (1).",
      +          "type": "integer"
      +        },
      +        "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"
      +        },
      +        "engine": {
      +          "description": "live: edited in the open app; nothing backed up or verified.",
      +          "type": "string"
      +        },
      +        "footprint": {
      +          "description": "Part name -> the paragraphs or items it touched in that part.",
      +          "type": "object"
      +        },
      +        "op_id": {
      +          "description": "Undo-log id of this write (history.undo / history.restore).",
      +          "type": [
      +            "string",
      +            "null"
      +          ]
      +        },
      +        "op_ids": {
      +          "description": "Live: one log entry per edit, in request order.",
      +          "items": {
      +            "type": "string"
      +          },
      +          "type": "array"
      +        },
      +        "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"
      +        },
      +        "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"
      +      ],
      +      "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.6/5.0
Behavior5/5

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

Annotations only declare the safety profile; the description goes well beyond them by disclosing the backup-first behavior, dry_run preview, expect.sha256 guard with its DOC_CHANGED_ON_DISK failure, history.undo logging, and the live-window side effect. This is exactly the mutation context an agent needs.

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 action and the `at` syntax, then engine/guard behavior. Dense but every clause carries information; only the long example list for `at` borders on over-length.

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 8-param mutation tool with nested expect, dual engines and an output schema, the description covers invocation formats, guards, side effects and the return value. An agent has everything needed 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 already 100%, so baseline is 3, but the description adds real format semantics: the three `at` forms with concrete examples, the newline-starts-a-new-paragraph rule for `text`, and the DOC_CONTROL_AUTHOR author default — none of which the terse schema descriptions spell out.

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?

Specific verb+resource ('Add one comment on a range') with the target scoping made explicit, and it is clearly distinguishable from comment_list, comment_reply and comment.resolve. The 'one comment' vs doc.batch split is stated outright.

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?

Names alternatives and the conditions that select them: doc.batch for several comments, comment.reply/comment.resolve for bundled all-or-nothing work, and live.open required before engine live. No explicit 'when not to use', but the routing guidance is concrete.

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