@azure-devops/mcp 2.0.0-nightly.20250902 → 2.0.0-nightly.20250904

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -27,7 +27,6 @@ The Azure DevOps MCP Server brings Azure DevOps context to your agents. Try prom
27
27
 
28
28
  - "List my ADO projects"
29
29
  - "List ADO Builds for 'Contoso'"
30
- - "List ADO Releases for 'Contoso'"
31
30
  - "List ADO Repos for 'Contoso'"
32
31
  - "List test plans for 'Contoso'"
33
32
  - "List teams for project 'Contoso'"
@@ -103,26 +102,21 @@ Interact with these Azure DevOps services:
103
102
  - **repo_search_commits**: Searches for commits.
104
103
  - **repo_create_pull_request_thread**: Creates a new comment thread on a pull request.
105
104
 
106
- ### 🛰️ Builds
105
+ ### 🚀 Pipelines
107
106
 
108
- - **build_get_definitions**: Retrieve a list of build definitions for a given project.
109
- - **build_get_definition_revisions**: Retrieve a list of revisions for a specific build definition.
110
- - **build_get_builds**: Retrieve a list of builds for a given project.
111
- - **build_get_log**: Retrieve the logs for a specific build.
112
- - **build_get_log_by_id**: Get a specific build log by log ID.
113
- - **build_get_changes**: Get the changes associated with a specific build.
114
- - **build_get_status**: Fetch the status of a specific build.
115
- - **build_update_build_stage**: Update the stage of a specific build.
107
+ - **pipelines_get_build_definitions**: Retrieve a list of build definitions for a given project.
108
+ - **pipelines_get_build_definition_revisions**: Retrieve a list of revisions for a specific build definition.
109
+ - **pipelines_get_builds**: Retrieve a list of builds for a given project.
110
+ - **pipelines_get_build_log**: Retrieve the logs for a specific build.
111
+ - **pipelines_get_build_log_by_id**: Get a specific build log by log ID.
112
+ - **pipelines_get_build_changes**: Get the changes associated with a specific build.
113
+ - **pipelines_get_build_status**: Fetch the status of a specific build.
114
+ - **pipelines_update_build_stage**: Update the stage of a specific build.
116
115
  - **pipelines_get_run**: Gets a run for a particular pipeline.
117
116
  - **pipelines_list_runs**: Gets top 10000 runs for a particular pipeline.
118
117
  - **pipelines_run_pipeline**: Starts a new run of a pipeline.
119
118
 
120
- ### 🚀 Releases
121
-
122
- - **release_get_definitions**: Retrieve a list of release definitions for a given project.
123
- - **release_get_releases**: Retrieve a list of releases for a given project.
124
-
125
- ### 🔒 Advanced Security
119
+ ### Advanced Security
126
120
 
127
121
  - **advsec_get_alerts**: Retrieve Advanced Security alerts for a repository.
128
122
  - **advsec_get_alert_details**: Get detailed information about a specific Advanced Security alert.
@@ -270,7 +264,7 @@ For example, use `"-d", "core", "work", "work-items"` to load only Work Item rel
270
264
  }
271
265
  ```
272
266
 
273
- Domains that are available are: `core`, `work`, `work-items`, `search`, `test-plans`, `repositories`, `wiki`, `builds`, `releases`, `advanced-security`
267
+ Domains that are available are: `core`, `work`, `work-items`, `search`, `test-plans`, `repositories`, `wiki`, `pipelines`, `advanced-security`
274
268
 
275
269
  We recommend that you always enable `core` tools so that you can fetch project level information.
276
270
 
@@ -6,9 +6,8 @@
6
6
  export var Domain;
7
7
  (function (Domain) {
8
8
  Domain["ADVANCED_SECURITY"] = "advanced-security";
9
- Domain["BUILDS"] = "builds";
9
+ Domain["PIPELINES"] = "pipelines";
10
10
  Domain["CORE"] = "core";
11
- Domain["RELEASES"] = "releases";
12
11
  Domain["REPOSITORIES"] = "repositories";
13
12
  Domain["SEARCH"] = "search";
14
13
  Domain["TEST_PLANS"] = "test-plans";
@@ -25,8 +24,7 @@ export class DomainsManager {
25
24
  enabledDomains;
26
25
  constructor(domainsInput) {
27
26
  this.enabledDomains = new Set();
28
- const normalizedInput = DomainsManager.parseDomainsInput(domainsInput);
29
- this.parseDomains(normalizedInput);
27
+ this.parseDomains(domainsInput);
30
28
  }
31
29
  /**
32
30
  * Parse and validate domains from input
@@ -48,10 +46,6 @@ export class DomainsManager {
48
46
  this.enableAllDomains();
49
47
  return;
50
48
  }
51
- if (domainsInput.length === 1 && domainsInput[0] === ALL_DOMAINS) {
52
- this.enableAllDomains();
53
- return;
54
- }
55
49
  const domains = domainsInput.map((d) => d.trim().toLowerCase());
56
50
  this.validateAndAddDomains(domains);
57
51
  }
@@ -60,7 +54,8 @@ export class DomainsManager {
60
54
  this.enableAllDomains();
61
55
  return;
62
56
  }
63
- const domains = [domainsInput.trim().toLowerCase()];
57
+ // Handle comma-separated domains
58
+ const domains = domainsInput.split(",").map((d) => d.trim().toLowerCase());
64
59
  this.validateAndAddDomains(domains);
65
60
  }
66
61
  validateAndAddDomains(domains) {
@@ -4,21 +4,21 @@ import { apiVersion, getEnumKeys, safeEnumConvert } from "../utils.js";
4
4
  import { BuildQueryOrder, DefinitionQueryOrder } from "azure-devops-node-api/interfaces/BuildInterfaces.js";
5
5
  import { z } from "zod";
6
6
  import { StageUpdateType } from "azure-devops-node-api/interfaces/BuildInterfaces.js";
7
- const BUILD_TOOLS = {
8
- get_builds: "build_get_builds",
9
- get_changes: "build_get_changes",
10
- get_definitions: "build_get_definitions",
11
- get_definition_revisions: "build_get_definition_revisions",
12
- get_log: "build_get_log",
13
- get_log_by_id: "build_get_log_by_id",
14
- get_status: "build_get_status",
7
+ const PIPELINE_TOOLS = {
8
+ pipelines_get_builds: "pipelines_get_builds",
9
+ pipelines_get_build_changes: "pipelines_get_build_changes",
10
+ pipelines_get_build_definitions: "pipelines_get_build_definitions",
11
+ pipelines_get_build_definition_revisions: "pipelines_get_build_definition_revisions",
12
+ pipelines_get_build_log: "pipelines_get_build_log",
13
+ pipelines_get_build_log_by_id: "pipelines_get_build_log_by_id",
14
+ pipelines_get_build_status: "pipelines_get_build_status",
15
+ pipelines_update_build_stage: "pipelines_update_build_stage",
15
16
  pipelines_get_run: "pipelines_get_run",
16
17
  pipelines_list_runs: "pipelines_list_runs",
17
18
  pipelines_run_pipeline: "pipelines_run_pipeline",
18
- update_build_stage: "build_update_build_stage",
19
19
  };
20
- function configureBuildTools(server, tokenProvider, connectionProvider, userAgentProvider) {
21
- server.tool(BUILD_TOOLS.get_definitions, "Retrieves a list of build definitions for a given project.", {
20
+ function configurePipelineTools(server, tokenProvider, connectionProvider, userAgentProvider) {
21
+ server.tool(PIPELINE_TOOLS.pipelines_get_build_definitions, "Retrieves a list of build definitions for a given project.", {
22
22
  project: z.string().describe("Project ID or name to get build definitions for"),
23
23
  repositoryId: z.string().optional().describe("Repository ID to filter build definitions"),
24
24
  repositoryType: z.enum(["TfsGit", "GitHub", "BitbucketCloud"]).optional().describe("Type of repository to filter build definitions"),
@@ -47,7 +47,7 @@ function configureBuildTools(server, tokenProvider, connectionProvider, userAgen
47
47
  content: [{ type: "text", text: JSON.stringify(buildDefinitions, null, 2) }],
48
48
  };
49
49
  });
50
- server.tool(BUILD_TOOLS.get_definition_revisions, "Retrieves a list of revisions for a specific build definition.", {
50
+ server.tool(PIPELINE_TOOLS.pipelines_get_build_definition_revisions, "Retrieves a list of revisions for a specific build definition.", {
51
51
  project: z.string().describe("Project ID or name to get the build definition revisions for"),
52
52
  definitionId: z.number().describe("ID of the build definition to get revisions for"),
53
53
  }, async ({ project, definitionId }) => {
@@ -58,7 +58,7 @@ function configureBuildTools(server, tokenProvider, connectionProvider, userAgen
58
58
  content: [{ type: "text", text: JSON.stringify(revisions, null, 2) }],
59
59
  };
60
60
  });
61
- server.tool(BUILD_TOOLS.get_builds, "Retrieves a list of builds for a given project.", {
61
+ server.tool(PIPELINE_TOOLS.pipelines_get_builds, "Retrieves a list of builds for a given project.", {
62
62
  project: z.string().describe("Project ID or name to get builds for"),
63
63
  definitions: z.array(z.number()).optional().describe("Array of build definition IDs to filter builds"),
64
64
  queues: z.array(z.number()).optional().describe("Array of queue IDs to filter builds"),
@@ -92,7 +92,7 @@ function configureBuildTools(server, tokenProvider, connectionProvider, userAgen
92
92
  content: [{ type: "text", text: JSON.stringify(builds, null, 2) }],
93
93
  };
94
94
  });
95
- server.tool(BUILD_TOOLS.get_log, "Retrieves the logs for a specific build.", {
95
+ server.tool(PIPELINE_TOOLS.pipelines_get_build_log, "Retrieves the logs for a specific build.", {
96
96
  project: z.string().describe("Project ID or name to get the build log for"),
97
97
  buildId: z.number().describe("ID of the build to get the log for"),
98
98
  }, async ({ project, buildId }) => {
@@ -103,7 +103,7 @@ function configureBuildTools(server, tokenProvider, connectionProvider, userAgen
103
103
  content: [{ type: "text", text: JSON.stringify(logs, null, 2) }],
104
104
  };
105
105
  });
106
- server.tool(BUILD_TOOLS.get_log_by_id, "Get a specific build log by log ID.", {
106
+ server.tool(PIPELINE_TOOLS.pipelines_get_build_log_by_id, "Get a specific build log by log ID.", {
107
107
  project: z.string().describe("Project ID or name to get the build log for"),
108
108
  buildId: z.number().describe("ID of the build to get the log for"),
109
109
  logId: z.number().describe("ID of the log to retrieve"),
@@ -117,7 +117,7 @@ function configureBuildTools(server, tokenProvider, connectionProvider, userAgen
117
117
  content: [{ type: "text", text: JSON.stringify(logLines, null, 2) }],
118
118
  };
119
119
  });
120
- server.tool(BUILD_TOOLS.get_changes, "Get the changes associated with a specific build.", {
120
+ server.tool(PIPELINE_TOOLS.pipelines_get_build_changes, "Get the changes associated with a specific build.", {
121
121
  project: z.string().describe("Project ID or name to get the build changes for"),
122
122
  buildId: z.number().describe("ID of the build to get changes for"),
123
123
  continuationToken: z.string().optional().describe("Continuation token for pagination"),
@@ -131,7 +131,7 @@ function configureBuildTools(server, tokenProvider, connectionProvider, userAgen
131
131
  content: [{ type: "text", text: JSON.stringify(changes, null, 2) }],
132
132
  };
133
133
  });
134
- server.tool(BUILD_TOOLS.pipelines_get_run, "Gets a run for a particular pipeline.", {
134
+ server.tool(PIPELINE_TOOLS.pipelines_get_run, "Gets a run for a particular pipeline.", {
135
135
  project: z.string().describe("Project ID or name to run the build in"),
136
136
  pipelineId: z.number().describe("ID of the pipeline to run"),
137
137
  runId: z.number().describe("ID of the run to get"),
@@ -143,7 +143,7 @@ function configureBuildTools(server, tokenProvider, connectionProvider, userAgen
143
143
  content: [{ type: "text", text: JSON.stringify(pipelineRun, null, 2) }],
144
144
  };
145
145
  });
146
- server.tool(BUILD_TOOLS.pipelines_list_runs, "Gets top 10000 runs for a particular pipeline.", {
146
+ server.tool(PIPELINE_TOOLS.pipelines_list_runs, "Gets top 10000 runs for a particular pipeline.", {
147
147
  project: z.string().describe("Project ID or name to run the build in"),
148
148
  pipelineId: z.number().describe("ID of the pipeline to run"),
149
149
  }, async ({ project, pipelineId }) => {
@@ -187,7 +187,7 @@ function configureBuildTools(server, tokenProvider, connectionProvider, userAgen
187
187
  }))
188
188
  .optional(),
189
189
  });
190
- server.tool(BUILD_TOOLS.pipelines_run_pipeline, "Starts a new run of a pipeline.", {
190
+ server.tool(PIPELINE_TOOLS.pipelines_run_pipeline, "Starts a new run of a pipeline.", {
191
191
  project: z.string().describe("Project ID or name to run the build in"),
192
192
  pipelineId: z.number().describe("ID of the pipeline to run"),
193
193
  pipelineVersion: z.number().optional().describe("Version of the pipeline to run. If not provided, the latest version will be used."),
@@ -223,7 +223,7 @@ function configureBuildTools(server, tokenProvider, connectionProvider, userAgen
223
223
  content: [{ type: "text", text: JSON.stringify(pipelineRun, null, 2) }],
224
224
  };
225
225
  });
226
- server.tool(BUILD_TOOLS.get_status, "Fetches the status of a specific build.", {
226
+ server.tool(PIPELINE_TOOLS.pipelines_get_build_status, "Fetches the status of a specific build.", {
227
227
  project: z.string().describe("Project ID or name to get the build status for"),
228
228
  buildId: z.number().describe("ID of the build to get the status for"),
229
229
  }, async ({ project, buildId }) => {
@@ -234,7 +234,7 @@ function configureBuildTools(server, tokenProvider, connectionProvider, userAgen
234
234
  content: [{ type: "text", text: JSON.stringify(build, null, 2) }],
235
235
  };
236
236
  });
237
- server.tool(BUILD_TOOLS.update_build_stage, "Updates the stage of a specific build.", {
237
+ server.tool(PIPELINE_TOOLS.pipelines_update_build_stage, "Updates the stage of a specific build.", {
238
238
  project: z.string().describe("Project ID or name to update the build stage for"),
239
239
  buildId: z.number().describe("ID of the build to update"),
240
240
  stageName: z.string().describe("Name of the stage to update"),
@@ -268,4 +268,4 @@ function configureBuildTools(server, tokenProvider, connectionProvider, userAgen
268
268
  };
269
269
  });
270
270
  }
271
- export { BUILD_TOOLS, configureBuildTools };
271
+ export { PIPELINE_TOOLS, configurePipelineTools };
package/dist/tools.js CHANGED
@@ -2,9 +2,8 @@
2
2
  // Licensed under the MIT License.
3
3
  import { Domain } from "./shared/domains.js";
4
4
  import { configureAdvSecTools } from "./tools/advanced-security.js";
5
- import { configureBuildTools } from "./tools/builds.js";
5
+ import { configurePipelineTools } from "./tools/pipelines.js";
6
6
  import { configureCoreTools } from "./tools/core.js";
7
- import { configureReleaseTools } from "./tools/releases.js";
8
7
  import { configureRepoTools } from "./tools/repositories.js";
9
8
  import { configureSearchTools } from "./tools/search.js";
10
9
  import { configureTestPlanTools } from "./tools/test-plans.js";
@@ -19,10 +18,9 @@ function configureAllTools(server, tokenProvider, connectionProvider, userAgentP
19
18
  };
20
19
  configureIfDomainEnabled(Domain.CORE, () => configureCoreTools(server, tokenProvider, connectionProvider, userAgentProvider));
21
20
  configureIfDomainEnabled(Domain.WORK, () => configureWorkTools(server, tokenProvider, connectionProvider));
22
- configureIfDomainEnabled(Domain.BUILDS, () => configureBuildTools(server, tokenProvider, connectionProvider, userAgentProvider));
21
+ configureIfDomainEnabled(Domain.PIPELINES, () => configurePipelineTools(server, tokenProvider, connectionProvider, userAgentProvider));
23
22
  configureIfDomainEnabled(Domain.REPOSITORIES, () => configureRepoTools(server, tokenProvider, connectionProvider, userAgentProvider));
24
23
  configureIfDomainEnabled(Domain.WORK_ITEMS, () => configureWorkItemTools(server, tokenProvider, connectionProvider, userAgentProvider));
25
- configureIfDomainEnabled(Domain.RELEASES, () => configureReleaseTools(server, tokenProvider, connectionProvider));
26
24
  configureIfDomainEnabled(Domain.WIKI, () => configureWikiTools(server, tokenProvider, connectionProvider));
27
25
  configureIfDomainEnabled(Domain.TEST_PLANS, () => configureTestPlanTools(server, tokenProvider, connectionProvider));
28
26
  configureIfDomainEnabled(Domain.SEARCH, () => configureSearchTools(server, tokenProvider, connectionProvider, userAgentProvider));
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const packageVersion = "2.0.0-nightly.20250902";
1
+ export const packageVersion = "2.0.0-nightly.20250904";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@azure-devops/mcp",
3
- "version": "2.0.0-nightly.20250902",
3
+ "version": "2.0.0-nightly.20250904",
4
4
  "description": "MCP server for interacting with Azure DevOps",
5
5
  "license": "MIT",
6
6
  "author": "Microsoft Corporation",
@@ -1,97 +0,0 @@
1
- // Copyright (c) Microsoft Corporation.
2
- // Licensed under the MIT License.
3
- import { ReleaseDefinitionExpands, ReleaseDefinitionQueryOrder, ReleaseExpands, ReleaseStatus, ReleaseQueryOrder } from "azure-devops-node-api/interfaces/ReleaseInterfaces.js";
4
- import { z } from "zod";
5
- import { getEnumKeys, safeEnumConvert } from "../utils.js";
6
- const RELEASE_TOOLS = {
7
- get_release_definitions: "release_get_definitions",
8
- get_releases: "release_get_releases",
9
- };
10
- function configureReleaseTools(server, tokenProvider, connectionProvider) {
11
- server.tool(RELEASE_TOOLS.get_release_definitions, "Retrieves list of release definitions for a given project.", {
12
- project: z.string().describe("Project ID or name to get release definitions for"),
13
- searchText: z.string().optional().describe("Search text to filter release definitions"),
14
- expand: z
15
- .enum(getEnumKeys(ReleaseDefinitionExpands))
16
- .default("None")
17
- .describe("Expand options for release definitions"),
18
- artifactType: z.string().optional().describe("Filter by artifact type"),
19
- artifactSourceId: z.string().optional().describe("Filter by artifact source ID"),
20
- top: z.number().optional().describe("Number of results to return (for pagination)"),
21
- continuationToken: z.string().optional().describe("Continuation token for pagination"),
22
- queryOrder: z
23
- .enum(getEnumKeys(ReleaseDefinitionQueryOrder))
24
- .default("NameAscending")
25
- .describe("Order of the results"),
26
- path: z.string().optional().describe("Path to filter release definitions"),
27
- isExactNameMatch: z.boolean().optional().default(false).describe("Whether to match the exact name of the release definition. Default is false."),
28
- tagFilter: z.array(z.string()).optional().describe("Filter by tags associated with the release definitions"),
29
- propertyFilters: z.array(z.string()).optional().describe("Filter by properties associated with the release definitions"),
30
- definitionIdFilter: z.array(z.string()).optional().describe("Filter by specific release definition IDs"),
31
- isDeleted: z.boolean().default(false).describe("Whether to include deleted release definitions. Default is false."),
32
- searchTextContainsFolderName: z.boolean().optional().describe("Whether to include folder names in the search text"),
33
- }, async ({ project, searchText, expand, artifactType, artifactSourceId, top, continuationToken, queryOrder, path, isExactNameMatch, tagFilter, propertyFilters, definitionIdFilter, isDeleted, searchTextContainsFolderName, }) => {
34
- const connection = await connectionProvider();
35
- const releaseApi = await connection.getReleaseApi();
36
- const releaseDefinitions = await releaseApi.getReleaseDefinitions(project, searchText, safeEnumConvert(ReleaseDefinitionExpands, expand), artifactType, artifactSourceId, top, continuationToken, safeEnumConvert(ReleaseDefinitionQueryOrder, queryOrder), path, isExactNameMatch, tagFilter, propertyFilters, definitionIdFilter, isDeleted, searchTextContainsFolderName);
37
- return {
38
- content: [{ type: "text", text: JSON.stringify(releaseDefinitions, null, 2) }],
39
- };
40
- });
41
- server.tool(RELEASE_TOOLS.get_releases, "Retrieves a list of releases for a given project.", {
42
- project: z.string().optional().describe("Project ID or name to get releases for"),
43
- definitionId: z.number().optional().describe("ID of the release definition to filter releases"),
44
- definitionEnvironmentId: z.number().optional().describe("ID of the definition environment to filter releases"),
45
- searchText: z.string().optional().describe("Search text to filter releases"),
46
- createdBy: z.string().optional().describe("User ID or name who created the release"),
47
- statusFilter: z
48
- .enum(getEnumKeys(ReleaseStatus))
49
- .optional()
50
- .default("Active")
51
- .describe("Status of the releases to filter (default: Active)"),
52
- environmentStatusFilter: z.number().optional().describe("Environment status to filter releases"),
53
- minCreatedTime: z.coerce
54
- .date()
55
- .optional()
56
- .default(() => {
57
- const sevenDaysAgo = new Date();
58
- sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7);
59
- return sevenDaysAgo;
60
- })
61
- .describe("Minimum created time for releases (default: 7 days ago)"),
62
- maxCreatedTime: z.coerce
63
- .date()
64
- .optional()
65
- .default(() => new Date())
66
- .describe("Maximum created time for releases (default: now)"),
67
- queryOrder: z
68
- .enum(getEnumKeys(ReleaseQueryOrder))
69
- .optional()
70
- .default("Ascending")
71
- .describe("Order in which to return releases (default: Ascending)"),
72
- top: z.number().optional().describe("Number of releases to return"),
73
- continuationToken: z.number().optional().describe("Continuation token for pagination"),
74
- expand: z
75
- .enum(getEnumKeys(ReleaseExpands))
76
- .optional()
77
- .default("None")
78
- .describe("Expand options for releases"),
79
- artifactTypeId: z.string().optional().describe("Filter releases by artifact type ID"),
80
- sourceId: z.string().optional().describe("Filter releases by artifact source ID"),
81
- artifactVersionId: z.string().optional().describe("Filter releases by artifact version ID"),
82
- sourceBranchFilter: z.string().optional().describe("Filter releases by source branch"),
83
- isDeleted: z.boolean().optional().default(false).describe("Whether to include deleted releases (default: false)"),
84
- tagFilter: z.array(z.string()).optional().describe("Filter releases by tags"),
85
- propertyFilters: z.array(z.string()).optional().describe("Filter releases by properties"),
86
- releaseIdFilter: z.array(z.number()).optional().describe("Filter by specific release IDs"),
87
- path: z.string().optional().describe("Path to filter releases"),
88
- }, async ({ project, definitionId, definitionEnvironmentId, searchText, createdBy, statusFilter, environmentStatusFilter, minCreatedTime, maxCreatedTime, queryOrder, top, continuationToken, expand, artifactTypeId, sourceId, artifactVersionId, sourceBranchFilter, isDeleted, tagFilter, propertyFilters, releaseIdFilter, path, }) => {
89
- const connection = await connectionProvider();
90
- const releaseApi = await connection.getReleaseApi();
91
- const releases = await releaseApi.getReleases(project, definitionId, definitionEnvironmentId, searchText, createdBy, safeEnumConvert(ReleaseStatus, statusFilter), environmentStatusFilter, minCreatedTime, maxCreatedTime, safeEnumConvert(ReleaseQueryOrder, queryOrder), top, continuationToken, safeEnumConvert(ReleaseExpands, expand), artifactTypeId, sourceId, artifactVersionId, sourceBranchFilter, isDeleted, tagFilter, propertyFilters, releaseIdFilter, path);
92
- return {
93
- content: [{ type: "text", text: JSON.stringify(releases, null, 2) }],
94
- };
95
- });
96
- }
97
- export { RELEASE_TOOLS, configureReleaseTools };