jira_update_issue
Update Jira issues by modifying fields like summary, description, priority, assignee, labels, and components. Only specified fields are changed, with plain text descriptions automatically formatted to Jira's ADF format.
Instructions
Updates an existing Jira issue by its key. Supports updating summary, description, priority, assignee, labels, and components. Description accepts plain text and is auto-formatted to ADF: headings (lines ending with ":"), numbered/bullet lists, and links. Only specified fields will be updated.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| assignee | No | New assignee account ID (optional, use null string to unassign) | |
| components | No | New components array (replaces existing components) - optional | |
| description | No | New issue description (optional). Accepts plain text (auto-formatted to ADF) or an ADF document. | |
| issueKey | Yes | Issue key to update (e.g., PROJECT-123) | |
| labels | No | New labels array (replaces existing labels) - optional | |
| priority | No | New priority name (e.g., High, Medium, Low) - optional | |
| returnIssue | No | If false, returns a success message without fetching the updated issue | |
| summary | No | New issue summary/title (optional) |
Implementation Reference
- src/tools/update-issue.ts:68-101 (handler)The main handler function `handleUpdateIssue` that implements the core logic for the `jira_update_issue` tool. It validates input using Zod schema, builds update parameters, calls the Jira API via `updateIssue` helper, optionally fetches the updated issue, formats the response, and handles errors.export async function handleUpdateIssue(input: unknown): Promise<McpToolResponse> { try { const validated = validateInput(UpdateIssueInputSchema, input); log.info(`Updating issue ${validated.issueKey}...`); const updateParams: any = {}; if (validated.summary !== undefined) updateParams.summary = validated.summary; if (validated.description !== undefined) updateParams.description = validated.description; if (validated.priority !== undefined) updateParams.priority = validated.priority; if (validated.assignee !== undefined) updateParams.assignee = validated.assignee; if (validated.labels !== undefined) updateParams.labels = validated.labels; if (validated.components !== undefined) updateParams.components = validated.components; if (validated.format !== undefined) updateParams.format = validated.format; await updateIssue(validated.issueKey, updateParams); if (validated.returnIssue === false) { log.info(`Updated issue ${validated.issueKey}`); return formatSuccessResponse(`Issue ${validated.issueKey} updated successfully`); } // Get the updated issue to return current state const updatedIssue = await getIssue(validated.issueKey); log.info(`Updated issue ${updatedIssue.key}`); return formatIssueResponse(updatedIssue); } catch (error) { log.error('Error in handleUpdateIssue:', error); return handleError(error); } }
- src/tools/update-issue.ts:14-66 (schema)MCP Tool object definition `updateIssueTool` including the name 'jira_update_issue' and JSON inputSchema for tool parameters used in ListTools response.export const updateIssueTool: Tool = { name: TOOL_NAMES.UPDATE_ISSUE, description: 'Updates an existing Jira issue by its key. Supports updating summary, description, priority, assignee, labels, and components. Description format is controlled by the "format" parameter (default: markdown). Only specified fields will be updated.', inputSchema: { type: 'object', properties: { issueKey: { type: 'string', description: 'Issue key to update (e.g., PROJECT-123)', }, summary: { type: 'string', description: 'New issue summary/title (optional)', }, description: { anyOf: [{ type: 'string' }, { type: 'object' }], description: 'New issue description (optional). Format depends on the "format" parameter.', }, priority: { type: 'string', description: 'New priority name (e.g., High, Medium, Low) - optional', }, assignee: { type: 'string', description: 'New assignee account ID (optional, use null string to unassign)', }, labels: { type: 'array', items: { type: 'string' }, description: 'New labels array (replaces existing labels) - optional', }, components: { type: 'array', items: { type: 'string' }, description: 'New components array (replaces existing components) - optional', }, returnIssue: { type: 'boolean', description: 'If false, returns a success message without fetching the updated issue', default: true, }, format: { type: 'string', enum: ['markdown', 'adf', 'plain'], description: 'Description format: "markdown" (converts Markdown to ADF, default), "adf" (use as-is ADF object), "plain" (converts plain text to ADF with basic formatting)', default: 'markdown', }, }, required: ['issueKey'], }, };
- src/types/tools.ts:85-107 (schema)Zod validation schema `UpdateIssueInputSchema` used in the handler for input validation via `validateInput`.export const UpdateIssueInputSchema = z.object({ issueKey: z .string() .describe('Issue key to update') .refine((v) => isValidIssueKey(v), 'Invalid issue key format'), summary: z.string().optional().describe('New summary'), description: z .union([z.string(), z.any()]) .optional() .describe('New description. Accepts plain text or ADF object.'), priority: z.string().optional().describe('New priority'), assignee: z.string().optional().describe('New assignee account ID'), labels: z.array(z.string()).optional().describe('New labels (replaces existing)'), components: z.array(z.string()).optional().describe('New components (replaces existing)'), returnIssue: z.boolean().optional().describe('When false, skip fetching full issue after update'), format: z .enum(['markdown', 'adf', 'plain']) .optional() .default('markdown') .describe( 'Description format: "markdown" (converts Markdown to ADF), "adf" (use as-is ADF object), "plain" (converts plain text to ADF with basic formatting). Default: "markdown"' ), });
- src/index.ts:32-49 (registration)Registration of all tool handlers in the `toolHandlers` Map, specifically mapping TOOL_NAMES.UPDATE_ISSUE ('jira_update_issue') to `tools.handleUpdateIssue` for execution handling.const toolHandlers = new Map<string, (input: unknown) => Promise<any>>([ [TOOL_NAMES.GET_VISIBLE_PROJECTS, tools.handleGetVisibleProjects], [TOOL_NAMES.GET_ISSUE, tools.handleGetIssue], [TOOL_NAMES.SEARCH_ISSUES, tools.handleSearchIssues], [TOOL_NAMES.GET_MY_ISSUES, tools.handleGetMyIssues], [TOOL_NAMES.GET_ISSUE_TYPES, tools.handleGetIssueTypes], [TOOL_NAMES.GET_USERS, tools.handleGetUsers], [TOOL_NAMES.GET_PRIORITIES, tools.handleGetPriorities], [TOOL_NAMES.GET_STATUSES, tools.handleGetStatuses], [TOOL_NAMES.CREATE_ISSUE, tools.handleCreateIssue], [TOOL_NAMES.UPDATE_ISSUE, tools.handleUpdateIssue], [TOOL_NAMES.ADD_COMMENT, tools.handleAddComment], [TOOL_NAMES.GET_PROJECT_INFO, tools.handleGetProjectInfo], [TOOL_NAMES.CREATE_SUBTASK, tools.handleCreateSubtask], [TOOL_NAMES.GET_CREATE_META, tools.handleGetCreateMeta], [TOOL_NAMES.GET_CUSTOM_FIELDS, tools.handleGetCustomFields], [TOOL_NAMES.CREATE_ISSUE_LINK, tools.handleCreateIssueLink], ]);
- src/index.ts:52-69 (registration)Registration of all tool objects in the `allTools` array, including `tools.updateIssueTool` for the ListTools MCP request handler.const allTools = [ tools.getVisibleProjectsTool, tools.getIssueTool, tools.searchIssuesTool, tools.getMyIssuesTool, tools.getIssueTypesTool, tools.getUsersTool, tools.getPrioritiesTool, tools.getStatusesTool, tools.createIssueTool, tools.updateIssueTool, tools.addCommentTool, tools.getProjectInfoTool, tools.createSubtaskTool, tools.getCreateMetaTool, tools.getCustomFieldsTool, tools.createIssueLinkTool, ];