@azure-devops/mcp 1.2.0-daily.20250715 → 1.2.1
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 +163 -98
- package/dist/index.js +32 -8
- package/dist/tools/builds.js +14 -7
- package/dist/tools/releases.js +26 -7
- package/dist/tools/repos.js +148 -17
- package/dist/tools/search.js +85 -80
- package/dist/tools/workitems.js +105 -89
- package/dist/utils.js +26 -0
- package/dist/version.js +1 -1
- package/package.json +6 -5
package/dist/tools/workitems.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
// Copyright (c) Microsoft Corporation.
|
|
2
2
|
// Licensed under the MIT License.
|
|
3
|
+
import { QueryExpand } from "azure-devops-node-api/interfaces/WorkItemTrackingInterfaces.js";
|
|
3
4
|
import { z } from "zod";
|
|
4
|
-
import { batchApiVersion } from "../utils.js";
|
|
5
|
+
import { batchApiVersion, markdownCommentsApiVersion, getEnumKeys, safeEnumConvert } from "../utils.js";
|
|
5
6
|
const WORKITEM_TOOLS = {
|
|
6
7
|
my_work_items: "wit_my_work_items",
|
|
7
8
|
list_backlogs: "wit_list_backlogs",
|
|
@@ -19,7 +20,6 @@ const WORKITEM_TOOLS = {
|
|
|
19
20
|
get_query: "wit_get_query",
|
|
20
21
|
get_query_results_by_id: "wit_get_query_results_by_id",
|
|
21
22
|
update_work_items_batch: "wit_update_work_items_batch",
|
|
22
|
-
close_and_link_workitem_duplicates: "wit_close_and_link_workitem_duplicates",
|
|
23
23
|
work_items_link: "wit_work_items_link",
|
|
24
24
|
};
|
|
25
25
|
function getLinkTypeFromName(name) {
|
|
@@ -42,6 +42,10 @@ function getLinkTypeFromName(name) {
|
|
|
42
42
|
return "Microsoft.VSTS.Common.TestedBy-Forward";
|
|
43
43
|
case "tests":
|
|
44
44
|
return "Microsoft.VSTS.Common.TestedBy-Reverse";
|
|
45
|
+
case "affects":
|
|
46
|
+
return "Microsoft.VSTS.Common.Affects-Forward";
|
|
47
|
+
case "affected by":
|
|
48
|
+
return "Microsoft.VSTS.Common.Affects-Reverse";
|
|
45
49
|
default:
|
|
46
50
|
throw new Error(`Unknown link type: ${name}`);
|
|
47
51
|
}
|
|
@@ -131,13 +135,30 @@ function configureWorkItemTools(server, tokenProvider, connectionProvider, userA
|
|
|
131
135
|
project: z.string().describe("The name or ID of the Azure DevOps project."),
|
|
132
136
|
workItemId: z.number().describe("The ID of the work item to add a comment to."),
|
|
133
137
|
comment: z.string().describe("The text of the comment to add to the work item."),
|
|
134
|
-
|
|
138
|
+
format: z.enum(["markdown", "html"]).optional().default("html"),
|
|
139
|
+
}, async ({ project, workItemId, comment, format }) => {
|
|
135
140
|
const connection = await connectionProvider();
|
|
136
|
-
const
|
|
137
|
-
const
|
|
138
|
-
const
|
|
141
|
+
const orgUrl = connection.serverUrl;
|
|
142
|
+
const accessToken = await tokenProvider();
|
|
143
|
+
const body = {
|
|
144
|
+
text: comment,
|
|
145
|
+
};
|
|
146
|
+
const formatParameter = format === "markdown" ? 0 : 1;
|
|
147
|
+
const response = await fetch(`${orgUrl}/${project}/_apis/wit/workItems/${workItemId}/comments?format=${formatParameter}&api-version=${markdownCommentsApiVersion}`, {
|
|
148
|
+
method: "POST",
|
|
149
|
+
headers: {
|
|
150
|
+
"Authorization": `Bearer ${accessToken.token}`,
|
|
151
|
+
"Content-Type": "application/json",
|
|
152
|
+
"User-Agent": userAgentProvider(),
|
|
153
|
+
},
|
|
154
|
+
body: JSON.stringify(body),
|
|
155
|
+
});
|
|
156
|
+
if (!response.ok) {
|
|
157
|
+
throw new Error(`Failed to add a work item comment: ${response.statusText}}`);
|
|
158
|
+
}
|
|
159
|
+
const comments = await response.text();
|
|
139
160
|
return {
|
|
140
|
-
content: [{ type: "text", text:
|
|
161
|
+
content: [{ type: "text", text: comments }],
|
|
141
162
|
};
|
|
142
163
|
});
|
|
143
164
|
server.tool(WORKITEM_TOOLS.add_child_work_items, "Create one or many child work items from a parent by work item type and parent id.", {
|
|
@@ -200,6 +221,13 @@ function configureWorkItemTools(server, tokenProvider, connectionProvider, userA
|
|
|
200
221
|
value: item.areaPath,
|
|
201
222
|
});
|
|
202
223
|
}
|
|
224
|
+
if (item.iterationPath && item.iterationPath.trim().length > 0) {
|
|
225
|
+
ops.push({
|
|
226
|
+
op: "add",
|
|
227
|
+
path: "/fields/System.IterationPath",
|
|
228
|
+
value: item.iterationPath,
|
|
229
|
+
});
|
|
230
|
+
}
|
|
203
231
|
if (item.format && item.format === "Markdown") {
|
|
204
232
|
ops.push({
|
|
205
233
|
op: "add",
|
|
@@ -212,13 +240,6 @@ function configureWorkItemTools(server, tokenProvider, connectionProvider, userA
|
|
|
212
240
|
value: item.format,
|
|
213
241
|
});
|
|
214
242
|
}
|
|
215
|
-
if (item.iterationPath && item.iterationPath.trim().length > 0) {
|
|
216
|
-
ops.push({
|
|
217
|
-
op: "add",
|
|
218
|
-
path: "/fields/System.IterationPath",
|
|
219
|
-
value: item.iterationPath,
|
|
220
|
-
});
|
|
221
|
-
}
|
|
222
243
|
return {
|
|
223
244
|
method: "PATCH",
|
|
224
245
|
uri: `/${project}/_apis/wit/workitems/$${workItemType}?api-version=${batchApiVersion}`,
|
|
@@ -254,17 +275,17 @@ function configureWorkItemTools(server, tokenProvider, connectionProvider, userA
|
|
|
254
275
|
}
|
|
255
276
|
});
|
|
256
277
|
server.tool(WORKITEM_TOOLS.link_work_item_to_pull_request, "Link a single work item to an existing pull request.", {
|
|
257
|
-
|
|
278
|
+
projectId: z.string().describe("The project ID of the Azure DevOps project (note: project name is not valid)."),
|
|
258
279
|
repositoryId: z.string().describe("The ID of the repository containing the pull request. Do not use the repository name here, use the ID instead."),
|
|
259
280
|
pullRequestId: z.number().describe("The ID of the pull request to link to."),
|
|
260
281
|
workItemId: z.number().describe("The ID of the work item to link to the pull request."),
|
|
261
|
-
}, async ({
|
|
282
|
+
}, async ({ projectId, repositoryId, pullRequestId, workItemId }) => {
|
|
262
283
|
try {
|
|
263
284
|
const connection = await connectionProvider();
|
|
264
285
|
const workItemTrackingApi = await connection.getWorkItemTrackingApi();
|
|
265
286
|
// Create artifact link relation using vstfs format
|
|
266
287
|
// Format: vstfs:///Git/PullRequestId/{project}/{repositoryId}/{pullRequestId}
|
|
267
|
-
const artifactPathValue = `${
|
|
288
|
+
const artifactPathValue = `${projectId}/${repositoryId}/${pullRequestId}`;
|
|
268
289
|
const vstfsUrl = `vstfs:///Git/PullRequestId/${encodeURIComponent(artifactPathValue)}`;
|
|
269
290
|
// Use the PATCH document format for adding a relation
|
|
270
291
|
const patchDocument = [
|
|
@@ -281,7 +302,7 @@ function configureWorkItemTools(server, tokenProvider, connectionProvider, userA
|
|
|
281
302
|
},
|
|
282
303
|
];
|
|
283
304
|
// Use the WorkItem API to update the work item with the new relation
|
|
284
|
-
const workItem = await workItemTrackingApi.updateWorkItem({}, patchDocument, workItemId,
|
|
305
|
+
const workItem = await workItemTrackingApi.updateWorkItem({}, patchDocument, workItemId, projectId);
|
|
285
306
|
if (!workItem) {
|
|
286
307
|
return { content: [{ type: "text", text: "Work item update failed" }], isError: true };
|
|
287
308
|
}
|
|
@@ -323,15 +344,25 @@ function configureWorkItemTools(server, tokenProvider, connectionProvider, userA
|
|
|
323
344
|
id: z.number().describe("The ID of the work item to update."),
|
|
324
345
|
updates: z
|
|
325
346
|
.array(z.object({
|
|
326
|
-
op: z
|
|
347
|
+
op: z
|
|
348
|
+
.string()
|
|
349
|
+
.transform((val) => val.toLowerCase())
|
|
350
|
+
.pipe(z.enum(["add", "replace", "remove"]))
|
|
351
|
+
.default("add")
|
|
352
|
+
.describe("The operation to perform on the field."),
|
|
327
353
|
path: z.string().describe("The path of the field to update, e.g., '/fields/System.Title'."),
|
|
328
|
-
value: z.string().describe("The new value for the field. This is required for '
|
|
354
|
+
value: z.string().describe("The new value for the field. This is required for 'Add' and 'Replace' operations, and should be omitted for 'Remove' operations."),
|
|
329
355
|
}))
|
|
330
356
|
.describe("An array of field updates to apply to the work item."),
|
|
331
357
|
}, async ({ id, updates }) => {
|
|
332
358
|
const connection = await connectionProvider();
|
|
333
359
|
const workItemApi = await connection.getWorkItemTrackingApi();
|
|
334
|
-
|
|
360
|
+
// Convert operation names to lowercase for API
|
|
361
|
+
const apiUpdates = updates.map((update) => ({
|
|
362
|
+
...update,
|
|
363
|
+
op: update.op,
|
|
364
|
+
}));
|
|
365
|
+
const updatedWorkItem = await workItemApi.updateWorkItem(null, apiUpdates, id);
|
|
335
366
|
return {
|
|
336
367
|
content: [{ type: "text", text: JSON.stringify(updatedWorkItem, null, 2) }],
|
|
337
368
|
};
|
|
@@ -351,17 +382,33 @@ function configureWorkItemTools(server, tokenProvider, connectionProvider, userA
|
|
|
351
382
|
project: z.string().describe("The name or ID of the Azure DevOps project."),
|
|
352
383
|
workItemType: z.string().describe("The type of work item to create, e.g., 'Task', 'Bug', etc."),
|
|
353
384
|
fields: z
|
|
354
|
-
.
|
|
355
|
-
.describe("
|
|
385
|
+
.array(z.object({
|
|
386
|
+
name: z.string().describe("The name of the field, e.g., 'System.Title'."),
|
|
387
|
+
value: z.string().describe("The value of the field."),
|
|
388
|
+
format: z.enum(["Html", "Markdown"]).optional().describe("the format of the field value, e.g., 'Html', 'Markdown'. Optional, defaults to 'Html'."),
|
|
389
|
+
}))
|
|
390
|
+
.describe("A record of field names and values to set on the new work item. Each fild is the field name and each value is the corresponding value to set for that field."),
|
|
356
391
|
}, async ({ project, workItemType, fields }) => {
|
|
357
392
|
try {
|
|
358
393
|
const connection = await connectionProvider();
|
|
359
394
|
const workItemApi = await connection.getWorkItemTrackingApi();
|
|
360
|
-
const document =
|
|
395
|
+
const document = fields.map(({ name, value }) => ({
|
|
361
396
|
op: "add",
|
|
362
|
-
path: `/fields/${
|
|
363
|
-
value,
|
|
397
|
+
path: `/fields/${name}`,
|
|
398
|
+
value: value,
|
|
364
399
|
}));
|
|
400
|
+
// Check if any field has format === "Markdown" and add the multilineFieldsFormat operation
|
|
401
|
+
// this should only happen for large text fields, but since we dont't know by field name, lets assume if the users
|
|
402
|
+
// passes a value longer than 50 characters, then we can set the format to Markdown
|
|
403
|
+
fields.forEach(({ name, value, format }) => {
|
|
404
|
+
if (value.length > 50 && format === "Markdown") {
|
|
405
|
+
document.push({
|
|
406
|
+
op: "add",
|
|
407
|
+
path: `/multilineFieldsFormat/${name}`,
|
|
408
|
+
value: "Markdown",
|
|
409
|
+
});
|
|
410
|
+
}
|
|
411
|
+
});
|
|
365
412
|
const newWorkItem = await workItemApi.createWorkItem(null, document, project, workItemType);
|
|
366
413
|
if (!newWorkItem) {
|
|
367
414
|
return { content: [{ type: "text", text: "Work item was not created" }], isError: true };
|
|
@@ -381,14 +428,17 @@ function configureWorkItemTools(server, tokenProvider, connectionProvider, userA
|
|
|
381
428
|
server.tool(WORKITEM_TOOLS.get_query, "Get a query by its ID or path.", {
|
|
382
429
|
project: z.string().describe("The name or ID of the Azure DevOps project."),
|
|
383
430
|
query: z.string().describe("The ID or path of the query to retrieve."),
|
|
384
|
-
expand: z
|
|
431
|
+
expand: z
|
|
432
|
+
.enum(getEnumKeys(QueryExpand))
|
|
433
|
+
.optional()
|
|
434
|
+
.describe("Optional expand parameter to include additional details in the response. Defaults to 'None'."),
|
|
385
435
|
depth: z.number().default(0).describe("Optional depth parameter to specify how deep to expand the query. Defaults to 0."),
|
|
386
436
|
includeDeleted: z.boolean().default(false).describe("Whether to include deleted items in the query results. Defaults to false."),
|
|
387
437
|
useIsoDateFormat: z.boolean().default(false).describe("Whether to use ISO date format in the response. Defaults to false."),
|
|
388
438
|
}, async ({ project, query, expand, depth, includeDeleted, useIsoDateFormat }) => {
|
|
389
439
|
const connection = await connectionProvider();
|
|
390
440
|
const workItemApi = await connection.getWorkItemTrackingApi();
|
|
391
|
-
const queryDetails = await workItemApi.getQuery(project, query, expand, depth, includeDeleted, useIsoDateFormat);
|
|
441
|
+
const queryDetails = await workItemApi.getQuery(project, query, safeEnumConvert(QueryExpand, expand), depth, includeDeleted, useIsoDateFormat);
|
|
392
442
|
return {
|
|
393
443
|
content: [{ type: "text", text: JSON.stringify(queryDetails, null, 2) }],
|
|
394
444
|
};
|
|
@@ -411,10 +461,11 @@ function configureWorkItemTools(server, tokenProvider, connectionProvider, userA
|
|
|
411
461
|
server.tool(WORKITEM_TOOLS.update_work_items_batch, "Update work items in batch", {
|
|
412
462
|
updates: z
|
|
413
463
|
.array(z.object({
|
|
414
|
-
op: z.enum(["
|
|
464
|
+
op: z.enum(["Add", "Replace", "Remove"]).default("Add").describe("The operation to perform on the field."),
|
|
415
465
|
id: z.number().describe("The ID of the work item to update."),
|
|
416
466
|
path: z.string().describe("The path of the field to update, e.g., '/fields/System.Title'."),
|
|
417
467
|
value: z.string().describe("The new value for the field. This is required for 'add' and 'replace' operations, and should be omitted for 'remove' operations."),
|
|
468
|
+
format: z.enum(["Html", "Markdown"]).optional().describe("The format of the field value. Only to be used for large text fields. e.g., 'Html', 'Markdown'. Optional, defaults to 'Html'."),
|
|
418
469
|
}))
|
|
419
470
|
.describe("An array of updates to apply to work items. Each update should include the operation (op), work item ID (id), field path (path), and new value (value)."),
|
|
420
471
|
}, async ({ updates }) => {
|
|
@@ -423,20 +474,32 @@ function configureWorkItemTools(server, tokenProvider, connectionProvider, userA
|
|
|
423
474
|
const accessToken = await tokenProvider();
|
|
424
475
|
// Extract unique IDs from the updates array
|
|
425
476
|
const uniqueIds = Array.from(new Set(updates.map((update) => update.id)));
|
|
426
|
-
const body = uniqueIds.map((id) =>
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
headers: {
|
|
430
|
-
"Content-Type": "application/json-patch+json",
|
|
431
|
-
},
|
|
432
|
-
body: updates
|
|
433
|
-
.filter((update) => update.id === id)
|
|
434
|
-
.map(({ op, path, value }) => ({
|
|
477
|
+
const body = uniqueIds.map((id) => {
|
|
478
|
+
const workItemUpdates = updates.filter((update) => update.id === id);
|
|
479
|
+
const operations = workItemUpdates.map(({ op, path, value }) => ({
|
|
435
480
|
op: op,
|
|
436
481
|
path: path,
|
|
437
482
|
value: value,
|
|
438
|
-
}))
|
|
439
|
-
|
|
483
|
+
}));
|
|
484
|
+
// Add format operations for Markdown fields
|
|
485
|
+
workItemUpdates.forEach(({ path, value, format }) => {
|
|
486
|
+
if (format === "Markdown" && value && value.length > 50) {
|
|
487
|
+
operations.push({
|
|
488
|
+
op: "Add",
|
|
489
|
+
path: `/multilineFieldsFormat${path.replace("/fields", "")}`,
|
|
490
|
+
value: "Markdown",
|
|
491
|
+
});
|
|
492
|
+
}
|
|
493
|
+
});
|
|
494
|
+
return {
|
|
495
|
+
method: "PATCH",
|
|
496
|
+
uri: `/_apis/wit/workitems/${id}?api-version=${batchApiVersion}`,
|
|
497
|
+
headers: {
|
|
498
|
+
"Content-Type": "application/json-patch+json",
|
|
499
|
+
},
|
|
500
|
+
body: operations,
|
|
501
|
+
};
|
|
502
|
+
});
|
|
440
503
|
const response = await fetch(`${orgUrl}/_apis/wit/$batch?api-version=${batchApiVersion}`, {
|
|
441
504
|
method: "PATCH",
|
|
442
505
|
headers: {
|
|
@@ -461,9 +524,9 @@ function configureWorkItemTools(server, tokenProvider, connectionProvider, userA
|
|
|
461
524
|
id: z.number().describe("The ID of the work item to update."),
|
|
462
525
|
linkToId: z.number().describe("The ID of the work item to link to."),
|
|
463
526
|
type: z
|
|
464
|
-
.enum(["parent", "child", "duplicate", "duplicate of", "related", "successor", "predecessor", "tested by", "tests"])
|
|
527
|
+
.enum(["parent", "child", "duplicate", "duplicate of", "related", "successor", "predecessor", "tested by", "tests", "affects", "affected by"])
|
|
465
528
|
.default("related")
|
|
466
|
-
.describe("Type of link to create between the work items. Options include 'parent', 'child', 'duplicate', 'duplicate of', 'related', 'successor', 'predecessor', 'tested by', 'tests', '
|
|
529
|
+
.describe("Type of link to create between the work items. Options include 'parent', 'child', 'duplicate', 'duplicate of', 'related', 'successor', 'predecessor', 'tested by', 'tests', 'affects', and 'affected by'. Defaults to 'related'."),
|
|
467
530
|
comment: z.string().optional().describe("Optional comment to include with the link. This can be used to provide additional context for the link being created."),
|
|
468
531
|
}))
|
|
469
532
|
.describe(""),
|
|
@@ -510,52 +573,5 @@ function configureWorkItemTools(server, tokenProvider, connectionProvider, userA
|
|
|
510
573
|
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
511
574
|
};
|
|
512
575
|
});
|
|
513
|
-
server.tool(WORKITEM_TOOLS.close_and_link_workitem_duplicates, "Close duplicate work items by id.", {
|
|
514
|
-
id: z.number().describe("The ID of the work item to close and link duplicates to."),
|
|
515
|
-
duplicateIds: z.array(z.number()).describe("An array of IDs of the duplicate work items to close and link to the specified work item."),
|
|
516
|
-
project: z.string().describe("The name or ID of the Azure DevOps project."),
|
|
517
|
-
state: z.string().default("Removed").describe("The state to set for the duplicate work items. Defaults to 'Removed'."),
|
|
518
|
-
}, async ({ id, duplicateIds, project, state }) => {
|
|
519
|
-
const connection = await connectionProvider();
|
|
520
|
-
const body = duplicateIds.map((duplicateId) => ({
|
|
521
|
-
method: "PATCH",
|
|
522
|
-
uri: `/_apis/wit/workitems/${duplicateId}?api-version=${batchApiVersion}`,
|
|
523
|
-
headers: {
|
|
524
|
-
"Content-Type": "application/json-patch+json",
|
|
525
|
-
},
|
|
526
|
-
body: [
|
|
527
|
-
{
|
|
528
|
-
op: "add",
|
|
529
|
-
path: "/fields/System.State",
|
|
530
|
-
value: `${state}`,
|
|
531
|
-
},
|
|
532
|
-
{
|
|
533
|
-
op: "add",
|
|
534
|
-
path: "/relations/-",
|
|
535
|
-
value: {
|
|
536
|
-
rel: "System.LinkTypes.Duplicate-Reverse",
|
|
537
|
-
url: `${connection.serverUrl}/${project}/_apis/wit/workItems/${id}`,
|
|
538
|
-
},
|
|
539
|
-
},
|
|
540
|
-
],
|
|
541
|
-
}));
|
|
542
|
-
const accessToken = await tokenProvider();
|
|
543
|
-
const response = await fetch(`${connection.serverUrl}/_apis/wit/$batch?api-version=${batchApiVersion}`, {
|
|
544
|
-
method: "PATCH",
|
|
545
|
-
headers: {
|
|
546
|
-
"Authorization": `Bearer ${accessToken.token}`,
|
|
547
|
-
"Content-Type": "application/json",
|
|
548
|
-
"User-Agent": userAgentProvider(),
|
|
549
|
-
},
|
|
550
|
-
body: JSON.stringify(body),
|
|
551
|
-
});
|
|
552
|
-
if (!response.ok) {
|
|
553
|
-
throw new Error(`Failed to update work items in batch: ${response.statusText}`);
|
|
554
|
-
}
|
|
555
|
-
const result = await response.json();
|
|
556
|
-
return {
|
|
557
|
-
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
558
|
-
};
|
|
559
|
-
});
|
|
560
576
|
}
|
|
561
577
|
export { WORKITEM_TOOLS, configureWorkItemTools };
|
package/dist/utils.js
CHANGED
|
@@ -2,3 +2,29 @@
|
|
|
2
2
|
// Licensed under the MIT License.
|
|
3
3
|
export const apiVersion = "7.2-preview.1";
|
|
4
4
|
export const batchApiVersion = "5.0";
|
|
5
|
+
export const markdownCommentsApiVersion = "7.2-preview.4";
|
|
6
|
+
/**
|
|
7
|
+
* Converts a TypeScript numeric enum to an array of string keys for use with z.enum().
|
|
8
|
+
* This ensures that enum schemas generate string values rather than numeric values.
|
|
9
|
+
* @param enumObject The TypeScript enum object
|
|
10
|
+
* @returns Array of string keys from the enum
|
|
11
|
+
*/
|
|
12
|
+
export function getEnumKeys(enumObject) {
|
|
13
|
+
return Object.keys(enumObject).filter((key) => isNaN(Number(key)));
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Safely converts a string enum key to its corresponding enum value.
|
|
17
|
+
* Validates that the key exists in the enum before conversion.
|
|
18
|
+
* @param enumObject The TypeScript enum object
|
|
19
|
+
* @param key The string key to convert
|
|
20
|
+
* @returns The enum value if key is valid, undefined otherwise
|
|
21
|
+
*/
|
|
22
|
+
export function safeEnumConvert(enumObject, key) {
|
|
23
|
+
if (!key)
|
|
24
|
+
return undefined;
|
|
25
|
+
const validKeys = getEnumKeys(enumObject);
|
|
26
|
+
if (!validKeys.includes(key)) {
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
29
|
+
return enumObject[key];
|
|
30
|
+
}
|
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const packageVersion = "1.2.
|
|
1
|
+
export const packageVersion = "1.2.1";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@azure-devops/mcp",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.1",
|
|
4
4
|
"description": "MCP server for interacting with Azure DevOps",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Microsoft Corporation",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"build": "tsc && shx chmod +x dist/*.js",
|
|
27
27
|
"prepare": "npm run build",
|
|
28
28
|
"watch": "tsc --watch",
|
|
29
|
-
"inspect": "npx @modelcontextprotocol/inspector node dist/index.js",
|
|
29
|
+
"inspect": "ALLOWED_ORIGINS=http://127.0.0.1:6274 npx @modelcontextprotocol/inspector node dist/index.js",
|
|
30
30
|
"start": "node -r tsconfig-paths/register dist/index.js",
|
|
31
31
|
"eslint": "eslint",
|
|
32
32
|
"eslint-fix": "eslint --fix",
|
|
@@ -37,18 +37,19 @@
|
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"@azure/identity": "^4.10.0",
|
|
40
|
-
"@modelcontextprotocol/sdk": "1.
|
|
40
|
+
"@modelcontextprotocol/sdk": "1.16.0",
|
|
41
41
|
"azure-devops-extension-api": "^4.252.0",
|
|
42
42
|
"azure-devops-extension-sdk": "^4.0.2",
|
|
43
43
|
"azure-devops-node-api": "^15.1.0",
|
|
44
|
+
"yargs": "^18.0.0",
|
|
44
45
|
"zod": "^3.25.63",
|
|
45
46
|
"zod-to-json-schema": "^3.24.5"
|
|
46
47
|
},
|
|
47
48
|
"devDependencies": {
|
|
48
|
-
"@modelcontextprotocol/inspector": "^0.
|
|
49
|
+
"@modelcontextprotocol/inspector": "^0.16.1",
|
|
49
50
|
"@types/jest": "^30.0.0",
|
|
50
51
|
"@types/node": "^22",
|
|
51
|
-
"eslint-config-prettier": "10.1.
|
|
52
|
+
"eslint-config-prettier": "10.1.8",
|
|
52
53
|
"eslint-plugin-header": "^3.1.1",
|
|
53
54
|
"jest": "^30.0.2",
|
|
54
55
|
"jest-extended": "^6.0.0",
|