@azure-devops/mcp 1.3.1-nightly.20250811 → 1.3.1-nightly.20250812
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 +3 -3
- package/dist/tools/workitems.js +133 -0
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -16,7 +16,7 @@ This TypeScript project provides a **local** MCP server for Azure DevOps, enabli
|
|
|
16
16
|
3. [⚙️ Supported Tools](#️-supported-tools)
|
|
17
17
|
4. [🔌 Installation & Getting Started](#-installation--getting-started)
|
|
18
18
|
5. [📝 Troubleshooting](#-troubleshooting)
|
|
19
|
-
6. [🎩 Examples & Best Practices](#-
|
|
19
|
+
6. [🎩 Examples & Best Practices](#-examples--best-practices)
|
|
20
20
|
7. [🙋♀️ Frequently Asked Questions](#️-frequently-asked-questions)
|
|
21
21
|
8. [📌 Contributing](#-contributing)
|
|
22
22
|
|
|
@@ -198,13 +198,13 @@ In your project, add a `.vscode\mcp.json` file with the following content:
|
|
|
198
198
|
|
|
199
199
|
Save the file, then click 'Start'.
|
|
200
200
|
|
|
201
|
-
|
|
201
|
+

|
|
202
202
|
|
|
203
203
|
In chat, switch to [Agent Mode](https://code.visualstudio.com/blogs/2025/02/24/introducing-copilot-agent-mode).
|
|
204
204
|
|
|
205
205
|
Click "Select Tools" and choose the available tools.
|
|
206
206
|
|
|
207
|
-
|
|
207
|
+

|
|
208
208
|
|
|
209
209
|
Open GitHub Copilot Chat and try a prompt like `List ADO projects`.
|
|
210
210
|
|
package/dist/tools/workitems.js
CHANGED
|
@@ -23,6 +23,7 @@ const WORKITEM_TOOLS = {
|
|
|
23
23
|
update_work_items_batch: "wit_update_work_items_batch",
|
|
24
24
|
work_items_link: "wit_work_items_link",
|
|
25
25
|
work_item_unlink: "wit_work_item_unlink",
|
|
26
|
+
add_artifact_link: "wit_add_artifact_link",
|
|
26
27
|
};
|
|
27
28
|
function getLinkTypeFromName(name) {
|
|
28
29
|
switch (name.toLowerCase()) {
|
|
@@ -658,5 +659,137 @@ function configureWorkItemTools(server, tokenProvider, connectionProvider, userA
|
|
|
658
659
|
};
|
|
659
660
|
}
|
|
660
661
|
});
|
|
662
|
+
server.tool(WORKITEM_TOOLS.add_artifact_link, "Add artifact links (repository, branch, commit, builds) to work items. You can either provide the full vstfs URI or the individual components to build it automatically.", {
|
|
663
|
+
workItemId: z.number().describe("The ID of the work item to add the artifact link to."),
|
|
664
|
+
project: z.string().describe("The name or ID of the Azure DevOps project."),
|
|
665
|
+
// Option 1: Provide full URI directly
|
|
666
|
+
artifactUri: z.string().optional().describe("The complete VSTFS URI of the artifact to link. If provided, individual component parameters are ignored."),
|
|
667
|
+
// Option 2: Provide individual components to build URI automatically based on linkType
|
|
668
|
+
projectId: z.string().optional().describe("The project ID (GUID) containing the artifact. Required for Git artifacts when artifactUri is not provided."),
|
|
669
|
+
repositoryId: z.string().optional().describe("The repository ID (GUID) containing the artifact. Required for Git artifacts when artifactUri is not provided."),
|
|
670
|
+
branchName: z.string().optional().describe("The branch name (e.g., 'main'). Required when linkType is 'Branch'."),
|
|
671
|
+
commitId: z.string().optional().describe("The commit SHA hash. Required when linkType is 'Fixed in Commit'."),
|
|
672
|
+
pullRequestId: z.number().optional().describe("The pull request ID. Required when linkType is 'Pull Request'."),
|
|
673
|
+
buildId: z.number().optional().describe("The build ID. Required when linkType is 'Build', 'Found in build', or 'Integrated in build'."),
|
|
674
|
+
linkType: z
|
|
675
|
+
.enum([
|
|
676
|
+
"Branch",
|
|
677
|
+
"Build",
|
|
678
|
+
"Fixed in Changeset",
|
|
679
|
+
"Fixed in Commit",
|
|
680
|
+
"Found in build",
|
|
681
|
+
"Integrated in build",
|
|
682
|
+
"Model Link",
|
|
683
|
+
"Pull Request",
|
|
684
|
+
"Related Workitem",
|
|
685
|
+
"Result Attachment",
|
|
686
|
+
"Source Code File",
|
|
687
|
+
"Tag",
|
|
688
|
+
"Test Result",
|
|
689
|
+
"Wiki",
|
|
690
|
+
])
|
|
691
|
+
.default("Branch")
|
|
692
|
+
.describe("Type of artifact link, defaults to 'Branch'. This determines both the link type and how to build the VSTFS URI from individual components."),
|
|
693
|
+
comment: z.string().optional().describe("Comment to include with the artifact link."),
|
|
694
|
+
}, async ({ workItemId, project, artifactUri, projectId, repositoryId, branchName, commitId, pullRequestId, buildId, linkType, comment }) => {
|
|
695
|
+
try {
|
|
696
|
+
const connection = await connectionProvider();
|
|
697
|
+
const workItemTrackingApi = await connection.getWorkItemTrackingApi();
|
|
698
|
+
let finalArtifactUri;
|
|
699
|
+
if (artifactUri) {
|
|
700
|
+
// Use the provided full URI
|
|
701
|
+
finalArtifactUri = artifactUri;
|
|
702
|
+
}
|
|
703
|
+
else {
|
|
704
|
+
// Build the URI from individual components based on linkType
|
|
705
|
+
switch (linkType) {
|
|
706
|
+
case "Branch":
|
|
707
|
+
if (!projectId || !repositoryId || !branchName) {
|
|
708
|
+
return {
|
|
709
|
+
content: [{ type: "text", text: "For 'Branch' links, 'projectId', 'repositoryId', and 'branchName' are required." }],
|
|
710
|
+
isError: true,
|
|
711
|
+
};
|
|
712
|
+
}
|
|
713
|
+
finalArtifactUri = `vstfs:///Git/Ref/${encodeURIComponent(projectId)}%2F${encodeURIComponent(repositoryId)}%2FGB${encodeURIComponent(branchName)}`;
|
|
714
|
+
break;
|
|
715
|
+
case "Fixed in Commit":
|
|
716
|
+
if (!projectId || !repositoryId || !commitId) {
|
|
717
|
+
return {
|
|
718
|
+
content: [{ type: "text", text: "For 'Fixed in Commit' links, 'projectId', 'repositoryId', and 'commitId' are required." }],
|
|
719
|
+
isError: true,
|
|
720
|
+
};
|
|
721
|
+
}
|
|
722
|
+
finalArtifactUri = `vstfs:///Git/Commit/${encodeURIComponent(projectId)}%2F${encodeURIComponent(repositoryId)}%2F${encodeURIComponent(commitId)}`;
|
|
723
|
+
break;
|
|
724
|
+
case "Pull Request":
|
|
725
|
+
if (!projectId || !repositoryId || pullRequestId === undefined) {
|
|
726
|
+
return {
|
|
727
|
+
content: [{ type: "text", text: "For 'Pull Request' links, 'projectId', 'repositoryId', and 'pullRequestId' are required." }],
|
|
728
|
+
isError: true,
|
|
729
|
+
};
|
|
730
|
+
}
|
|
731
|
+
finalArtifactUri = `vstfs:///Git/PullRequestId/${encodeURIComponent(projectId)}%2F${encodeURIComponent(repositoryId)}%2F${encodeURIComponent(pullRequestId.toString())}`;
|
|
732
|
+
break;
|
|
733
|
+
case "Build":
|
|
734
|
+
case "Found in build":
|
|
735
|
+
case "Integrated in build":
|
|
736
|
+
if (buildId === undefined) {
|
|
737
|
+
return {
|
|
738
|
+
content: [{ type: "text", text: `For '${linkType}' links, 'buildId' is required.` }],
|
|
739
|
+
isError: true,
|
|
740
|
+
};
|
|
741
|
+
}
|
|
742
|
+
finalArtifactUri = `vstfs:///Build/Build/${encodeURIComponent(buildId.toString())}`;
|
|
743
|
+
break;
|
|
744
|
+
default:
|
|
745
|
+
return {
|
|
746
|
+
content: [{ type: "text", text: `URI building from components is not supported for link type '${linkType}'. Please provide the full 'artifactUri' instead.` }],
|
|
747
|
+
isError: true,
|
|
748
|
+
};
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
// Create the patch document for adding an artifact link relation
|
|
752
|
+
const patchDocument = [
|
|
753
|
+
{
|
|
754
|
+
op: "add",
|
|
755
|
+
path: "/relations/-",
|
|
756
|
+
value: {
|
|
757
|
+
rel: "ArtifactLink",
|
|
758
|
+
url: finalArtifactUri,
|
|
759
|
+
attributes: {
|
|
760
|
+
name: linkType,
|
|
761
|
+
...(comment && { comment }),
|
|
762
|
+
},
|
|
763
|
+
},
|
|
764
|
+
},
|
|
765
|
+
];
|
|
766
|
+
// Use the WorkItem API to update the work item with the new relation
|
|
767
|
+
const workItem = await workItemTrackingApi.updateWorkItem({}, patchDocument, workItemId, project);
|
|
768
|
+
if (!workItem) {
|
|
769
|
+
return { content: [{ type: "text", text: "Work item update failed" }], isError: true };
|
|
770
|
+
}
|
|
771
|
+
return {
|
|
772
|
+
content: [
|
|
773
|
+
{
|
|
774
|
+
type: "text",
|
|
775
|
+
text: JSON.stringify({
|
|
776
|
+
workItemId,
|
|
777
|
+
artifactUri: finalArtifactUri,
|
|
778
|
+
linkType,
|
|
779
|
+
comment: comment || null,
|
|
780
|
+
success: true,
|
|
781
|
+
}, null, 2),
|
|
782
|
+
},
|
|
783
|
+
],
|
|
784
|
+
};
|
|
785
|
+
}
|
|
786
|
+
catch (error) {
|
|
787
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
|
|
788
|
+
return {
|
|
789
|
+
content: [{ type: "text", text: `Error adding artifact link to work item: ${errorMessage}` }],
|
|
790
|
+
isError: true,
|
|
791
|
+
};
|
|
792
|
+
}
|
|
793
|
+
});
|
|
661
794
|
}
|
|
662
795
|
export { WORKITEM_TOOLS, configureWorkItemTools };
|
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const packageVersion = "1.3.1-nightly.
|
|
1
|
+
export const packageVersion = "1.3.1-nightly.20250812";
|