azure-devops-cli-mcp
azure-devops-cli-mcp
本地 MCP server,把 Claude Desktop / Cowork 橋接到本機的 Azure DevOps CLI。
Claude 可透過它完整使用 az devops、az repos、az boards、az pipelines、az artifacts。
前置需求
Node.js >= 20
Azure CLI(含 azure-devops extension):
az extension add --name azure-devops已完成
az login不需要
az devops configure --defaults:server 會自動帶入預設 organization / project / repository(見下方「啟動參數」)。
安裝(團隊成員)
npm install -g git+https://github.com/A016098Tony/azure-devops-cli-mcp.gitrepo 內已含編譯好的 dist/,安裝時不需要編譯。更新版本時重跑同一行命令即可。
註:script 刻意不叫
build/prepare——npm 11 全域安裝 git 套件時, 只要 package.json 有build/prepare/prepack/install類 script 就會觸發安裝端編譯,且因npm_config_global洩漏到內層 npm 而失敗。 命名為compile可讓安裝流程完全跳過編譯步驟。
Claude Desktop 設定
開啟 claude_desktop_config.json(Windows 完整路徑:
C:\Users\<你的帳號>\AppData\Roaming\Claude\claude_desktop_config.json;也可從
Claude Desktop → Settings → Developer → Edit Config 開啟),在 mcpServers 加入:
{
"mcpServers": {
"azure-devops-cli": {
"command": "npx",
"args": ["azure-devops-cli-mcp", "--project", "MS", "--repository", "MS-Web"]
}
}
}此設定檔 Claude Desktop(含 Cowork)與 Claude Code 共用同一格式。 claude.ai 網頁版不支援本機 stdio MCP server。
Claude Code 設定
在專案根目錄建立 .mcp.json,讓團隊成員 clone 後即可使用:
{
"mcpServers": {
"azure-devops-cli": {
"type": "stdio",
"command": "azure-devops-cli-mcp",
"args": ["--project", "MS", "--repository", "MS-Web"],
"env": {}
}
}
}再於 .claude/settings.json 加入以下設定,略過首次使用時的信任確認:
{
"enabledMcpjsonServers": ["azure-devops-cli"]
}兩個檔案都建議一起 commit。
啟動參數
三個參數皆選填,未指定時使用內建預設值:
參數 | 預設值 | 說明 |
|
| 可只給短名(如 |
|
| 預設專案 |
|
| 只套用在 |
命令未指定 --org / --project(repos pr 未指定 --repository)時,
server 會自動補上這些預設值;命令中明確指定時以命令為準。
若某個 az 子命令不接受被補上的參數,server 會自動移除該參數重試一次。
Windows + nvm 注意:桌面應用(GUI 程序)繼承的 PATH 可能與終端機不同, 若出現「找不到 npx」,把
command改成npx.cmd的絕對路徑 (用(Get-Command npx.cmd).Source查出,例如C:\nvm4w\nodejs\npx.cmd),args不變。
務必完整結束並重新啟動 Claude Desktop(關閉分頁不夠,要整個結束再開)才會載入。
啟動後可在對話框左下角的「+」→ Connectors 看到 azure-devops-cli 及其工具。
工具
工具 | 用途 |
| 執行任意 DevOps 家族命令,例如 |
| 查詢命令語法,等同 |
| 上傳本機檔案為 work item 附件並建立連結(文字與 binary 皆可,上限 100MB)。例如把 code review 報告或錯誤截圖附到 work item。 |
| 下載 work item 的圖與附件到系統暫存目錄(路徑由 server 決定)。同時收 HTML 欄位的內嵌 |
| 取得 PR 完整資訊(REST),含 source/target branch 與狀態,並預設一併回傳關聯 work item( |
| 取得 PR 異動檔案清單(REST iterations/changes),自動使用最新 iteration。 |
| 取得 PR 關聯的 work item 清單(REST)。 |
| 取得 work item 含 relations(REST,$expand=relations),可檢查附件重名。注意 |
| 在 PR 建立討論串留言或回覆既有討論串(REST)。 |
| 更新 work item 欄位/寫入 Discussion(REST json-patch,僅允許 /fields/*)。 |
| 通用 Azure DevOps REST 呼叫(GET/POST/PATCH),供未涵蓋的端點使用。 |
| 在主機端對本機 repo 執行 |
| 在主機端查詢遠端 refs( |
REST 工具的認證與 az_workitem_attach 相同:優先使用 AZURE_DEVOPS_EXT_PAT
環境變數,否則使用 az login 的憑證。所有 REST URL 鎖定在預設 organization,
無法對其他主機發送請求。
僅允許 devops、repos、boards、pipelines、artifacts 五個命令群組;
其餘 az 命令(如 vm、account)一律拒絕。認證依賴本機的 az login
(az_workitem_attach 會內部執行 az account get-access-token 取 token;
若設定了 AZURE_DEVOPS_EXT_PAT 環境變數則優先使用該 PAT),
server 不儲存任何憑證。
PR 與 work item 串接
常見流程是「從 PR 找到關聯 work item,再把報告或截圖附上去」。
az_pr_show 預設就會回傳 workItemRefs,所以一次呼叫即可:
// 1. 取 PR 資訊,順便拿到關聯 work item
az_pr_show { "prNumber": 104443 }
// → { "pullRequestId": 104443, "status": "active", ...,
// "workItemRefs": [{ "id": "160708", "url": "..." }] }
// 2. 上傳檔案到該 work item
az_workitem_attach { "workItemId": 160708, "filePath": "D:\\report.md" }有兩點容易踩到:
workItemRefs[].id是字串("160708"),而az_workitem_attach的workItemId要求數字,串接時必須轉型。az_workitem_attach的附件一律上傳到預設 project(沒有 per-call 覆寫參數)。 若 work item 不在預設 project,請改用az_rest自行呼叫 attachments 端點。
只需要確認附件是否已存在(避免重複上傳)時,用 az_workitem_relations
檢查 AttachedFile 的 attributes.name。反向要把 work item 的圖與附件抓到本機,
用 az_attachment_download(見下節)。
下載 work item 的圖與附件
Azure DevOps 把圖片存在兩個不同的地方,az_attachment_download 兩邊都會收:
來源 | 出現在哪 | 存到 |
描述裡貼上的截圖 | HTML 欄位的 |
|
掛在 work item 上的附件 |
|
|
掃描的 HTML 欄位有三個:System.Description、
Microsoft.VSTS.Common.AcceptanceCriteria、Microsoft.VSTS.TCM.ReproSteps。
內嵌圖片不會出現在 relations 裡,所以只用 az_workitem_relations 檢查會漏掉
需求描述裡的 UI 截圖 —— 實測 work item 160132 有 2 張內嵌圖與 6 個 .md 附件,
relations 只看得到後者。
檔案存在哪
固定在系統暫存目錄底下的 azure-devops-mcp/(Windows 是
%TEMP%\azure-devops-mcp\),呼叫端無法指定路徑:
%TEMP%/azure-devops-mcp/
├─ workitem-160132/
│ ├─ images/ 內嵌截圖
│ └─ attachments/ AttachedFile
└─ single/ url 模式的單檔這是刻意的設計。呼叫這個工具的是模型,而模型可能剛讀完一份外部可控的 work item 描述;若讓呼叫參數決定寫檔位置,等於讓描述內容有機會指定路徑。 移除參數就沒有這個著陸點。回傳訊息會給出絕對路徑,直接讀取即可。
檔案屬暫存性質,作業系統會自行清理,需要時重抓即可。 每次下載同一個 work item 會先清空該資料夾再重抓, 所以本機內容一定對應 ADO 現況,不會留下已刪除或改名的舊檔誤導判讀。
// 一次抓齊兩個來源
az_attachment_download { "workItemId": 160132 }
// → C:\Users\<你>\AppData\Local\Temp\azure-devops-mcp\workitem-160132
// images/ image.png (221071 bytes)、image-2.png (295748 bytes)
// attachments/ design.md (11918 bytes)、spec.md (11956 bytes)…
// 只抓單一附件(relations 的 URL 不帶檔名,記得一併給 fileName)
az_attachment_download { "url": "https://dev.azure.com/...", "fileName": "design.md" }
// → …\azure-devops-mcp\single\design.mdworkItemId 與 url 擇一,兩個都給或都不給會被拒絕。
url 模式可另外給 fileName 指定存檔名稱。relations 的附件 URL 不帶檔名
(回應的 content-disposition 也沒有 filename),所以從 az_workitem_relations
拿到 url 要單獨下載時,請把該附件的 attributes.name 一併傳進來,否則會存成
attachment、連抓兩個還會互相覆蓋。內嵌圖的 URL 本身帶 ?fileName=,不受影響。
fileName 只決定固定暫存目錄裡的檔名,決定不了目錄,且同樣會經過檔名清理。
同一次下載內的同名檔會自動改名(image.png → image-2.png)——
ADO 內嵌圖的預設檔名都叫 image.png,這在實務上很常見。
附件名含 Windows 不允許的字元(< > : " | ? * 與控制字元)時會換成 _。
: 特別重要:NTFS 會把 report:v1.md 當成 alternate data stream,
寫入不會報錯,但目錄裡只留下 0 bytes 的 report,內容藏在資料流裡。
ADO 的附件名可能來自 Mac/Linux,這些字元在那裡是合法的。
單檔上限 100MB。附件 URL 必須與預設 organization 同網域,否則直接拒絕且 不發出請求,避免認證 token 外洩到其他主機。個別檔案下載失敗不會中斷整批, 會列在回傳訊息的失敗清單裡。
安全防護
命令經由 shell 執行,因此雙引號外含有 shell 控制字元(& | ; < > ( ) \ ^或換行) 或有未配對雙引號的命令會被拒絕,以免repos list & <任意命令>之類的串接繞過群組 限制而執行任意本機命令。含特殊字元的參數值(例如 WIQL 或--query的 JMESPath 運算式) 用雙引號包起來即可正常執行,例如:boards query --wiql "SELECT [System.Id] FROM WorkItems WHERE [System.State] <> 'Closed'"`。
Git 工具
az_git_fetch / az_git_ls_remote 在主機端執行 git 的唯讀網路操作,
repoPath 必須是主機端的絕對路徑。az_git_ls_remote 的 patterns
可給多個 pattern,符合任一者的 ref 即列出(同原生 git ls-remote)。
參數經嚴格驗證:remote 只接受名稱(不接受 URL)、refspec/patterns
不可以 - 開頭(擋 --upload-pack 等危險選項)。不提供 push、pull 或任何寫入操作。認證使用主機端的
git credential(如 Git Credential Manager)。
開發
git clone https://github.com/A016098Tony/azure-devops-cli-mcp.git
npm install
npm test # vitest 單元 + 整合測試(不需要 az)
node scripts/smoke.mjs # 實機煙霧測試(需要 az login)改動 src/ 後務必執行 npm run compile 並把 dist/ 一起 commit——
安裝端直接使用 repo 內的 dist/,忘記重新編譯會讓使用者裝到舊版行為。