@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 +39 -5
- package/dist/tools/builds.js +82 -19
- package/dist/version.js +1 -1
- package/package.json +1 -1
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. [
|
|
19
|
-
6. [
|
|
20
|
-
7. [
|
|
21
|
-
8. [
|
|
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.
|
package/dist/tools/builds.js
CHANGED
|
@@ -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.
|
|
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
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
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
|
-
|
|
145
|
-
self: {
|
|
146
|
-
refName: sourceBranch || definition.repository?.defaultBranch || "refs/heads/main",
|
|
147
|
-
},
|
|
148
|
-
},
|
|
209
|
+
...resources,
|
|
149
210
|
},
|
|
150
|
-
|
|
211
|
+
stagesToSkip: stagesToSkip,
|
|
212
|
+
templateParameters: templateParameters,
|
|
213
|
+
variables: variables,
|
|
214
|
+
yamlOverride: yamlOverride,
|
|
151
215
|
};
|
|
152
|
-
const pipelineRun = await pipelinesApi.runPipeline(runRequest, project,
|
|
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(
|
|
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.
|
|
1
|
+
export const packageVersion = "2.0.0-nightly.20250828";
|