@mcp-apps/azure-devops-mcp-server
Version:
A Model Context Protocol (MCP) server for Azure DevOps integration
133 lines (131 loc) • 6.88 kB
JavaScript
;
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.listPullRequestsTool = void 0;
const zod_1 = require("zod");
const GitInterfaces = __importStar(require("azure-devops-node-api/interfaces/GitInterfaces"));
const azure_devops_client_1 = require("../utils/azure-devops-client");
// Tool to list pull requests
exports.listPullRequestsTool = {
name: "git-list-pull-requests",
description: `
Lists pull requests in an Azure DevOps repository with filtering options.
This tool retrieves information about pull requests in the specified repository,
including title, ID, status, creator, source branch, target branch, and URL.
Parameters:
- organizationUrl: The Azure DevOps organization URL in the format https://dev.azure.com/{organization}
Example: https://dev.azure.com/fabrikam
- project: The exact name of the Azure DevOps project containing the repository
Example: "FabrikamFiber"
- repositoryName: The exact name of the Git repository to list pull requests from
Example: "FabrikamFiber-Web"
- status: The status of pull requests to retrieve (default: "active")
Valid values:
- "active": In progress pull requests
- "abandoned": Discarded pull requests
- "completed": Merged/completed pull requests
- "all": All pull requests regardless of status
- days: Optional number of days back to look for PRs (only applies to completed PRs)
Example: 7 for last 7 days, 30 for last 30 days
`,
parameters: {
organizationUrl: zod_1.z.string().describe("Azure DevOps organization URL (e.g., https://dev.azure.com/organization)"),
project: zod_1.z.string().describe("Project name"),
repositoryName: zod_1.z.string().describe("Repository name"),
status: zod_1.z.enum(["active", "abandoned", "completed", "all"]).default("active").describe("Pull request status"),
days: zod_1.z.number().int().min(1).max(365).optional().describe("Number of days back to look for PRs (only applies to completed PRs)"),
},
handler: async ({ organizationUrl, project, repositoryName, status, days }) => {
try {
const gitApi = await (0, azure_devops_client_1.getGitApi)(organizationUrl);
// Get the repository ID
const repositories = await gitApi.getRepositories(project);
const repository = repositories.find((repo) => repo.name && repo.name.toLowerCase() === repositoryName.toLowerCase());
if (!repository || !repository.id) {
return {
content: [{ type: "text", text: `Repository "${repositoryName}" not found in project "${project}".` }],
};
}
// Map status string to GitInterfaces.PullRequestStatus
let statusFilter;
if (status === "active")
statusFilter = GitInterfaces.PullRequestStatus.Active;
else if (status === "abandoned")
statusFilter = GitInterfaces.PullRequestStatus.Abandoned;
else if (status === "completed")
statusFilter = GitInterfaces.PullRequestStatus.Completed;
// Get pull requests
const pullRequests = await gitApi.getPullRequests(repository.id, {
status: statusFilter,
});
if (!pullRequests || pullRequests.length === 0) {
return {
content: [{ type: "text", text: `No ${status} pull requests found in repository "${repositoryName}".` }],
};
}
// Filter by days if specified and status is completed
let filteredPRs = pullRequests;
if (days && (status === "completed" || status === "all")) {
const cutoffDate = new Date();
cutoffDate.setDate(cutoffDate.getDate() - days);
filteredPRs = pullRequests.filter(pr => {
if (pr.closedDate) {
return new Date(pr.closedDate) >= cutoffDate;
}
return false;
});
}
// Format the results
const formattedText = filteredPRs.map((pr) => {
const closedInfo = pr.closedDate ? `\nClosed: ${pr.closedDate}` : '';
return `Title: ${pr.title}\nID: ${pr.pullRequestId}\nStatus: ${pr.status}\nCreated by: ${pr.createdBy?.displayName || "Unknown"}\nSource Branch: ${pr.sourceRefName}\nTarget Branch: ${pr.targetRefName}${closedInfo}\nURL: ${pr.url}\n-------------------------`;
}).join("\n");
const resultSummary = days && (status === "completed" || status === "all")
? `Found ${filteredPRs.length} ${status} pull requests in the last ${days} days:`
: `Found ${filteredPRs.length} ${status} pull requests:`;
return {
content: [{ type: "text", text: `${resultSummary}\n\n${formattedText}` }],
};
}
catch (error) {
console.error("Error listing pull requests:", error);
const errorMessage = error instanceof Error ? error.message : String(error);
return {
content: [{ type: "text", text: `Error listing pull requests: ${errorMessage}` }],
};
}
}
};
//# sourceMappingURL=git-list-pull-requests.js.map