@azure-devops/mcp 2.9.0-nightly.20260729 → 2.9.0-nightly.20260731

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 CHANGED
@@ -1,14 +1,19 @@
1
1
  # ⭐ Azure DevOps MCP Server
2
2
 
3
- > [!IMPORTANT]
4
- > We recommend using the [Remote MCP Server](https://learn.microsoft.com/en-us/azure/devops/mcp-server/remote-mcp-server) instead of this local server. It requires no installation and gets new features first.
3
+ > [!WARNING]
4
+ > We recently completed a full tool consolidation that includes renaming of existing tools. Please see the [Toolset documentation](docs/TOOLSET.md) for the complete list of new tool names.
5
5
  >
6
- > [Learn more](#-remote-mcp-server-recommended)
6
+ > If this is a breaking change for your agents or skills, you can temporarily pin the version to `@azure-devops/mcp@2.8.1`
7
7
 
8
8
  This project provides Azure DevOps MCP tooling for AI agents, with a **remote-first** onboarding experience and a local server option when you need it.
9
9
 
10
10
  ## 📄 Table of Contents
11
11
 
12
+ > [!IMPORTANT]
13
+ > We recommend using the [Remote MCP Server](https://learn.microsoft.com/en-us/azure/devops/mcp-server/remote-mcp-server) instead of this local server. It requires no installation and gets new features first.
14
+ >
15
+ > [Learn more](#-remote-mcp-server-recommended)
16
+
12
17
  1. [📺 Overview](#-overview)
13
18
  2. [🏆 Expectations](#-expectations)
14
19
  3. [🚀 Remote MCP Server (Recommended)](#-remote-mcp-server-recommended)
@@ -43,6 +43,8 @@ function getLinkTypeFromName(name) {
43
43
  return "Microsoft.VSTS.Common.Affects-Reverse";
44
44
  case "artifact":
45
45
  return "ArtifactLink";
46
+ case "hyperlink":
47
+ return "Hyperlink";
46
48
  default:
47
49
  throw new Error(`Unknown link type: ${name}`);
48
50
  }
@@ -729,9 +731,10 @@ function configureWorkItemTools(server, tokenProvider, connectionProvider, userA
729
731
  updates: z
730
732
  .array(z.object({
731
733
  id: z.coerce.number().min(1).describe("The ID of the work item to update."),
732
- linkToId: z.coerce.number().min(1).describe("The ID of the work item to link to."),
734
+ linkToId: z.coerce.number().min(1).optional().describe("The ID of the work item to link to. Required unless type is 'hyperlink'."),
735
+ url: z.string().optional().describe("The URL for a hyperlink. Required when type is 'hyperlink'."),
733
736
  type: z
734
- .enum(["parent", "child", "duplicate", "duplicate of", "related", "successor", "predecessor", "tested by", "tests", "affects", "affected by"])
737
+ .enum(["parent", "child", "duplicate", "duplicate of", "related", "successor", "predecessor", "tested by", "tests", "affects", "affected by", "hyperlink"])
735
738
  .default("related")
736
739
  .describe("Type of link. Defaults to 'related'."),
737
740
  comment: z.string().optional().describe("Optional comment for the link."),
@@ -741,7 +744,7 @@ function configureWorkItemTools(server, tokenProvider, connectionProvider, userA
741
744
  // unlink
742
745
  id: z.coerce.number().min(1).optional().describe("Work item ID to remove links from. Required for: unlink."),
743
746
  type: z
744
- .enum(["parent", "child", "duplicate", "duplicate of", "related", "successor", "predecessor", "tested by", "tests", "affects", "affected by", "artifact"])
747
+ .enum(["parent", "child", "duplicate", "duplicate of", "related", "successor", "predecessor", "tested by", "tests", "affects", "affected by", "artifact", "hyperlink"])
745
748
  .optional()
746
749
  .describe("Link type to remove. Required for: unlink."),
747
750
  url: z.string().optional().describe("URL to match when removing a link. Used for: unlink. If not provided, all links of the specified type are removed."),
@@ -801,15 +804,23 @@ function configureWorkItemTools(server, tokenProvider, connectionProvider, userA
801
804
  headers: { "Content-Type": "application/json-patch+json" },
802
805
  body: updates
803
806
  .filter((update) => update.id === uid)
804
- .map(({ linkToId, type: linkTypeName, comment: linkComment }) => ({
805
- op: "add",
806
- path: "/relations/-",
807
- value: {
808
- rel: `${getLinkTypeFromName(linkTypeName)}`,
809
- url: `${orgUrl}/${resolvedProject}/_apis/wit/workItems/${linkToId}`,
810
- attributes: { comment: linkComment || "" },
811
- },
812
- })),
807
+ .map(({ linkToId, url: linkUrl, type: linkTypeName, comment: linkComment }) => {
808
+ if (linkTypeName === "hyperlink" && !linkUrl) {
809
+ throw new Error("url is required for hyperlink links");
810
+ }
811
+ if (linkTypeName !== "hyperlink" && !linkToId) {
812
+ throw new Error("linkToId is required for work item links");
813
+ }
814
+ return {
815
+ op: "add",
816
+ path: "/relations/-",
817
+ value: {
818
+ rel: getLinkTypeFromName(linkTypeName),
819
+ url: linkTypeName === "hyperlink" ? linkUrl : `${orgUrl}/${resolvedProject}/_apis/wit/workItems/${linkToId}`,
820
+ attributes: { comment: linkComment || "" },
821
+ },
822
+ };
823
+ }),
813
824
  }));
814
825
  const response = await fetch(`${orgUrl}/_apis/wit/$batch?api-version=${batchApiVersion}`, {
815
826
  method: "PATCH",
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const packageVersion = "2.9.0-nightly.20260729";
1
+ export const packageVersion = "2.9.0-nightly.20260731";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@azure-devops/mcp",
3
- "version": "2.9.0-nightly.20260729",
3
+ "version": "2.9.0-nightly.20260731",
4
4
  "mcpName": "microsoft.com/azure-devops",
5
5
  "description": "MCP server for interacting with Azure DevOps",
6
6
  "license": "MIT",