朱
    
一 主控程序 服务器用于 Zuul CI 的.通过提问而不是点击web UI来调试构建失败。
38个工具(31个只读+5个写入+1个LogJuicer+1个控制台流)、3个提示模板和3个资源——涵盖构建、日志、管道、作业、基础设施和实时状态。支持stdio、SSE和可流式传输的http。适用于Claude Code、Claude Desktop、Cursor和任何兼容MCP的客户端。
You: "Why did the latest gate job fail?"
Claude: → get_build_failures(uuid="abc123")
→ get_build_log(uuid="abc123", log_name="controller/logs/ci_script_008_run.log",
grep="error|failed|timed out", context=2)
Root cause: cert-manager pod in Completed state blocked oc wait.
Confidence: Confirmed — verified in ci_script_008_run.log:325-329.快速开始
uvx (不安装,推荐):
claude mcp add zuul -- uvx mcp-zuul然后设置所需的env变量:
claude mcp add -e ZUUL_URL=https://softwarefactory-project.io/zuul \
-e ZUUL_DEFAULT_TENANT=rdoproject.org \
zuul -- uvx mcp-zuul点:
pip install mcp-zuul码头工人:
docker build -t mcp-zuul .看 设置 获取包括Kerberos和多实例在内的完整配置选项。
特性
结构化故障分析 — get_build_failures 解析Zuul的 job-output.json 并返回哪个Ansible任务失败、在哪个主机上失败、错误消息、返回代码和stderr。无需滚动日志。
读取任何日志文件 — get_build_log 不仅限于 job-output.txt.通行证 log_name 读取具有完整grep、tail和行范围支持的构建日志目录中的任何文件(ciscript日志、ansible.log、部署日志)。
精确的日志导航 --使用跳转到精确的线条范围 start_line/end_line在第6148行发现错误后,读取第6130-6160行,而不是滚动200行块。
智能grep --使用上下文行搜索正则表达式。自动转换通用shell grep \| Python正则表达式的语法 | 所以像这样的模式 error\|failed\|timeout 只是工作。
实时管道意识 — get_change_status 返回实时作业进度,包括经过的时间、估计完成时间和故障前检测(pre_fail 现场)。当更改未在管道中时,会自动获取最新完成的构建集。
Kerberos/SPNEGO身份验证 --OIDC+Kerberos背后对Zuul实例的一流支持。自动驱动完整的SPNEGO重定向链。会话Cookie会持续存在,并在到期时透明地重新进行身份验证。
基于URL的输入 --直接粘贴Zuul构建URL。工具自动从URL解析租户和UUID,如 https://zuul.example.com/t/tenant/build/abc123 --无需手动提取。
缺陷作业检测 — find_flaky_jobs 分析最近的构建历史并计算通过/失败统计数据,以自动识别间歇性故障。
作业依赖关系图 — get_freeze_jobs 返回管道/项目/分支的完全解析的作业图,显示继承解析后的所有作业及其依赖关系。
可流式HTTP传输 --作为持久HTTP服务器运行 MCP_TRANSPORT=streamable-http 用于远程/共享部署。支持stdio(默认)、SSE和可流式传输的http。
工具过滤 --通过以下方式降低LLM刀具选择噪音 ZUUL_ENABLED_TOOLS 或 ZUUL_DISABLED_TOOLS。只公开您的工作流程所需的工具。
写入操作 --对更改进行排队/排队,对引用和构建集进行重新排队,并管理自主权。默认情况下已禁用(ZUUL_READ_ONLY=true),写入工具完全从服务器中删除,因此LLM在显式启用之前甚至看不到它们。
LogJuicer集成 — get_build_anomalies 使用基于ML的日志分析,通过将失败的日志与成功的基线进行比较来发现异常行。可选--必需 LOGJUICER_URL.
令牌高效输出 --所有响应都会删除“无”值并使用紧凑的格式化程序。 tail_build_log 只返回最后N行,这是检查构建失败原因的最快方法。
工具
构建与失败
| 工具 | 它做什么 |
|---|---|
list_builds | 按项目、管道、作业、变更、结果搜索构建。包含 buildset_uuid 用于交叉引用。 |
get_build | 完整的构建细节——节点集、日志URL、工件、错误细节。接受 url 或 uuid. |
get_build_failures | 从这里开始失败。 来自的结构化任务级数据 job-output.json --播放、任务、主机、消息、rc、标准错误/标准输出失败。接受 url 或 uuid. |
diagnose_build | 一次呼叫失败诊断。 结合以下结构性故障 job-output.json 具有目标日志上下文(包含周围上下文的致命/失败行 job-output.txt).使用而不是呼叫 get_build_failures + get_build_log 单独。接受 url 或 uuid. |
get_build_log | 读取和搜索日志文件。模式: summary (尾部+误差线), full (分页), grep (正则表达式+上下文), start_line/end_line (精确范围)。支持 log_name 对于任何文件。接受 url 或 uuid. |
tail_build_log | 最快的故障检查。 日志的最后N行(默认50行,最大500行)。令牌效率高于 get_build_log 摘要模式。接受 url 或 uuid. |
browse_build_logs | 列出日志目录内容或获取特定文件(库存、工件、必须收集)。每个文件最大512KB。接受 url 或 uuid. |
stream_build_console | RUNNING构建的实时控制台。 连接到Zuul WebSocket,返回最后N行(尾部)。对于已完成的构建,请使用 tail_build_log.可选--必需 pip install mcp-zuul[console]. |
构建集
| 工具 | 它做什么 |
|---|---|
list_buildsets | 搜索构建集。使用 include_builds=true 内联完整的构建细节(节省往返时间)。 |
get_buildset | 包含所有构建和事件的完整构建集。接受 url 或 uuid. |
管道和状态
| 工具 | 它做什么 |
|---|---|
get_status | 实时管道状态——排队、运行、作业进度和预计到达时间。可按管道和项目进行过滤。 |
get_change_status | 更改/PR/MR的状态。正在处理中:具有已用时间的实时作业。不在管道中:自动获取最新完成的构建集。接受 url 或 change. |
list_pipelines | 所有管道及其触发类型。 |
工作和项目
| 工具 | 它做什么 |
|---|---|
list_tenants | 所有有项目计数的租户。 |
list_jobs | 列出具有可选名称筛选器的作业。 |
get_job | 作业配置——父项、节点集、超时、变量、源项目。 |
get_project | 为项目配置了哪些管道和作业。 |
list_projects | 使用可选的名称过滤器列出租户中的所有项目。 |
get_config_errors | 在作业未运行时检查此项。 配置错误、缺少引用、配置中断。可按项目筛选。 |
get_freeze_jobs | 已解析管道/项目/分支的作业依赖关系图。准确显示哪些作业将在继承已解决的情况下运行。 |
get_freeze_job | 继承后已解析作业配置。 最终合并了特定作业的节点集、剧本、变量和超时。回答“这份工作实际会做什么?” |
find_flaky_jobs | 分析间歇性故障的最近构建历史。计算通过/失败率,并将作业标记为不稳定(失败率>20%,结果喜忧参半)。 |
get_build_times | 使用平均/最小/最大统计数据构建持续时间趋势。检测性能退化或易超时的作业。 |
get_job_durations | 一次呼叫中多个作业的批处理平均/分钟/最大持续时间。设计用于监控整个管道链,无需N个单独的调用。 |
get_tenant_info | 租户功能——身份验证领域、作业历史支持、websocket URL |
基础设施
| 工具 | 它做什么 |
|---|---|
list_nodes | 具有状态(就绪、使用中、正在构建)、提供者和标签的节点池节点。包括状态摘要。 |
list_labels | 可用节点池标签——作业可以请求的节点类型。 |
list_semaphores | 具有当前持有者和最大容量的资源锁。检查作业何时意外等待。 |
list_autoholds | 主动自动保持请求——故障后为调试而保留的节点。 |
get_connections | 已配置源连接——Gerrit、GitHub、GitLab实例,带有驱动程序和主机名。 |
get_components | 系统组件——调度器、执行器、合并器、带状态和版本的web服务器。 |
写入操作
默认情况下已禁用(ZUUL_READ_ONLY=true).集 ZUUL_READ_ONLY=false 以启用。需要身份验证令牌或Kerberos。
| 工具 | 它做什么 |
|---|---|
enqueue | 将更改或引用排入管道。支持基于更改(检查/门)和基于引用(定期)的入队。 |
reenqueue_buildset | 重新排队构建集——从上一个构建集读取项目/管道/ref并再次排队。 |
dequeue | 从管道中删除更改或引用。 破坏性的。 |
autohold_create | 创建自动保持请求——在失败后保持节点以进行调试。 |
autohold_delete | 删除自动持有请求。 破坏性的。 |
测试结果和日志分析
| 工具 | 它做什么 |
|---|---|
get_build_test_results | 解析JUnitXML测试结果。 通过以下方式发现测试文件 zuul-manifest.json,返回结构化的通过/失败/跳过计数以及失败详细信息。适用于storst、tobiko和任何JUnitXML输出。 |
get_build_anomalies | 基于机器学习的日志异常检测 LogJuicer。将失败的日志与成功的基线进行比较。需要 LOGJUICER_URL. |
提示
预加载上下文并指导分析的预构建提示模板:
| 提示 | 它做什么 |
|---|---|
debug_build | 获取构建细节+结构化故障,检查最近历史中的不稳定信号,然后指导根本原因分析。 |
compare_builds | 将两个构建与内联故障数据并排加载以进行差异分析——“为什么这开始失败了?” |
check_change | 确定实时管道状态或更改的最新结果,以及相应的后续步骤。 |
资源
客户端可以附加到对话而无需工具调用的可浏览上下文:
| 资源 | URI模式 |
|---|---|
| 构建详细信息 | zuul://{tenant}/build/{uuid} |
| 作业配置 | zuul://{tenant}/job/{name} |
| 项目配置 | zuul://{tenant}/project/{org}/{repo} |
设置
MCP客户端配置
所有客户端都使用相同的JSON结构。添加到客户的MCP配置文件中:
克劳德代码 (~/.claude.json → mcpServers):
{
"mcpServers": {
"zuul": {
"command": "uvx",
"args": ["mcp-zuul"],
"env": {
"ZUUL_URL": "https://softwarefactory-project.io/zuul",
"ZUUL_DEFAULT_TENANT": "rdoproject.org"
}
}
}
}克劳德桌面版 (claude_desktop_config.json), 光标 (.cursor/mcp.json),其他MCP客户端使用相同的格式。基于GUI的客户端不会继承你的shell PATH -使用完整路径 uvx (奔跑 which uvx 找到它)。
或者通过CLI:
claude mcp add -e ZUUL_URL=https://softwarefactory-project.io/zuul \
-e ZUUL_DEFAULT_TENANT=rdoproject.org \
zuul -- uvx mcp-zuul环境变量
| 变量 | 必填 | 默认 | 描述 |
|---|---|---|---|
ZUUL_URL | 是 | -- | Zuul基本URL(例如。 https://softwarefactory-project.io/zuul) |
ZUUL_DEFAULT_TENANT | 否 | -- | 默认租户(保存传递 tenant 每次通话) |
ZUUL_AUTH_TOKEN | 没有 | -- | 经过身份验证的实例的承载令牌 |
ZUUL_USE_KERBEROS | 没有 | false | 启用Kerberos/SPNEGO身份验证 |
ZUUL_TIMEOUT | 没有 | 30 | HTTP超时(秒) |
ZUUL_VERIFY_SSL | 没有 | true | SSL证书验证 |
MCP_TRANSPORT | 没有 | stdio | 运输: stdio, sse,或 streamable-http |
MCP_HOST | 没有 | 127.0.0.1 | HTTP服务器绑定地址(非stdio传输) |
MCP_PORT | 没有 | 8000 | HTTP服务器端口(非stdio传输) |
ZUUL_ENABLED_TOOLS | 否 | -- | 以逗号分隔的要启用的工具列表(禁用所有其他工具) |
ZUUL_DISABLED_TOOLS | 否 | -- | 以逗号分隔的禁用工具列表(与上述工具互斥) |
ZUUL_READ_ONLY | 没有 | true | 设置为 false 启用写操作(入队、重排队构建集、出队、自动保持) |
LOGJUICER_URL | 没有 | -- | LogJuicer基本URL用于基于ML的日志异常检测 |
令牌身份验证
通过 ZUUL_AUTH_TOKEN 通过主机环境-- 永远不要在配置文件中硬编码令牌 (可见于 ps 输出):
export ZUUL_AUTH_TOKEN=对于Docker,无需从主机继承值即可转发:
"args": ["run", "-i", "--rm", "-e", "ZUUL_AUTH_TOKEN", "mcp-zuul"]Kerberos/SPNEGO
对于OIDC+Kerberos背后的Zuul。需要有效的Kerberos票证(kinit)以及 gssapi 包裹。
Linux先决条件 - gssapi 没有预构建的Linux轮子,必须从源代码编译:
# Fedora/RHEL/CentOS
sudo dnf install krb5-devel python3-devel gcc
# Debian/Ubuntu
sudo apt install libkrb5-dev python3-dev gccmacOS和Windows都有预构建的轮子,不需要额外的软件包。
然后安装Kerberos支持:
pip install mcp-zuul[kerberos] # or: uvx --with "mcp-zuul[kerberos]" mcp-zuul通过CLI:
claude mcp add -s user \
-e ZUUL_URL=https://internal-zuul.example.com/zuul \
-e ZUUL_DEFAULT_TENANT=my-tenant \
-e ZUUL_USE_KERBEROS=true \
-e ZUUL_VERIFY_SSL=false \
zuul -- uvx --with "mcp-zuul[kerberos]" mcp-zuul或者通过JSON配置:
{
"zuul-internal": {
"command": "uvx",
"args": ["--with", "mcp-zuul[kerberos]", "mcp-zuul"],
"env": {
"ZUUL_URL": "https://internal-zuul.example.com/zuul",
"ZUUL_USE_KERBEROS": "true",
"ZUUL_VERIFY_SSL": "false"
}
}
}对于Docker,挂载Kerberos票证缓存:
docker run -i --rm \
-v /etc/krb5.conf:/etc/krb5.conf:ro \
-v /tmp/krb5cc_$(id -u):/tmp/krb5cc_$(id -u):ro \
-e KRB5CCNAME=/tmp/krb5cc_$(id -u) \
-e ZUUL_URL=https://internal-zuul.example.com/zuul \
-e ZUUL_USE_KERBEROS=true \
mcp-zuul多个实例
为每个Zuul实例添加单独的条目:
{
"mcpServers": {
"zuul-rdo": {
"command": "uvx", "args": ["mcp-zuul"],
"env": { "ZUUL_URL": "https://softwarefactory-project.io/zuul", "ZUUL_DEFAULT_TENANT": "rdoproject.org" }
},
"zuul-internal": {
"command": "mcp-zuul",
"env": { "ZUUL_URL": "https://internal.example.com/zuul", "ZUUL_USE_KERBEROS": "true" }
}
}
}故障排除
krb5-config: not found 或 Python.h: No such file 安装时 mcp-zuul[kerberos] 在Linux上:
gssapi 没有预构建的Linux轮子,它是从源代码编译的。首先安装系统包:
# Fedora/RHEL/CentOS
sudo dnf install krb5-devel python3-devel gcc
# Debian/Ubuntu
sudo apt install libkrb5-dev python3-dev gccuvx: command not found 在光标或克劳德桌面中:
基于GUI的MCP客户端不会继承您的shell PATH.使用完整路径 uvx:
which uvx # find the path, e.g. /usr/bin/uvx or ~/.local/bin/uvx然后使用该绝对路径作为 command 在MCP配置中:
"command": "/usr/bin/uvx"权限错误 上 ~/.local/share/uv/:
如果 uv 以前运行过 sudo,缓存目录可以是root拥有的:
sudo chown -R $(whoami) ~/.local/share/uv/用法示例
调试构建失败
"Why did the latest build of my-project fail?"→ list_builds(project="my-project", result="FAILURE", limit=1) → get_build_failures(uuid="...") → 包含任务名称、错误和返回代码的根本原因。
深入研究原木
"The structured data says 'non-zero return code' but no error detail.
Check the ci_script logs."→ browse_build_logs(uuid="...", path="controller/ci-framework-data/logs/") → finds ci_script_008_run.log → get_build_log(uuid="...", log_name="controller/ci-framework-data/logs/ci_script_008_run.log", grep="error|timed out|Error 1", context=2) → 与周围环境完全错误。
导航到特定错误
"Show me lines 6478-6484 of the job output"→ get_build_log(uuid="...", start_line=6478, end_line=6484) → 正是这7条线。
检查带电管道状态
"Is change 54321 in any pipeline?"→ get_change_status(change="54321") → 实时作业,包括已用时间和预计到达时间,或者最新完成的构建集(如果不在管道中)。
比较管道中的构建结果
"Show me all builds from the latest buildset"→ list_builds 得到 buildset_uuid → get_buildset(uuid="...") → 所有兄弟构建都有结果和持续时间。
直接粘贴Zuul URL
"What went wrong with this build?
https://zuul.example.com/t/tenant/build/abc123def"→ get_build_failures(url="https://zuul.example.com/t/tenant/build/abc123def") → 租户和UUID自动提取。
调试作业未运行的原因
"My project's check pipeline seems broken — jobs aren't triggering"→ get_config_errors(project="org/my-project") → 配置错误、缺少引用或仓库访问问题。
检查节点可用性
"Jobs are stuck in queue — are there nodes available?"→ list_nodes() → 带有by_state摘要的节点状态→ list_labels() → 可用节点类型。
检测不稳定的作业
"Is this job flaky? It keeps failing intermittently"→ find_flaky_jobs(job_name="my-deploy-job", limit=30) → 通过/失败统计数据、失败率、flaky=真/假。
查看项目运行的作业
"What jobs are configured for openstack-operator in the check pipeline?"→ get_freeze_jobs(pipeline="check", project="openstack-k8s-operators/openstack-operator") → 解析了具有依赖关系的作业图。
快速原木尾
"Show me the last 30 lines of the build log"→ tail_build_log(uuid="...", lines=30) → 只有尾巴,最小的代币。
继承后,我的作业使用什么节点集?
"What nodeset and playbooks will deploy-job actually use?"→ get_freeze_job(pipeline="check", project="org/repo", job_name="deploy-job") → 解析节点集、剧本、变量、所有父继承后的超时。
发展
git clone https://github.com/imatza-rh/mcp-zuul.git
cd mcp-zuul
uv sync --extra dev
# Run locally
ZUUL_URL=https://softwarefactory-project.io/zuul uv run mcp-zuul
# Run tests
uv run pytest tests/ -v
# Lint and format
uv run ruff check src/ tests/
uv run ruff format --check src/ tests/
# Type check
uv run mypy src/mcp_zuul/
# Build Docker image
docker build -t mcp-zuul .架构: 多模块封装 src/mcp_zuul/ — config.py (环境变量、传输、工具过滤、只读模式), auth.py (Kerberos/SPNEGO), server.py (FastMCP+寿命+工具过滤+写入工具门控), helpers.py (API客户端,带有GET/POST/DELETE、URL解析、日志流), formatters.py (令牌高效输出), errors.py (统一错误处理), tools.py (38个工具), prompts.py (3个提示), resources.py (3个资源)。看 CLAUDE.md 以获取完整的架构描述。
贡献
欢迎捐款。请先打开一个问题来讨论重大更改。
# Fork, clone, and install dev dependencies
uv sync --extra dev
# Make changes, then verify
uv run pytest tests/ -v
uv run ruff check src/ tests/
uv run ruff format src/ tests/
uv run mypy src/mcp_zuul/许可证
阿帕奇-2.0
