Skip to main content
Glama

Update document

update

Replace a document's whole body or a specific line range while preserving its id, type, status, created and version fields. Validates the result before writing to disk.

Instructions

Whole-body or line-range replace of an existing document's content across the whole-body domains (type is one of req, uc, tsk, qa, prb, gol, rsk, dec, sop, feat, vcr, sysrs, txt), preserving its id/type/status/created/version; only updated changes. With no offset/limit, content is the full replacement body (body markdown only, no frontmatter block). With offset, content replaces the body line(s) starting at 1-based line offset of the current on-disk body: limit is the number of lines to replace (offset..offset+limit-1; limit omitted = through the last body line, limit=0 = pure insert), and offset=N+1 (one past the last body line) appends after it; the spliced result is validated as a whole document before anything is written. offset/limit address the frontmatter-stripped body, never the raw on-disk .md file: the YAML frontmatter block is variable-length, so a raw file read's line numbers are never the same as body-line coordinates -- the only safe source of coordinates is a get_<d>(id, raw=True) read, never a raw file read minus an assumed constant. A get_<d>(raw=True, numbered=True) read's numbered output must never be fed back verbatim into content -- strip the "<n>: " prefix from each line first (it is likewise never a valid edit old_str). status is never settable -- use the generic set_status tool. A document that exists but fails to parse returns a ParseFailureResult (error/path/id) instead of raising the domain's not-found error -- its error text is byte-identical to the domain's list_<d> failed row's error for the same file (identical field path and cause, including the trailing pydantic documentation line; ADR 9080b37c-82b3-4f63-81f1-79641d0bf14c) -- and a truly-absent id still raises the domain's not-found error. A content-validation failure on the submitted new content (or, in range mode, on the spliced result) returns a non-raising ValidateResult (valid=False, errors=[{message}]) with the message capped at 300 chars as the generic validate tool caps it, instead of raising AssertionError/pydantic.ValidationError (ADR b8c9bfea-6dcf-4158-bfc5-4ec17abb842f, GitHub issue #170 -- case 4 of the ADR 519d1206 non-raising-structured-result workaround chain). An invalid id (path-injection attempt or wrong format for type) or misused range coordinates (limit without offset) is a ValueError raised before any file access. Each domain's structure reference is its own get_<d>_schema tool (the generated JSON Schema), with get_<d>_template/get_<d>_example as the authoring starting points. Returns an UpdateResult: frontmatter, the updated frontmatter (no body) of the dispatched domain, plus snippet -- in range mode, the before/after window of the touched range (dropped lines numbered pre-splice, inserted lines numbered post-splice, up to 2 unchanged context lines per side, each line <marker> <n>: <line text>); snippet is None in whole-body mode and for the whole-body-equivalent range (offset=1 with limit omitted). Use the corresponding get_<d> tool to fetch the full document afterward. The optional language parameter (default 'en', feat-197-i18n) selects the language variant to act on: omitted/'en' = the flat default-language document, exactly the default behavior; a non-default ISO 639-1-shaped lowercase two-letter code (e.g. 'de') = that language's variant at docs//{language}/ (found by id-scan of that subdirectory), acting on that file ONLY -- the EN file's content and updated timestamp stay untouched -- with the submitted content validated through that language's heading-mapping table (translated headings are accepted). Every whole-body type except feat supports a non-default language; for feat (always English) a non-default language raises a ValueError, as does a malformed language or one with no packaged heading-mapping table -- all raised before any file access.

Input Schema

NameRequiredDescriptionDefault
idYes
typeYes
limitNo
offsetNo
contentYes
languageNoen

Output Schema

NameRequiredDescriptionDefault
resultYes

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed4 schema fields changedv0.38.0
    • addedInput schema / properties / language
      Added value: +{
      +  "default": "en",
      +  "title": "Language",
      +  "type": "string"
      +}
    • changedInput schema / properties / type / enum
      Previous value: -[
      -  "req",
      -  "uc",
      -  "tsk",
      -  "qa",
      -  "prb",
      -  "gol",
      -  "rsk",
      -  "dec",
      -  "sop",
      -  "feat",
      -  "vcr",
      -  "sysrs"
      -]New value: +[
      +  "req",
      +  "uc",
      +  "tsk",
      +  "qa",
      +  "prb",
      +  "gol",
      +  "rsk",
      +  "dec",
      +  "sop",
      +  "feat",
      +  "vcr",
      +  "sysrs",
      +  "txt"
      +]
    • addedOutput schema / $defs / TxtFrontmatter
      Added value: +{
      +  "description": "Free-Form Text (TXT) frontmatter: `MarkdownFrontmatter` narrowed for the ``txt`` document type.\n\nParameters\n----------\ntype:\n    Fixed discriminator, always ``\"txt\"``. Narrows the base's mandatory,\n    default-less ``str`` field to a ``Literal[\"txt\"] = \"txt\"``, so a document\n    omitting ``type`` entirely still parses as a free-form text document.\nstatus:\n    One of ``\"draft\"``, ``\"progress\"``, ``\"done\"``. Narrows the base's\n    free-form ``str = \"draft\"`` default to this closed three-value set.\n    Blank/absent still defaults to ``\"draft\"`` (inherited from the base's\n    ``_default_blank_status_to_draft`` validator, which runs before this\n    one).\nversion:\n    The ``models.md`` schema major.minor.patch version this document's\n    frontmatter was written with. DO NOT CHANGE!\n\nAll other fields (``id``, ``created``, ``updated``, ``version``,\n``classification``) are inherited unchanged from\n:class:`MarkdownFrontmatter`.",
      +  "properties": {
      +    "classification": {
      +      "anyOf": [
      +        {
      +          "type": "string"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ],
      +      "default": null,
      +      "title": "Classification"
      +    },
      +    "created": {
      +      "anyOf": [
      +        {
      +          "type": "string"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ],
      +      "default": null,
      +      "pattern": "^\\d{4}-\\d{2}-\\d{2}[T ]\\d{2}:\\d{2}:\\d{2}\\.\\d{3}(?:Z|[+-]\\d{2}:\\d{2})$",
      +      "title": "Created"
      +    },
      +    "id": {
      +      "anyOf": [
      +        {
      +          "type": "string"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ],
      +      "default": null,
      +      "title": "Id"
      +    },
      +    "status": {
      +      "default": "draft",
      +      "enum": [
      +        "done",
      +        "draft",
      +        "progress"
      +      ],
      +      "title": "Status",
      +      "type": "string"
      +    },
      +    "type": {
      +      "const": "txt",
      +      "default": "txt",
      +      "title": "Type",
      +      "type": "string"
      +    },
      +    "updated": {
      +      "anyOf": [
      +        {
      +          "type": "string"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ],
      +      "default": null,
      +      "pattern": "^\\d{4}-\\d{2}-\\d{2}[T ]\\d{2}:\\d{2}:\\d{2}\\.\\d{3}(?:Z|[+-]\\d{2}:\\d{2})$",
      +      "title": "Updated"
      +    },
      +    "version": {
      +      "default": "1.0.0",
      +      "title": "Version",
      +      "type": "string"
      +    }
      +  },
      +  "title": "TxtFrontmatter",
      +  "type": "object"
      +}
    • changedOutput schema / $defs / UpdateResult / properties / frontmatter / anyOf
      Previous value: -[
      -  {
      -    "$ref": "#/$defs/ReqFrontmatter"
      -  },
      -  {
      -    "$ref": "#/$defs/UcFrontmatter"
      -  },
      -  {
      -    "$ref": "#/$defs/TskFrontmatter"
      -  },
      -  {
      -    "$ref": "#/$defs/QaFrontmatter"
      -  },
      -  {
      -    "$ref": "#/$defs/PrbFrontmatter"
      -  },
      -  {
      -    "$ref": "#/$defs/GolFrontmatter"
      -  },
      -  {
      -    "$ref": "#/$defs/RskFrontmatter"
      -  },
      -  {
      -    "$ref": "#/$defs/DecFrontmatter"
      -  },
      -  {
      -    "$ref": "#/$defs/FeatFrontmatter"
      -  },
      -  {
      -    "$ref": "#/$defs/SopFrontmatter"
      -  },
      -  {
      -    "$ref": "#/$defs/VcrFrontmatter"
      -  },
      -  {
      -    "$ref": "#/$defs/SysrsFrontmatter"
      -  }
      -]New value: +[
      +  {
      +    "$ref": "#/$defs/ReqFrontmatter"
      +  },
      +  {
      +    "$ref": "#/$defs/UcFrontmatter"
      +  },
      +  {
      +    "$ref": "#/$defs/TskFrontmatter"
      +  },
      +  {
      +    "$ref": "#/$defs/QaFrontmatter"
      +  },
      +  {
      +    "$ref": "#/$defs/PrbFrontmatter"
      +  },
      +  {
      +    "$ref": "#/$defs/GolFrontmatter"
      +  },
      +  {
      +    "$ref": "#/$defs/RskFrontmatter"
      +  },
      +  {
      +    "$ref": "#/$defs/DecFrontmatter"
      +  },
      +  {
      +    "$ref": "#/$defs/FeatFrontmatter"
      +  },
      +  {
      +    "$ref": "#/$defs/SopFrontmatter"
      +  },
      +  {
      +    "$ref": "#/$defs/VcrFrontmatter"
      +  },
      +  {
      +    "$ref": "#/$defs/SysrsFrontmatter"
      +  },
      +  {
      +    "$ref": "#/$defs/TxtFrontmatter"
      +  }
      +]
  2. Changed12 schema fields changedv0.37.0
    • addedOutput schema / $defs / DecFrontmatter / properties / status / enum
      Added value: +[
      +  "accepted",
      +  "deprecated",
      +  "draft",
      +  "proposed",
      +  "rejected",
      +  "superseded"
      +]
    • addedOutput schema / $defs / FeatFrontmatter / properties / status / enum
      Added value: +[
      +  "done",
      +  "planning",
      +  "progress",
      +  "review"
      +]
    • addedOutput schema / $defs / GolFrontmatter / properties / status / enum
      Added value: +[
      +  "accepted",
      +  "deprecated",
      +  "draft",
      +  "implemented",
      +  "proposed",
      +  "rejected",
      +  "superseded"
      +]
    • addedOutput schema / $defs / PrbFrontmatter / properties / status / enum
      Added value: +[
      +  "active",
      +  "cancelled",
      +  "draft",
      +  "resolved"
      +]
    • addedOutput schema / $defs / QaFrontmatter / properties / status / enum
      Added value: +[
      +  "active",
      +  "cancelled",
      +  "done",
      +  "draft"
      +]
    • addedOutput schema / $defs / ReqFrontmatter / properties / status / enum
      Added value: +[
      +  "accepted",
      +  "deprecated",
      +  "draft",
      +  "implemented",
      +  "proposed",
      +  "rejected",
      +  "superseded"
      +]
    • addedOutput schema / $defs / RskFrontmatter / properties / status / enum
      Added value: +[
      +  "accepted",
      +  "closed",
      +  "dropped",
      +  "mitigating",
      +  "occurred",
      +  "open"
      +]
    • addedOutput schema / $defs / SopFrontmatter / properties / status / enum
      Added value: +[
      +  "active",
      +  "approved",
      +  "draft",
      +  "retired",
      +  "review"
      +]
    • addedOutput schema / $defs / SysrsFrontmatter / properties / status / enum
      Added value: +[
      +  "active",
      +  "approved",
      +  "draft",
      +  "retired",
      +  "review"
      +]
    • addedOutput schema / $defs / TskFrontmatter / properties / status / enum
      Added value: +[
      +  "active",
      +  "cancelled",
      +  "done",
      +  "draft"
      +]
    • addedOutput schema / $defs / UcFrontmatter / properties / status / enum
      Added value: +[
      +  "accepted",
      +  "deprecated",
      +  "draft",
      +  "proposed",
      +  "superseded"
      +]
    • addedOutput schema / $defs / VcrFrontmatter / properties / status / enum
      Added value: +[
      +  "approved",
      +  "complete",
      +  "draft",
      +  "progress"
      +]
  3. First observedv0.36.0

TDQS

A4.1/5.0
Behavior5/5

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

With no annotations supplied, the description carries the full burden and does so unusually well: it states what is preserved (id/type/status/created/version) and what changes (`updated`), that the spliced result is validated as a whole document before any write, and that id/coordinate misuse raises before any file access. It enumerates non-raising outcomes precisely — `ParseFailureResult` for unparseable existing documents versus the domain not-found error for absent ids, and `ValidateResult(valid=False)` with a 300-char-capped message for content failures. It even explains the frontmatter-stripped coordinate space and the numbered-output stripping hazard, which is exactly the kind of trap an agent would otherwise fall into.

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?

The essential mode/coordinate information is front-loaded in the first two sentences, which is the right structure. But the single unbroken paragraph is bloated with provenance that does nothing for tool selection or invocation — ADR hex ids, 'GitHub issue #170', 'case 4 of the ADR 519d1206 non-raising-structured-result workaround chain' — and it re-narrates the `UpdateResult` shape that the output schema already provides. Trimming those would roughly halve the length without losing decision-relevant content.

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 6-parameter mutation tool with 0% schema description coverage, the description covers the things that actually determine a correct call: coordinate space, mode selection, language routing, validation-before-write, and the three distinct failure channels. It does redundantly re-specify the return payload that the output schema already declares, and it says nothing about concurrency or whether `updated` is bumped on a no-op replacement. These are modest gaps against an otherwise thorough disclosure.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate and it does: `offset`/`limit` are given precise semantics (1-based body line coordinates, inclusive range, `limit` omitted = to end, `limit=0` = pure insert, `offset=N+1` = append), and `content` is differentiated by mode (full body without frontmatter versus replacement/insert lines). `language` is covered in depth (default 'en' meaning, ISO 639-1 lowercase shape, per-language subdirectory, target-file isolation, translated-heading validation, and the `feat` exclusion that raises). `id` and `type` get failure semantics rather than value semantics, which is adequate given the type value set already lives in the enum.

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 opening clause gives a specific verb and resource — 'Whole-body or line-range replace of an existing document's content' — and scopes it to the enumerated whole-body domains and the two operating modes. It also names adjacent tools (`set_status`, `edit`, `get_<d>`) in passing, so an agent can place it in the family. It stops short of a crisp 'this is not update_section/update_frontmatter' contrast, so sibling differentiation is inferential rather than stated.

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

Usage Guidelines3/5

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

There is real usage guidance: status is explicitly out of scope and must go through `set_status`, and the only safe source of line coordinates is a `get_<d>(id, raw=True)` read. However, the description never tells the agent when to reach for `update` versus `edit`, `update_section`, or `update_frontmatter`, which are the genuinely confusable siblings listed nearby. The when-to-use decision is left to be reconstructed from the mode semantics.

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

Deploy Server

Other Tools