Skip to main content
Glama

Update any issue fields in one write (requires version)

update_issue
Destructive

Update any issue fields in one write (requires version).

One call = one new version, whatever the number of fields (PO 2026-09-25). links replaces the whole list; board-core adds/removes the inverse links on the other issues in the same commit. transition_issue, assign_issue, move_to_sprint and link_issues stay available as single-purpose tools and follow the same rules. fields (custom fields, spec D129) is merged key by key: send only the keys you change, null removes one.

Call get_issue first and pass its version. Change ANY number of fields in ONE call (title, body, type, priority, severity, status, assignee, points, sprint, release, parent, labels, links) — one call makes exactly one new version, so do not split an edit into several calls. links replaces the whole list. Images in body: upload + attach_file first, then ![file name](path) (never base64). severity (bugs, D113): critical / high / medium / low — how bad it is, separate from priority. release: a planned release id, or null — children of an epic follow the epic's release unless they name another; use move_to_release when the user gives a reason. comment is needed when status enters a requires_comment status (see transition_issue). fields (custom fields, D129) is merged key by key: send only the keys you change, null deletes a value; same types and errors as create_issue (400 unknown_field / invalid_field_value / formula_readonly; types of the field must include the issue's type). Sales & Billing installments (D130): "invoiced" = set invoiced_at (+ invoice_no); "paid" = set paid_at and paid_amount (= amount when paid in full) — dates YYYY-MM-DD, today's date unless the user says another. Do not move the deal to Closed on your own: the deal's all_paid flag says when everything is collected — tell the user and move it only when asked. Rollup fields (D131: a goal's progress / linked, a deal's delivery_progress) are computed like formulas — never in fields (400 formula_readonly); read them in computed. links entries take an issue key of this or another project of the company (403 link_target_forbidden when you cannot open the target's project) or {type: "delivers", id: "KEY/R-n"} for a release (404 release_not_found when it does not exist). For a Roadmap & Goals goal, moving start / end is a fields change like any other. Agent work context (D179): working = what you are doing on this card, how and why (markdown, ≤ 600 characters) and touches = the files, modules or APIs you change (≤ 10 entries ≤ 120) — the next agent or person on a linked card reads them before changing the same things. When you START a card, do it in ONE call: status (the in-progress status), working, touches and if_unassigned: true — an unassigned card becomes yours in the same commit; 409 already_assigned (details.assignee) means someone else holds it: nothing was written, pick another card or ask the user. Update working again only when your approach changes — not every step (comments are for decisions people should be emailed about). null clears; entering a done status clears both. working_at / working_by / working_by_agent are set by BoardMark. A result warnings[] item with code: unresolved_blocker means this card is blocked_by a card that is not done (blocker: key, title, status, its working): the move is done — read that card (get_issue_context) and agree the order before you change what it touches. code: touch_overlap (D180) means another in-progress card touches the same files / folders (overlap: key, title, assignee, its touch, yours, its working): the move is done — read its working and agree who changes what first. Body: Optional colour (D137, use sparingly; markdown stays the main format): <mark>text</mark> highlights (yellow; or <mark data-color="green">), <span data-color="red">text</span> colours text; colours yellow, green, red, blue, purple (e.g. green = passed / expected, red = bug / actual, purple = question); any other HTML is shown as plain text; keep the open and close tag in the same paragraph.

WRITE: version = from your latest read (get_issue, list_comments, list_sprints, get_doc, read_file). 409 version_conflict (details.current, details.current_version): re-read, re-apply your change, retry — never overwrite blindly; when the changes disagree, ask the user.

Input Schema

NameRequiredDescriptionDefault
bodyNo
typeNo
linksNoThe complete new list; inverse links on other issues are kept in step.
titleNo
fieldsNoCustom field values (spec D129 (3), (6)), keyed by the project's field ids (get_project `frontmatter.fields`): text / select / customer / url / person = string, number / money = number, date = `YYYY-MM-DD`. Merged key by key with the stored values; `null` deletes a key. Unknown id → 400 `unknown_field` (details.field); wrong type, option not in `options`, bad date or url → 400 `invalid_field_value` (details.field, details.expected); formula field → 400 `formula_readonly`; a `required` field missing on create → 400 `invalid_field_value`.
labelsNo
parentNo
pointsNo
reasonNoSpec D144: why you make this change (≤ 200 characters). Optional, but give it when you act as an agent account — it is shown in the agent's run log ("moved KJ-12 To Do → In Progress because <reason>"). board-mcp records it in `agent.run`; board-core / board-files accept it and ignore it (it never changes the file, the version or the history).
sprintNo
statusNoStatus id; must exist in the project's `project.md` statuses.
as_roleNoAI agents (spec D136): the role you work as in this session (e.g. Developer, QA, BA, DevOps) when the user told you one; else your token's role is used. Only changes lane warnings, never what you may do. Ignored for people.
commentNoSpec D143 (6): a comment written in the same commit as a status change (same rule as `transition_issue`). Needed when `status` moves into a status with `requires_comment: true` — missing or empty → 400 `comment_required` (`details.status`). Ignored (and refused with 400 `validation_failed`) when the request does not change the status.
releaseNoReleases on only (D113); a planned release of this project.
touchesNoSpec D179: the files, modules or APIs your work changes (≤ 10 entries of ≤ 120 characters, e.g. `board-core/internal/engine/`), the complete list. `null` or [] clears it.
versionYesOptimistic-lock version of the file; +1 on every write. Every write must send the version it read.
workingNoSpec D179: what you are doing on this card, how and why (markdown, ≤ 600 characters) — read by the next agent or person on a linked card. Write it when you start and again only when your approach changes, not every step. `null` or "" clears it. Stamps `working_at` / `working_by`; cleared by board-core when the issue enters a done status.
assigneeNoA person `usr_…` or an agent account `agt_…` (D144) from list_people.
priorityNoIssue priority, highest first (spec D89). Missing = `medium`.medium
severityNoBug severity (D113), every plan.
issue_keyYesIssue key `{PROJECT}-{n}`, e.g. `KJ-101`.
project_keyYesProject key, e.g. `KJ`. 2–10 chars, uppercase letters and digits, starts with a letter.
if_unassignedNoSpec D179: claim the issue atomically. true → if someone else holds it (`assignee` set and not you) nothing is written and the answer is `409 already_assigned` (`details.assignee`); otherwise the write goes ahead and, when the issue has no assignee and the request names none, you become the assignee in the same commit. "You" = your agent account `agt_…` (D144), else your user. Use it with `status`, `working` and `touches` in one call when you start a card.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed3 schema fields changed
    • addedInput schema / properties / if_unassigned
      Added value: +{
      +  "description": "Spec D179: claim the issue atomically. true → if someone else holds it (`assignee` set and not you) nothing is written and the answer is `409 already_assigned` (`details.assignee`); otherwise the write goes ahead and, when the issue has no assignee and the request names none, you become the assignee in the same commit. \"You\" = your agent account `agt_…` (D144), else your user. Use it with `status`, `working` and `touches` in one call when you start a card.",
      +  "type": "boolean"
      +}
    • addedInput schema / properties / touches
      Added value: +{
      +  "anyOf": [
      +    {
      +      "items": {
      +        "maxLength": 120,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "maxItems": 10,
      +      "type": "array",
      +      "uniqueItems": true
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "description": "Spec D179: the files, modules or APIs your work changes (≤ 10 entries of ≤ 120 characters, e.g. `board-core/internal/engine/`), the complete list. `null` or [] clears it."
      +}
    • addedInput schema / properties / working
      Added value: +{
      +  "description": "Spec D179: what you are doing on this card, how and why (markdown, ≤ 600 characters) — read by the next agent or person on a linked card. Write it when you start and again only when your approach changes, not every step. `null` or \"\" clears it. Stamps `working_at` / `working_by`; cleared by board-core when the issue enters a done status.",
      +  "maxLength": 600,
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
  2. Changed4 schema fields changed
    • changedInput schema / properties / assignee / anyOf
      Previous value: -[
      -  {
      -    "description": "User id: `usr_` + ULID.",
      -    "pattern": "^usr_[0-9A-HJKMNP-TV-Z]{26}$",
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "description": "Who an issue can be assigned to or @mentioned (spec D144): a person `usr_…` or an agent account `agt_…` listed by list_people for the project. One pattern (not anyOf) so generated types and MCP tool inputs stay a plain string.",
      +    "pattern": "^(usr|agt)_[0-9A-HJKMNP-TV-Z]{26}$",
      +    "type": "string"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • addedInput schema / properties / assignee / description
      Added value: +"A person `usr_…` or an agent account `agt_…` (D144) from list_people."
    • addedInput schema / properties / comment
      Added value: +{
      +  "description": "Spec D143 (6): a comment written in the same commit as a status change (same rule as `transition_issue`). Needed when `status` moves into a status with `requires_comment: true` — missing or empty → 400 `comment_required` (`details.status`). Ignored (and refused with 400 `validation_failed`) when the request does not change the status.",
      +  "maxLength": 20000,
      +  "minLength": 1,
      +  "type": "string"
      +}
    • addedInput schema / properties / reason
      Added value: +{
      +  "description": "Spec D144: why you make this change (≤ 200 characters). Optional, but give it when you act as an agent account — it is shown in the agent's run log (\"moved KJ-12 To Do → In Progress because <reason>\"). board-mcp records it in `agent.run`; board-core / board-files accept it and ignore it (it never changes the file, the version or the history).",
      +  "maxLength": 200,
      +  "type": "string"
      +}
  3. First observed

TDQS

A4.7/5.0
Behavior5/5

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

Annotations only say this is a destructive, non-idempotent write; the description goes far beyond them, disclosing optimistic-lock conflict handling (409 version_conflict: re-read, re-apply, never overwrite), 409 already_assigned semantics ('nothing was written'), link-replacement and inverse-link behaviour, formula/rollup fields refusing writes, and the meaning of warnings[] codes unresolved_blocker and touch_overlap. It also flags side effects (deal's all_paid, done status clearing working/touches) that no annotation carries.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness2/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The main rule and the version/write contract are front-loaded, which is good, but the body is a dense wall of internal spec IDs (D113, D129, D130, D131, D137, D179, D180, 'PO 2026-09-25') and niche policy (Sales & Billing installments, markdown colour tags) that dilute the operational core. It also repeats itself verbatim — '`links` replaces the whole list' and '`fields` ... merged key by key' each appear twice.

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?

With 23 parameters, nested link objects, no output schema and a destructive write, the description must carry a lot — and it does: error codes and their details payloads, warning shapes, return-side effects, and the prerequisite read chain (get_issue, list_comments, list_sprints, get_doc, read_file). Little an agent needs to invoke it correctly is missing.

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 coverage is 70%, and the description closes much of the remaining gap: `links` replaces the whole list, `fields` merges key by key with null deleting, `release` null semantics and epic inheritance, `comment` required only when entering a requires_comment status, `working`/`touches` limits and lifecycle, `if_unassigned` atomic claim. This is meaning beyond what the JSON schema states, particularly for interaction between parameters.

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?

Opens with a specific verb+resource: 'Update any issue fields in one write (requires version)'. It also names the single-purpose siblings (transition_issue, assign_issue, move_to_sprint, link_issues) and explains they follow the same rules, so the agent can tell this general tool apart from the narrow ones without opening a schema.

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?

Explicit when-to-use: 'Call get_issue first and pass its version', 'Change ANY number of fields in ONE call ... do not split an edit into several calls'. It also states the alternative single-purpose tools and the exact one-call pattern for starting a card (status + working + touches + if_unassigned) and when to update `working` again rather than commenting.

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.

Resources