@lotfihoc/ado-on-prem-mcp 1.0.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.
Files changed (45) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +305 -0
  3. package/dist/auth.js +117 -0
  4. package/dist/auth.js.map +1 -0
  5. package/dist/index.js +153 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/logger.js +35 -0
  8. package/dist/logger.js.map +1 -0
  9. package/dist/org-tenants.js +79 -0
  10. package/dist/org-tenants.js.map +1 -0
  11. package/dist/prompts.js +21 -0
  12. package/dist/prompts.js.map +1 -0
  13. package/dist/shared/domains.js +126 -0
  14. package/dist/shared/domains.js.map +1 -0
  15. package/dist/shared/tool-validation.js +93 -0
  16. package/dist/shared/tool-validation.js.map +1 -0
  17. package/dist/tools/advanced-security.js +109 -0
  18. package/dist/tools/advanced-security.js.map +1 -0
  19. package/dist/tools/auth.js +64 -0
  20. package/dist/tools/auth.js.map +1 -0
  21. package/dist/tools/core.js +96 -0
  22. package/dist/tools/core.js.map +1 -0
  23. package/dist/tools/pipelines.js +322 -0
  24. package/dist/tools/pipelines.js.map +1 -0
  25. package/dist/tools/repositories.js +938 -0
  26. package/dist/tools/repositories.js.map +1 -0
  27. package/dist/tools/search.js +242 -0
  28. package/dist/tools/search.js.map +1 -0
  29. package/dist/tools/test-plans.js +387 -0
  30. package/dist/tools/test-plans.js.map +1 -0
  31. package/dist/tools/wiki.js +390 -0
  32. package/dist/tools/wiki.js.map +1 -0
  33. package/dist/tools/work-items.js +1007 -0
  34. package/dist/tools/work-items.js.map +1 -0
  35. package/dist/tools/work.js +299 -0
  36. package/dist/tools/work.js.map +1 -0
  37. package/dist/tools.js +30 -0
  38. package/dist/tools.js.map +1 -0
  39. package/dist/useragent.js +21 -0
  40. package/dist/useragent.js.map +1 -0
  41. package/dist/utils.js +94 -0
  42. package/dist/utils.js.map +1 -0
  43. package/dist/version.js +2 -0
  44. package/dist/version.js.map +1 -0
  45. package/package.json +86 -0
package/LICENSE.md ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) Microsoft Corporation.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE
package/README.md ADDED
@@ -0,0 +1,305 @@
1
+ # ⭐ Azure DevOps On-Premise MCP Server
2
+
3
+ This project provides a lightweight server to interact with on-premises Azure DevOps, enabling automation, project management, and streamlined workflows.
4
+
5
+ Forked from [web-marketing-hr](https://www.npmjs.com/package/@web-marketing-hr/azure-devops-mcp), which itself is a fork of [Microsoft's Azure DevOps MCP](https://github.com/microsoft/azure-devops-mcp)
6
+
7
+ ### Environment variables
8
+
9
+ - `ADO_MCP_AUTH_TOKEN`:
10
+ - DevOps Personal Access Token (PAT)
11
+ - `ADO_MCP_MODE`:
12
+ - Whether Azure DevOps is on-premises or in the cloud
13
+ - `"cloud"` (default) or `"onprem"`
14
+ - `ADO_MCP_AUTH_TYPE`
15
+ - DevOps authentication mode
16
+ - `"bearer"` (default) or `"basic"`
17
+ - `ADO_MCP_ORG_URL`:
18
+ - Full URL of the on-premises instance, for example:
19
+ `https://my-server/tfs/MyCollection`
20
+ - `ADO_MCP_API_VERSION`:
21
+ - Set Azure DevOps API version
22
+ - default: `"6.0-preview"`
23
+ - `ADO_MCP_BATCH_API_VERSION`:
24
+ - Set Azure DevOps Batch API version
25
+ - default: `"6.0-preview"`
26
+ - `ADO_MCP_MARKDOWN_COMMENTS_API_VERSION`:
27
+ - Set Azure DevOps Markdown API version
28
+ - default: `"5.0"`
29
+
30
+ ### Set environment variables in mcp.json
31
+
32
+ You can set environment variables in `mcp.json`, for example:
33
+
34
+ ```json
35
+ {
36
+ "servers": {
37
+ "ado-on-prem-mcp": {
38
+ "type": "stdio",
39
+ "command": "npx",
40
+ "args": ["-y", "@lotfihoc/ado-on-prem-mcp", "<your_devops_project_name>", "--authentication", "envvar"],
41
+ "env": {
42
+ "LOG_LEVEL": "info",
43
+ "ADO_MCP_MODE": "onprem",
44
+ "ADO_MCP_AUTH_TYPE": "basic",
45
+ "ADO_MCP_ORG_URL": "https://<on-prem-host>/tfs/<collection_name>",
46
+ "ADO_MCP_API_VERSION": "6.0",
47
+ "ADO_MCP_BATCH_API_VERSION": "6.0",
48
+ "ADO_MCP_MARKDOWN_COMMENTS_API_VERSION": "5.0",
49
+ "NODE_EXTRA_CA_CERTS": "your_cert_path", // make this availble system wide if needed
50
+ "ADO_MCP_AUTH_TOKEN": "your_ado_pat" // make this availble system wide
51
+ }
52
+ }
53
+ }
54
+ }
55
+ ```
56
+
57
+ If you are using continue dev on vscode, you can use this config
58
+
59
+ ```yaml
60
+ mcpServers:
61
+ - name: ado-on-prem-mcp
62
+ type: stdio
63
+ command: npx
64
+ args:
65
+ - -y
66
+ - "@lotfihoc/ado-on-prem-mcp"
67
+ - "<your_devops_project_name>"
68
+ - "--authentication"
69
+ - "envvar"
70
+ env:
71
+ LOG_LEVEL: "info"
72
+ ADO_MCP_MODE: "onprem"
73
+ ADO_MCP_AUTH_TYPE: "basic"
74
+ ADO_MCP_ORG_URL: "https://<on-prem-host>/tfs/<collection_name>"
75
+ ADO_MCP_API_VERSION: "6.0"
76
+ ADO_MCP_BATCH_API_VERSION: "6.0"
77
+ ADO_MCP_MARKDOWN_COMMENTS_API_VERSION: "5.0"
78
+ ADO_MCP_AUTH_TOKEN: ${{ secrets.ADO_TOKEN }}
79
+ NODE_EXTRA_CA_CERTS: ${{ secrets.NODE_EXTRA_CA_CERTS }}
80
+ ```
81
+
82
+ It's recommended to set `ADO_MCP_AUTH_TOKEN` in your terminal or command line. Windows example:
83
+
84
+ ```bat
85
+ setx ADO_MCP_AUTH_TOKEN "<pat_token>"`
86
+ ```
87
+
88
+ ## Upstream README
89
+
90
+ ## 📄 Table of Contents
91
+
92
+ 1. [📺 Overview](#-overview)
93
+ 2. [🏆 Expectations](#-expectations)
94
+ 3. [⚙️ Supported Tools](#️-supported-tools)
95
+ 4. [🔌 Installation & Getting Started](#-installation--getting-started)
96
+ 5. [🌏 Using Domains](#-using-domains)
97
+ 6. [📝 Troubleshooting](#-troubleshooting)
98
+ 7. [🎩 Examples & Best Practices](#-examples--best-practices)
99
+ 8. [🙋‍♀️ Frequently Asked Questions](#️-frequently-asked-questions)
100
+ 9. [📌 Contributing](#-contributing)
101
+
102
+ ## 📺 Overview
103
+
104
+ The Azure DevOps MCP Server brings Azure DevOps context to your agents. Try prompts like:
105
+
106
+ - "List my ADO projects"
107
+ - "List ADO Builds for 'Contoso'"
108
+ - "List ADO Repos for 'Contoso'"
109
+ - "List test plans for 'Contoso'"
110
+ - "List teams for project 'Contoso'"
111
+ - "List iterations for project 'Contoso'"
112
+ - "List my work items for project 'Contoso'"
113
+ - "List work items in current iteration for 'Contoso' project and 'Contoso Team'"
114
+ - "List all wikis in the 'Contoso' project"
115
+ - "Create a wiki page '/Architecture/Overview' with content about system design"
116
+ - "Update the wiki page '/Getting Started' with new onboarding instructions"
117
+ - "Get the content of the wiki page '/API/Authentication' from the Documentation wiki"
118
+
119
+ ## 🏆 Expectations
120
+
121
+ The Azure DevOps MCP Server is built from tools that are concise, simple, focused, and easy to use—each designed for a specific scenario. We intentionally avoid complex tools that try to do too much. The goal is to provide a thin abstraction layer over the REST APIs, making data access straightforward and letting the language model handle complex reasoning.
122
+
123
+ ## ⚙️ Supported Tools
124
+
125
+ See [TOOLSET.md](./docs/TOOLSET.md) for a comprehensive list.
126
+
127
+ ## 🔌 Installation & Getting Started
128
+
129
+ For the best experience, use Visual Studio Code and GitHub Copilot. See the [getting started documentation](./docs/GETTINGSTARTED.md) to use our MCP Server with other tools such as Visual Studio 2022, Claude Code, and Cursor.
130
+
131
+ ### Prerequisites
132
+
133
+ 1. Install [VS Code](https://code.visualstudio.com/download) or [VS Code Insiders](https://code.visualstudio.com/insiders)
134
+ 2. Install [Node.js](https://nodejs.org/en/download) 20+
135
+ 3. Open VS Code in an empty folder
136
+
137
+ ### Installation
138
+
139
+ #### ✨ One-Click Install
140
+
141
+ [![Install with NPX in VS Code](https://img.shields.io/badge/VS_Code-Install_AzureDevops_MCP_Server-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white)](https://insiders.vscode.dev/redirect/mcp/install?name=ado&config=%7B%20%22type%22%3A%20%22stdio%22%2C%20%22command%22%3A%20%22npx%22%2C%20%22args%22%3A%20%5B%22-y%22%2C%20%22%40azure-devops%2Fmcp%22%2C%20%22%24%7Binput%3Aado_org%7D%22%5D%7D&inputs=%5B%7B%22id%22%3A%20%22ado_org%22%2C%20%22type%22%3A%20%22promptString%22%2C%20%22description%22%3A%20%22Azure%20DevOps%20organization%20name%20%20%28e.g.%20%27contoso%27%29%22%7D%5D)
142
+ [![Install with NPX in VS Code Insiders](https://img.shields.io/badge/VS_Code_Insiders-Install_AzureDevops_MCP_Server-24bfa5?style=flat-square&logo=visualstudiocode&logoColor=white)](https://insiders.vscode.dev/redirect/mcp/install?name=ado&quality=insiders&config=%7B%20%22type%22%3A%20%22stdio%22%2C%20%22command%22%3A%20%22npx%22%2C%20%22args%22%3A%20%5B%22-y%22%2C%20%22%40azure-devops%2Fmcp%22%2C%20%22%24%7Binput%3Aado_org%7D%22%5D%7D&inputs=%5B%7B%22id%22%3A%20%22ado_org%22%2C%20%22type%22%3A%20%22promptString%22%2C%20%22description%22%3A%20%22Azure%20DevOps%20organization%20name%20%20%28e.g.%20%27contoso%27%29%22%7D%5D)
143
+
144
+ After installation, select GitHub Copilot Agent Mode and refresh the tools list. Learn more about Agent Mode in the [VS Code Documentation](https://code.visualstudio.com/docs/copilot/chat/chat-agent-mode).
145
+
146
+ #### 🧨 Install from Public Feed (Recommended)
147
+
148
+ This installation method is the easiest for all users of Visual Studio Code.
149
+
150
+ 🎥 [Watch this quick start video to get up and running in under two minutes!](https://youtu.be/EUmFM6qXoYk)
151
+
152
+ ##### Steps
153
+
154
+ In your project, add a `.vscode\mcp.json` file with the following content:
155
+
156
+ ```json
157
+ {
158
+ "inputs": [
159
+ {
160
+ "id": "ado_org",
161
+ "type": "promptString",
162
+ "description": "Azure DevOps organization name"
163
+ }
164
+ ],
165
+ "servers": {
166
+ "ado-on-prem-mcp": {
167
+ "type": "stdio",
168
+ "command": "npx",
169
+ "args": ["-y", "@lotfihoc/ado-on-prem-mcp", "${input:ado_org}"],
170
+ "env": {
171
+ "LOG_LEVEL": "info",
172
+ "ADO_MCP_MODE": "onprem",
173
+ "ADO_MCP_AUTH_TYPE": "basic",
174
+ "ADO_MCP_ORG_URL": "https://<on-prem-host>/tfs/<collection_name>",
175
+ "ADO_MCP_API_VERSION": "6.0",
176
+ "ADO_MCP_BATCH_API_VERSION": "6.0",
177
+ "ADO_MCP_MARKDOWN_COMMENTS_API_VERSION": "5.0",
178
+ "NODE_EXTRA_CA_CERTS": "<path_to_cert>",
179
+ "ADO_MCP_AUTH_TOKEN": "<your_ado_pat>"
180
+ }
181
+ }
182
+ }
183
+ }
184
+ ```
185
+
186
+ 🔥 To stay up to date with the latest features, you can use our nightly builds. Simply update your `mcp.json` configuration to use `@lotfihoc/ado-on-prem-mcp@next`. Here is an updated example:
187
+
188
+ ```json
189
+ {
190
+ "inputs": [
191
+ {
192
+ "id": "ado_org",
193
+ "type": "promptString",
194
+ "description": "Azure DevOps organization name"
195
+ }
196
+ ],
197
+ "servers": {
198
+ "ado-on-prem-mcp": {
199
+ "type": "stdio",
200
+ "command": "npx",
201
+ "args": ["-y", "@lotfihoc/ado-on-prem-mcp@next", "${input:ado_org}"],
202
+ "env": {
203
+ "LOG_LEVEL": "info",
204
+ "ADO_MCP_MODE": "onprem",
205
+ "ADO_MCP_AUTH_TYPE": "basic",
206
+ "ADO_MCP_ORG_URL": "https://<on-prem-host>/tfs/<collection_name>",
207
+ "ADO_MCP_API_VERSION": "6.0",
208
+ "ADO_MCP_BATCH_API_VERSION": "6.0",
209
+ "ADO_MCP_MARKDOWN_COMMENTS_API_VERSION": "5.0",
210
+ "NODE_EXTRA_CA_CERTS": "<path_to_cert>",
211
+ "ADO_MCP_AUTH_TOKEN": "<your_ado_pat>"
212
+ }
213
+ }
214
+ }
215
+ }
216
+ ```
217
+
218
+ Save the file, then click 'Start'.
219
+
220
+ ![start mcp server](./docs/media/start-mcp-server.gif)
221
+
222
+ In chat, switch to [Agent Mode](https://code.visualstudio.com/blogs/2025/02/24/introducing-copilot-agent-mode).
223
+
224
+ Click "Select Tools" and choose the available tools.
225
+
226
+ ![configure mcp server tools](./docs/media/configure-mcp-server-tools.gif)
227
+
228
+ Open GitHub Copilot Chat and try a prompt like `List ADO projects`. The first time an ADO tool is executed browser will open prompting to login with your Microsoft account. Please ensure you are using credentials matching selected Azure DevOps organization.
229
+
230
+ > 💥 We strongly recommend creating a `.github\copilot-instructions.md` in your project. This will enhance your experience using the Azure DevOps MCP Server with GitHub Copilot Chat.
231
+ > To start, just include "`This project uses Azure DevOps. Always check to see if the Azure DevOps MCP server has a tool relevant to the user's request`" in your copilot instructions file.
232
+
233
+ See the [getting started documentation](./docs/GETTINGSTARTED.md) to use our MCP Server with other tools such as Visual Studio 2022, Claude Code, and Cursor.
234
+
235
+ ## 🌏 Using Domains
236
+
237
+ Azure DevOps exposes a large surface area. As a result, our Azure DevOps MCP Server includes many tools. To keep the toolset manageable, avoid confusing the model, and respect client limits on loaded tools, use Domains to load only the areas you need. Domains are named groups of related tools (for example: core, work, work-items, repositories, wiki). Add the `-d` argument and the domain names to the server args in your `mcp.json` to list the domains to enable.
238
+
239
+ For example, use `"-d", "core", "work", "work-items"` to load only Work Item related tools (see the example below).
240
+
241
+ > By default all domains are loaded
242
+
243
+ ```json
244
+ {
245
+ "inputs": [
246
+ {
247
+ "id": "ado_org",
248
+ "type": "promptString",
249
+ "description": "Azure DevOps organization name"
250
+ }
251
+ ],
252
+ "servers": {
253
+ "ado-on-prem-mcp-with-filtered-domains": {
254
+ "type": "stdio",
255
+ "command": "npx",
256
+ "args": ["-y", "@lotfihoc/ado-on-prem-mcp", "${input:ado_org}", "-d", "core", "work", "work-items"]
257
+ "env": {
258
+ "LOG_LEVEL": "info",
259
+ "ADO_MCP_MODE": "onprem",
260
+ "ADO_MCP_AUTH_TYPE": "basic",
261
+ "ADO_MCP_ORG_URL": "https://<on-prem-host>/tfs/<collection_name>",
262
+ "ADO_MCP_API_VERSION": "6.0",
263
+ "ADO_MCP_BATCH_API_VERSION": "6.0",
264
+ "ADO_MCP_MARKDOWN_COMMENTS_API_VERSION": "5.0",
265
+ "NODE_EXTRA_CA_CERTS": "<path_to_cert>",
266
+ "ADO_MCP_AUTH_TOKEN": "<your_ado_pat>"
267
+ }
268
+ }
269
+ }
270
+ }
271
+
272
+ ```
273
+
274
+ Domains that are available are: `core`, `work`, `work-items`, `search`, `test-plans`, `repositories`, `wiki`, `pipelines`, `advanced-security`
275
+
276
+ We recommend that you always enable `core` tools so that you can fetch project level information.
277
+
278
+ If you are using continiue dev, you can use the following config
279
+
280
+ ```yml
281
+ mcpServers:
282
+ - name: ado-on-prem-mcp-domains
283
+ type: stdio
284
+ command: npx
285
+ args:
286
+ - -y
287
+ - "@lotfihoc/ado-on-prem-mcp"
288
+ - "<your_devops_project_name>"
289
+ - "-d"
290
+ - "core"
291
+ - "work"
292
+ - "work-items"
293
+ - "--authentication"
294
+ - "envvar"
295
+ env:
296
+ LOG_LEVEL: "info"
297
+ ADO_MCP_MODE: "onprem"
298
+ ADO_MCP_AUTH_TYPE: "basic"
299
+ ADO_MCP_ORG_URL: "https://<on-prem-host>/tfs/<collection_name>"
300
+ ADO_MCP_API_VERSION: "6.0"
301
+ ADO_MCP_BATCH_API_VERSION: "6.0"
302
+ ADO_MCP_MARKDOWN_COMMENTS_API_VERSION: "5.0"
303
+ ADO_MCP_AUTH_TOKEN: ${{ secrets.ADO_TOKEN }}
304
+ NODE_EXTRA_CA_CERTS: ${{ secrets.NODE_EXTRA_CA_CERTS }}
305
+ ```
package/dist/auth.js ADDED
@@ -0,0 +1,117 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+ import { AzureCliCredential, ChainedTokenCredential, DefaultAzureCredential } from "@azure/identity";
4
+ import { PublicClientApplication } from "@azure/msal-node";
5
+ import open from "open";
6
+ import { logger } from "./logger.js";
7
+ const scopes = ["499b84ac-1321-427f-aa17-267ca6975798/.default"];
8
+ class OAuthAuthenticator {
9
+ static clientId = "0d50963b-7bb9-4fe7-94c7-a99af00b5136";
10
+ static defaultAuthority = "https://login.microsoftonline.com/common";
11
+ static zeroTenantId = "00000000-0000-0000-0000-000000000000";
12
+ accountId;
13
+ publicClientApp;
14
+ constructor(tenantId) {
15
+ this.accountId = null;
16
+ let authority = OAuthAuthenticator.defaultAuthority;
17
+ if (tenantId && tenantId !== OAuthAuthenticator.zeroTenantId) {
18
+ authority = `https://login.microsoftonline.com/${tenantId}`;
19
+ logger.debug(`OAuthAuthenticator: Using tenant-specific authority for tenantId='${tenantId}'`);
20
+ }
21
+ else {
22
+ logger.debug(`OAuthAuthenticator: Using default common authority`);
23
+ }
24
+ this.publicClientApp = new PublicClientApplication({
25
+ auth: {
26
+ clientId: OAuthAuthenticator.clientId,
27
+ authority,
28
+ },
29
+ });
30
+ logger.debug(`OAuthAuthenticator: Initialized with clientId='${OAuthAuthenticator.clientId}'`);
31
+ }
32
+ async getToken() {
33
+ let authResult = null;
34
+ if (this.accountId) {
35
+ logger.debug(`OAuthAuthenticator: Attempting silent token acquisition for cached account`);
36
+ try {
37
+ authResult = await this.publicClientApp.acquireTokenSilent({
38
+ scopes,
39
+ account: this.accountId,
40
+ });
41
+ logger.debug(`OAuthAuthenticator: Successfully acquired token silently`);
42
+ }
43
+ catch (error) {
44
+ logger.debug(`OAuthAuthenticator: Silent token acquisition failed: ${error instanceof Error ? error.message : String(error)}`);
45
+ authResult = null;
46
+ }
47
+ }
48
+ else {
49
+ logger.debug(`OAuthAuthenticator: No cached account available, interactive auth required`);
50
+ }
51
+ if (!authResult) {
52
+ logger.debug(`OAuthAuthenticator: Starting interactive token acquisition`);
53
+ authResult = await this.publicClientApp.acquireTokenInteractive({
54
+ scopes,
55
+ openBrowser: async (url) => {
56
+ logger.debug(`OAuthAuthenticator: Opening browser for authentication`);
57
+ open(url);
58
+ },
59
+ });
60
+ this.accountId = authResult.account;
61
+ logger.debug(`OAuthAuthenticator: Successfully acquired token interactively, account cached`);
62
+ }
63
+ if (!authResult.accessToken) {
64
+ logger.error(`OAuthAuthenticator: Authentication result contains no access token`);
65
+ throw new Error("Failed to obtain Azure DevOps OAuth token.");
66
+ }
67
+ logger.debug(`OAuthAuthenticator: Token obtained successfully`);
68
+ return authResult.accessToken;
69
+ }
70
+ }
71
+ function createAuthenticator(type, tenantId) {
72
+ logger.debug(`Creating authenticator of type '${type}' with tenantId='${tenantId ?? "undefined"}'`);
73
+ switch (type) {
74
+ case "envvar":
75
+ logger.debug(`Authenticator: Using environment variable authentication (ADO_MCP_AUTH_TOKEN)`);
76
+ // Read token from fixed environment variable
77
+ return async () => {
78
+ logger.debug(`${type}: Reading token from ADO_MCP_AUTH_TOKEN environment variable`);
79
+ const token = process.env["ADO_MCP_AUTH_TOKEN"];
80
+ if (!token) {
81
+ logger.error(`${type}: ADO_MCP_AUTH_TOKEN environment variable is not set or empty`);
82
+ throw new Error("Environment variable 'ADO_MCP_AUTH_TOKEN' is not set or empty. Please set it with a valid Azure DevOps Personal Access Token.");
83
+ }
84
+ logger.debug(`${type}: Successfully retrieved token from environment variable`);
85
+ return token;
86
+ };
87
+ case "azcli":
88
+ case "env":
89
+ if (type !== "env") {
90
+ logger.debug(`${type}: Setting AZURE_TOKEN_CREDENTIALS to 'dev' for development credential chain`);
91
+ process.env.AZURE_TOKEN_CREDENTIALS = "dev";
92
+ }
93
+ let credential = new DefaultAzureCredential(); // CodeQL [SM05138] resolved by explicitly setting AZURE_TOKEN_CREDENTIALS
94
+ if (tenantId) {
95
+ // Use Azure CLI credential if tenantId is provided for multi-tenant scenarios
96
+ const azureCliCredential = new AzureCliCredential({ tenantId });
97
+ credential = new ChainedTokenCredential(azureCliCredential, credential);
98
+ }
99
+ return async () => {
100
+ const result = await credential.getToken(scopes);
101
+ if (!result) {
102
+ logger.error(`${type}: Failed to obtain token - credential.getToken returned null/undefined`);
103
+ throw new Error("Failed to obtain Azure DevOps token. Ensure you have Azure CLI logged or use interactive type of authentication.");
104
+ }
105
+ logger.debug(`${type}: Successfully obtained Azure DevOps token`);
106
+ return result.token;
107
+ };
108
+ default:
109
+ logger.debug(`Authenticator: Using OAuth interactive authentication (default)`);
110
+ const authenticator = new OAuthAuthenticator(tenantId);
111
+ return () => {
112
+ return authenticator.getToken();
113
+ };
114
+ }
115
+ }
116
+ export { createAuthenticator };
117
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC,OAAO,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,sBAAsB,EAAmB,MAAM,iBAAiB,CAAC;AACtH,OAAO,EAAqC,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAC9F,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,MAAM,MAAM,GAAG,CAAC,+CAA+C,CAAC,CAAC;AAEjE,MAAM,kBAAkB;IACtB,MAAM,CAAC,QAAQ,GAAG,sCAAsC,CAAC;IACzD,MAAM,CAAC,gBAAgB,GAAG,0CAA0C,CAAC;IACrE,MAAM,CAAC,YAAY,GAAG,sCAAsC,CAAC;IAErD,SAAS,CAAqB;IAC9B,eAAe,CAA0B;IAEjD,YAAY,QAAiB;QAC3B,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QAEtB,IAAI,SAAS,GAAG,kBAAkB,CAAC,gBAAgB,CAAC;QACpD,IAAI,QAAQ,IAAI,QAAQ,KAAK,kBAAkB,CAAC,YAAY,EAAE,CAAC;YAC7D,SAAS,GAAG,qCAAqC,QAAQ,EAAE,CAAC;YAC5D,MAAM,CAAC,KAAK,CAAC,qEAAqE,QAAQ,GAAG,CAAC,CAAC;QACjG,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,KAAK,CAAC,oDAAoD,CAAC,CAAC;QACrE,CAAC;QAED,IAAI,CAAC,eAAe,GAAG,IAAI,uBAAuB,CAAC;YACjD,IAAI,EAAE;gBACJ,QAAQ,EAAE,kBAAkB,CAAC,QAAQ;gBACrC,SAAS;aACV;SACF,CAAC,CAAC;QACH,MAAM,CAAC,KAAK,CAAC,kDAAkD,kBAAkB,CAAC,QAAQ,GAAG,CAAC,CAAC;IACjG,CAAC;IAEM,KAAK,CAAC,QAAQ;QACnB,IAAI,UAAU,GAAgC,IAAI,CAAC;QACnD,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACnB,MAAM,CAAC,KAAK,CAAC,4EAA4E,CAAC,CAAC;YAC3F,IAAI,CAAC;gBACH,UAAU,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,kBAAkB,CAAC;oBACzD,MAAM;oBACN,OAAO,EAAE,IAAI,CAAC,SAAS;iBACxB,CAAC,CAAC;gBACH,MAAM,CAAC,KAAK,CAAC,0DAA0D,CAAC,CAAC;YAC3E,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,CAAC,KAAK,CAAC,wDAAwD,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;gBAC/H,UAAU,GAAG,IAAI,CAAC;YACpB,CAAC;QACH,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,KAAK,CAAC,4EAA4E,CAAC,CAAC;QAC7F,CAAC;QACD,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,MAAM,CAAC,KAAK,CAAC,4DAA4D,CAAC,CAAC;YAC3E,UAAU,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,uBAAuB,CAAC;gBAC9D,MAAM;gBACN,WAAW,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;oBACzB,MAAM,CAAC,KAAK,CAAC,wDAAwD,CAAC,CAAC;oBACvE,IAAI,CAAC,GAAG,CAAC,CAAC;gBACZ,CAAC;aACF,CAAC,CAAC;YACH,IAAI,CAAC,SAAS,GAAG,UAAU,CAAC,OAAO,CAAC;YACpC,MAAM,CAAC,KAAK,CAAC,+EAA+E,CAAC,CAAC;QAChG,CAAC;QAED,IAAI,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC;YAC5B,MAAM,CAAC,KAAK,CAAC,oEAAoE,CAAC,CAAC;YACnF,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;QAChE,CAAC;QACD,MAAM,CAAC,KAAK,CAAC,iDAAiD,CAAC,CAAC;QAChE,OAAO,UAAU,CAAC,WAAW,CAAC;IAChC,CAAC;;AAGH,SAAS,mBAAmB,CAAC,IAAY,EAAE,QAAiB;IAC1D,MAAM,CAAC,KAAK,CAAC,mCAAmC,IAAI,oBAAoB,QAAQ,IAAI,WAAW,GAAG,CAAC,CAAC;IACpG,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,QAAQ;YACX,MAAM,CAAC,KAAK,CAAC,+EAA+E,CAAC,CAAC;YAC9F,6CAA6C;YAC7C,OAAO,KAAK,IAAI,EAAE;gBAChB,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,8DAA8D,CAAC,CAAC;gBACpF,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;gBAChD,IAAI,CAAC,KAAK,EAAE,CAAC;oBACX,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,+DAA+D,CAAC,CAAC;oBACrF,MAAM,IAAI,KAAK,CAAC,+HAA+H,CAAC,CAAC;gBACnJ,CAAC;gBACD,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,0DAA0D,CAAC,CAAC;gBAChF,OAAO,KAAK,CAAC;YACf,CAAC,CAAC;QAEJ,KAAK,OAAO,CAAC;QACb,KAAK,KAAK;YACR,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC;gBACnB,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,6EAA6E,CAAC,CAAC;gBACnG,OAAO,CAAC,GAAG,CAAC,uBAAuB,GAAG,KAAK,CAAC;YAC9C,CAAC;YACD,IAAI,UAAU,GAAoB,IAAI,sBAAsB,EAAE,CAAC,CAAC,0EAA0E;YAC1I,IAAI,QAAQ,EAAE,CAAC;gBACb,8EAA8E;gBAC9E,MAAM,kBAAkB,GAAG,IAAI,kBAAkB,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;gBAChE,UAAU,GAAG,IAAI,sBAAsB,CAAC,kBAAkB,EAAE,UAAU,CAAC,CAAC;YAC1E,CAAC;YACD,OAAO,KAAK,IAAI,EAAE;gBAChB,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;gBACjD,IAAI,CAAC,MAAM,EAAE,CAAC;oBACZ,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,wEAAwE,CAAC,CAAC;oBAC9F,MAAM,IAAI,KAAK,CAAC,kHAAkH,CAAC,CAAC;gBACtI,CAAC;gBACD,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,4CAA4C,CAAC,CAAC;gBAClE,OAAO,MAAM,CAAC,KAAK,CAAC;YACtB,CAAC,CAAC;QAEJ;YACE,MAAM,CAAC,KAAK,CAAC,iEAAiE,CAAC,CAAC;YAChF,MAAM,aAAa,GAAG,IAAI,kBAAkB,CAAC,QAAQ,CAAC,CAAC;YACvD,OAAO,GAAG,EAAE;gBACV,OAAO,aAAa,CAAC,QAAQ,EAAE,CAAC;YAClC,CAAC,CAAC;IACN,CAAC;AACH,CAAC;AACD,OAAO,EAAE,mBAAmB,EAAE,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,153 @@
1
+ #!/usr/bin/env node
2
+ // Copyright (c) Microsoft Corporation.
3
+ // Licensed under the MIT License.
4
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
5
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
6
+ import { getBasicHandler, getBearerHandler, WebApi } from "azure-devops-node-api";
7
+ import yargs from "yargs";
8
+ import { hideBin } from "yargs/helpers";
9
+ import { createAuthenticator } from "./auth.js";
10
+ import { logger } from "./logger.js";
11
+ import { getOrgTenant } from "./org-tenants.js";
12
+ //import { configurePrompts } from "./prompts.js";
13
+ import { configureAllTools } from "./tools.js";
14
+ import { UserAgentComposer } from "./useragent.js";
15
+ import { packageVersion } from "./version.js";
16
+ import { DomainsManager } from "./shared/domains.js";
17
+ import { getAzureDevOpsConfig } from "./utils.js";
18
+ function isGitHubCodespaceEnv() {
19
+ return process.env.CODESPACES === "true" && !!process.env.CODESPACE_NAME;
20
+ }
21
+ const defaultAuthenticationType = isGitHubCodespaceEnv() ? "azcli" : "interactive";
22
+ // Parse command line arguments using yargs
23
+ const argv = yargs(hideBin(process.argv))
24
+ .scriptName("mcp-server-azuredevops")
25
+ .usage("Usage: $0 <organization> [options]")
26
+ .version(packageVersion)
27
+ .command("$0 <organization> [options]", "Azure DevOps MCP Server", (yargs) => {
28
+ yargs.positional("organization", {
29
+ describe: "Azure DevOps organization name",
30
+ type: "string",
31
+ demandOption: true,
32
+ });
33
+ })
34
+ .option("domains", {
35
+ alias: "d",
36
+ describe: "Domain(s) to enable: 'all' for everything, or specific domains like 'repositories builds work'. Defaults to 'all'.",
37
+ type: "string",
38
+ array: true,
39
+ default: "all",
40
+ })
41
+ .option("authentication", {
42
+ alias: "a",
43
+ describe: "Type of authentication to use",
44
+ type: "string",
45
+ choices: ["interactive", "azcli", "env", "envvar"],
46
+ default: defaultAuthenticationType,
47
+ })
48
+ .option("tenant", {
49
+ alias: "t",
50
+ describe: "Azure tenant ID (optional, applied when using 'interactive' and 'azcli' type of authentication)",
51
+ type: "string",
52
+ })
53
+ .help()
54
+ .parseSync();
55
+ export const orgName = argv.organization;
56
+ const { orgUrl, mode: deploymentMode } = getAzureDevOpsConfig(orgName);
57
+ const domainsManager = new DomainsManager(argv.domains);
58
+ export const enabledDomains = domainsManager.getEnabledDomains();
59
+ function getAzureDevOpsClient(getAzureDevOpsToken, userAgentComposer, authentication) {
60
+ return async () => {
61
+ const accessToken = await getAzureDevOpsToken();
62
+ const isBasicAuth = process.env["ADO_MCP_AUTH_TYPE"] == "basic";
63
+ const authHandler = isBasicAuth ? getBasicHandler("", accessToken) : getBearerHandler(accessToken);
64
+ const connection = new WebApi(orgUrl, authHandler, undefined, {
65
+ productName: "AzureDevOps.MCP",
66
+ productVersion: packageVersion,
67
+ userAgent: userAgentComposer.userAgent,
68
+ });
69
+ return connection;
70
+ };
71
+ }
72
+ async function main() {
73
+ logger.info("Starting Azure DevOps MCP Server v" + packageVersion);
74
+ logger.info("Used params and settings", {
75
+ organization: orgName,
76
+ organizationUrl: orgUrl,
77
+ deploymentMode: deploymentMode,
78
+ authentication: argv.authentication,
79
+ enabledDomains: Array.from(enabledDomains),
80
+ version: packageVersion,
81
+ });
82
+ const server = new McpServer({
83
+ name: "DevOps MCP Server - WEM Fork (On Premise)",
84
+ version: packageVersion,
85
+ icons: [
86
+ {
87
+ src: "https://cdn.vsassets.io/content/icons/favicon.ico",
88
+ },
89
+ ],
90
+ });
91
+ const userAgentComposer = new UserAgentComposer(packageVersion);
92
+ server.server.oninitialized = () => {
93
+ userAgentComposer.appendMcpClientInfo(server.server.getClientVersion());
94
+ };
95
+ const tenantId = deploymentMode === "cloud" ? ((await getOrgTenant(orgName)) ?? argv.tenant) : undefined;
96
+ const authenticator = createAuthenticator(argv.authentication, tenantId);
97
+ // removing prompts untill further notice
98
+ // configurePrompts(server);
99
+ const connectionProvider = getAzureDevOpsClient(authenticator, userAgentComposer, argv.authentication);
100
+ configureAllTools(server, authenticator, connectionProvider, () => userAgentComposer.userAgent, enabledDomains);
101
+ // TESTING CONNECTION TO DevOps API
102
+ // await testApi(connectionProvider, authenticator);
103
+ const transport = new StdioServerTransport();
104
+ await server.connect(transport);
105
+ }
106
+ async function testApi(connectionProvider, tokenProvider) {
107
+ const connection = await connectionProvider();
108
+ const coreApi = await connection.getCoreApi();
109
+ const workItemApi = await connection.getWorkItemTrackingApi();
110
+ const accessToken = await tokenProvider();
111
+ const baseUrl = connection.serverUrl.replace(/\/$/, "");
112
+ const isOnPrem = process.env["ADO_MCP_MODE"] === "onprem";
113
+ const url = isOnPrem
114
+ ? `${baseUrl}/${orgName}/_apis/search/workitemsearchresults?api-version=6.0-preview`
115
+ : `https://almsearch.dev.azure.com/${orgName}/_apis/search/workitemsearchresults?api-version=6.0`;
116
+ const searchText = "Antonio";
117
+ const includeFacets = false;
118
+ const requestBody = {
119
+ searchText,
120
+ includeFacets,
121
+ $skip: 0,
122
+ $top: 10,
123
+ };
124
+ const isBasicAuth = process.env["ADO_MCP_AUTH_TYPE"] === "basic";
125
+ const authHeader = isBasicAuth ? `Basic ${Buffer.from(":" + accessToken).toString("base64")}` : `Bearer ${accessToken}`;
126
+ const response = await fetch(url, {
127
+ method: "POST",
128
+ headers: {
129
+ "Content-Type": "application/json",
130
+ "Authorization": authHeader,
131
+ "User-Agent": "AzureDevOps.MCP TestApi",
132
+ },
133
+ body: JSON.stringify(requestBody),
134
+ });
135
+ if (!response.ok) {
136
+ const errorBody = await response.text();
137
+ logger.error("Azure DevOps Work Item Search API error", {
138
+ status: response.status,
139
+ statusText: response.statusText,
140
+ url,
141
+ requestBody,
142
+ responseBody: errorBody,
143
+ });
144
+ throw new Error(`Azure DevOps Work Item Search API error: ${response.status} ${response.statusText}`);
145
+ }
146
+ const result = await response.text();
147
+ logger.info("Test API Work Item Search result:", result);
148
+ }
149
+ main().catch((error) => {
150
+ logger.error("Fatal error in main():", error);
151
+ process.exit(1);
152
+ });
153
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/logger.js ADDED
@@ -0,0 +1,35 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+ import winston from "winston";
4
+ import { setLogLevel } from "@azure/logger";
5
+ const logLevel = process.env.LOG_LEVEL?.toLowerCase();
6
+ if (logLevel && ["verbose", "debug", "info", "warning", "error"].includes(logLevel)) {
7
+ // Map Winston log levels to Azure log levels
8
+ const logLevelMap = {
9
+ verbose: "verbose",
10
+ debug: "info",
11
+ info: "info",
12
+ warning: "warning",
13
+ error: "error",
14
+ };
15
+ const azureLogLevel = logLevelMap[logLevel];
16
+ setLogLevel(azureLogLevel);
17
+ }
18
+ /**
19
+ * Logger utility for MCP server
20
+ *
21
+ * Since MCP servers use stdio transport for communication on stdout,
22
+ * we log to stderr to avoid interfering with the MCP protocol.
23
+ */
24
+ export const logger = winston.createLogger({
25
+ level: process.env.LOG_LEVEL || "info",
26
+ format: winston.format.combine(winston.format.timestamp(), winston.format.errors({ stack: true }), winston.format.json()),
27
+ transports: [
28
+ new winston.transports.Stream({
29
+ stream: process.stderr,
30
+ }),
31
+ ],
32
+ // Prevent Winston from exiting on error
33
+ exitOnError: false,
34
+ });
35
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,EAAE,WAAW,EAAiB,MAAM,eAAe,CAAC;AAE3D,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,WAAW,EAAE,CAAC;AACtD,IAAI,QAAQ,IAAI,CAAC,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;IACpF,6CAA6C;IAC7C,MAAM,WAAW,GAAkC;QACjD,OAAO,EAAE,SAAS;QAClB,KAAK,EAAE,MAAM;QACb,IAAI,EAAE,MAAM;QACZ,OAAO,EAAE,SAAS;QAClB,KAAK,EAAE,OAAO;KACf,CAAC;IAEF,MAAM,aAAa,GAAkB,WAAW,CAAC,QAAQ,CAAC,CAAC;IAC3D,WAAW,CAAC,aAAa,CAAC,CAAC;AAC7B,CAAC;AAED;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IACzC,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,MAAM;IACtC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;IACzH,UAAU,EAAE;QACV,IAAI,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC;YAC5B,MAAM,EAAE,OAAO,CAAC,MAAM;SACvB,CAAC;KACH;IACD,wCAAwC;IACxC,WAAW,EAAE,KAAK;CACnB,CAAC,CAAC"}