Skip to main content
Glama

azure-devops-cli-mcp

本地 MCP server,把 Claude Desktop / Cowork 橋接到本機的 Azure DevOps CLI。 Claude 可透過它完整使用 az devopsaz reposaz boardsaz pipelinesaz 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.git

repo 內已含編譯好的 dist/,安裝時不需要編譯。更新版本時重跑同一行命令即可。

註:script 刻意不叫 buildprepare——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。

啟動參數

三個參數皆選填,未指定時使用內建預設值:

參數

預設值

說明

--organization

https://dev.azure.com/SKMHHIS

可只給短名(如 SKMHHIS),自動補完整 URL

--project

MS

預設專案

--repository

MS-Web

只套用在 repos pr 命令

命令未指定 --org / --projectrepos 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 及其工具。

工具

工具

用途

az_devops

執行任意 DevOps 家族命令,例如 repos pr list --status active。未指定輸出格式時自動用 JSON。

az_devops_help

查詢命令語法,等同 az <command> --help

az_workitem_attach

上傳本機檔案為 work item 附件並建立連結(文字與 binary 皆可,上限 100MB)。例如把 code review 報告或錯誤截圖附到 work item。

az_attachment_download

下載 work item 的圖與附件到系統暫存目錄(路徑由 server 決定)。同時收 HTML 欄位的內嵌 <img>relationsAttachedFile;內嵌圖不在 relations 裡,只查 relations 會漏掉需求描述的截圖。也可用 url 模式下載單一附件。

az_pr_show

取得 PR 完整資訊(REST),含 source/target branch 與狀態,並預設一併回傳關聯 work item(workItemRefs);可用 includeWorkItemRefs: false 關閉。

az_pr_changes

取得 PR 異動檔案清單(REST iterations/changes),自動使用最新 iteration。

az_pr_workitems

取得 PR 關聯的 work item 清單(REST)。az_pr_show 已預設含這份清單,只在單獨要 work item、不想拉整包 PR 資訊時才需要。

az_workitem_relations

取得 work item 含 relations(REST,$expand=relations),可檢查附件重名。注意 relations 看不到描述裡的內嵌圖片,要取圖請用 az_attachment_download

az_pr_comment

在 PR 建立討論串留言或回覆既有討論串(REST)。

az_workitem_update

更新 work item 欄位/寫入 Discussion(REST json-patch,僅允許 /fields/*)。

az_rest

通用 Azure DevOps REST 呼叫(GET/POST/PATCH),供未涵蓋的端點使用。

az_git_fetch

在主機端對本機 repo 執行 git fetch(唯讀)。Cowork sandbox 內 fetch 被 proxy 擋下(403)時的替代路徑,fetch 完成後 sandbox 內即可用本機 git 操作 origin/<branch>

az_git_ls_remote

在主機端查詢遠端 refs(git ls-remote,不下載物件),可先確認遠端分支存在。

REST 工具的認證與 az_workitem_attach 相同:優先使用 AZURE_DEVOPS_EXT_PAT 環境變數,否則使用 az login 的憑證。所有 REST URL 鎖定在預設 organization, 無法對其他主機發送請求。

僅允許 devopsreposboardspipelinesartifacts 五個命令群組; 其餘 az 命令(如 vmaccount)一律拒絕。認證依賴本機的 az loginaz_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_attachworkItemId 要求數字,串接時必須轉型。

  • az_workitem_attach 的附件一律上傳到預設 project(沒有 per-call 覆寫參數)。 若 work item 不在預設 project,請改用 az_rest 自行呼叫 attachments 端點。

只需要確認附件是否已存在(避免重複上傳)時,用 az_workitem_relations 檢查 AttachedFileattributes.name。反向要把 work item 的圖與附件抓到本機, 用 az_attachment_download(見下節)。

下載 work item 的圖與附件

Azure DevOps 把圖片存在兩個不同的地方,az_attachment_download 兩邊都會收:

來源

出現在哪

存到

描述裡貼上的截圖

HTML 欄位的 <img src>

<暫存根目錄>/workitem-<id>/images/

掛在 work item 上的附件

relationsAttachedFile

<暫存根目錄>/workitem-<id>/attachments/

掃描的 HTML 欄位有三個:System.DescriptionMicrosoft.VSTS.Common.AcceptanceCriteriaMicrosoft.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.md

workItemIdurl 擇一,兩個都給或都不給會被拒絕。

url 模式可另外給 fileName 指定存檔名稱。relations 的附件 URL 不帶檔名 (回應的 content-disposition 也沒有 filename),所以從 az_workitem_relations 拿到 url 要單獨下載時,請把該附件的 attributes.name 一併傳進來,否則會存成 attachment、連抓兩個還會互相覆蓋。內嵌圖的 URL 本身帶 ?fileName=,不受影響。 fileName 只決定固定暫存目錄裡的檔名,決定不了目錄,且同樣會經過檔名清理。 同一次下載內的同名檔會自動改名(image.pngimage-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_remotepatterns 可給多個 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/,忘記重新編譯會讓使用者裝到舊版行為。