@azure-devops/mcp 2.0.0-nightly.20250826 → 2.0.0-nightly.20250828

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
@@ -15,10 +15,11 @@ This TypeScript project provides a **local** MCP server for Azure DevOps, enabli
15
15
  2. [🏆 Expectations](#-expectations)
16
16
  3. [⚙️ Supported Tools](#️-supported-tools)
17
17
  4. [🔌 Installation & Getting Started](#-installation--getting-started)
18
- 5. [📝 Troubleshooting](#-troubleshooting)
19
- 6. [🎩 Examples & Best Practices](#-examples--best-practices)
20
- 7. [🙋‍♀️ Frequently Asked Questions](#️-frequently-asked-questions)
21
- 8. [📌 Contributing](#-contributing)
18
+ 5. [🌏 Using Domains](#-using-domains)
19
+ 6. [📝 Troubleshooting](#-troubleshooting)
20
+ 7. [🎩 Examples & Best Practices](#-examples--best-practices)
21
+ 8. [🙋‍♀️ Frequently Asked Questions](#️-frequently-asked-questions)
22
+ 9. [📌 Contributing](#-contributing)
22
23
 
23
24
  ## 📺 Overview
24
25
 
@@ -110,9 +111,11 @@ Interact with these Azure DevOps services:
110
111
  - **build_get_log**: Retrieve the logs for a specific build.
111
112
  - **build_get_log_by_id**: Get a specific build log by log ID.
112
113
  - **build_get_changes**: Get the changes associated with a specific build.
113
- - **build_run_build**: Trigger a new build for a specified definition.
114
114
  - **build_get_status**: Fetch the status of a specific build.
115
115
  - **build_update_build_stage**: Update the stage of a specific build.
116
+ - **pipelines_get_run**: Gets a run for a particular pipeline.
117
+ - **pipelines_list_runs**: Gets top 10000 runs for a particular pipeline.
118
+ - **pipelines_run_pipeline**: Starts a new run of a pipeline.
116
119
 
117
120
  ### 🚀 Releases
118
121
 
@@ -242,6 +245,37 @@ Open GitHub Copilot Chat and try a prompt like `List ADO projects`.
242
245
 
243
246
  See the [getting started documentation](./docs/GETTINGSTARTED.md) to use our MCP Server with other tools such as Visual Studio 2022, Claude Code, and Cursor.
244
247
 
248
+ ## 🌏 Using Domains
249
+
250
+ Azure DevOps exposes a large surface area. As a result, our Azure DevOps MCP Server includes many tools. To keep the toolset manageable, avoid confusing the model, and respect client limits on loaded tools, use Domains to load only the areas you need. Domains are named groups of related tools (for example: core, work, work-items, repositories, wiki). Add the `-d` argument and the domain names to the server args in your `mcp.json` to list the domains to enable.
251
+
252
+ For example, use `"-d", "core", "work", "work-items"` to load only Work Item related tools (see the example below).
253
+
254
+ ```json
255
+ {
256
+ "inputs": [
257
+ {
258
+ "id": "ado_org",
259
+ "type": "promptString",
260
+ "description": "Azure DevOps organization name (e.g. 'contoso')"
261
+ }
262
+ ],
263
+ "servers": {
264
+ "ado": {
265
+ "type": "stdio",
266
+ "command": "mcp-server-azuredevops",
267
+ "args": ["${input:ado_org}", "-d", "core", "work", "work-items"]
268
+ }
269
+ }
270
+ }
271
+ ```
272
+
273
+ Domains that are available are: `core`, `work`, `work-items`, `search`, `test-plans`, `repositories`, `wiki`, `builds`, `releases`, `advanced-security`
274
+
275
+ We recommend that you always enable `core` tools so that you can fetch project level information.
276
+
277
+ > By default all domains are loaded
278
+
245
279
  ## 📝 Troubleshooting
246
280
 
247
281
  See the [Troubleshooting guide](./docs/TROUBLESHOOTING.md) for help with common issues and logging.
@@ -5,14 +5,16 @@ import { BuildQueryOrder, DefinitionQueryOrder } from "azure-devops-node-api/int
5
5
  import { z } from "zod";
6
6
  import { StageUpdateType } from "azure-devops-node-api/interfaces/BuildInterfaces.js";
7
7
  const BUILD_TOOLS = {
8
+ get_builds: "build_get_builds",
9
+ get_changes: "build_get_changes",
8
10
  get_definitions: "build_get_definitions",
9
11
  get_definition_revisions: "build_get_definition_revisions",
10
- get_builds: "build_get_builds",
11
12
  get_log: "build_get_log",
12
13
  get_log_by_id: "build_get_log_by_id",
13
- get_changes: "build_get_changes",
14
- run_build: "build_run_build",
15
14
  get_status: "build_get_status",
15
+ pipelines_get_run: "pipelines_get_run",
16
+ pipelines_list_runs: "pipelines_list_runs",
17
+ pipelines_run_pipeline: "pipelines_run_pipeline",
16
18
  update_build_stage: "build_update_build_stage",
17
19
  };
18
20
  function configureBuildTools(server, tokenProvider, connectionProvider, userAgentProvider) {
@@ -129,35 +131,96 @@ function configureBuildTools(server, tokenProvider, connectionProvider, userAgen
129
131
  content: [{ type: "text", text: JSON.stringify(changes, null, 2) }],
130
132
  };
131
133
  });
132
- server.tool(BUILD_TOOLS.run_build, "Triggers a new build for a specified definition.", {
134
+ server.tool(BUILD_TOOLS.pipelines_get_run, "Gets a run for a particular pipeline.", {
133
135
  project: z.string().describe("Project ID or name to run the build in"),
134
- definitionId: z.number().describe("ID of the build definition to run"),
135
- sourceBranch: z.string().optional().describe("Source branch to run the build from. If not provided, the default branch will be used."),
136
- parameters: z.record(z.string(), z.string()).optional().describe("Custom build parameters as key-value pairs"),
137
- }, async ({ project, definitionId, sourceBranch, parameters }) => {
136
+ pipelineId: z.number().describe("ID of the pipeline to run"),
137
+ runId: z.number().describe("ID of the run to get"),
138
+ }, async ({ project, pipelineId, runId }) => {
139
+ const connection = await connectionProvider();
140
+ const pipelinesApi = await connection.getPipelinesApi();
141
+ const pipelineRun = await pipelinesApi.getRun(project, pipelineId, runId);
142
+ return {
143
+ content: [{ type: "text", text: JSON.stringify(pipelineRun, null, 2) }],
144
+ };
145
+ });
146
+ server.tool(BUILD_TOOLS.pipelines_list_runs, "Gets top 10000 runs for a particular pipeline.", {
147
+ project: z.string().describe("Project ID or name to run the build in"),
148
+ pipelineId: z.number().describe("ID of the pipeline to run"),
149
+ }, async ({ project, pipelineId }) => {
150
+ const connection = await connectionProvider();
151
+ const pipelinesApi = await connection.getPipelinesApi();
152
+ const pipelineRuns = await pipelinesApi.listRuns(project, pipelineId);
153
+ return {
154
+ content: [{ type: "text", text: JSON.stringify(pipelineRuns, null, 2) }],
155
+ };
156
+ });
157
+ const variableSchema = z.object({
158
+ value: z.string().optional(),
159
+ isSecret: z.boolean().optional(),
160
+ });
161
+ const resourcesSchema = z.object({
162
+ builds: z
163
+ .record(z.string().describe("Name of the build resource."), z.object({
164
+ version: z.string().optional().describe("Version of the build resource."),
165
+ }))
166
+ .optional(),
167
+ containers: z
168
+ .record(z.string().describe("Name of the container resource."), z.object({
169
+ version: z.string().optional().describe("Version of the container resource."),
170
+ }))
171
+ .optional(),
172
+ packages: z
173
+ .record(z.string().describe("Name of the package resource."), z.object({
174
+ version: z.string().optional().describe("Version of the package resource."),
175
+ }))
176
+ .optional(),
177
+ pipelines: z.record(z.string().describe("Name of the pipeline resource."), z.object({
178
+ runId: z.number().describe("Id of the source pipeline run that triggered or is referenced by this pipeline run."),
179
+ version: z.string().optional().describe("Version of the source pipeline run."),
180
+ })),
181
+ repositories: z
182
+ .record(z.string().describe("Name of the repository resource."), z.object({
183
+ refName: z.string().describe("Reference name, e.g., refs/heads/main."),
184
+ token: z.string().optional(),
185
+ tokenType: z.string().optional(),
186
+ version: z.string().optional().describe("Version of the repository resource, git commit sha."),
187
+ }))
188
+ .optional(),
189
+ });
190
+ server.tool(BUILD_TOOLS.pipelines_run_pipeline, "Starts a new run of a pipeline.", {
191
+ project: z.string().describe("Project ID or name to run the build in"),
192
+ pipelineId: z.number().describe("ID of the pipeline to run"),
193
+ pipelineVersion: z.number().optional().describe("Version of the pipeline to run. If not provided, the latest version will be used."),
194
+ previewRun: z.boolean().optional().describe("If true, returns the final YAML document after parsing templates without creating a new run."),
195
+ resources: resourcesSchema.optional().describe("A dictionary of resources to pass to the pipeline."),
196
+ stagesToSkip: z.array(z.string()).optional().describe("A list of stages to skip."),
197
+ templateParameters: z.record(z.string(), z.string()).optional().describe("Custom build parameters as key-value pairs"),
198
+ variables: z.record(z.string(), variableSchema).optional().describe("A dictionary of variables to pass to the pipeline."),
199
+ yamlOverride: z.string().optional().describe("YAML override for the pipeline run."),
200
+ }, async ({ project, pipelineId, pipelineVersion, previewRun, resources, stagesToSkip, templateParameters, variables, yamlOverride }) => {
201
+ if (!previewRun && yamlOverride) {
202
+ throw new Error("Parameter 'yamlOverride' can only be specified together with parameter 'previewRun'.");
203
+ }
138
204
  const connection = await connectionProvider();
139
- const buildApi = await connection.getBuildApi();
140
205
  const pipelinesApi = await connection.getPipelinesApi();
141
- const definition = await buildApi.getDefinition(project, definitionId);
142
206
  const runRequest = {
207
+ previewRun: previewRun,
143
208
  resources: {
144
- repositories: {
145
- self: {
146
- refName: sourceBranch || definition.repository?.defaultBranch || "refs/heads/main",
147
- },
148
- },
209
+ ...resources,
149
210
  },
150
- templateParameters: parameters,
211
+ stagesToSkip: stagesToSkip,
212
+ templateParameters: templateParameters,
213
+ variables: variables,
214
+ yamlOverride: yamlOverride,
151
215
  };
152
- const pipelineRun = await pipelinesApi.runPipeline(runRequest, project, definitionId);
216
+ const pipelineRun = await pipelinesApi.runPipeline(runRequest, project, pipelineId, pipelineVersion);
153
217
  const queuedBuild = { id: pipelineRun.id };
154
218
  const buildId = queuedBuild.id;
155
219
  if (buildId === undefined) {
156
220
  throw new Error("Failed to get build ID from pipeline run");
157
221
  }
158
- const buildReport = await buildApi.getBuildReport(project, buildId);
159
222
  return {
160
- content: [{ type: "text", text: JSON.stringify(buildReport, null, 2) }],
223
+ content: [{ type: "text", text: JSON.stringify(pipelineRun, null, 2) }],
161
224
  };
162
225
  });
163
226
  server.tool(BUILD_TOOLS.get_status, "Fetches the status of a specific build.", {
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const packageVersion = "2.0.0-nightly.20250826";
1
+ export const packageVersion = "2.0.0-nightly.20250828";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@azure-devops/mcp",
3
- "version": "2.0.0-nightly.20250826",
3
+ "version": "2.0.0-nightly.20250828",
4
4
  "description": "MCP server for interacting with Azure DevOps",
5
5
  "license": "MIT",
6
6
  "author": "Microsoft Corporation",