get_comments
Retrieve comments for a Jira ticket to track discussions and updates directly within your editor.
Instructions
Get comments for a specific Jira ticket
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| ticketId | Yes | The Jira ticket ID (e.g., PROJECT-123) |
Implementation Reference
- src/server.ts:229-268 (handler)The handler function for the 'get_comments' tool. It validates Jira configuration, fetches comments using the Jira API, formats them with author, date, and extracted text body using the extractTextFromADF helper, and handles errors including 404 for non-existent tickets.async ({ ticketId }: { ticketId: string }) => { const configError = validateJiraConfig(); if (configError) { return { content: [{ type: "text", text: `Configuration error: ${configError}` }], }; } try { const commentsResult = await jira.issueComments.getComments({ issueIdOrKey: ticketId }); if (!commentsResult.comments || commentsResult.comments.length === 0) { return { content: [{ type: "text", text: "No comments found for this ticket." }], }; } const formattedComments = commentsResult.comments.map(comment => { const author = comment.author?.displayName || 'Unknown Author'; // Comments also use ADF, so we need to parse them const body = extractTextFromADF(comment.body) || 'No comment body'; const createdDate = comment.created ? new Date(comment.created).toLocaleString() : 'Unknown date'; return `[${createdDate}] ${author}:\n${body.trim()}\n---`; // Added trim() and separator }).join('\n\n'); // Separate comments with double newline return { content: [{ type: "text", text: formattedComments }], }; } catch (error) { // Handle cases where the ticket might not exist or other API errors if ((error as any).response?.status === 404) { return { content: [{ type: "text", text: `Ticket ${ticketId} not found.` }], }; } return { content: [{ type: "text", text: `Failed to fetch comments: ${(error as Error).message}` }], }; } }
- src/server.ts:226-228 (schema)Input schema for the 'get_comments' tool, defining the required 'ticketId' parameter as a string with description.{ ticketId: z.string().describe("The Jira ticket ID (e.g., PROJECT-123)"), },
- src/server.ts:223-269 (registration)Registration of the 'get_comments' tool using server.tool(), including name, description, input schema, and handler function.server.tool( "get_comments", "Get comments for a specific Jira ticket", { ticketId: z.string().describe("The Jira ticket ID (e.g., PROJECT-123)"), }, async ({ ticketId }: { ticketId: string }) => { const configError = validateJiraConfig(); if (configError) { return { content: [{ type: "text", text: `Configuration error: ${configError}` }], }; } try { const commentsResult = await jira.issueComments.getComments({ issueIdOrKey: ticketId }); if (!commentsResult.comments || commentsResult.comments.length === 0) { return { content: [{ type: "text", text: "No comments found for this ticket." }], }; } const formattedComments = commentsResult.comments.map(comment => { const author = comment.author?.displayName || 'Unknown Author'; // Comments also use ADF, so we need to parse them const body = extractTextFromADF(comment.body) || 'No comment body'; const createdDate = comment.created ? new Date(comment.created).toLocaleString() : 'Unknown date'; return `[${createdDate}] ${author}:\n${body.trim()}\n---`; // Added trim() and separator }).join('\n\n'); // Separate comments with double newline return { content: [{ type: "text", text: formattedComments }], }; } catch (error) { // Handle cases where the ticket might not exist or other API errors if ((error as any).response?.status === 404) { return { content: [{ type: "text", text: `Ticket ${ticketId} not found.` }], }; } return { content: [{ type: "text", text: `Failed to fetch comments: ${(error as Error).message}` }], }; } } );
- src/server.ts:66-87 (helper)Helper function to recursively extract plain text from Jira's ADF (Atlassian Document Format) structures, used to parse comment bodies in the handler.function extractTextFromADF(node: any): string { if (!node) { return ''; } // Handle text nodes directly if (node.type === 'text' && node.text) { return node.text; } let text = ''; // Handle block nodes like paragraph, heading, etc. if (node.content && Array.isArray(node.content)) { text = node.content.map(extractTextFromADF).join(''); // Add a newline after paragraphs for better formatting if (node.type === 'paragraph') { text += '\n'; } } return text; }