Skip to main content
Glama

skein_update

Patch an existing issue. Supports field updates (title / description / type / priority / assignee / due dates / design / acceptance / notes / external ref / source context / estimated minutes), status transitions, component-set replace, and label add/remove — all in one tool call. Required: id (full hierarchical) and expectedVersion for optimistic concurrency. On version mismatch returns {error:"version_conflict", currentVersion:<int>}. Locks are honoured: caller must hold the lock or pass force=true (force_unlock: project owner, space owner, instance admin). This tool does NOT touch the lock — to release the lock use skein_unclaim(id, nextStatus, reason) (atomic over lock+status) or skein_close (terminal close). Multi-op note: when the call sets a mix of fields, status, components, and labels, each sub-operation is committed independently — a failure mid-way leaves a partial state and you should re-fetch with skein_show before retrying. ANSWERS WITH AN ACKNOWLEDGEMENT by default — the id, the applied state and the new version, no issue card and no prose — so the expectedVersion cycle continues without a re-read; pass verbose for the full IssueDetail.

A transaction abort with an unchanged declared version returns serialization_retry. Earlier sub-operations may have committed: re-read and resend only unapplied changes.

closeOutcome is required when transitioning to closed; repeating a close without it preserves the previous outcome.

Text patches (description, design, acceptanceCriteria, notes, externalRef, sourceContext): omitted leaves unchanged; null or an empty string clears. Other non-string values are refused before any write with validation_error, code text_field_not_string and field naming the argument.

⚠ Field bleed: tool-call wrapper literals (<invoke, <parameter name=, </parameter>) in the prose fields (description / acceptanceCriteria / notes / design) are rejected with validation_error (code: tool_call_syntax_leaked) — a hit means you closed a parameter block with the wrong tag. Closed set + the look-alikes that are NOT rejected: skein_get_instructions ("Text fields — forbidden literals").

Tool call template

Replace each placeholder with a value matching the input schema. Only required parameters are included; add optional parameters as needed.

{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "arguments": {
      "id": "<id>",
      "expectedVersion": "<expectedVersion>"
    },
    "name": "skein_update"
  }
}

Input Schema

NameRequiredDescriptionDefault
idYesFull hierarchical issue id (e.g. "demo-42").
typeNoChange issue type.
dueAtNoRFC3339 timestamp; replaces due date.
forceNoBypass lock + version + pinned predicates. Needs force_unlock on the issue's project (project owner, space owner, instance admin); others get `force_unlock_forbidden`. Default: false.
notesNoReplace notes.
titleNoNew title (1..1000 chars).
designNoReplace design notes.
reasonNoFree-form reason annotation; only meaningful when `status` is set (lands in events.reason and, for closed, issues.closed_reason).
statusNoStatus transition. Routed through UpdateStatus. `standing` promotes the issue: STANDING task = perpetual obligation: acted on via spawned children (skein_create parentId=<this>), never claimed or worked in place, excluded from open-work counts / skein_ready / inbox. The sole demote leg is back to 'open'. Rejected standing legs — `cannot_promote_locked_to_standing`, `cannot_work_standing_directly`, `cannot_defer_standing`, `nested_standing_forbidden` — are structural invariants that force does NOT bypass. See skein_get_instructions ("Standing tasks"). `blocked` is no longer accepted — blocked-ness is derived from the dep graph (use skein_dep_add with type='blocks' or 'waits-for' on the issue you want labelled blocked).
verboseNoReturn the full IssueDetail, prose included. Default false = acknowledgement: `id`, `ok`, `version` plus the post-state stamps that apply (`status`, `assignee`, lock / claim / close stamps) — no issue card and no free text. The version is always there, so the expectedVersion cycle needs no extra read. Details: skein_get_instructions. If the write applied but its card could not be read back, the answer is the acknowledgement plus `cardUnavailable: true` — read the card with skein_show; do not repeat the write.
assigneeNoReplace assignee handle. Pass an empty string (or null) to clear. A user UUID that does not name a person who may work in the project is refused with assignee_not_allowed and nothing is written; a username or email is stored as text. A non-string value (number, array, object, boolean) is refused with validation_error, code assignee_not_string, and nothing is written.
priorityNoPriority 0..4.
labelsAddNoLabels to add (idempotent — already-present labels are no-ops).
deferUntilNoRFC3339 timestamp; replaces defer-until date.
closeTargetNoThe issue this one duplicates (duplicate) or that replaced it (superseded); creates that edge in the same transaction.
descriptionNoReplace description body.
externalRefNoReplace external-system reference.
closeOutcomeNoHow the issue ENDED. Only done counts toward progress; the other three are excluded from scope.
componentIdsNoReplace the issue's component set. UUID strings; must belong to the issue's project.
labelsRemoveNoLabels to remove (must currently be set on the issue).
sourceContextNoReplace source-context annotation.
reviewRequiredNoWhether this issue needs the AUTHOR's review once it is closed. Only the issue's author may set it — anyone else, admins included, gets `review_forbidden`. It does NOT travel the ordinary update path: send it ALONE. Combined with any other changing argument (a field, `status`, `reason`, `componentIds`, `labelsAdd` / `labelsRemove`) the whole call is refused with `validation_error` and nothing is written — the flag is never applied half-way. Flipping it moves neither `version` nor the issue's updated-at stamp, so the acknowledgement's version is the one you already held; `expectedVersion` is still required and still checked, as the assertion that you are flipping the state you read. Clearing the flag is NOT a review mark — it leaves any existing mark untouched. There is deliberately no agent tool for the mark itself. The acknowledgement of this branch is always the lean one — `verbose=true` does NOT widen it to the card, because the card would carry the mechanism's own keys. Read them with `skein_show`.
expectedVersionYesThe version the agent expects to see on the issue. The update only proceeds when the live version matches; otherwise returns version_conflict with the live version.
estimatedMinutesNoReplace estimated-minutes (>=0).
acceptanceCriteriaNoReplace acceptance criteria.

Schema Changelog

Changes observed during successful MCP inspections.

  1. First observed

TDQS

A4.3/5.0
Behavior3/5

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

Annotations already declare readOnly=false, destructive=false, idempotent=false, so the agent knows the mutation profile. The description nonetheless adds substantial behavior: optimistic concurrency via expectedVersion, the version_conflict payload shape, force bypass scope (and that it does NOT bypass standing invariants), independent commit of sub-operations leaving partial state, serialization_retry after aborts, and the lean-acknowledgement default. This is far richer than the annotations, though a few claims (e.g. that reviewRequired flips move neither version nor updated-at) are asserted without pointing at how to verify partial outcomes beyond skein_show.

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?

Purpose and the two required arguments are front-loaded and each paragraph maps to a behavior (concurrency, locks, multi-op atomicity, return shape, close, text fields, field bleed). It is dense but mostly earns its place; the ⚠ field-bleed block and the acknowledgement/verbose exposition restate material already in the parameter descriptions, making the prose longer than strictly needed for a 25-param schema.

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?

With 25 parameters, three enums, no output schema, and a mutation that can partially commit, the description covers return shape (lean acknowledgement vs verbose IssueDetail, cardUnavailable), error codes, and force/lock scope — enough for correct invocation. It still leaves some outcomes to skein_get_instructions and skein_show by reference, which is acceptable given the tool's breadth but keeps it short of fully self-contained.

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; the description earns more by adding semantics the schema does not carry — the text-field rule that omission leaves unchanged while null/empty clears with text_field_not_string, the closeOutcome requirement on closed transitions, closeTarget's edge creation, and the single-op constraint on reviewRequired. It also explains the tool-call-literal rejection (tool_call_syntax_leaked) which no property description mentions.

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 ("Patch an existing issue") and enumerates exactly what the patch covers: field updates, status transitions, component-set replace, label add/remove. It also marks the boundaries of the operation (does NOT touch the lock) and names the siblings that do, so an agent can separate it from skein_close/skein_unclaim without opening another 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?

Gives explicit use conditions and exclusions: lock release goes to skein_unclaim or skein_close, close transitions need closeOutcome, and reviewRequired must be sent ALONE or the whole call is refused. The multi-op note tells the agent when a single call mixes concerns and what to do if it fails mid-way. Alternatives and when-not-to-use are both stated rather than inferred.

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.