@azure-devops/mcp 2.10.0-nightly.20260923 → 2.10.0-nightly.20260924
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.
|
@@ -32,6 +32,7 @@ const TOOL_ANNOTATIONS = {
|
|
|
32
32
|
repo_branch: READ_ONLY_ANNOTATIONS,
|
|
33
33
|
repo_create_branch: ADDITIVE_ANNOTATIONS,
|
|
34
34
|
repo_file: READ_ONLY_ANNOTATIONS,
|
|
35
|
+
repo_file_write: MUTATING_ANNOTATIONS,
|
|
35
36
|
repo_pull_request: READ_ONLY_ANNOTATIONS,
|
|
36
37
|
repo_pull_request_org: READ_ONLY_ANNOTATIONS,
|
|
37
38
|
repo_pull_request_thread: READ_ONLY_ANNOTATIONS,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Copyright (c) Microsoft Corporation.
|
|
2
2
|
// Licensed under the MIT License.
|
|
3
|
-
import { PullRequestStatus, GitVersionType, GitPullRequestQueryType, CommentThreadStatus, GitPullRequestMergeStrategy, VersionControlRecursionType, } from "azure-devops-node-api/interfaces/GitInterfaces.js";
|
|
3
|
+
import { PullRequestStatus, GitVersionType, GitPullRequestQueryType, CommentThreadStatus, GitPullRequestMergeStrategy, ItemContentType, VersionControlChangeType, VersionControlRecursionType, } from "azure-devops-node-api/interfaces/GitInterfaces.js";
|
|
4
4
|
import { z } from "zod";
|
|
5
5
|
import { getCurrentUserDetails, getUserIdFromEmail } from "./auth.js";
|
|
6
6
|
import { extractAdoStreamError, getEnumKeys, streamToString, apiVersion } from "../utils.js";
|
|
@@ -13,6 +13,7 @@ const REPO_TOOLS = {
|
|
|
13
13
|
repo_pull_request_thread: "repo_pull_request_thread",
|
|
14
14
|
repo_branch: "repo_branch",
|
|
15
15
|
repo_file: "repo_file",
|
|
16
|
+
repo_file_write: "repo_file_write",
|
|
16
17
|
repo_search_commits: "repo_search_commits",
|
|
17
18
|
repo_pull_request_write: "repo_pull_request_write",
|
|
18
19
|
repo_pull_request_thread_write: "repo_pull_request_thread_write",
|
|
@@ -199,9 +200,13 @@ function configureRepoTools(server, tokenProvider, connectionProvider, userAgent
|
|
|
199
200
|
project: z.string().optional().describe("Project ID or project name. Required for list_by_commits. Optional for get and list."),
|
|
200
201
|
includeWorkItemRefs: z.boolean().optional().default(false).describe("Whether to include work item references. Used for get."),
|
|
201
202
|
includeLabels: z.boolean().optional().default(false).describe("Whether to include labels. Used for get."),
|
|
202
|
-
includeChangedFiles: z
|
|
203
|
-
|
|
204
|
-
|
|
203
|
+
includeChangedFiles: z
|
|
204
|
+
.boolean()
|
|
205
|
+
.optional()
|
|
206
|
+
.default(false)
|
|
207
|
+
.describe("Whether to include the list of changed files. When changedFilesSummary returns a nextSkip greater than 0, pass nextSkip and nextTop back as skip and top for the next page. Used for get."),
|
|
208
|
+
top: z.coerce.number().default(100).describe("The maximum number of pull requests to return (list), or of changed files to return (get with includeChangedFiles). Defaults to 100."),
|
|
209
|
+
skip: z.coerce.number().default(0).describe("The number of pull requests to skip (list), or of changed files to skip (get with includeChangedFiles). Defaults to 0."),
|
|
205
210
|
created_by_me: z.boolean().default(false).describe("Filter pull requests created by the current user. Used for list."),
|
|
206
211
|
created_by_user: z.string().optional().describe("Filter pull requests created by a specific user email. Used for list."),
|
|
207
212
|
i_am_reviewer: z.boolean().default(false).describe("Filter pull requests where the current user is a reviewer. Used for list."),
|
|
@@ -249,7 +254,7 @@ function configureRepoTools(server, tokenProvider, connectionProvider, userAgent
|
|
|
249
254
|
if (iterations?.length) {
|
|
250
255
|
const latestIteration = iterations[iterations.length - 1];
|
|
251
256
|
if (latestIteration.id != null) {
|
|
252
|
-
const changes = await gitApi.getPullRequestIterationChanges(repositoryId, pullRequestId, latestIteration.id, project);
|
|
257
|
+
const changes = await gitApi.getPullRequestIterationChanges(repositoryId, pullRequestId, latestIteration.id, project, top, skip);
|
|
253
258
|
enhancedResponse = {
|
|
254
259
|
...enhancedResponse,
|
|
255
260
|
changedFilesSummary: {
|
|
@@ -567,6 +572,63 @@ function configureRepoTools(server, tokenProvider, connectionProvider, userAgent
|
|
|
567
572
|
return { content: [{ type: "text", text: `Error with file operation: ${errorMessage}` }], isError: true };
|
|
568
573
|
}
|
|
569
574
|
});
|
|
575
|
+
// --- repo_file_write -------------------------------------------------------
|
|
576
|
+
server.tool(REPO_TOOLS.repo_file_write, "Create or update a text file in an existing repository branch and commit the change.", {
|
|
577
|
+
action: z.enum(["create", "update"]).describe("Whether to create a new file or update an existing file."),
|
|
578
|
+
repositoryId: z.string().describe("The ID or name of the repository."),
|
|
579
|
+
project: z.string().optional().describe("Project ID or project name. Required when repositoryId is a name."),
|
|
580
|
+
branchName: z.string().min(1).describe("The name of the existing branch to update, without the 'refs/heads/' prefix."),
|
|
581
|
+
path: z.string().min(1).describe("The absolute repository path of the file, for example '/src/example.ts'."),
|
|
582
|
+
content: z.string().describe("The complete UTF-8 text content to write to the file."),
|
|
583
|
+
commitMessage: z.string().min(1).describe("The commit message for the file change."),
|
|
584
|
+
expectedOldObjectId: z
|
|
585
|
+
.string()
|
|
586
|
+
.optional()
|
|
587
|
+
.describe("The expected current commit ID of the branch. When provided, the push fails if the branch has moved. If omitted, the current branch head is retrieved before pushing."),
|
|
588
|
+
}, async ({ action, repositoryId, project, branchName, path, content, commitMessage, expectedOldObjectId }) => {
|
|
589
|
+
try {
|
|
590
|
+
const connection = await connectionProvider();
|
|
591
|
+
const gitApi = await connection.getGitApi();
|
|
592
|
+
const refName = `refs/heads/${branchName}`;
|
|
593
|
+
const refs = await gitApi.getRefs(repositoryId, project, "heads/", false, false, undefined, false, undefined, branchName);
|
|
594
|
+
const branch = refs.find((ref) => ref.name === refName);
|
|
595
|
+
if (!branch?.objectId) {
|
|
596
|
+
return { content: [{ type: "text", text: `Error: Branch '${branchName}' not found in repository ${repositoryId}` }], isError: true };
|
|
597
|
+
}
|
|
598
|
+
if (expectedOldObjectId && expectedOldObjectId !== branch.objectId) {
|
|
599
|
+
return { content: [{ type: "text", text: `Error: Branch '${branchName}' has moved from expected commit ${expectedOldObjectId}` }], isError: true };
|
|
600
|
+
}
|
|
601
|
+
const oldObjectId = branch.objectId;
|
|
602
|
+
const filePath = path.startsWith("/") ? path : `/${path}`;
|
|
603
|
+
const push = await gitApi.createPush({
|
|
604
|
+
refUpdates: [{ name: refName, oldObjectId }],
|
|
605
|
+
commits: [
|
|
606
|
+
{
|
|
607
|
+
comment: commitMessage,
|
|
608
|
+
changes: [
|
|
609
|
+
{
|
|
610
|
+
changeType: action === "create" ? VersionControlChangeType.Add : VersionControlChangeType.Edit,
|
|
611
|
+
item: { path: filePath },
|
|
612
|
+
newContent: { content, contentType: ItemContentType.RawText },
|
|
613
|
+
},
|
|
614
|
+
],
|
|
615
|
+
},
|
|
616
|
+
],
|
|
617
|
+
}, repositoryId, project);
|
|
618
|
+
return {
|
|
619
|
+
content: [
|
|
620
|
+
{
|
|
621
|
+
type: "text",
|
|
622
|
+
text: JSON.stringify({ pushId: push.pushId, commitId: push.commits?.[0]?.commitId, branchName, path: filePath }, null, 2),
|
|
623
|
+
},
|
|
624
|
+
],
|
|
625
|
+
};
|
|
626
|
+
}
|
|
627
|
+
catch (error) {
|
|
628
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
|
|
629
|
+
return { content: [{ type: "text", text: `Error writing repository file: ${errorMessage}` }], isError: true };
|
|
630
|
+
}
|
|
631
|
+
});
|
|
570
632
|
// --- repo_search_commits ---------------------------------------------------
|
|
571
633
|
server.tool(REPO_TOOLS.repo_search_commits, "Search commits with filtering by text, author, date range, and more.", {
|
|
572
634
|
searchText: z.string().describe("Keywords to search for in commit messages"),
|
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const packageVersion = "2.10.0-nightly.
|
|
1
|
+
export const packageVersion = "2.10.0-nightly.20260924";
|
package/package.json
CHANGED