@azure-devops/mcp 1.1.0 β†’ 1.2.0

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
@@ -5,20 +5,20 @@ Easily install the Azure DevOps MCP Server for VS Code or VS Code Insiders:
5
5
  [![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)
6
6
  [![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)
7
7
 
8
- This TypeScript project defines the **local** MCP server for Azure DevOps, enabling you to perform a wide range of Azure DevOps tasks directly from your code editor.
8
+ This TypeScript project provides a **local** MCP server for Azure DevOps, enabling you to perform a wide range of Azure DevOps tasks directly from your code editor.
9
9
 
10
- > 🚨 **Public Preview:** This project is in public preview. You can expect that the tools will change before general availability.
10
+ > 🚨 **Public Preview:** This project is in public preview. Tools and features may change before general availability.
11
11
 
12
- ## πŸ“„ Table of contents
12
+ ## πŸ“„ Table of Contents
13
13
 
14
14
  1. [πŸ“Ί Overview](#-overview)
15
15
  2. [πŸ† Expectations](#-expectations)
16
- 3. [βš™οΈ Supported tools](#️-supported-tools)
17
- 4. [πŸ”Œ Installation & getting started](#-installation--getting-started)
16
+ 3. [βš™οΈ Supported Tools](#️-supported-tools)
17
+ 4. [πŸ”Œ Installation & Getting Started](#-installation--getting-started)
18
18
  5. [πŸ”¦ Usage](#-usage)
19
19
  6. [πŸ“ Troubleshooting](#-troubleshooting)
20
- 7. [🎩 Samples & best practices](#-samples--best-practices)
21
- 8. [πŸ™‹β€β™€οΈ Frequently asked questions](#️-frequently-asked-questions)
20
+ 7. [🎩 Samples & Best Practices](#-samples--best-practices)
21
+ 8. [πŸ™‹β€β™€οΈ Frequently Asked Questions](#️-frequently-asked-questions)
22
22
  9. [πŸ“Œ Contributing](#-contributing)
23
23
 
24
24
  ## πŸ“Ί Overview
@@ -37,9 +37,9 @@ The Azure DevOps MCP Server brings Azure DevOps context to your agents. Try prom
37
37
 
38
38
  ## πŸ† Expectations
39
39
 
40
- 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 the complex reasoning.
40
+ 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.
41
41
 
42
- ## βš™οΈ Supported tools
42
+ ## βš™οΈ Supported Tools
43
43
 
44
44
  Interact with these Azure DevOps services:
45
45
 
@@ -47,6 +47,7 @@ Interact with these Azure DevOps services:
47
47
 
48
48
  - **core_list_project_teams**: Retrieve a list of teams for the specified Azure DevOps project.
49
49
  - **core_list_projects**: Retrieve a list of projects in your Azure DevOps organization.
50
+ - **core_get_identity_ids**: Retrieve Azure DevOps identity IDs for a list of unique names.
50
51
 
51
52
  ### βš’οΈ Work
52
53
 
@@ -60,32 +61,32 @@ Interact with these Azure DevOps services:
60
61
  - **wit_list_backlogs**: Retrieve a list of backlogs for a given project and team.
61
62
  - **wit_list_backlog_work_items**: Retrieve a list of backlogs for a given project, team, and backlog category.
62
63
  - **wit_get_work_item**: Get a single work item by ID.
63
- - **wit_get_work_items_batch_by_ids**: Retrieves a list of work items by IDs in batch.
64
+ - **wit_get_work_items_batch_by_ids**: Retrieve a list of work items by IDs in batch.
64
65
  - **wit_update_work_item**: Update a work item by ID with specified fields.
65
66
  - **wit_create_work_item**: Create a new work item in a specified project and work item type.
66
- - **wit_list_work_item_comments**: Retrieves a list of comments for a work item by ID.
67
- - **wit_get_work_items_for_iteration**: Retrieves a list of work items for a specified iteration.
68
- - **wit_add_work_item_comment**: Add comment to a work item by ID.
69
- - **wit_add_child_work_items**: Create one or many child work items of a specific work item type for the given parent Id
67
+ - **wit_list_work_item_comments**: Retrieve a list of comments for a work item by ID.
68
+ - **wit_get_work_items_for_iteration**: Retrieve a list of work items for a specified iteration.
69
+ - **wit_add_work_item_comment**: Add a comment to a work item by ID.
70
+ - **wit_add_child_work_items**: Create one or more child work items of a specific work item type for the given parent ID.
70
71
  - **wit_link_work_item_to_pull_request**: Link a single work item to an existing pull request.
71
72
  - **wit_get_work_item_type**: Get a specific work item type.
72
73
  - **wit_get_query**: Get a query by its ID or path.
73
74
  - **wit_get_query_results_by_id**: Retrieve the results of a work item query given the query ID.
74
75
  - **wit_update_work_items_batch**: Update work items in batch.
75
- - **wit_close_and_link_workitem_duplicates**: Close duplicate work items by id.
76
+ - **wit_close_and_link_workitem_duplicates**: Close duplicate work items by ID.
76
77
  - **wit_work_items_link**: Link work items together in batch.
77
78
 
78
- #### Deprecated tools
79
+ #### Deprecated Tools
79
80
 
80
- - **wit_add_child_work_item**: Replaced by `wit_add_child_work_items` so that you can create one or many child items per call.
81
+ - **wit_add_child_work_item**: Replaced by `wit_add_child_work_items` to allow creating one or more child items per call.
81
82
 
82
83
  ### πŸ“ Repositories
83
84
 
84
85
  - **repo_list_repos_by_project**: Retrieve a list of repositories for a given project.
85
86
  - **repo_list_pull_requests_by_repo**: Retrieve a list of pull requests for a given repository.
86
- - **repo_list_pull_requests_by_project**: Retrieve a list of pull requests for a given project Id or Name.
87
+ - **repo_list_pull_requests_by_project**: Retrieve a list of pull requests for a given project ID or name.
87
88
  - **repo_list_branches_by_repo**: Retrieve a list of branches for a given repository.
88
- - **repo_list_my_branches_by_repo**: Retrieve a list of my branches for a given repository Id.
89
+ - **repo_list_my_branches_by_repo**: Retrieve a list of your branches for a given repository ID.
89
90
  - **repo_list_pull_requests_by_commits**: List pull requests associated with commits.
90
91
  - **repo_list_pull_request_threads**: Retrieve a list of comment threads for a pull request.
91
92
  - **repo_list_pull_request_thread_comments**: Retrieve a list of comments in a pull request thread.
@@ -93,48 +94,52 @@ Interact with these Azure DevOps services:
93
94
  - **repo_get_branch_by_name**: Get a branch by its name.
94
95
  - **repo_get_pull_request_by_id**: Get a pull request by its ID.
95
96
  - **repo_create_pull_request**: Create a new pull request.
96
- - **repo_update_pull_request_status**: Update status of an existing pull request to active or abandoned.
97
- - **repo_reply_to_comment**: Replies to a specific comment on a pull request.
98
- - **repo_resolve_comment**: Resolves a specific comment thread on a pull request.
99
- - **repo_search_commits**: Searches for commits.
97
+ - **repo_update_pull_request_status**: Update the status of an existing pull request to active or abandoned.
98
+ - **repo_update_pull_request_reviewers**: Add or remove reviewers for an existing pull request.
99
+ - **repo_reply_to_comment**: Reply to a specific comment on a pull request.
100
+ - **repo_resolve_comment**: Resolve a specific comment thread on a pull request.
101
+ - **repo_search_commits**: Search for commits.
100
102
 
101
103
  ### πŸ›°οΈ Builds
102
104
 
103
- - **build_get_definitions**: Retrieves a list of build definitions for a given project.
104
- - **build_get_definition_revisions**: Retrieves a list of revisions for a specific build definition.
105
- - **build_get_builds**: Retrieves a list of builds for a given project.
106
- - **build_get_log**: Retrieves the logs for a specific build.
105
+ - **build_get_definitions**: Retrieve a list of build definitions for a given project.
106
+ - **build_get_definition_revisions**: Retrieve a list of revisions for a specific build definition.
107
+ - **build_get_builds**: Retrieve a list of builds for a given project.
108
+ - **build_get_log**: Retrieve the logs for a specific build.
107
109
  - **build_get_log_by_id**: Get a specific build log by log ID.
108
110
  - **build_get_changes**: Get the changes associated with a specific build.
109
- - **build_run_build**: Triggers a new build for a specified definition.
110
- - **build_get_status**: Fetches the status of a specific build.
111
- - **build_update_build_stage**: Updates the stage of a specific build.
111
+ - **build_run_build**: Trigger a new build for a specified definition.
112
+ - **build_get_status**: Fetch the status of a specific build.
113
+ - **build_update_build_stage**: Update the stage of a specific build.
112
114
 
113
115
  ### πŸš€ Releases
114
116
 
115
- - **release_get_definitions**: Retrieves a list of release definitions for a given project.
116
- - **release_get_releases**: Retrieves a list of releases for a given project.
117
+ - **release_get_definitions**: Retrieve a list of release definitions for a given project.
118
+ - **release_get_releases**: Retrieve a list of releases for a given project.
117
119
 
118
120
  ### πŸ§ͺ Test Plans
119
121
 
120
- - **testplan_create_test_plan**: Creates a new test plan in the project.
121
- - **testplan_create_test_case**: Creates a new test case work item.
122
- - **testplan_add_test_cases_to_suite**: Adds existing test cases to a test suite.
122
+ - **testplan_create_test_plan**: Create a new test plan in the project.
123
+ - **testplan_create_test_case**: Create a new test case work item.
124
+ - **testplan_add_test_cases_to_suite**: Add existing test cases to a test suite.
123
125
  - **testplan_list_test_plans**: Retrieve a paginated list of test plans from an Azure DevOps project. Allows filtering for active plans and toggling detailed information.
124
- - **testplan_list_test_cases**: Gets a list of test cases in the test plan.
125
- - **testplan_show_test_results_from_build_id**: Gets a list of test results for a given project and build ID.
126
+ - **testplan_list_test_cases**: Get a list of test cases in the test plan.
127
+ - **testplan_show_test_results_from_build_id**: Get a list of test results for a given project and build ID.
126
128
 
127
129
  ### πŸ”Ž Search
128
130
 
129
- - **search_code**: Get the code search results for a given search text.
131
+ - **search_code**: Get code search results for a given search text.
130
132
  - **search_wiki**: Get wiki search results for a given search text.
131
133
  - **search_workitem**: Get work item search results for a given search text.
132
134
 
133
- ## πŸ”Œ Installation & getting started
135
+ ## πŸ”Œ Installation & Getting Started
134
136
 
135
137
  Clone the repository, install dependencies, and add it to your MCP client configuration.
136
138
 
137
- ### Visual Studio Code & GitHub Copilot
139
+ [VS Code and GitHub Copilot](#%EF%B8%8F-visual-studio-code--github-copilot)<br/>
140
+ [Visual Studio 2022 and GitHub Copilot](#%EF%B8%8F-visual-studio-2022--github-copilot)
141
+
142
+ ### ➑️ Visual Studio Code & GitHub Copilot
138
143
 
139
144
  For the best experience, use Visual Studio Code and GitHub Copilot.
140
145
 
@@ -155,51 +160,51 @@ az login
155
160
 
156
161
  ### Installation
157
162
 
158
- #### ✨ One-Click install
163
+ #### ✨ One-Click Install
159
164
 
160
165
  [![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)
161
166
  [![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)
162
167
 
163
168
  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).
164
169
 
165
- #### 🧨 Installing from public feed (recommended)
170
+ #### 🧨 Install from Public Feed (Recommended)
166
171
 
167
- This installation method is the easiest for all users using Visual Studio Code.
172
+ This installation method is the easiest for all users of Visual Studio Code.
168
173
 
169
174
  πŸŽ₯ [Watch this quick start video to get up and running in under two minutes!](https://youtu.be/EUmFM6qXoYk)
170
175
 
171
176
  ##### Steps
172
177
 
173
- 1. In your project, add a `.vscode\mcp.json` file and add the following:
174
-
175
- ```json
176
- {
177
- "inputs": [
178
- {
179
- "id": "ado_org",
180
- "type": "promptString",
181
- "description": "Azure DevOps organization name (e.g. 'contoso')"
182
- }
183
- ],
184
- "servers": {
185
- "ado": {
186
- "type": "stdio",
187
- "command": "npx",
188
- "args": ["-y", "@azure-devops/mcp", "${input:ado_org}"]
189
- }
190
- }
191
- }
192
- ```
193
-
194
- 2. Save the file, then click 'Start`
195
-
196
- <img src="./docs/media/start-mcp-server.gif" alt="start mcp server" width="250"/>
178
+ 1. In your project, add a `.vscode\mcp.json` file with the following content:
179
+
180
+ ```json
181
+ {
182
+ "inputs": [
183
+ {
184
+ "id": "ado_org",
185
+ "type": "promptString",
186
+ "description": "Azure DevOps organization name (e.g. 'contoso')"
187
+ }
188
+ ],
189
+ "servers": {
190
+ "ado": {
191
+ "type": "stdio",
192
+ "command": "npx",
193
+ "args": ["-y", "@azure-devops/mcp", "${input:ado_org}"]
194
+ }
195
+ }
196
+ }
197
+ ```
198
+
199
+ 2. Save the file, then click 'Start'.
200
+
201
+ <img src="./docs/media/start-mcp-server.gif" alt="start mcp server" width="250"/>
197
202
 
198
203
  3. In chat, switch to [Agent Mode](https://code.visualstudio.com/blogs/2025/02/24/introducing-copilot-agent-mode).
199
204
  4. Click "Select Tools" and choose the available tools.
200
- 5. We strongly recommend that you create a `.github\copilot-instructions.md` in your project and copy and paste the contents from this [copilot-instructions.md](./.github/copilot-instructions.md) file. This will enhance your experience using the Azure DevOps MCP Server with GitHub Copilot Chat.
205
+ 5. We strongly recommend creating a `.github\copilot-instructions.md` in your project and copying the contents from this [copilot-instructions.md](./.github/copilot-instructions.md) file. This will enhance your experience using the Azure DevOps MCP Server with GitHub Copilot Chat.
201
206
 
202
- #### πŸ› οΈ Installing from source (dev mode)
207
+ #### πŸ› οΈ Install from Source (Dev Mode)
203
208
 
204
209
  This installation method is recommended for advanced users and contributors who want immediate access to the latest updates from the main branch. It is ideal if you are developing new tools, enhancing existing features, or maintaining a custom fork.
205
210
 
@@ -209,39 +214,100 @@ This installation method is recommended for advanced users and contributors who
209
214
 
210
215
  1. Clone the repository.
211
216
  2. Install dependencies:
212
- ```sh
213
- npm install
214
- ```
217
+
218
+ ```sh
219
+ npm install
220
+ ```
221
+
215
222
  3. Edit or add `.vscode/mcp.json`:
216
223
 
217
- ```json
218
- {
219
- "inputs": [
220
- {
221
- "id": "ado_org",
222
- "type": "promptString",
223
- "description": "Azure DevOps organization's name (e.g. 'contoso')"
224
- }
225
- ],
226
- "servers": {
227
- "ado": {
228
- "type": "stdio",
229
- "command": "mcp-server-azuredevops",
230
- "args": ["${input:ado_org}"]
231
- }
232
- }
233
- }
234
- ```
235
-
236
- 4. Start the Azure DevOps MCP Server
237
-
238
- <img src="./docs/media/start-mcp-server.gif" alt="start mcp server" width="250"/>
224
+ ```json
225
+ {
226
+ "inputs": [
227
+ {
228
+ "id": "ado_org",
229
+ "type": "promptString",
230
+ "description": "Azure DevOps organization's name (e.g. 'contoso')"
231
+ }
232
+ ],
233
+ "servers": {
234
+ "ado": {
235
+ "type": "stdio",
236
+ "command": "mcp-server-azuredevops",
237
+ "args": ["${input:ado_org}"]
238
+ }
239
+ }
240
+ }
241
+ ```
242
+
243
+ 4. Start the Azure DevOps MCP Server.
244
+
245
+ <img src="./docs/media/start-mcp-server.gif" alt="start mcp server" width="250"/>
239
246
 
240
247
  5. In chat, switch to [Agent Mode](https://code.visualstudio.com/blogs/2025/02/24/introducing-copilot-agent-mode).
241
248
  6. Click "Select Tools" and choose the available tools.
242
- 7. We strongly recommend that you create a `.github\copilot-instructions.md` in your project and copy and paste the contents from this [copilot-instructions.md](./.github/copilot-instructions.md) file. This will help your experience when it comes to using the Azure DevOps MCP Server in GitHub Copilot Chat.
249
+ 7. We strongly recommend creating a `.github\copilot-instructions.md` in your project and copying the contents from this [copilot-instructions.md](./.github/copilot-instructions.md) file. This will help you get the best experience using the Azure DevOps MCP Server in GitHub Copilot Chat.
250
+
251
+ See the [How To](./docs/HOWTO.md) section for details.
252
+
253
+ ### ➑️ Visual Studio 2022 & GitHub Copilot
254
+
255
+ For the best experience, use Visual Studio Code and GitHub Copilot πŸ‘†.
256
+
257
+ ### Prerequisites
258
+
259
+ 1. Install [VS Studio 2022 version 17.14](https://learn.microsoft.com/en-us/visualstudio/releases/2022/release-history) or later
260
+ 2. Install [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli?view=azure-cli-latest)
261
+ 3. Open a project in Visual Studio.
262
+
263
+ ### Azure Login
264
+
265
+ Ensure you are logged in to Azure DevOps via the Azure CLI:
266
+
267
+ ```sh
268
+ az login
269
+ ```
270
+
271
+ #### 🧨 Install from Public Feed (Recommended)
272
+
273
+ This installation method is the easiest for all users of Visual Studio 2022.
274
+
275
+ πŸŽ₯ [Watch this quick start video to get up and running in under two minutes!](https://youtu.be/nz_Gn-WL7j0)
276
+
277
+ ##### Steps
278
+
279
+ 1. Add a `.mcp.json` file to the solution folder with the following content:
280
+
281
+ ```json
282
+ {
283
+ "inputs": [
284
+ {
285
+ "id": "ado_org",
286
+ "type": "promptString",
287
+ "description": "Azure DevOps organization name (e.g. 'contoso')"
288
+ }
289
+ ],
290
+ "servers": {
291
+ "ado": {
292
+ "type": "stdio",
293
+ "command": "npx",
294
+ "args": ["-y", "@azure-devops/mcp", "${input:ado_org}"]
295
+ }
296
+ }
297
+ }
298
+ ```
299
+
300
+ 2. Save the file.
301
+ 3. Add your organization name by clicking on the `input` option.
302
+
303
+ <img src="./docs/media/start-mcp-server-from-vs.png" alt="start mcp server from visual studio 2022" width="250"/>
304
+
305
+ 4. Open Copilot chat and switch to [Agent Mode](https://learn.microsoft.com/en-us/visualstudio/ide/copilot-agent-mode?view=vs-2022).
306
+ 5. Click the "Tools" icon and choose the available tools.
307
+
308
+ <img src="./docs/media/set-tools-from-vs.png" alt="set tools to use in visual studio 2022" width="250"/>
243
309
 
244
- See [How To](./docs/HOWTO.md) section for details
310
+ 6. We strongly recommend creating a `.github\copilot-instructions.md` in your project and copying the contents from this [copilot-instructions.md](./.github/copilot-instructions.md) file. This will enhance your experience using the Azure DevOps MCP Server with GitHub Copilot Chat.
245
311
 
246
312
  ## πŸ”¦ Usage
247
313
 
@@ -261,23 +327,23 @@ See [How To](./docs/HOWTO.md) section for details
261
327
  3. Select desired `ado` tools.
262
328
  4. Try prompts like "List ADO projects".
263
329
 
264
- For more details, see [Visual Studio MCP Servers documentation](https://learn.microsoft.com/en-us/visualstudio/ide/mcp-servers?view=vs-2022) and [Getting Started Video](https://www.youtube.com/watch?v=oPFecZHBCkg).
330
+ For more details, see [Visual Studio MCP Servers documentation](https://learn.microsoft.com/en-us/visualstudio/ide/mcp-servers?view=vs-2022) and the [Getting Started Video](https://www.youtube.com/watch?v=oPFecZHBCkg).
265
331
 
266
332
  ## πŸ“ Troubleshooting
267
333
 
268
334
  See the [Troubleshooting guide](./docs/TROUBLESHOOTING.md) for help with common issues and logging.
269
335
 
270
- ## 🎩 Samples & best practices
336
+ ## 🎩 Samples & Best Practices
271
337
 
272
338
  Find sample prompts and best practices in our [How-to Guide](./docs/HOWTO.md).
273
339
 
274
- ## πŸ™‹β€β™€οΈ Frequently asked questions
340
+ ## πŸ™‹β€β™€οΈ Frequently Asked Questions
275
341
 
276
342
  For answers to common questions about the Azure DevOps MCP Server, see the [Frequently Asked Questions](./docs/FAQ.md).
277
343
 
278
344
  ## πŸ“Œ Contributing
279
345
 
280
- We welcome contributions! During preview, please file Issues for bugs, enhancements, or documentation improvements.
346
+ We welcome contributions! During preview, please file issues for bugs, enhancements, or documentation improvements.
281
347
 
282
348
  See our [Contributions Guide](./CONTRIBUTING.md) for:
283
349
 
@@ -286,7 +352,7 @@ See our [Contributions Guide](./CONTRIBUTING.md) for:
286
352
  - πŸ“ Code style & testing
287
353
  - πŸ”„ Pull request process
288
354
 
289
- ## 🀝 Code of conduct
355
+ ## 🀝 Code of Conduct
290
356
 
291
357
  This project follows the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
292
358
  For questions, see the [FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [open@microsoft.com](mailto:open@microsoft.com).
package/dist/index.js CHANGED
@@ -4,22 +4,51 @@
4
4
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
5
5
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
6
6
  import * as azdev from "azure-devops-node-api";
7
- import { DefaultAzureCredential } from "@azure/identity";
7
+ import { AzureCliCredential, ChainedTokenCredential, DefaultAzureCredential } from "@azure/identity";
8
+ import yargs from "yargs";
9
+ import { hideBin } from "yargs/helpers";
8
10
  import { configurePrompts } from "./prompts.js";
9
11
  import { configureAllTools } from "./tools.js";
10
12
  import { UserAgentComposer } from "./useragent.js";
11
13
  import { packageVersion } from "./version.js";
12
- const args = process.argv.slice(2);
13
- if (args.length === 0) {
14
- console.error("Usage: mcp-server-azuredevops <organization_name>");
15
- process.exit(1);
16
- }
17
- export const orgName = args[0];
14
+ // Parse command line arguments using yargs
15
+ const argv = yargs(hideBin(process.argv))
16
+ .scriptName("mcp-server-azuredevops")
17
+ .usage("Usage: $0 <organization> [options]")
18
+ .version(packageVersion)
19
+ .command("$0 <organization>", "Azure DevOps MCP Server", (yargs) => {
20
+ yargs.positional("organization", {
21
+ describe: "Azure DevOps organization name",
22
+ type: "string",
23
+ });
24
+ })
25
+ .option("tenant", {
26
+ alias: "t",
27
+ describe: "Azure tenant ID (optional, required for multi-tenant scenarios)",
28
+ type: "string",
29
+ })
30
+ .help()
31
+ .parseSync();
32
+ export const orgName = argv.organization;
33
+ const tenantId = argv.tenant;
18
34
  const orgUrl = "https://dev.azure.com/" + orgName;
19
35
  async function getAzureDevOpsToken() {
20
- process.env.AZURE_TOKEN_CREDENTIALS = "dev";
21
- const credential = new DefaultAzureCredential(); // CodeQL [SM05138] resolved by explicitly setting AZURE_TOKEN_CREDENTIALS
36
+ if (process.env.ADO_MCP_AZURE_TOKEN_CREDENTIALS) {
37
+ process.env.AZURE_TOKEN_CREDENTIALS = process.env.ADO_MCP_AZURE_TOKEN_CREDENTIALS;
38
+ }
39
+ else {
40
+ process.env.AZURE_TOKEN_CREDENTIALS = "dev";
41
+ }
42
+ let credential = new DefaultAzureCredential(); // CodeQL [SM05138] resolved by explicitly setting AZURE_TOKEN_CREDENTIALS
43
+ if (tenantId) {
44
+ // Use Azure CLI credential if tenantId is provided for multi-tenant scenarios
45
+ const azureCliCredential = new AzureCliCredential({ tenantId });
46
+ credential = new ChainedTokenCredential(azureCliCredential, credential);
47
+ }
22
48
  const token = await credential.getToken("499b84ac-1321-427f-aa17-267ca6975798/.default");
49
+ if (!token) {
50
+ throw new Error("Failed to obtain Azure DevOps token. Ensure you have Azure CLI logged in or another token source setup correctly.");
51
+ }
23
52
  return token;
24
53
  }
25
54
  function getAzureDevOpsClient(userAgentComposer) {
@@ -1,6 +1,6 @@
1
1
  // Copyright (c) Microsoft Corporation.
2
2
  // Licensed under the MIT License.
3
- import { apiVersion } from "../utils.js";
3
+ import { apiVersion, getEnumKeys, safeEnumConvert } from "../utils.js";
4
4
  import { BuildQueryOrder, DefinitionQueryOrder } from "azure-devops-node-api/interfaces/BuildInterfaces.js";
5
5
  import { z } from "zod";
6
6
  import { StageUpdateType } from "azure-devops-node-api/interfaces/BuildInterfaces.js";
@@ -22,7 +22,10 @@ function configureBuildTools(server, tokenProvider, connectionProvider) {
22
22
  repositoryType: z.enum(["TfsGit", "GitHub", "BitbucketCloud"]).optional().describe("Type of repository to filter build definitions"),
23
23
  name: z.string().optional().describe("Name of the build definition to filter"),
24
24
  path: z.string().optional().describe("Path of the build definition to filter"),
25
- queryOrder: z.nativeEnum(DefinitionQueryOrder).optional().describe("Order in which build definitions are returned"),
25
+ queryOrder: z
26
+ .enum(getEnumKeys(DefinitionQueryOrder))
27
+ .optional()
28
+ .describe("Order in which build definitions are returned"),
26
29
  top: z.number().optional().describe("Maximum number of build definitions to return"),
27
30
  continuationToken: z.string().optional().describe("Token for continuing paged results"),
28
31
  minMetricsTime: z.coerce.date().optional().describe("Minimum metrics time to filter build definitions"),
@@ -37,7 +40,7 @@ function configureBuildTools(server, tokenProvider, connectionProvider) {
37
40
  }, async ({ project, repositoryId, repositoryType, name, path, queryOrder, top, continuationToken, minMetricsTime, definitionIds, builtAfter, notBuiltAfter, includeAllProperties, includeLatestBuilds, taskIdFilter, processType, yamlFilename, }) => {
38
41
  const connection = await connectionProvider();
39
42
  const buildApi = await connection.getBuildApi();
40
- const buildDefinitions = await buildApi.getDefinitions(project, name, repositoryId, repositoryType, queryOrder, top, continuationToken, minMetricsTime, definitionIds, path, builtAfter, notBuiltAfter, includeAllProperties, includeLatestBuilds, taskIdFilter, processType, yamlFilename);
43
+ const buildDefinitions = await buildApi.getDefinitions(project, name, repositoryId, repositoryType, safeEnumConvert(DefinitionQueryOrder, queryOrder), top, continuationToken, minMetricsTime, definitionIds, path, builtAfter, notBuiltAfter, includeAllProperties, includeLatestBuilds, taskIdFilter, processType, yamlFilename);
41
44
  return {
42
45
  content: [{ type: "text", text: JSON.stringify(buildDefinitions, null, 2) }],
43
46
  };
@@ -70,7 +73,11 @@ function configureBuildTools(server, tokenProvider, connectionProvider) {
70
73
  continuationToken: z.string().optional().describe("Token for continuing paged results"),
71
74
  maxBuildsPerDefinition: z.number().optional().describe("Maximum number of builds per definition"),
72
75
  deletedFilter: z.number().optional().describe("Filter for deleted builds (see QueryDeletedOption enum)"),
73
- queryOrder: z.nativeEnum(BuildQueryOrder).default(BuildQueryOrder.QueueTimeDescending).optional().describe("Order in which builds are returned"),
76
+ queryOrder: z
77
+ .enum(getEnumKeys(BuildQueryOrder))
78
+ .default("QueueTimeDescending")
79
+ .optional()
80
+ .describe("Order in which builds are returned"),
74
81
  branchName: z.string().optional().describe("Branch name to filter builds"),
75
82
  buildIds: z.array(z.number()).optional().describe("Array of build IDs to retrieve"),
76
83
  repositoryId: z.string().optional().describe("Repository ID to filter builds"),
@@ -78,7 +85,7 @@ function configureBuildTools(server, tokenProvider, connectionProvider) {
78
85
  }, async ({ project, definitions, queues, buildNumber, minTime, maxTime, requestedFor, reasonFilter, statusFilter, resultFilter, tagFilters, properties, top, continuationToken, maxBuildsPerDefinition, deletedFilter, queryOrder, branchName, buildIds, repositoryId, repositoryType, }) => {
79
86
  const connection = await connectionProvider();
80
87
  const buildApi = await connection.getBuildApi();
81
- const builds = await buildApi.getBuilds(project, definitions, queues, buildNumber, minTime, maxTime, requestedFor, reasonFilter, statusFilter, resultFilter, tagFilters, properties, top, continuationToken, maxBuildsPerDefinition, deletedFilter, queryOrder, branchName, buildIds, repositoryId, repositoryType);
88
+ const builds = await buildApi.getBuilds(project, definitions, queues, buildNumber, minTime, maxTime, requestedFor, reasonFilter, statusFilter, resultFilter, tagFilters, properties, top, continuationToken, maxBuildsPerDefinition, deletedFilter, safeEnumConvert(BuildQueryOrder, queryOrder), branchName, buildIds, repositoryId, repositoryType);
82
89
  return {
83
90
  content: [{ type: "text", text: JSON.stringify(builds, null, 2) }],
84
91
  };
@@ -168,7 +175,7 @@ function configureBuildTools(server, tokenProvider, connectionProvider) {
168
175
  project: z.string().describe("Project ID or name to update the build stage for"),
169
176
  buildId: z.number().describe("ID of the build to update"),
170
177
  stageName: z.string().describe("Name of the stage to update"),
171
- status: z.nativeEnum(StageUpdateType).describe("New status for the stage"),
178
+ status: z.enum(getEnumKeys(StageUpdateType)).describe("New status for the stage"),
172
179
  forceRetryAllJobs: z.boolean().default(false).describe("Whether to force retry all jobs in the stage."),
173
180
  }, async ({ project, buildId, stageName, status, forceRetryAllJobs }) => {
174
181
  const connection = await connectionProvider();
@@ -177,7 +184,7 @@ function configureBuildTools(server, tokenProvider, connectionProvider) {
177
184
  const token = await tokenProvider();
178
185
  const body = {
179
186
  forceRetryAllJobs: forceRetryAllJobs,
180
- state: status.valueOf(),
187
+ state: safeEnumConvert(StageUpdateType, status),
181
188
  };
182
189
  const response = await fetch(endpoint, {
183
190
  method: "PATCH",
@@ -1,9 +1,11 @@
1
1
  // Copyright (c) Microsoft Corporation.
2
2
  // Licensed under the MIT License.
3
3
  import { z } from "zod";
4
+ import { apiVersion } from "../utils.js";
4
5
  const CORE_TOOLS = {
5
6
  list_project_teams: "core_list_project_teams",
6
7
  list_projects: "core_list_projects",
8
+ get_identity_ids: "core_get_identity_ids",
7
9
  };
8
10
  function filterProjectsByName(projects, projectNameFilter) {
9
11
  const lowerCaseFilter = projectNameFilter.toLowerCase();
@@ -62,5 +64,51 @@ function configureCoreTools(server, tokenProvider, connectionProvider) {
62
64
  };
63
65
  }
64
66
  });
67
+ server.tool(CORE_TOOLS.get_identity_ids, "Retrieve Azure DevOps identity IDs for a provided search filter.", {
68
+ searchFilter: z.string().describe("Search filter (unique namme, display name, email) to retrieve identity IDs for."),
69
+ }, async ({ searchFilter }) => {
70
+ try {
71
+ const token = await tokenProvider();
72
+ const connection = await connectionProvider();
73
+ const orgName = connection.serverUrl.split("/")[3];
74
+ const baseUrl = `https://vssps.dev.azure.com/${orgName}/_apis/identities`;
75
+ const params = new URLSearchParams({
76
+ "api-version": apiVersion,
77
+ "searchFilter": "General",
78
+ "filterValue": searchFilter,
79
+ });
80
+ const response = await fetch(`${baseUrl}?${params}`, {
81
+ headers: {
82
+ "Authorization": `Bearer ${token.token}`,
83
+ "Content-Type": "application/json",
84
+ },
85
+ });
86
+ if (!response.ok) {
87
+ const errorText = await response.text();
88
+ throw new Error(`HTTP ${response.status}: ${errorText}`);
89
+ }
90
+ const identities = await response.json();
91
+ if (!identities || identities.value?.length === 0) {
92
+ return { content: [{ type: "text", text: "No identities found" }], isError: true };
93
+ }
94
+ const identitiesTrimmed = identities.value?.map((identity) => {
95
+ return {
96
+ id: identity.id,
97
+ displayName: identity.providerDisplayName,
98
+ descriptor: identity.descriptor,
99
+ };
100
+ });
101
+ return {
102
+ content: [{ type: "text", text: JSON.stringify(identitiesTrimmed, null, 2) }],
103
+ };
104
+ }
105
+ catch (error) {
106
+ const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
107
+ return {
108
+ content: [{ type: "text", text: `Error fetching identities: ${errorMessage}` }],
109
+ isError: true,
110
+ };
111
+ }
112
+ });
65
113
  }
66
114
  export { CORE_TOOLS, configureCoreTools };