Azure DevOps 管理服务器

一个Python MCP服务器,用于管理和操作Azure DevOps Server (on-prem)的工作项、Git拉取请求和Wiki页面。

  • by aslamovyura
  • Python
  • 本地部署
  • 更新于
在 GitHub 查看 aslamovyura/azure-devops-mcp

使用说明

Azure DevOps(基于Prem)MCP服务器

  • Python MCP服务器公开了用于读取和管理Azure DevOps服务器(本地)Board工作项(任务、Bug、PBI、用户故事)、Git Pull Request和Wiki页面的工具。
  • 通过stdio与Codex代理(以及任何MCP客户端)合作。

特性

  • 工作项目(板):
    • 列出项目: list_projects
    • 使用WIQL搜索: search_work_items
    • 获取工作项: get_work_item
    • 创建: create_task
    • 更新字段/状态/受让人/标签: update_work_item
    • 添加历史评论: add_comment
    • 分配: assign_work_item
    • 过渡状态: transition_state
    • 链接项目: link_work_items
  • 拉取请求(Git):
    • 列出存储库: list_repositories
    • 列出PR: list_pull_requests
    • 获取PR: get_pull_request
    • 获取公关差异: get_pr_diffs
    • 列出PR承诺: list_pr_commits
    • 列出PR线程: list_pr_threads
    • PR评论: create_pr_comment
    • 列出审阅者: list_pr_reviewers
    • 添加审阅者: add_pr_reviewer
    • 设置审阅者投票: set_reviewer_vote
    • 更新PR: update_pull_request
    • 完整PR: complete_pull_request
    • 放弃公关: abandon_pull_request
  • Wiki(预览API):
    • 列出Wiki: list_wikis
    • 列表页面: list_wiki_pages
    • 获取页面: get_wiki_page
    • 更新页面: update_wiki_page
    • 上一页: upsert_wiki_page
    • 删除页面: delete_wiki_page
  • 测试计划/套件/案例(预览API):
  • 列出测试计划: list_test_plans
  • 列出平面图中的套房: list_test_suites
  • 列出套房中的案例: list_test_cases
  • 创建测试用例: create_test_case
  • 将案例添加到套件: add_test_case_to_suite
  • 从套件中删除案例: remove_test_case_from_suite

兼容性

  • Azure DevOps Server 2019+(大多数具有PAT或NTLM身份验证的TFS/DevOps服务器实例)。
  • 身份验证:个人访问令牌(推荐)或NTLM(Windows集成)。

安装(诗歌)

  • Python 3.12+
  • 安装诗歌: pip install poetry 或官方安装人员
  • 在repo根目录中: poetry install
  • 运行: poetry run azure-devops-mcp

配置

  • 所需的环境变量:
    • AZDO_BASE_URL:基本URL,例如。 https://devops.corp.local/tfs (或包括收藏,如 /tfs/DefaultCollection)
    • AZDO_COLLECTION:如果未包含在中,则可选 AZDO_BASE_URL (例如。 DefaultCollection)
    • AZDO_PROJECT:默认项目名称
    • AZDO_API_VERSION:REST API版本,默认 7.0
    • AZDO_VERIFY_SSL: true|false,默认值 true
    • AZDO_AUTH_TYPE: pat|ntlm,默认值 pat
    • 对于PAT: AZDO_PAT (范围:工作项读/写;对于PR Git读/写)
    • 对于NTLM: AZDO_NTLM_USERNAME, AZDO_NTLM_PASSWORD,可选 AZDO_NTLM_DOMAIN
  • Git(拉取请求):
    • AZDO_REPOSITORY:默认存储库名称或ID

例子

  • PAT示例:
    • AZDO_BASE_URL=https://devops.corp.local/tfs
    • AZDO_COLLECTION=DefaultCollection
    • AZDO_PROJECT=MyProject
    • AZDO_PAT=xxxxxxxxxxxxxxxxxxxxxxxxxxxx
  • NTLM示例:
    • AZDO_BASE_URL=https://tfs.corp.local/tfs/DefaultCollection
    • AZDO_PROJECT=Engineering
    • AZDO_AUTH_TYPE=ntlm
    • AZDO_NTLM_USERNAME=jdoe
    • AZDO_NTLM_PASSWORD=...
    • AZDO_NTLM_DOMAIN=CORP

运行(手动)

  • 通过Poetry启动MCP服务器:
    • poetry run azure-devops-mcp
    • 或者,在 poetry config virtualenvs.create false && poetry install,跑 azure-devops-mcp

与Codex试剂一起使用

  • 在Codex MCP配置中添加服务器条目:
    • "mcpServers": { "azure-devops-mcp": { "command": "azure-devops-mcp" } }
  • 如果你的启动器没有继承env变量,请用Poetry括起来:
    • "mcpServers": { "azure-devops-mcp": { "command": "poetry", "args": ["run", "azure-devops-mcp"] } }
  • 确保在启动服务器的过程中设置了上述环境变量。

码头工人

  • 构建: docker build -t azure-devops-mcp:latest .
  • 运行(PAT示例):
    • docker run --rm -it \ -e AZDO_BASE_URL=https://devops.corp.local/tfs \ -e AZDO_COLLECTION=DefaultCollection \ -e AZDO_PROJECT=MyProject \ -e AZDO_AUTH_TYPE=pat \ -e AZDO_PAT=xxxxxxxxxxxxxxxxxxxxxxxxxxxx \ -e AZDO_REPOSITORY=MyRepo \ azure-devops-mcp:latest
  • 运行(NTLM示例):
    • docker run --rm -it \ -e AZDO_BASE_URL=https://tfs.corp.local/tfs/DefaultCollection \ -e AZDO_PROJECT=Engineering \ -e AZDO_AUTH_TYPE=ntlm \ -e AZDO_NTLM_USERNAME=jdoe \ -e AZDO_NTLM_PASSWORD=... \ -e AZDO_NTLM_DOMAIN=CORP \ -e AZDO_REPOSITORY=MyRepo \ azure-devops-mcp:latest

Docker Compose

  • 复制env模板并编辑:
    • 窗户: copy .env.example .env
    • macOS/Linux: cp .env.example .env
  • 构建图像: docker compose build
  • 以交互方式运行: docker compose run --rm azure-devops-mcp
  • 与Codex一起使用:将MCP服务器命令设置为 docker compose run --rm azure-devops-mcp.

工具(签名)

  • 工作项
    • list_projects()
    • search_work_items(wiql, project?, top=50, expand="Relations")
    • get_work_item(id, expand="All")
    • create_task(project?, title, description?, assigned_to?, area_path?, iteration_path?, tags?, work_item_type="Task", state?)
    • update_work_item(id, title?, description?, assigned_to?, state?, add_tags?, remove_tags?, fields?, comment?)
    • add_comment(id, text)
    • assign_work_item(id, assigned_to)
    • transition_state(id, new_state)
    • link_work_items(source_id, target_id, link_type="System.LinkTypes.Hierarchy-Forward")
  • 拉取请求
    • list_repositories(project?)
    • list_pull_requests(repository?, project?, status='active', creator_id?, reviewer_id?, target_ref_name?, source_ref_name?, top?)
    • get_pull_request(pr_id, repository?, project?)
    • get_pr_diffs(pr_id, repository?, project?, include_content=false, top?, skip?)
      • 通过以下方式返回文件级差异 diffs/commits在某些本地服务器上,即使在以下情况下,大块内容也不可用 include_content=true.
      • 如果无法解析分支引用,则自动回退到基于提交的比较(例如,TF401175/GitUnsolvableToCommitException)。
    • get_pr_file_content(pr_id, path, repository?, project?, side='source')
      • 使用带有versionDescriptor的Git Items API在PR的源、目标或两侧下载文件的内容。
      • side: source | target | both.返回base64内容和commit/ref元数据。
    • list_pr_commits(pr_id, repository?, project?)
    • list_pr_threads(pr_id, repository?, project?)
    • create_pr_comment(pr_id, text, repository?, project?, file_path?, start_line?, end_line?)
    • list_pr_reviewers(pr_id, repository?, project?)
    • add_pr_reviewer(pr_id, reviewer_id, repository?, project?)
    • set_reviewer_vote(pr_id, reviewer_id, vote, repository?, project?)
    • update_pull_request(pr_id, repository?, project?, title?, description?, auto_complete_set?, completion_options?, status?)
    • complete_pull_request(pr_id, repository?, project?, delete_source_branch?, merge_commit_message?, merge_strategy?, transition_work_items?, squash_merge?)
    • abandon_pull_request(pr_id, repository?, project?)
  • Wiki(预览)
    • list_wikis(project?)
    • list_wiki_pages(wiki, project?, path?, recursion_level?, include_content=false)
    • get_wiki_page(wiki, path, project?, include_content=true)
    • update_wiki_page(wiki, path, content, project?, comment?, version?)
    • upsert_wiki_page(wiki, path, content, project?, comment?)
    • delete_wiki_page(wiki, path, project?, comment?)
  • 测试(预览)
  • list_test_plans(project?)
  • list_test_suites(plan_id, project?)
  • list_test_cases(plan_id, suite_id, project?)
  • create_test_case(project?, title, description?, assigned_to?, area_path?, iteration_path?, tags?, state?, extra_fields?)
  • add_test_case_to_suite(plan_id, suite_id, test_case_id, project?)
  • remove_test_case_from_suite(plan_id, suite_id, test_case_id, project?)

关于Prem Notes

  • 集合:许多本地实例在REST基础路径中包含一个集合(例如。, /tfs/DefaultCollection).通过设置 AZDO_COLLECTION 或包括在 AZDO_BASE_URL.
  • API版本:使用服务器支持的版本(例如6.0、7.0)。如果您看到版本错误,请降低 AZDO_API_VERSION.
  • 评论:对于工作项,评论是通过以下方式添加的 System.History 更新兼容性。

权限

  • PAT范围:至少工作项(读写);PR工具包括Git权限;for Wiki工具包括所需的Wiki权限。
  • 确保项目权限允许编辑工作项和完成PR。

故障排除

  • 身份验证失败:
    • PAT:验证PAT的有效性;在浏览器中尝试REST调用。
    • NTLM:确认域\用户名和密码;测试与 curl --ntlm.
  • API版本错误:调整 AZDO_API_VERSION (例如。, 6.0, 7.0).
  • SSL/PKI问题:设置 AZDO_VERIFY_SSL=false 用于测试环境或安装企业根CA。

发展

  • 安装: poetry install
  • 运行日志:set MCP_LOG_LEVEL=DEBUG 然后 poetry run azure-devops-mcp
  • 代码布局:
    • src/azure_devops_mcp/server.py
    • src/azure_devops_mcp/ado_client.py
    • src/azure_devops_mcp/config.py

锁定和再现性

  • 生成锁文件: poetry lock (或在中使用辅助脚本 scripts/ 如果存在)
  • 提交 poetry.lock 用于确定性安装。Dockerfile副本 poetry.lock* 利用层缓存。

安全

  • 安全地存储PAT(操作系统密钥链/秘密管理器)。避免提交env值。
  • 对于服务集成,更喜欢PAT而不是NTLM。