jira_write
Update a JIRA issue by key, modifying description, assignee, reporter, or custom fields. Supports JFM markdown or raw ADF, and includes a dry-run mode for validation.
Instructions
Update a JIRA issue by key (e.g. PROJ-123). content updates the description (JFM markdown by default, or raw ADF JSON when format = "adf"); omit it to leave the description unchanged. Supply the description as content (inline) OR content_path (a filesystem path the server reads) — not both; prefer the path form when the body is already on disk. JFM is GitHub-style markdown — see resource omni-dev://specs/jfm for syntax. To set the parent for hierarchy (Epic → Story, Story → Sub-task) use the jira_link_parent tool — the canonical hierarchy surface. assignee/reporter accept an accountId (use the empty string "" to clear, "-1" for JIRA automatic assignment); call jira_user_search first if you only have a name or email. fields is an escape hatch — a map of canonical JIRA field id to its API JSON value (e.g. {"priority": {"name": "High"}}) — for fields without a typed parameter. String values targeting rich-text custom fields (e.g. Acceptance Criteria) are auto-converted from JFM to ADF; pass the empty string "" to clear such a field. Pass a JSON object value to bypass conversion (raw ADF). To set fields by display name with automatic value coercion, prefer the jira_edit tool. At least one of content, assignee, reporter, or fields must be supplied. Set dry_run: true first when uncertain about required fields or formatting — validates the input and returns the request that would be sent (method, path, body) without updating the issue. Mirrors the CLI's omni-dev atlassian jira write --dry-run.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| key | Yes | JIRA issue key (e.g., `PROJ-123`). | |
| fields | No | Additional `fields` keys merged into the issue update payload. Keys must already be canonical JIRA field ids (e.g. `priority`, `labels`, `customfield_10010`). Values must already be in the API's JSON shape (e.g. `{"name": "High"}` for priority, `["a", "b"]` for labels) — with one ergonomic exception: a string value targeting a rich-text textarea custom field (e.g. `{"customfield_19300": "- bullet\n- bullet"}`) is auto-converted from JFM markdown to ADF, and the empty string `""` clears such a field. Pass a JSON object instead of a string to bypass conversion (raw ADF). Setting `assignee` or `reporter` here collides with the typed parameters and is rejected — pass the typed parameter instead. | |
| format | No | Content format — `jfm` (default) parses Markdown/JFM; `adf` accepts a raw ADF JSON document. | |
| content | No | New description body. Interpreted per `format`. Omit to leave the existing description unchanged (useful when only updating `assignee`/`reporter`/`fields`). For `format = "jfm"` (the default), this is GitHub-style markdown, NOT JIRA wiki markup. Use `##` not `h2.`, triple-backtick fences not `{code}`, backtick inline code not `{{...}}`. Full reference: MCP resource `omni-dev://specs/jfm`. | |
| dry_run | No | When true, validate and return the would-be request (method, path, body) without updating the issue. Defaults to `false`. | |
| assignee | No | Assignee `accountId`. The empty string `""` clears the assignee; `"-1"` triggers JIRA automatic assignment. Use `jira_user_search` to resolve a name or email to an `accountId`. | |
| reporter | No | Reporter `accountId`. Same conventions as `assignee` (`""` clears, `"-1"` is JIRA automatic). | |
| content_path | No | Filesystem path the server reads the description body from, instead of `content`. Prefer this when the body is already on disk — it avoids re-emitting a large body inline. Mutually exclusive with `content`. |