UNPKG

github-repos-manager-mcp

Version:

Model Context Protocol (MCP) server that enables your MCP client (e.g., Claude Desktop, Cline, Roo Code, Cursor, Windsurf, etc.) to interact with GitHub repositories using your GitHub personal access token.

236 lines (220 loc) 5.83 kB
// src/formatters/issues.cjs function formatListIssuesOutput(issues, owner, repo, state) { if (!Array.isArray(issues)) { return { content: [ { type: "text", text: `Error: Could not retrieve ${state} issues for ${owner}/${repo}.`, }, ], isError: true, }; } if (issues.length === 0) { return { content: [ { type: "text", text: `No ${state} issues found in ${owner}/${repo}`, }, ], }; } const formatted = issues .map( (issue) => `**#${issue.number} ${issue.title}**\n` + `State: ${issue.state} | Author: ${issue.user.login}\n` + `Created: ${new Date(issue.created_at).toLocaleDateString()}\n` + `URL: ${issue.html_url}\n` + `Labels: ${issue.labels.map((l) => l.name).join(", ") || "None"}\n` + `Assignees: ${issue.assignees.map((a) => a.login).join(", ") || "None"}` ) .join("\n\n"); // Changed from \n to \n\n for better readability between issues return { content: [ { type: "text", text: `Found ${issues.length} ${state} issues in ${owner}/${repo}:\n\n${formatted}`, }, ], }; } function formatCreateIssueOutput(issue, owner, repo) { if (!issue || typeof issue !== "object" || !issue.number) { return { content: [ { type: "text", text: `Error: Could not create issue in ${owner}/${repo}.`, }, ], isError: true, }; } return { content: [ { type: "text", text: `Created issue #${issue.number} in ${owner}/${repo}:\n\n` + `**${issue.title}**\n` + `URL: ${issue.html_url}\n` + `State: ${issue.state}\n` + `Created: ${new Date(issue.created_at).toLocaleDateString()}`, }, ], }; } function formatEditIssueOutput(updatedIssue, owner, repo) { if ( !updatedIssue || typeof updatedIssue !== "object" || !updatedIssue.number ) { return { content: [ { type: "text", text: `Error: Could not edit issue in ${owner}/${repo}.`, }, ], isError: true, }; } return { content: [ { type: "text", text: `Successfully edited issue #${updatedIssue.number} in ${owner}/${repo}:\n\n` + `**${updatedIssue.title}**\n` + `URL: ${updatedIssue.html_url}\n` + `State: ${updatedIssue.state}`, }, ], }; } function formatGetIssueDetailsOutput(issue, owner, repo) { if (!issue || typeof issue !== "object" || !issue.number) { return { content: [ { type: "text", text: `Error: Could not retrieve details for issue in ${owner}/${repo}.`, }, ], isError: true, }; } const details = ` **Issue #${issue.number}: ${issue.title}** Status: ${issue.state} ${issue.locked ? "(Locked)" : ""} Repository: ${owner}/${repo} Author: @${issue.user.login} Created: ${new Date(issue.created_at).toLocaleString()} Updated: ${new Date(issue.updated_at).toLocaleString()} ${ issue.closed_at ? `Closed: ${new Date(issue.closed_at).toLocaleString()} by @${ issue.closed_by?.login || "N/A" }` : "" } Labels: ${ issue.labels.length > 0 ? issue.labels.map((l) => l.name).join(", ") : "None" } Assignees: ${ issue.assignees.length > 0 ? issue.assignees.map((a) => `@${a.login}`).join(", ") : "None" } Milestone: ${issue.milestone ? issue.milestone.title : "None"} URL: ${issue.html_url} **Body:** ${issue.body || "No description provided."} `.trim(); return { content: [{ type: "text", text: details }], }; } function formatLockIssueOutput(issue_number, lock_reason) { return { content: [ { type: "text", text: `Issue #${issue_number} locked successfully.${ lock_reason ? ` Reason: ${lock_reason}` : "" }`, }, ], }; } function formatUnlockIssueOutput(issue_number) { return { content: [ { type: "text", text: `Issue #${issue_number} unlocked successfully.` }, ], }; } function formatAddAssigneesToIssueOutput(updatedIssue, issue_number) { if (!updatedIssue || !Array.isArray(updatedIssue.assignees)) { return { content: [ { type: "text", text: `Error: Could not update assignees for issue #${issue_number}.`, }, ], isError: true, }; } const assignedNames = updatedIssue.assignees.map((a) => a.login).join(", "); return { content: [ { type: "text", text: `Successfully added/updated assignees for issue #${issue_number}. Current assignees: ${ assignedNames || "None" }`, // GitHub API for add assignees returns the full issue object with all current assignees }, ], }; } function formatRemoveAssigneesFromIssueOutput(updatedIssue, issue_number) { if (!updatedIssue || !Array.isArray(updatedIssue.assignees)) { return { content: [ { type: "text", text: `Error: Could not update assignees for issue #${issue_number}.`, }, ], isError: true, }; } const remainingAssignees = updatedIssue.assignees ? updatedIssue.assignees.map((a) => a.login).join(", ") : "None"; return { content: [ { type: "text", text: `Successfully removed assignees from issue #${issue_number}. Remaining assignees: ${remainingAssignees}`, }, ], }; } module.exports = { formatListIssuesOutput, formatCreateIssueOutput, formatEditIssueOutput, formatGetIssueDetailsOutput, formatLockIssueOutput, formatUnlockIssueOutput, formatAddAssigneesToIssueOutput, formatRemoveAssigneesFromIssueOutput, };