From 3f3f4738beb881515657446d43229924684c889e Mon Sep 17 00:00:00 2001 From: Nikola Pejic Date: Wed, 2 Jul 2025 16:29:30 +0000 Subject: [PATCH 1/3] WIP issue 90 --- src/tools/repos.ts | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/src/tools/repos.ts b/src/tools/repos.ts index f43202a8..1678b1db 100644 --- a/src/tools/repos.ts +++ b/src/tools/repos.ts @@ -4,7 +4,7 @@ import { AccessToken } from "@azure/identity"; import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { WebApi } from "azure-devops-node-api"; -import { GitRef } from "azure-devops-node-api/interfaces/GitInterfaces.js"; +import { GitRef, PullRequestStatus } from "azure-devops-node-api/interfaces/GitInterfaces.js"; import { z } from "zod"; import { getCurrentUserDetails } from "./auth.js"; @@ -36,6 +36,23 @@ function branchesFilterOutIrrelevantProperties( .slice(0, top); } +function pullRequestStatusStringToInt( + status: string) +: number { + switch (status) { + case "abandoned": + return PullRequestStatus.Abandoned.valueOf(); + case "active": + return PullRequestStatus.Active.valueOf(); + case "completed": + return PullRequestStatus.Completed.valueOf(); + case "notSet": + return PullRequestStatus.NotSet.valueOf(); + default: + throw new Error(`Unknown pull request status: ${status}`); + } +} + function configureRepoTools( server: McpServer, tokenProvider: () => Promise, @@ -149,8 +166,9 @@ function configureRepoTools( repositoryId: z.string().describe("The ID of the repository where the pull requests are located."), created_by_me: z.boolean().default(false).describe("Filter pull requests created by the current user."), i_am_reviewer: z.boolean().default(false).describe("Filter pull requests where the current user is a reviewer."), + status: z.enum(["abandoned", "active", "all", "completed", "notSet"]).default("notSet").describe("Filter pull requests by status. Defaults to 'notSet'."), }, - async ({ repositoryId, created_by_me, i_am_reviewer }) => { + async ({ repositoryId, created_by_me, i_am_reviewer, status }) => { const connection = await connectionProvider(); const gitApi = await connection.getGitApi(); @@ -161,7 +179,7 @@ function configureRepoTools( creatorId?: string; reviewerId?: string; } = { - status: 1, + status: pullRequestStatusStringToInt(status), repositoryId: repositoryId, }; @@ -213,8 +231,9 @@ function configureRepoTools( project: z.string().describe("The name or ID of the Azure DevOps project."), created_by_me: z.boolean().default(false).describe("Filter pull requests created by the current user."), i_am_reviewer: z.boolean().default(false).describe("Filter pull requests where the current user is a reviewer."), + status: z.enum(["abandoned", "active", "all", "completed", "notSet"]).default("notSet").describe("Filter pull requests by status. Defaults to 'notSet'."), }, - async ({ project, created_by_me, i_am_reviewer }) => { + async ({ project, created_by_me, i_am_reviewer, status }) => { const connection = await connectionProvider(); const gitApi = await connection.getGitApi(); @@ -224,7 +243,7 @@ function configureRepoTools( creatorId?: string; reviewerId?: string; } = { - status: 1, + status: pullRequestStatusStringToInt(status), }; if (created_by_me || i_am_reviewer) { From 32445764a2e433d1e1367f72b243e3341ceae5ab Mon Sep 17 00:00:00 2001 From: Nikola Pejic Date: Wed, 2 Jul 2025 19:46:38 +0000 Subject: [PATCH 2/3] Adding missing "all" option, tested --- src/tools/repos.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tools/repos.ts b/src/tools/repos.ts index 1678b1db..cece2cfc 100644 --- a/src/tools/repos.ts +++ b/src/tools/repos.ts @@ -44,6 +44,8 @@ function pullRequestStatusStringToInt( return PullRequestStatus.Abandoned.valueOf(); case "active": return PullRequestStatus.Active.valueOf(); + case "all": + return PullRequestStatus.All.valueOf(); case "completed": return PullRequestStatus.Completed.valueOf(); case "notSet": From 2673e730f5e99baeac4d78cb41d11f54016ec7bb Mon Sep 17 00:00:00 2001 From: Nikola Pejic Date: Wed, 2 Jul 2025 20:00:53 +0000 Subject: [PATCH 3/3] Reverting default state to 'active' to match previous default state --- src/tools/repos.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/repos.ts b/src/tools/repos.ts index cece2cfc..68b50f89 100644 --- a/src/tools/repos.ts +++ b/src/tools/repos.ts @@ -168,7 +168,7 @@ function configureRepoTools( repositoryId: z.string().describe("The ID of the repository where the pull requests are located."), created_by_me: z.boolean().default(false).describe("Filter pull requests created by the current user."), i_am_reviewer: z.boolean().default(false).describe("Filter pull requests where the current user is a reviewer."), - status: z.enum(["abandoned", "active", "all", "completed", "notSet"]).default("notSet").describe("Filter pull requests by status. Defaults to 'notSet'."), + status: z.enum(["abandoned", "active", "all", "completed", "notSet"]).default("active").describe("Filter pull requests by status. Defaults to 'active'."), }, async ({ repositoryId, created_by_me, i_am_reviewer, status }) => { const connection = await connectionProvider(); @@ -233,7 +233,7 @@ function configureRepoTools( project: z.string().describe("The name or ID of the Azure DevOps project."), created_by_me: z.boolean().default(false).describe("Filter pull requests created by the current user."), i_am_reviewer: z.boolean().default(false).describe("Filter pull requests where the current user is a reviewer."), - status: z.enum(["abandoned", "active", "all", "completed", "notSet"]).default("notSet").describe("Filter pull requests by status. Defaults to 'notSet'."), + status: z.enum(["abandoned", "active", "all", "completed", "notSet"]).default("active").describe("Filter pull requests by status. Defaults to 'active'."), }, async ({ project, created_by_me, i_am_reviewer, status }) => { const connection = await connectionProvider();