Change the same fields on up to 200 issues at once, of one project or of SEVERAL (full issue keys; project is optional and, when given, every key must be in it), or delete them (delete=true, no other field), or undo a delete (restore=true, no other field: give the keys of the deleted issues; each comes back under its key with the parent it had, when that parent is live, and the children the delete orphaned). Only provided fields change (formats and cross-project rules are in the argument descriptions). All or nothing: needs edit access to every project involved, and if any key is unknown or the change is invalid for any issue, nothing changes. Each issue gets its own history entry and event; followers are e-mailed once. expect (one project only) skips an issue whose CURRENT value differs, e.g. to undo an earlier bulk edit without overwriting someone else's change. preview=true is a dry run: nothing is written; it answers a summary, one outcome per issue (change with from/to per field, unchanged, skipped_expect, skipped_gate, invalid with a reason) and a plan token. Commit it by repeating the SAME arguments with plan=<token> (no preview): if any issue or your rights changed meanwhile, NOTHING is written and bulk_plan_stale lists fresh outcomes: preview again. Without plan the call commits at once; a preview with invalid issues cannot be committed. With format=json the bulk_plan_stale error text (after "Error: ") is a JSON object with the rows of a preview.
add_labelsstring[]optionalLabel names to add. Across projects a label is looked up by name in each, and a project without an added name is skipped for it, with a note; for ONE project an unknown label is an errorassigneestringoptionalUsername, or empty to unassign; must be a member of every project involvedconfirm_open_criteriabooleanoptionalConfirm, for every issue of the call, the open acceptance criteria / definition of done items of a move to a done status under done_gate warn. Issues the gate holds back (open items not confirmed, or done_gate block) are skipped, not written at all, and listed with their open items. Agents cannot confirm in bulk: they use update_issue_status with the idscyclestringoptionalcurrent, next or a cycle number; "" removes it. A number needs one projectdeletebooleanoptionalDelete the issues instead of changing them (cannot be combined with other fields)due_datestringoptionalDue date, YYYY-MM-DD, or empty to clear itexpectobjectoptionalOnly change an issue that still has these values: an issue whose CURRENT value differs is skipped (nothing written) and listed as skipped (patch mode, one project only)formatenumoptionalAnswer format: "json" (default) is one compact JSON document; "text" is a readable Markdown answerjsontextkeysstring[]requiredIssue keys, e.g. ["ITR-1", "ITR-2"] (1–200); may span projectsparentstringoptionalParent issue key, or empty to detachplanstringoptionalThe plan token of an earlier preview with the SAME arguments: commits only if every issue still reads as previewed, else nothing is written (bulk_plan_stale) and the fresh outcomes are listed. A plan commits ONCE (reuse: bulk_plan_used); names (assignee, parent, labels) that mean something else by commit time answer bulk_plan_invalidpreviewbooleanoptionalDry run (a rolled-back transaction): write nothing, answer the outcome per issue (long lists cut with "N more"; rows show @usernames, keys and label names) and a plan token, valid 10 minutes, bound to you, these arguments and issues (cannot be combined with plan). Never a guarantee that a later commit will succeedpriorityenumoptionalPrioritynonelowmediumhighurgentprojectstringoptionalProject key; optional: when given, every issue must belong to itremove_labelsstring[]optionalLabel names to removerestorebooleanoptionalUndo the delete of these (deleted) issues, parents before children (cannot be combined with other fields or delete)statusstringoptionalNew status: a key or name from list_statuses; across projects one every project hasstatus_categoryenumoptionalMove every issue to the FIRST status of this category in ITS projecttodoin_progressreviewdonetypeenumoptionalIssue typeepicstorytask
Returns
One of these shapes, depending on the arguments:
Shape 1
actionstringrequiredupdate, delete or restoreskippedarray of string | nullrequiredKeys skipped because they no longer match expectupdatedintegerrequiredIssues written
Shape 2
committablebooleanrequiredfalse: some issue is invalid, the plan cannot be committedexpiresAtstring (date-time)requiredmoreOutcomesintegerrequiredOutcomes not listed (counted in the summary)noteanyrequiredoutcomesarray of object | nullrequiredOne per issue, what needs attention firstplanstringrequiredToken to send as plan= with the same arguments to commit; empty when not committablepreviewbooleanrequiredsummaryobjectrequired
Optional fields, when present
criteriaSkippedarray of objectoptionalIssues the done gate held back; nothing was written for themlabelsSkippedarray of objectoptionalparent_readyarrayoptionalplanMatchedbooleanoptionalA plan was sent and every issue was as previewedtotalintegeroptionalIssues the call named (update)
- 2026-10-03 — New preview=true: a dry run that writes nothing and answers one outcome per issue (change, unchanged, skipped_expect, skipped_gate, invalid) plus a plan token; send the same arguments with plan=<token> to commit only if nothing changed meanwhile (else bulk_plan_stale with fresh outcomes, nothing written). A preview never guarantees the commit.
- 2026-10-04 — The answer gains parent_ready [{key,title,type,children,status}]: when the call moved the last open child of a story or epic to done, that parent is listed (suggested done status in status). Nothing is changed for it.
- 2026-10-05 — New optional cycle argument: current, next or a cycle number (list_cycles); "" takes the issue out of its cycle (update only). Across projects only current and next (resolved in each project).
- 2026-10-03 — New optional confirm_open_criteria (true) for done_gate warn. Issues the gate holds back are skipped, nothing written, and listed with their open items. Agents cannot confirm in bulk: use update_issue_status.
- 2026-10-03 — Also answers structuredContent (see outputSchema); a failed call adds structuredContent.error. Text unchanged. Details: /docs/mcp, "Structured results and errors".
- 2026-10-04 — Claude Code 2.1.288+ (clientInfo claude-code): the text of a successful answer is itself up to 512 bytes, else "Result in structuredContent (N bytes)."; structuredContent and errors are unchanged. See /docs/mcp.