@azure-devops/mcp 1.3.1 → 2.0.0-nightly.20250825
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/LICENSE.md +21 -21
- package/README.md +39 -9
- package/dist/index.js +14 -3
- package/dist/prompts.js +6 -6
- package/dist/shared/domains.js +122 -0
- package/dist/tools/auth.js +44 -2
- package/dist/tools/builds.js +2 -1
- package/dist/tools/core.js +3 -22
- package/dist/tools/{repos.js → repositories.js} +57 -14
- package/dist/tools/{testplans.js → test-plans.js} +4 -1
- package/dist/tools/wiki.js +219 -11
- package/dist/tools/{workitems.js → work-items.js} +160 -10
- package/dist/tools.js +21 -15
- package/dist/useragent.js +0 -0
- package/dist/utils.js +0 -0
- package/dist/version.js +1 -1
- package/package.json +1 -1
- package/dist/tools/core.test.js +0 -1
- package/dist/tools/testplan.test.js +0 -125
- package/dist/tools/utils.js +0 -6
- package/dist/tools/wiki.test.js +0 -87
- package/dist/tools/workitem.test.js +0 -101
- package/dist/tools/workitems.test.js +0 -530
- /package/dist/tools/{advsec.js → advanced-security.js} +0 -0
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
// Copyright (c) Microsoft Corporation.
|
|
2
|
-
// Licensed under the MIT License.
|
|
3
|
-
import { describe, expect, it } from '@jest/globals';
|
|
4
|
-
import { configureTestPlanTools } from '../../../src/tools/testplans';
|
|
5
|
-
describe("configureTestPlanTools", () => {
|
|
6
|
-
let server;
|
|
7
|
-
let tokenProvider;
|
|
8
|
-
let connectionProvider;
|
|
9
|
-
let mockConnection;
|
|
10
|
-
let mockTestPlanApi;
|
|
11
|
-
let mockTestResultsApi;
|
|
12
|
-
beforeEach(() => {
|
|
13
|
-
server = { tool: jest.fn() };
|
|
14
|
-
tokenProvider = jest.fn();
|
|
15
|
-
mockTestPlanApi = {
|
|
16
|
-
getTestPlans: jest.fn(),
|
|
17
|
-
createTestPlan: jest.fn(),
|
|
18
|
-
addTestCasesToSuite: jest.fn(),
|
|
19
|
-
getTestCaseList: jest.fn(),
|
|
20
|
-
};
|
|
21
|
-
mockTestResultsApi = {
|
|
22
|
-
getTestResultDetailsForBuild: jest.fn(),
|
|
23
|
-
};
|
|
24
|
-
mockConnection = {
|
|
25
|
-
getTestPlanApi: jest.fn().mockResolvedValue(mockTestPlanApi),
|
|
26
|
-
getTestResultsApi: jest.fn().mockResolvedValue(mockTestResultsApi),
|
|
27
|
-
};
|
|
28
|
-
connectionProvider = jest.fn().mockResolvedValue(mockConnection);
|
|
29
|
-
});
|
|
30
|
-
describe("tool registration", () => {
|
|
31
|
-
it("registers test plan tools on the server", () => {
|
|
32
|
-
configureTestPlanTools(server, tokenProvider, connectionProvider);
|
|
33
|
-
expect(server.tool.mock.calls.map(call => call[0])).toEqual(expect.arrayContaining([
|
|
34
|
-
"ado_list_test_plans",
|
|
35
|
-
"ado_create_test_plan",
|
|
36
|
-
"ado_add_test_cases_to_suite",
|
|
37
|
-
"ado_list_test_cases",
|
|
38
|
-
"ado_show_test_results_from_build_id",
|
|
39
|
-
]));
|
|
40
|
-
});
|
|
41
|
-
});
|
|
42
|
-
describe("list_test_plans tool", () => {
|
|
43
|
-
it("should call getTestPlans with the correct parameters and return the expected result", async () => {
|
|
44
|
-
configureTestPlanTools(server, tokenProvider, connectionProvider);
|
|
45
|
-
const call = server.tool.mock.calls.find(([toolName]) => toolName === "ado_list_test_plans");
|
|
46
|
-
if (!call)
|
|
47
|
-
throw new Error("ado_list_test_plans tool not registered");
|
|
48
|
-
const [, , , handler] = call;
|
|
49
|
-
mockTestPlanApi.getTestPlans.mockResolvedValue([{ id: 1, name: "Test Plan 1" }]);
|
|
50
|
-
const params = {
|
|
51
|
-
project: "proj1",
|
|
52
|
-
filterActivePlans: true,
|
|
53
|
-
includePlanDetails: false,
|
|
54
|
-
continuationToken: undefined,
|
|
55
|
-
};
|
|
56
|
-
const result = await handler(params);
|
|
57
|
-
expect(mockTestPlanApi.getTestPlans).toHaveBeenCalledWith("proj1", "", undefined, false, true);
|
|
58
|
-
expect(result.content[0].text).toBe(JSON.stringify([{ id: 1, name: "Test Plan 1" }], null, 2));
|
|
59
|
-
});
|
|
60
|
-
});
|
|
61
|
-
describe("create_test_plan tool", () => {
|
|
62
|
-
it("should call createTestPlan with the correct parameters and return the expected result", async () => {
|
|
63
|
-
configureTestPlanTools(server, tokenProvider, connectionProvider);
|
|
64
|
-
const call = server.tool.mock.calls.find(([toolName]) => toolName === "ado_create_test_plan");
|
|
65
|
-
if (!call)
|
|
66
|
-
throw new Error("ado_create_test_plan tool not registered");
|
|
67
|
-
const [, , , handler] = call;
|
|
68
|
-
mockTestPlanApi.createTestPlan.mockResolvedValue({ id: 1, name: "New Test Plan" });
|
|
69
|
-
const params = {
|
|
70
|
-
project: "proj1",
|
|
71
|
-
name: "New Test Plan",
|
|
72
|
-
iteration: "Iteration 1",
|
|
73
|
-
description: "Description",
|
|
74
|
-
startDate: "2025-05-01",
|
|
75
|
-
endDate: "2025-05-31",
|
|
76
|
-
areaPath: "Area 1",
|
|
77
|
-
};
|
|
78
|
-
const result = await handler(params);
|
|
79
|
-
expect(mockTestPlanApi.createTestPlan).toHaveBeenCalledWith({
|
|
80
|
-
name: "New Test Plan",
|
|
81
|
-
iteration: "Iteration 1",
|
|
82
|
-
description: "Description",
|
|
83
|
-
startDate: new Date("2025-05-01"),
|
|
84
|
-
endDate: new Date("2025-05-31"),
|
|
85
|
-
areaPath: "Area 1",
|
|
86
|
-
}, "proj1");
|
|
87
|
-
expect(result.content[0].text).toBe(JSON.stringify({ id: 1, name: "New Test Plan" }, null, 2));
|
|
88
|
-
});
|
|
89
|
-
});
|
|
90
|
-
describe("list_test_cases tool", () => {
|
|
91
|
-
it("should call getTestCaseList with the correct parameters and return the expected result", async () => {
|
|
92
|
-
configureTestPlanTools(server, tokenProvider, connectionProvider);
|
|
93
|
-
const call = server.tool.mock.calls.find(([toolName]) => toolName === "ado_list_test_cases");
|
|
94
|
-
if (!call)
|
|
95
|
-
throw new Error("ado_list_test_cases tool not registered");
|
|
96
|
-
const [, , , handler] = call;
|
|
97
|
-
mockTestPlanApi.getTestCaseList.mockResolvedValue([{ id: 1, name: "Test Case 1" }]);
|
|
98
|
-
const params = {
|
|
99
|
-
project: "proj1",
|
|
100
|
-
planid: 1,
|
|
101
|
-
suiteid: 2,
|
|
102
|
-
};
|
|
103
|
-
const result = await handler(params);
|
|
104
|
-
expect(mockTestPlanApi.getTestCaseList).toHaveBeenCalledWith("proj1", 1, 2);
|
|
105
|
-
expect(result.content[0].text).toBe(JSON.stringify([{ id: 1, name: "Test Case 1" }], null, 2));
|
|
106
|
-
});
|
|
107
|
-
});
|
|
108
|
-
describe("test_results_from_build_id tool", () => {
|
|
109
|
-
it("should call getTestResultDetailsForBuild with the correct parameters and return the expected result", async () => {
|
|
110
|
-
configureTestPlanTools(server, tokenProvider, connectionProvider);
|
|
111
|
-
const call = server.tool.mock.calls.find(([toolName]) => toolName === "ado_show_test_results_from_build_id");
|
|
112
|
-
if (!call)
|
|
113
|
-
throw new Error("ado_show_test_results_from_build_id tool not registered");
|
|
114
|
-
const [, , , handler] = call;
|
|
115
|
-
mockTestResultsApi.getTestResultDetailsForBuild.mockResolvedValue({ results: ["Result 1"] });
|
|
116
|
-
const params = {
|
|
117
|
-
project: "proj1",
|
|
118
|
-
buildid: 123,
|
|
119
|
-
};
|
|
120
|
-
const result = await handler(params);
|
|
121
|
-
expect(mockTestResultsApi.getTestResultDetailsForBuild).toHaveBeenCalledWith("proj1", 123);
|
|
122
|
-
expect(result.content[0].text).toBe(JSON.stringify({ results: ["Result 1"] }, null, 2));
|
|
123
|
-
});
|
|
124
|
-
});
|
|
125
|
-
});
|
package/dist/tools/utils.js
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
// Copyright (c) Microsoft Corporation.
|
|
2
|
-
// Licensed under the MIT License.
|
|
3
|
-
import { packageVersion } from "./version.js";
|
|
4
|
-
export const apiVersion = "7.2-preview.1";
|
|
5
|
-
export const batchApiVersion = "5.0";
|
|
6
|
-
export const userAgent = `AzureDevOps.MCP/${packageVersion} (local)`;
|
package/dist/tools/wiki.test.js
DELETED
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
// Copyright (c) Microsoft Corporation.
|
|
2
|
-
// Licensed under the MIT License.
|
|
3
|
-
import { describe, expect, it } from '@jest/globals';
|
|
4
|
-
import { configureWikiTools } from '../../../src/tools/wiki';
|
|
5
|
-
describe("configureWikiTools", () => {
|
|
6
|
-
let server;
|
|
7
|
-
let tokenProvider;
|
|
8
|
-
let connectionProvider;
|
|
9
|
-
let mockConnection;
|
|
10
|
-
let mockWikiApi;
|
|
11
|
-
beforeEach(() => {
|
|
12
|
-
server = { tool: jest.fn() };
|
|
13
|
-
tokenProvider = jest.fn();
|
|
14
|
-
mockWikiApi = {
|
|
15
|
-
getWiki: jest.fn(),
|
|
16
|
-
getAllWikis: jest.fn(),
|
|
17
|
-
getPagesBatch: jest.fn(),
|
|
18
|
-
getPageText: jest.fn(),
|
|
19
|
-
};
|
|
20
|
-
mockConnection = {
|
|
21
|
-
getWikiApi: jest.fn().mockResolvedValue(mockWikiApi),
|
|
22
|
-
};
|
|
23
|
-
connectionProvider = jest.fn().mockResolvedValue(mockConnection);
|
|
24
|
-
});
|
|
25
|
-
describe("tool registration", () => {
|
|
26
|
-
it("registers wiki tools on the server", () => {
|
|
27
|
-
configureWikiTools(server, tokenProvider, connectionProvider);
|
|
28
|
-
expect(server.tool).toHaveBeenCalled();
|
|
29
|
-
});
|
|
30
|
-
});
|
|
31
|
-
describe("get_wiki_page_content tool", () => {
|
|
32
|
-
it("should call getPageText with the correct parameters and return the expected result", async () => {
|
|
33
|
-
configureWikiTools(server, tokenProvider, connectionProvider);
|
|
34
|
-
const call = server.tool.mock.calls.find(([toolName]) => toolName === "ado_get_wiki_page_content");
|
|
35
|
-
if (!call)
|
|
36
|
-
throw new Error("ado_get_wiki_page_content tool not registered");
|
|
37
|
-
const [, , , handler] = call;
|
|
38
|
-
// Mock a stream-like object for getPageText
|
|
39
|
-
const mockStream = {
|
|
40
|
-
setEncoding: jest.fn(),
|
|
41
|
-
on: function (event, cb) {
|
|
42
|
-
if (event === "data") {
|
|
43
|
-
setImmediate(() => cb("mock page text"));
|
|
44
|
-
}
|
|
45
|
-
if (event === "end") {
|
|
46
|
-
setImmediate(() => cb());
|
|
47
|
-
}
|
|
48
|
-
return this;
|
|
49
|
-
}
|
|
50
|
-
};
|
|
51
|
-
mockWikiApi.getPageText.mockResolvedValue(mockStream);
|
|
52
|
-
const params = {
|
|
53
|
-
wikiIdentifier: "wiki1",
|
|
54
|
-
project: "proj1",
|
|
55
|
-
path: "/page1"
|
|
56
|
-
};
|
|
57
|
-
const result = await handler(params);
|
|
58
|
-
expect(mockWikiApi.getPageText).toHaveBeenCalledWith("proj1", "wiki1", "/page1", undefined, undefined, true);
|
|
59
|
-
expect(result.content[0].text).toBe("\"mock page text\"");
|
|
60
|
-
});
|
|
61
|
-
});
|
|
62
|
-
describe("list_wiki_pages tool", () => {
|
|
63
|
-
it("should call getPagesBatch with the correct parameters and return the expected result", async () => {
|
|
64
|
-
configureWikiTools(server, tokenProvider, connectionProvider);
|
|
65
|
-
const call = server.tool.mock.calls.find(([toolName]) => toolName === "ado_list_wiki_pages");
|
|
66
|
-
if (!call)
|
|
67
|
-
throw new Error("ado_list_wiki_pages tool not registered");
|
|
68
|
-
const [, , , handler] = call;
|
|
69
|
-
mockWikiApi.getPagesBatch.mockResolvedValue({ value: ["page1", "page2"] });
|
|
70
|
-
const params = {
|
|
71
|
-
wikiIdentifier: "wiki2",
|
|
72
|
-
project: "proj2",
|
|
73
|
-
top: 10,
|
|
74
|
-
continuationToken: "token123",
|
|
75
|
-
pageViewsForDays: 7
|
|
76
|
-
};
|
|
77
|
-
const result = await handler(params);
|
|
78
|
-
const parsedResult = JSON.parse(result.content[0].text);
|
|
79
|
-
expect(mockWikiApi.getPagesBatch).toHaveBeenCalledWith({
|
|
80
|
-
top: 10,
|
|
81
|
-
continuationToken: "token123",
|
|
82
|
-
pageViewsForDays: 7
|
|
83
|
-
}, "proj2", "wiki2");
|
|
84
|
-
expect(parsedResult.value).toEqual(["page1", "page2"]);
|
|
85
|
-
});
|
|
86
|
-
});
|
|
87
|
-
});
|
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from "@jest/globals";
|
|
2
|
-
import { configureWorkItemTools } from "../../../src/tools/workitems";
|
|
3
|
-
describe("configureWorkItemTools", () => {
|
|
4
|
-
let server;
|
|
5
|
-
let tokenProvider;
|
|
6
|
-
let connectionProvider;
|
|
7
|
-
let mockConnection;
|
|
8
|
-
let mockWorkApi;
|
|
9
|
-
let mockWorkItemTrackingApi;
|
|
10
|
-
beforeEach(() => {
|
|
11
|
-
server = { tool: jest.fn() };
|
|
12
|
-
tokenProvider = jest.fn();
|
|
13
|
-
mockWorkApi = {
|
|
14
|
-
getBacklogs: jest.fn(),
|
|
15
|
-
getPredefinedQueryResults: jest.fn(),
|
|
16
|
-
getTeamIterations: jest.fn(),
|
|
17
|
-
getIterationWorkItems: jest.fn(),
|
|
18
|
-
};
|
|
19
|
-
mockWorkItemTrackingApi = {
|
|
20
|
-
getWorkItemsBatch: jest.fn(),
|
|
21
|
-
getWorkItem: jest.fn(),
|
|
22
|
-
getComments: jest.fn(),
|
|
23
|
-
addComment: jest.fn(),
|
|
24
|
-
updateWorkItem: jest.fn(),
|
|
25
|
-
createWorkItem: jest.fn(),
|
|
26
|
-
getWorkItemType: jest.fn(),
|
|
27
|
-
getQuery: jest.fn(),
|
|
28
|
-
queryById: jest.fn(),
|
|
29
|
-
};
|
|
30
|
-
mockConnection = {
|
|
31
|
-
getWorkApi: jest.fn().mockResolvedValue(mockWorkApi),
|
|
32
|
-
getWorkItemTrackingApi: jest.fn().mockResolvedValue(mockWorkItemTrackingApi),
|
|
33
|
-
};
|
|
34
|
-
connectionProvider = jest.fn().mockResolvedValue(mockConnection);
|
|
35
|
-
});
|
|
36
|
-
describe("tool registration", () => {
|
|
37
|
-
it("registers core tools on the server", () => {
|
|
38
|
-
configureWorkItemTools(server, tokenProvider, connectionProvider);
|
|
39
|
-
expect(server.tool).toHaveBeenCalled();
|
|
40
|
-
});
|
|
41
|
-
});
|
|
42
|
-
describe("list_backlogs tool", () => {
|
|
43
|
-
it("should call getBacklogs API with the correct parameters and return the expected result", async () => {
|
|
44
|
-
configureWorkItemTools(server, tokenProvider, connectionProvider);
|
|
45
|
-
const call = server.tool.mock.calls.find(([toolName]) => toolName === "ado_list_backlogs");
|
|
46
|
-
if (!call)
|
|
47
|
-
throw new Error("ado_list_backlogs tool not registered");
|
|
48
|
-
const [, , , handler] = call;
|
|
49
|
-
mockWorkApi.getBacklogs.mockResolvedValue([
|
|
50
|
-
{
|
|
51
|
-
id: "eb6e4656-77fc-42a1-9181-4c6d8e9da5d1",
|
|
52
|
-
name: "Fabrikam-Fiber-TFVC",
|
|
53
|
-
description: "Team Foundation Version Control projects.",
|
|
54
|
-
url: "https://dev.azure.com/fabrikam/_apis/projects/eb6e4656-77fc-42a1-9181-4c6d8e9da5d1",
|
|
55
|
-
state: "wellFormed",
|
|
56
|
-
},
|
|
57
|
-
{
|
|
58
|
-
id: "6ce954b1-ce1f-45d1-b94d-e6bf2464ba2c",
|
|
59
|
-
name: "Fabrikam-Fiber-Git",
|
|
60
|
-
description: "Git projects",
|
|
61
|
-
url: "https://dev.azure.com/fabrikam/_apis/projects/6ce954b1-ce1f-45d1-b94d-e6bf2464ba2c",
|
|
62
|
-
state: "wellFormed",
|
|
63
|
-
},
|
|
64
|
-
{
|
|
65
|
-
id: "281f9a5b-af0d-49b4-a1df-fe6f5e5f84d0",
|
|
66
|
-
name: "TestGit",
|
|
67
|
-
url: "https://dev.azure.com/fabrikam/_apis/projects/281f9a5b-af0d-49b4-a1df-fe6f5e5f84d0",
|
|
68
|
-
state: "wellFormed",
|
|
69
|
-
},
|
|
70
|
-
]);
|
|
71
|
-
const params = {
|
|
72
|
-
project: "Contoso",
|
|
73
|
-
team: "Fabrikam",
|
|
74
|
-
};
|
|
75
|
-
const result = await handler(params);
|
|
76
|
-
expect(mockWorkApi.getBacklogs).toHaveBeenCalledWith({ project: "Contoso", team: "Fabrikam" });
|
|
77
|
-
expect(result.content[0].text).toBe(JSON.stringify([
|
|
78
|
-
{
|
|
79
|
-
id: "eb6e4656-77fc-42a1-9181-4c6d8e9da5d1",
|
|
80
|
-
name: "Fabrikam-Fiber-TFVC",
|
|
81
|
-
description: "Team Foundation Version Control projects.",
|
|
82
|
-
url: "https://dev.azure.com/fabrikam/_apis/projects/eb6e4656-77fc-42a1-9181-4c6d8e9da5d1",
|
|
83
|
-
state: "wellFormed",
|
|
84
|
-
},
|
|
85
|
-
{
|
|
86
|
-
id: "6ce954b1-ce1f-45d1-b94d-e6bf2464ba2c",
|
|
87
|
-
name: "Fabrikam-Fiber-Git",
|
|
88
|
-
description: "Git projects",
|
|
89
|
-
url: "https://dev.azure.com/fabrikam/_apis/projects/6ce954b1-ce1f-45d1-b94d-e6bf2464ba2c",
|
|
90
|
-
state: "wellFormed",
|
|
91
|
-
},
|
|
92
|
-
{
|
|
93
|
-
id: "281f9a5b-af0d-49b4-a1df-fe6f5e5f84d0",
|
|
94
|
-
name: "TestGit",
|
|
95
|
-
url: "https://dev.azure.com/fabrikam/_apis/projects/281f9a5b-af0d-49b4-a1df-fe6f5e5f84d0",
|
|
96
|
-
state: "wellFormed",
|
|
97
|
-
},
|
|
98
|
-
], null, 2));
|
|
99
|
-
});
|
|
100
|
-
});
|
|
101
|
-
});
|