UNPKG

@mcp-apps/azure-devops-mcp-server

Version:

A Model Context Protocol (MCP) server for Azure DevOps integration

141 lines (138 loc) 6.82 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.replyPullRequestCommentTool = void 0; const zod_1 = require("zod"); const azure_devops_client_1 = require("../utils/azure-devops-client"); const GitInterfaces = __importStar(require("azure-devops-node-api/interfaces/GitInterfaces")); const STATUS_MAP = { active: GitInterfaces.CommentThreadStatus.Active, fixed: GitInterfaces.CommentThreadStatus.Fixed, "won't-fix": GitInterfaces.CommentThreadStatus.WontFix, closed: GitInterfaces.CommentThreadStatus.Closed, "by-design": GitInterfaces.CommentThreadStatus.ByDesign, pending: GitInterfaces.CommentThreadStatus.Pending, }; exports.replyPullRequestCommentTool = { name: "git-reply-pr-comment", description: ` Replies to an existing comment thread on a pull request, optionally updating the thread's status (e.g. resolve to "fixed" or "closed"). Always call "git-list-pr-threads" first to discover the threadId. Note that Azure DevOps renders thread comments as a flat list, so parentCommentId is largely cosmetic — leaving it at 0 (thread root) is correct in almost all cases. updateStatus values (use to resolve or change a thread's state in the same call): - "active": Open / unresolved - "fixed": Resolved as fixed (typical "resolve" after the author addressed feedback) - "closed": Discussion ended without explicit resolution - "won't-fix": Acknowledged but won't be addressed - "by-design": Behavior is intentional - "pending": Draft / not yet published Parameters: - organizationUrl: Azure DevOps organization URL - project: Project name - repositoryName: Repository name - pullRequestId: Pull request ID - threadId: ID of the existing comment thread to reply to (from git-list-pr-threads) - content: Reply text (Markdown supported) - parentCommentId: Optional parent commentId within the thread (default: 0 = thread root). Leave at 0 unless you have a specific reason; comments render flat regardless. - updateStatus: Optional new thread status to set after replying. `, parameters: { organizationUrl: zod_1.z.string().describe("Azure DevOps organization URL"), project: zod_1.z.string().describe("Project name"), repositoryName: zod_1.z.string().describe("Repository name"), pullRequestId: zod_1.z.number().int().describe("Pull request ID"), threadId: zod_1.z.number().int().describe("Existing thread ID"), content: zod_1.z.string().describe("Reply content (Markdown supported)"), parentCommentId: zod_1.z.number().int().default(0).describe("Parent comment id within the thread (0 = root)"), updateStatus: zod_1.z .enum(["active", "fixed", "won't-fix", "closed", "by-design", "pending"]) .optional() .describe("Optional new status for the thread after replying"), }, handler: async ({ organizationUrl, project, repositoryName, pullRequestId, threadId, content, parentCommentId, updateStatus, }) => { try { const gitApi = await (0, azure_devops_client_1.getGitApi)(organizationUrl); const repositories = await gitApi.getRepositories(project); const repository = repositories.find((r) => r.name && r.name.toLowerCase() === repositoryName.toLowerCase()); if (!repository?.id) { return { content: [{ type: "text", text: `Repository "${repositoryName}" not found in project "${project}".`, }], }; } const createdComment = await gitApi.createComment({ parentCommentId, content, commentType: GitInterfaces.CommentType.Text, }, repository.id, pullRequestId, threadId, project); let updatedStatusValue; if (updateStatus) { const updated = await gitApi.updateThread({ status: STATUS_MAP[updateStatus] }, repository.id, pullRequestId, threadId, project); updatedStatusValue = updated?.status; } return { content: [{ type: "text", text: JSON.stringify({ pullRequestId, threadId, commentId: createdComment?.id, parentCommentId: createdComment?.parentCommentId, author: createdComment?.author?.displayName, publishedDate: createdComment?.publishedDate, updatedThreadStatus: updateStatus ? { name: updateStatus, value: updatedStatusValue } : null, }, null, 2), }], }; } catch (error) { const msg = error instanceof Error ? error.message : String(error); return { content: [{ type: "text", text: `Error replying to pull request comment: ${msg}`, }], }; } }, }; //# sourceMappingURL=git-reply-pr-comment.js.map