@azure-devops/mcp 1.2.0-daily.20250715 β 1.2.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.
- package/README.md +163 -98
- package/dist/index.js +32 -8
- package/dist/tools/builds.js +14 -7
- package/dist/tools/releases.js +26 -7
- package/dist/tools/repos.js +148 -17
- package/dist/tools/search.js +85 -80
- package/dist/tools/workitems.js +105 -89
- package/dist/utils.js +26 -0
- package/dist/version.js +1 -1
- package/package.json +6 -5
package/README.md
CHANGED
|
@@ -5,20 +5,20 @@ Easily install the Azure DevOps MCP Server for VS Code or VS Code Insiders:
|
|
|
5
5
|
[](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
|
[](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
|
|
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.
|
|
10
|
+
> π¨ **Public Preview:** This project is in public preview. Tools and features may change before general availability.
|
|
11
11
|
|
|
12
|
-
## π Table of
|
|
12
|
+
## π Table of Contents
|
|
13
13
|
|
|
14
14
|
1. [πΊ Overview](#-overview)
|
|
15
15
|
2. [π Expectations](#-expectations)
|
|
16
|
-
3. [βοΈ Supported
|
|
17
|
-
4. [π Installation &
|
|
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 &
|
|
21
|
-
8. [πββοΈ Frequently
|
|
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
|
|
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
|
|
42
|
+
## βοΈ Supported Tools
|
|
43
43
|
|
|
44
44
|
Interact with these Azure DevOps services:
|
|
45
45
|
|
|
@@ -61,32 +61,32 @@ Interact with these Azure DevOps services:
|
|
|
61
61
|
- **wit_list_backlogs**: Retrieve a list of backlogs for a given project and team.
|
|
62
62
|
- **wit_list_backlog_work_items**: Retrieve a list of backlogs for a given project, team, and backlog category.
|
|
63
63
|
- **wit_get_work_item**: Get a single work item by ID.
|
|
64
|
-
- **wit_get_work_items_batch_by_ids**:
|
|
64
|
+
- **wit_get_work_items_batch_by_ids**: Retrieve a list of work items by IDs in batch.
|
|
65
65
|
- **wit_update_work_item**: Update a work item by ID with specified fields.
|
|
66
66
|
- **wit_create_work_item**: Create a new work item in a specified project and work item type.
|
|
67
|
-
- **wit_list_work_item_comments**:
|
|
68
|
-
- **wit_get_work_items_for_iteration**:
|
|
69
|
-
- **wit_add_work_item_comment**: Add comment to a work item by ID.
|
|
70
|
-
- **wit_add_child_work_items**: Create one or
|
|
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.
|
|
71
71
|
- **wit_link_work_item_to_pull_request**: Link a single work item to an existing pull request.
|
|
72
72
|
- **wit_get_work_item_type**: Get a specific work item type.
|
|
73
73
|
- **wit_get_query**: Get a query by its ID or path.
|
|
74
74
|
- **wit_get_query_results_by_id**: Retrieve the results of a work item query given the query ID.
|
|
75
75
|
- **wit_update_work_items_batch**: Update work items in batch.
|
|
76
|
-
- **wit_close_and_link_workitem_duplicates**: Close duplicate work items by id.
|
|
77
76
|
- **wit_work_items_link**: Link work items together in batch.
|
|
78
77
|
|
|
79
|
-
#### Deprecated
|
|
78
|
+
#### Deprecated Tools
|
|
80
79
|
|
|
81
|
-
- **wit_add_child_work_item**: Replaced by `wit_add_child_work_items`
|
|
80
|
+
- **wit_add_child_work_item**: Replaced by `wit_add_child_work_items` to allow creating one or more child items per call.
|
|
81
|
+
- **wit_close_and_link_workitem_duplicates**: This tool is no longer needed. Finding and marking duplicates can be done with other tools.
|
|
82
82
|
|
|
83
83
|
### π Repositories
|
|
84
84
|
|
|
85
85
|
- **repo_list_repos_by_project**: Retrieve a list of repositories for a given project.
|
|
86
86
|
- **repo_list_pull_requests_by_repo**: Retrieve a list of pull requests for a given repository.
|
|
87
|
-
- **repo_list_pull_requests_by_project**: Retrieve a list of pull requests for a given project
|
|
87
|
+
- **repo_list_pull_requests_by_project**: Retrieve a list of pull requests for a given project ID or name.
|
|
88
88
|
- **repo_list_branches_by_repo**: Retrieve a list of branches for a given repository.
|
|
89
|
-
- **repo_list_my_branches_by_repo**: Retrieve a list of
|
|
89
|
+
- **repo_list_my_branches_by_repo**: Retrieve a list of your branches for a given repository ID.
|
|
90
90
|
- **repo_list_pull_requests_by_commits**: List pull requests associated with commits.
|
|
91
91
|
- **repo_list_pull_request_threads**: Retrieve a list of comment threads for a pull request.
|
|
92
92
|
- **repo_list_pull_request_thread_comments**: Retrieve a list of comments in a pull request thread.
|
|
@@ -94,49 +94,53 @@ Interact with these Azure DevOps services:
|
|
|
94
94
|
- **repo_get_branch_by_name**: Get a branch by its name.
|
|
95
95
|
- **repo_get_pull_request_by_id**: Get a pull request by its ID.
|
|
96
96
|
- **repo_create_pull_request**: Create a new pull request.
|
|
97
|
-
- **repo_update_pull_request_status**: Update status of an existing pull request to active or abandoned.
|
|
97
|
+
- **repo_update_pull_request_status**: Update the status of an existing pull request to active or abandoned.
|
|
98
98
|
- **repo_update_pull_request_reviewers**: Add or remove reviewers for an existing pull request.
|
|
99
99
|
- **repo_reply_to_comment**: Replies to a specific comment on a pull request.
|
|
100
100
|
- **repo_resolve_comment**: Resolves a specific comment thread on a pull request.
|
|
101
101
|
- **repo_search_commits**: Searches for commits.
|
|
102
|
+
- **repo_create_pull_request_thread**: Creates a new comment thread on a pull request.
|
|
102
103
|
|
|
103
104
|
### π°οΈ Builds
|
|
104
105
|
|
|
105
|
-
- **build_get_definitions**:
|
|
106
|
-
- **build_get_definition_revisions**:
|
|
107
|
-
- **build_get_builds**:
|
|
108
|
-
- **build_get_log**:
|
|
106
|
+
- **build_get_definitions**: Retrieve a list of build definitions for a given project.
|
|
107
|
+
- **build_get_definition_revisions**: Retrieve a list of revisions for a specific build definition.
|
|
108
|
+
- **build_get_builds**: Retrieve a list of builds for a given project.
|
|
109
|
+
- **build_get_log**: Retrieve the logs for a specific build.
|
|
109
110
|
- **build_get_log_by_id**: Get a specific build log by log ID.
|
|
110
111
|
- **build_get_changes**: Get the changes associated with a specific build.
|
|
111
|
-
- **build_run_build**:
|
|
112
|
-
- **build_get_status**:
|
|
113
|
-
- **build_update_build_stage**:
|
|
112
|
+
- **build_run_build**: Trigger a new build for a specified definition.
|
|
113
|
+
- **build_get_status**: Fetch the status of a specific build.
|
|
114
|
+
- **build_update_build_stage**: Update the stage of a specific build.
|
|
114
115
|
|
|
115
116
|
### π Releases
|
|
116
117
|
|
|
117
|
-
- **release_get_definitions**:
|
|
118
|
-
- **release_get_releases**:
|
|
118
|
+
- **release_get_definitions**: Retrieve a list of release definitions for a given project.
|
|
119
|
+
- **release_get_releases**: Retrieve a list of releases for a given project.
|
|
119
120
|
|
|
120
121
|
### π§ͺ Test Plans
|
|
121
122
|
|
|
122
|
-
- **testplan_create_test_plan**:
|
|
123
|
-
- **testplan_create_test_case**:
|
|
124
|
-
- **testplan_add_test_cases_to_suite**:
|
|
123
|
+
- **testplan_create_test_plan**: Create a new test plan in the project.
|
|
124
|
+
- **testplan_create_test_case**: Create a new test case work item.
|
|
125
|
+
- **testplan_add_test_cases_to_suite**: Add existing test cases to a test suite.
|
|
125
126
|
- **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.
|
|
126
|
-
- **testplan_list_test_cases**:
|
|
127
|
-
- **testplan_show_test_results_from_build_id**:
|
|
127
|
+
- **testplan_list_test_cases**: Get a list of test cases in the test plan.
|
|
128
|
+
- **testplan_show_test_results_from_build_id**: Get a list of test results for a given project and build ID.
|
|
128
129
|
|
|
129
130
|
### π Search
|
|
130
131
|
|
|
131
|
-
- **search_code**: Get
|
|
132
|
+
- **search_code**: Get code search results for a given search text.
|
|
132
133
|
- **search_wiki**: Get wiki search results for a given search text.
|
|
133
134
|
- **search_workitem**: Get work item search results for a given search text.
|
|
134
135
|
|
|
135
|
-
## π Installation &
|
|
136
|
+
## π Installation & Getting Started
|
|
136
137
|
|
|
137
138
|
Clone the repository, install dependencies, and add it to your MCP client configuration.
|
|
138
139
|
|
|
139
|
-
|
|
140
|
+
[VS Code and GitHub Copilot](#%EF%B8%8F-visual-studio-code--github-copilot)<br/>
|
|
141
|
+
[Visual Studio 2022 and GitHub Copilot](#%EF%B8%8F-visual-studio-2022--github-copilot)
|
|
142
|
+
|
|
143
|
+
### β‘οΈ Visual Studio Code & GitHub Copilot
|
|
140
144
|
|
|
141
145
|
For the best experience, use Visual Studio Code and GitHub Copilot.
|
|
142
146
|
|
|
@@ -157,51 +161,51 @@ az login
|
|
|
157
161
|
|
|
158
162
|
### Installation
|
|
159
163
|
|
|
160
|
-
#### β¨ One-Click
|
|
164
|
+
#### β¨ One-Click Install
|
|
161
165
|
|
|
162
166
|
[](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)
|
|
163
167
|
[](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)
|
|
164
168
|
|
|
165
169
|
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).
|
|
166
170
|
|
|
167
|
-
#### π§¨
|
|
171
|
+
#### 𧨠Install from Public Feed (Recommended)
|
|
168
172
|
|
|
169
|
-
This installation method is the easiest for all users
|
|
173
|
+
This installation method is the easiest for all users of Visual Studio Code.
|
|
170
174
|
|
|
171
175
|
π₯ [Watch this quick start video to get up and running in under two minutes!](https://youtu.be/EUmFM6qXoYk)
|
|
172
176
|
|
|
173
177
|
##### Steps
|
|
174
178
|
|
|
175
|
-
1. In your project, add a `.vscode\mcp.json` file
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
2. Save the file, then click 'Start
|
|
197
|
-
|
|
198
|
-
|
|
179
|
+
1. In your project, add a `.vscode\mcp.json` file with the following content:
|
|
180
|
+
|
|
181
|
+
```json
|
|
182
|
+
{
|
|
183
|
+
"inputs": [
|
|
184
|
+
{
|
|
185
|
+
"id": "ado_org",
|
|
186
|
+
"type": "promptString",
|
|
187
|
+
"description": "Azure DevOps organization name (e.g. 'contoso')"
|
|
188
|
+
}
|
|
189
|
+
],
|
|
190
|
+
"servers": {
|
|
191
|
+
"ado": {
|
|
192
|
+
"type": "stdio",
|
|
193
|
+
"command": "npx",
|
|
194
|
+
"args": ["-y", "@azure-devops/mcp", "${input:ado_org}"]
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
2. Save the file, then click 'Start'.
|
|
201
|
+
|
|
202
|
+
<img src="./docs/media/start-mcp-server.gif" alt="start mcp server" width="250"/>
|
|
199
203
|
|
|
200
204
|
3. In chat, switch to [Agent Mode](https://code.visualstudio.com/blogs/2025/02/24/introducing-copilot-agent-mode).
|
|
201
205
|
4. Click "Select Tools" and choose the available tools.
|
|
202
|
-
5. We strongly recommend
|
|
206
|
+
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.
|
|
203
207
|
|
|
204
|
-
#### π οΈ
|
|
208
|
+
#### π οΈ Install from Source (Dev Mode)
|
|
205
209
|
|
|
206
210
|
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.
|
|
207
211
|
|
|
@@ -211,39 +215,100 @@ This installation method is recommended for advanced users and contributors who
|
|
|
211
215
|
|
|
212
216
|
1. Clone the repository.
|
|
213
217
|
2. Install dependencies:
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
218
|
+
|
|
219
|
+
```sh
|
|
220
|
+
npm install
|
|
221
|
+
```
|
|
222
|
+
|
|
217
223
|
3. Edit or add `.vscode/mcp.json`:
|
|
218
224
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
4. Start the Azure DevOps MCP Server
|
|
239
|
-
|
|
240
|
-
|
|
225
|
+
```json
|
|
226
|
+
{
|
|
227
|
+
"inputs": [
|
|
228
|
+
{
|
|
229
|
+
"id": "ado_org",
|
|
230
|
+
"type": "promptString",
|
|
231
|
+
"description": "Azure DevOps organization's name (e.g. 'contoso')"
|
|
232
|
+
}
|
|
233
|
+
],
|
|
234
|
+
"servers": {
|
|
235
|
+
"ado": {
|
|
236
|
+
"type": "stdio",
|
|
237
|
+
"command": "mcp-server-azuredevops",
|
|
238
|
+
"args": ["${input:ado_org}"]
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
4. Start the Azure DevOps MCP Server.
|
|
245
|
+
|
|
246
|
+
<img src="./docs/media/start-mcp-server.gif" alt="start mcp server" width="250"/>
|
|
241
247
|
|
|
242
248
|
5. In chat, switch to [Agent Mode](https://code.visualstudio.com/blogs/2025/02/24/introducing-copilot-agent-mode).
|
|
243
249
|
6. Click "Select Tools" and choose the available tools.
|
|
244
|
-
7. We strongly recommend
|
|
250
|
+
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.
|
|
251
|
+
|
|
252
|
+
See the [How To](./docs/HOWTO.md) section for details.
|
|
253
|
+
|
|
254
|
+
### β‘οΈ Visual Studio 2022 & GitHub Copilot
|
|
255
|
+
|
|
256
|
+
For the best experience, use Visual Studio Code and GitHub Copilot π.
|
|
257
|
+
|
|
258
|
+
### Prerequisites
|
|
259
|
+
|
|
260
|
+
1. Install [VS Studio 2022 version 17.14](https://learn.microsoft.com/en-us/visualstudio/releases/2022/release-history) or later
|
|
261
|
+
2. Install [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli?view=azure-cli-latest)
|
|
262
|
+
3. Open a project in Visual Studio.
|
|
263
|
+
|
|
264
|
+
### Azure Login
|
|
265
|
+
|
|
266
|
+
Ensure you are logged in to Azure DevOps via the Azure CLI:
|
|
267
|
+
|
|
268
|
+
```sh
|
|
269
|
+
az login
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
#### 𧨠Install from Public Feed (Recommended)
|
|
273
|
+
|
|
274
|
+
This installation method is the easiest for all users of Visual Studio 2022.
|
|
275
|
+
|
|
276
|
+
π₯ [Watch this quick start video to get up and running in under two minutes!](https://youtu.be/nz_Gn-WL7j0)
|
|
277
|
+
|
|
278
|
+
##### Steps
|
|
279
|
+
|
|
280
|
+
1. Add a `.mcp.json` file to the solution folder with the following content:
|
|
281
|
+
|
|
282
|
+
```json
|
|
283
|
+
{
|
|
284
|
+
"inputs": [
|
|
285
|
+
{
|
|
286
|
+
"id": "ado_org",
|
|
287
|
+
"type": "promptString",
|
|
288
|
+
"description": "Azure DevOps organization name (e.g. 'contoso')"
|
|
289
|
+
}
|
|
290
|
+
],
|
|
291
|
+
"servers": {
|
|
292
|
+
"ado": {
|
|
293
|
+
"type": "stdio",
|
|
294
|
+
"command": "npx",
|
|
295
|
+
"args": ["-y", "@azure-devops/mcp", "${input:ado_org}"]
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
2. Save the file.
|
|
302
|
+
3. Add your organization name by clicking on the `input` option.
|
|
303
|
+
|
|
304
|
+
<img src="./docs/media/start-mcp-server-from-vs.png" alt="start mcp server from visual studio 2022" width="250"/>
|
|
305
|
+
|
|
306
|
+
4. Open Copilot chat and switch to [Agent Mode](https://learn.microsoft.com/en-us/visualstudio/ide/copilot-agent-mode?view=vs-2022).
|
|
307
|
+
5. Click the "Tools" icon and choose the available tools.
|
|
308
|
+
|
|
309
|
+
<img src="./docs/media/set-tools-from-vs.png" alt="set tools to use in visual studio 2022" width="250"/>
|
|
245
310
|
|
|
246
|
-
|
|
311
|
+
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.
|
|
247
312
|
|
|
248
313
|
## π¦ Usage
|
|
249
314
|
|
|
@@ -263,23 +328,23 @@ See [How To](./docs/HOWTO.md) section for details
|
|
|
263
328
|
3. Select desired `ado` tools.
|
|
264
329
|
4. Try prompts like "List ADO projects".
|
|
265
330
|
|
|
266
|
-
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).
|
|
331
|
+
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).
|
|
267
332
|
|
|
268
333
|
## π Troubleshooting
|
|
269
334
|
|
|
270
335
|
See the [Troubleshooting guide](./docs/TROUBLESHOOTING.md) for help with common issues and logging.
|
|
271
336
|
|
|
272
|
-
## π© Samples &
|
|
337
|
+
## π© Samples & Best Practices
|
|
273
338
|
|
|
274
339
|
Find sample prompts and best practices in our [How-to Guide](./docs/HOWTO.md).
|
|
275
340
|
|
|
276
|
-
## πββοΈ Frequently
|
|
341
|
+
## πββοΈ Frequently Asked Questions
|
|
277
342
|
|
|
278
343
|
For answers to common questions about the Azure DevOps MCP Server, see the [Frequently Asked Questions](./docs/FAQ.md).
|
|
279
344
|
|
|
280
345
|
## π Contributing
|
|
281
346
|
|
|
282
|
-
We welcome contributions! During preview, please file
|
|
347
|
+
We welcome contributions! During preview, please file issues for bugs, enhancements, or documentation improvements.
|
|
283
348
|
|
|
284
349
|
See our [Contributions Guide](./CONTRIBUTING.md) for:
|
|
285
350
|
|
|
@@ -288,7 +353,7 @@ See our [Contributions Guide](./CONTRIBUTING.md) for:
|
|
|
288
353
|
- π Code style & testing
|
|
289
354
|
- π Pull request process
|
|
290
355
|
|
|
291
|
-
## π€ Code of
|
|
356
|
+
## π€ Code of Conduct
|
|
292
357
|
|
|
293
358
|
This project follows the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
|
|
294
359
|
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,17 +4,33 @@
|
|
|
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
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
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
36
|
if (process.env.ADO_MCP_AZURE_TOKEN_CREDENTIALS) {
|
|
@@ -23,8 +39,16 @@ async function getAzureDevOpsToken() {
|
|
|
23
39
|
else {
|
|
24
40
|
process.env.AZURE_TOKEN_CREDENTIALS = "dev";
|
|
25
41
|
}
|
|
26
|
-
|
|
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
|
+
}
|
|
27
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
|
+
}
|
|
28
52
|
return token;
|
|
29
53
|
}
|
|
30
54
|
function getAzureDevOpsClient(userAgentComposer) {
|
package/dist/tools/builds.js
CHANGED
|
@@ -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
|
|
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
|
|
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.
|
|
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
|
|
187
|
+
state: safeEnumConvert(StageUpdateType, status),
|
|
181
188
|
};
|
|
182
189
|
const response = await fetch(endpoint, {
|
|
183
190
|
method: "PATCH",
|
package/dist/tools/releases.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
// Licensed under the MIT License.
|
|
3
3
|
import { ReleaseDefinitionExpands, ReleaseDefinitionQueryOrder, ReleaseExpands, ReleaseStatus, ReleaseQueryOrder } from "azure-devops-node-api/interfaces/ReleaseInterfaces.js";
|
|
4
4
|
import { z } from "zod";
|
|
5
|
+
import { getEnumKeys, safeEnumConvert } from "../utils.js";
|
|
5
6
|
const RELEASE_TOOLS = {
|
|
6
7
|
get_release_definitions: "release_get_definitions",
|
|
7
8
|
get_releases: "release_get_releases",
|
|
@@ -10,12 +11,18 @@ function configureReleaseTools(server, tokenProvider, connectionProvider) {
|
|
|
10
11
|
server.tool(RELEASE_TOOLS.get_release_definitions, "Retrieves list of release definitions for a given project.", {
|
|
11
12
|
project: z.string().describe("Project ID or name to get release definitions for"),
|
|
12
13
|
searchText: z.string().optional().describe("Search text to filter release definitions"),
|
|
13
|
-
expand: z
|
|
14
|
+
expand: z
|
|
15
|
+
.enum(getEnumKeys(ReleaseDefinitionExpands))
|
|
16
|
+
.default("None")
|
|
17
|
+
.describe("Expand options for release definitions"),
|
|
14
18
|
artifactType: z.string().optional().describe("Filter by artifact type"),
|
|
15
19
|
artifactSourceId: z.string().optional().describe("Filter by artifact source ID"),
|
|
16
20
|
top: z.number().optional().describe("Number of results to return (for pagination)"),
|
|
17
21
|
continuationToken: z.string().optional().describe("Continuation token for pagination"),
|
|
18
|
-
queryOrder: z
|
|
22
|
+
queryOrder: z
|
|
23
|
+
.enum(getEnumKeys(ReleaseDefinitionQueryOrder))
|
|
24
|
+
.default("NameAscending")
|
|
25
|
+
.describe("Order of the results"),
|
|
19
26
|
path: z.string().optional().describe("Path to filter release definitions"),
|
|
20
27
|
isExactNameMatch: z.boolean().optional().default(false).describe("Whether to match the exact name of the release definition. Default is false."),
|
|
21
28
|
tagFilter: z.array(z.string()).optional().describe("Filter by tags associated with the release definitions"),
|
|
@@ -26,7 +33,7 @@ function configureReleaseTools(server, tokenProvider, connectionProvider) {
|
|
|
26
33
|
}, async ({ project, searchText, expand, artifactType, artifactSourceId, top, continuationToken, queryOrder, path, isExactNameMatch, tagFilter, propertyFilters, definitionIdFilter, isDeleted, searchTextContainsFolderName, }) => {
|
|
27
34
|
const connection = await connectionProvider();
|
|
28
35
|
const releaseApi = await connection.getReleaseApi();
|
|
29
|
-
const releaseDefinitions = await releaseApi.getReleaseDefinitions(project, searchText, expand, artifactType, artifactSourceId, top, continuationToken, queryOrder, path, isExactNameMatch, tagFilter, propertyFilters, definitionIdFilter, isDeleted, searchTextContainsFolderName);
|
|
36
|
+
const releaseDefinitions = await releaseApi.getReleaseDefinitions(project, searchText, safeEnumConvert(ReleaseDefinitionExpands, expand), artifactType, artifactSourceId, top, continuationToken, safeEnumConvert(ReleaseDefinitionQueryOrder, queryOrder), path, isExactNameMatch, tagFilter, propertyFilters, definitionIdFilter, isDeleted, searchTextContainsFolderName);
|
|
30
37
|
return {
|
|
31
38
|
content: [{ type: "text", text: JSON.stringify(releaseDefinitions, null, 2) }],
|
|
32
39
|
};
|
|
@@ -37,7 +44,11 @@ function configureReleaseTools(server, tokenProvider, connectionProvider) {
|
|
|
37
44
|
definitionEnvironmentId: z.number().optional().describe("ID of the definition environment to filter releases"),
|
|
38
45
|
searchText: z.string().optional().describe("Search text to filter releases"),
|
|
39
46
|
createdBy: z.string().optional().describe("User ID or name who created the release"),
|
|
40
|
-
statusFilter: z
|
|
47
|
+
statusFilter: z
|
|
48
|
+
.enum(getEnumKeys(ReleaseStatus))
|
|
49
|
+
.optional()
|
|
50
|
+
.default("Active")
|
|
51
|
+
.describe("Status of the releases to filter (default: Active)"),
|
|
41
52
|
environmentStatusFilter: z.number().optional().describe("Environment status to filter releases"),
|
|
42
53
|
minCreatedTime: z.coerce
|
|
43
54
|
.date()
|
|
@@ -53,10 +64,18 @@ function configureReleaseTools(server, tokenProvider, connectionProvider) {
|
|
|
53
64
|
.optional()
|
|
54
65
|
.default(() => new Date())
|
|
55
66
|
.describe("Maximum created time for releases (default: now)"),
|
|
56
|
-
queryOrder: z
|
|
67
|
+
queryOrder: z
|
|
68
|
+
.enum(getEnumKeys(ReleaseQueryOrder))
|
|
69
|
+
.optional()
|
|
70
|
+
.default("Ascending")
|
|
71
|
+
.describe("Order in which to return releases (default: Ascending)"),
|
|
57
72
|
top: z.number().optional().describe("Number of releases to return"),
|
|
58
73
|
continuationToken: z.number().optional().describe("Continuation token for pagination"),
|
|
59
|
-
expand: z
|
|
74
|
+
expand: z
|
|
75
|
+
.enum(getEnumKeys(ReleaseExpands))
|
|
76
|
+
.optional()
|
|
77
|
+
.default("None")
|
|
78
|
+
.describe("Expand options for releases"),
|
|
60
79
|
artifactTypeId: z.string().optional().describe("Filter releases by artifact type ID"),
|
|
61
80
|
sourceId: z.string().optional().describe("Filter releases by artifact source ID"),
|
|
62
81
|
artifactVersionId: z.string().optional().describe("Filter releases by artifact version ID"),
|
|
@@ -69,7 +88,7 @@ function configureReleaseTools(server, tokenProvider, connectionProvider) {
|
|
|
69
88
|
}, async ({ project, definitionId, definitionEnvironmentId, searchText, createdBy, statusFilter, environmentStatusFilter, minCreatedTime, maxCreatedTime, queryOrder, top, continuationToken, expand, artifactTypeId, sourceId, artifactVersionId, sourceBranchFilter, isDeleted, tagFilter, propertyFilters, releaseIdFilter, path, }) => {
|
|
70
89
|
const connection = await connectionProvider();
|
|
71
90
|
const releaseApi = await connection.getReleaseApi();
|
|
72
|
-
const releases = await releaseApi.getReleases(project, definitionId, definitionEnvironmentId, searchText, createdBy, statusFilter, environmentStatusFilter, minCreatedTime, maxCreatedTime, queryOrder, top, continuationToken, expand, artifactTypeId, sourceId, artifactVersionId, sourceBranchFilter, isDeleted, tagFilter, propertyFilters, releaseIdFilter, path);
|
|
91
|
+
const releases = await releaseApi.getReleases(project, definitionId, definitionEnvironmentId, searchText, createdBy, safeEnumConvert(ReleaseStatus, statusFilter), environmentStatusFilter, minCreatedTime, maxCreatedTime, safeEnumConvert(ReleaseQueryOrder, queryOrder), top, continuationToken, safeEnumConvert(ReleaseExpands, expand), artifactTypeId, sourceId, artifactVersionId, sourceBranchFilter, isDeleted, tagFilter, propertyFilters, releaseIdFilter, path);
|
|
73
92
|
return {
|
|
74
93
|
content: [{ type: "text", text: JSON.stringify(releases, null, 2) }],
|
|
75
94
|
};
|