io.github.imatza-rh/mcp-zuul MCP Server
io.github.imatza-rh/mcp-zuul
Debug Zuul CI build failures with structured analysis, log search, and live pipeline status—no web UI clicking.
What is the io.github.imatza-rh/mcp-zuul MCP server?
The mcp-zuul MCP server provides AI agents with tools to analyze Zuul CI build failures, search logs, monitor pipeline status, and inspect job configurations. It exposes 48 tools covering builds, logs, pipelines, jobs, infrastructure, and live status, with structured failure parsing, regex log search, flaky job detection, and ML-based anomaly detection via LogJuicer.
mcp-zuul lets you debug Zuul CI failures by asking questions instead of clicking through web UIs. It parses Ansible task-level failure data from job-output.json, supports regex log search with context, detects flaky jobs, monitors live pipeline progress with ETAs, and integrates LogJuicer for ML-based anomaly detection. Works with Claude, Cursor, Codex, and any MCP-compatible client.
How to install io.github.imatza-rh/mcp-zuul
Copy-paste configuration for popular MCP clients.
ZUUL_URLZuul base URL (e.g. https://softwarefactory-project.io/zuul)
ZUUL_DEFAULT_TENANTDefault tenant name
ZUUL_AUTH_TOKENBearer token for authenticated instances
ZUUL_USE_KERBEROSEnable Kerberos/SPNEGO authentication (true/false)
MCP_TRANSPORTTransport mode: stdio, sse, or streamable-http (default: stdio)
ZUUL_ENABLED_TOOLSComma-separated list of tools to enable (disables all others)
ZUUL_DISABLED_TOOLSComma-separated list of tools to disable
Tools & capabilities
Tools this server exposes to the agent.
get_build_failures— Structured task-level failure data from job-output.json — failed play, task, host, message, return code, stderr/stdout.diagnose_build— One-call failure diagnosis combining structured failures with targeted log context (fatal/FAILED lines with surrounding context).get_build_log— Read and search log files with modes: summary, full (paginated), grep (regex + context), or exact line ranges. Supports any log file in the build directory.tail_build_log— Last N lines of a log (default 50, max 500) — token-efficient way to check why a build failed.get_build— Full build details — nodeset, log URL, artifacts, error detail. Accepts URL or UUID.list_builds— Search builds by project, pipeline, job, change, result with buildset UUID for cross-referencing.browse_build_logs— List log directory contents or fetch specific files (inventory, artifacts, must-gather). Max 512KB per file.stream_build_console— Live console from RUNNING builds via WebSocket. Returns last N lines; for completed builds use tail_build_log.get_buildset— Full buildset with all builds and events. Accepts URL or UUID.list_buildsets— Search buildsets with optional inline build details to save round-trips.get_status— Live pipeline status — queued/running jobs with progress and ETA, filterable by pipeline and project.get_change_status— Status for a change/PR/MR. In pipeline: live jobs with elapsed times. Not in pipeline: auto-fetches latest completed buildset.list_pipelines— All pipelines with their trigger types.list_jobs— List jobs with optional name filter.get_job— Job configuration — parent, nodeset, timeout, variants, source project.get_project— Which pipelines and jobs are configured for a project.list_projects— List all projects in a tenant with optional name filter.get_freeze_jobs— Resolved job dependency graph for a pipeline/project/branch showing all jobs with inheritance resolved.get_freeze_job— Resolved job config after inheritance — final merged nodeset, playbooks, variables, and timeout.find_flaky_jobs— Analyze recent build history for intermittent failures. Computes pass/fail rate and flags jobs as flaky (>20% failure).
Use cases
- Debug Ansible task failures with structured error messages, return codes, and stderr without scrolling through logs
- Search build logs with regex patterns and context lines to find specific errors or warnings
- Detect flaky jobs by analyzing recent build history and pass/fail statistics
- Monitor live pipeline status with job progress, elapsed times, and estimated completion ETAs
- Diagnose queue delays by checking node availability, semaphore locks, and system state
io.github.imatza-rh/mcp-zuul MCP server FAQ
mcp-zuul is an MCP server that gives AI agents like Claude and Cursor access to Zuul CI. It provides 48 tools for analyzing build failures, searching logs, monitoring pipelines, and inspecting job configurations—all with structured data instead of raw JSON or web UI clicking.
Yes, mcp-zuul is open-source (licensed under the repository's LICENSE file) and available on PyPI. Installation via uvx or pip is free.
Use `claude mcp add zuul -e ZUUL_URL=https://your-zuul.example.com -- uvx mcp-zuul` or add it to your client's MCP config file (~/.claude.json, .cursor/mcp.json, or claude_desktop_config.json) with the ZUUL_URL and optional ZUUL_DEFAULT_TENANT environment variables.
mcp-zuul supports bearer tokens (ZUUL_AUTH_TOKEN), Kerberos/SPNEGO (ZUUL_USE_KERBEROS=true), and unauthenticated access. Kerberos sessions persist and re-authenticate transparently on expiry.
Yes, you can configure multiple MCP server entries in your client config, each with a different ZUUL_URL and ZUUL_DEFAULT_TENANT.
By default ZUUL_READ_ONLY=true, which disables write operations (enqueue, dequeue, promote, reenqueue_buildset) and removes them from the server entirely. Set ZUUL_READ_ONLY=false to enable pipeline-affecting operations. Autohold management (create/delete) is always available.
README (reference)
Source of truth, from the repository.
mcp-zuul
<p align="center"> <a href="https://pypi.org/project/mcp-zuul/"><img src="https://img.shields.io/pypi/v/mcp-zuul" alt="PyPI"></a> <a href="https://pypi.org/project/mcp-zuul/"><img src="https://img.shields.io/pypi/pyversions/mcp-zuul" alt="Python"></a> <a href="https://github.com/imatza-rh/mcp-zuul/blob/main/LICENSE"><img src="https://img.shields.io/github/license/imatza-rh/mcp-zuul" alt="License"></a> <a href="https://github.com/imatza-rh/mcp-zuul/actions/workflows/ci.yml"><img src="https://github.com/imatza-rh/mcp-zuul/actions/workflows/ci.yml/badge.svg" alt="CI"></a> <a href="https://glama.ai/mcp/servers/imatza-rh/mcp-zuul"><img src="https://glama.ai/mcp/servers/imatza-rh/mcp-zuul/badges/score.svg" alt="MCP"></a> <a href="https://pepy.tech/projects/mcp-zuul"><img src="https://img.shields.io/pepy/dt/mcp-zuul" alt="Downloads"></a> <a href="https://codecov.io/gh/imatza-rh/mcp-zuul"><img src="https://codecov.io/gh/imatza-rh/mcp-zuul/graph/badge.svg" alt="codecov"></a> <a href="https://hifriendbot.com/ai-list/zuul-ci-by-imatza-rh/"><img src="https://hifriendbot.com/ai-list/badge/zuul-ci-by-imatza-rh.svg" alt="Listed on AiList"></a> </p>Debug build failures by asking questions, not clicking through web UIs. An MCP server for Zuul CI.
<p align="center"> <img src="assets/demo.gif" alt="mcp-zuul diagnosing a build failure" width="800" /> </p>If mcp-zuul saves you a debugging session, a ⭐ star helps others find it.
One command, no install:
claude mcp add zuul -e ZUUL_URL=https://your-zuul.example.com -- uvx mcp-zuul
48 tools, 5 prompts, 3 resources — covering builds, logs, pipelines, jobs, infrastructure, and live status. Works with Claude Code, Claude Desktop, Cursor, Codex, Windsurf, and any MCP-compatible client.
Why mcp-zuul?
| mcp-zuul | Raw Zuul API | Zuul web UI | |
|---|---|---|---|
| Failure analysis | Structured — task, host, error, rc | Raw JSON, parse yourself | Click through log pages |
| Log search | Regex + context lines + line ranges | Not available | Browser Ctrl+F |
| Flaky detection | Automatic pass/fail statistics | Manual query + calculate | Not available |
| Test results | Parsed JUnit XML with failure details | Not available | External link |
| Anomaly detection | ML-based via LogJuicer | Not available | Not available |
| Live status | Job progress, ETA, pre-failure alerts | Polling API | Manual refresh |
| Multi-instance | One config entry per Zuul | Different base URLs | Different browser tabs |
Quick Start
uvx (no install, recommended):
claude mcp add zuul \
-e ZUUL_URL=https://softwarefactory-project.io/zuul \
-e ZUUL_DEFAULT_TENANT=rdoproject.org \
-- uvx mcp-zuul
pip:
pip install mcp-zuul
Docker:
docker build -t mcp-zuul .
LobeHub — send this to your AI agent:
Read https://lobehub.com/mcp/imatza-rh-mcp-zuul/skill.md and follow the instructions to install the MCP server.
See Setup for full configuration options including Kerberos and multi-instance.
Features
Structured failure analysis — get_build_failures parses Zuul's job-output.json and returns exactly which Ansible task failed, on which host, with error message, return code, and stderr. No log scrolling needed.
Read any log file — get_build_log isn't limited to job-output.txt. Pass log_name to read any file in the build's log directory (ci_script logs, ansible.log, deployment logs) with full grep, tail, and line-range support.
Precise log navigation — Jump to exact line ranges with start_line/end_line. After finding an error at line 6148, read lines 6130-6160 instead of scrolling through 200-line chunks.
Smart grep — Regex search with context lines. Auto-converts common shell-grep \| syntax to Python regex | so patterns like error\|failed\|timeout just work.
Live pipeline awareness — get_change_status returns live job progress with elapsed times, estimated completion, and pre-failure detection (pre_fail field). When the change isn't in pipeline, automatically fetches the latest completed buildset.
Tool filtering — Reduce LLM tool-selection noise with ZUUL_ENABLED_TOOLS or ZUUL_DISABLED_TOOLS. Only expose the tools your workflow needs — the rest are removed from the server entirely.
URL-based input — Paste a Zuul build URL directly. Tools auto-parse the tenant and UUID from URLs like https://zuul.example.com/t/tenant/build/abc123 — no manual extraction needed.
Flaky job detection — find_flaky_jobs analyzes recent build history and computes pass/fail statistics to identify intermittent failures automatically.
Job dependency graph — get_freeze_jobs returns the fully-resolved job graph for a pipeline/project/branch, showing all jobs with their dependencies after inheritance resolution.
Kerberos/SPNEGO auth — First-class support for Zuul instances behind OIDC + Kerberos. Drives the full SPNEGO redirect chain automatically. Session cookies persist and re-authenticate transparently on expiry.
Streamable HTTP transport — Run as a persistent HTTP server with MCP_TRANSPORT=streamable-http for remote/shared deployment. Supports stdio (default), SSE, and streamable-http.
Write operations — Enqueue/dequeue/promote changes and re-enqueue buildsets. Pipeline-affecting tools are disabled by default (ZUUL_READ_ONLY=true) and removed from the server entirely so LLMs don't even see them. Autohold management (create/delete) is always available since it doesn't affect running pipelines.
LogJuicer integration — get_build_anomalies uses ML-based log analysis to find unusual lines by comparing failed logs against successful baselines. Optional — requires LOGJUICER_URL.
Token-efficient output — All responses strip None values and use compact formatters. tail_build_log returns just the last N lines — the fastest way to check why a build failed.
Error handling — All tools return JSON, errors included. Network failures, auth issues, and invalid parameters produce {"error": "descriptive message"}. Tools never raise unhandled exceptions.
Tools
Builds & Failures
| Tool | What it does |
|---|---|
list_builds | Search builds by project, pipeline, job, change, result. Includes buildset_uuid for cross-referencing. |
get_build | Full build details — nodeset, log URL, artifacts, error detail. Accepts url or uuid. |
get_build_failures | Start here for failures. Structured task-level data from job-output.json — failed play, task, host, msg, rc, stderr/stdout. Accepts url or uuid. |
diagnose_build | One-call failure diagnosis. Combines structured failures from job-output.json with targeted log context (fatal/FAILED lines with surrounding context from job-output.txt). Use instead of calling get_build_failures + get_build_log separately. Accepts url or uuid. |
get_build_log | Read and search log files. Modes: summary (tail + error lines), full (paginated), grep (regex + context), start_line/end_line (exact range). Supports log_name for any file. Accepts url or uuid. |
tail_build_log | Fastest failure check. Last N lines of a log (default 50, max 500). More token-efficient than get_build_log summary mode. Accepts url or uuid. |
browse_build_logs | List log directory contents or fetch specific files (inventory, artifacts, must-gather). Max 512KB per file. Accepts url or uuid. |
stream_build_console | Live console from RUNNING builds. Connects to Zuul WebSocket, returns last N lines (tail). For completed builds, use tail_build_log. Optional — requires pip install mcp-zuul[console]. |
Buildsets
| Tool | What it does |
|---|---|
list_buildsets | Search buildsets. Use include_builds=true to inline full build details (saves round-trips). |
get_buildset | Full buildset with all builds and events. Accepts url or uuid. |
Pipeline & Status
| Tool | What it does |
|---|---|
get_status | Live pipeline status — what's queued, running, with job progress and ETA. Filterable by pipeline and project. |
get_change_status | Status for a change/PR/MR. In pipeline: live jobs with elapsed times. Not in pipeline: auto-fetches latest completed buildset. Accepts url or change. |
list_pipelines | All pipelines with their trigger types. |
Jobs & Projects
| Tool | What it does |
|---|---|
list_tenants | All tenants with project counts. |
list_jobs | List jobs with optional name filter. |
get_job | Job configuration — parent, nodeset, timeout, variants, source project. |
get_project | Which pipelines and jobs are configured for a project. |
list_projects | List all projects in a tenant with optional name filter. |
get_config_errors | Check this when jobs aren't running. Configuration errors, missing refs, broken configs. Filterable by project. |
get_freeze_jobs | Resolved job dependency graph for a pipeline/project/branch. Shows exactly which jobs will run with inheritance resolved. |
get_freeze_job | Resolved job config after inheritance. Final merged nodeset, playbooks, variables, and timeout for a specific job. Answers "what will this job actually do?" |
find_flaky_jobs | Analyze recent build history for intermittent failures. Computes pass/fail rate and flags jobs as flaky (>20% failure with mixed results). |
get_build_times | Build duration trends with avg/min/max stats. Detect performance regressions or timeout-prone jobs. |
get_job_durations | Batch avg/min/max duration for multiple jobs in one call. Designed for monitoring an entire pipeline chain without N separate calls. |
check_health | Test API connectivity, auth status, and config. Triggers re-auth automatically if the Kerberos session expired. |
get_tenant_info | Tenant capabilities — auth realms, job history support, websocket URL. |
Infrastructure
| Tool | What it does |
|---|---|
list_nodes | Nodepool nodes with state (ready, in-use, building), provider, and label. Includes state summary. |
list_labels | Available nodepool labels — what node types jobs can request. |
list_semaphores | Resource locks with current holders and max capacity. Check when jobs wait unexpectedly. |
list_autoholds | Active autohold requests — nodes held after failure for debugging. |
get_autohold | Full details of a specific autohold request — held nodes, timing, project/job. |
list_providers | Nodepool cloud providers with flavors (VM sizes), images, and labels. |
list_images | Nodepool disk images with build status and provider upload state. |
list_system_events | System events — config updates, reconfigurations, pipeline changes. Useful for "why did my job stop running?" |
get_badge | CI status badge URL (SVG) for a project — embeddable in READMEs with Markdown snippet. |
get_connections | Configured source connections — Gerrit, GitHub, GitLab instances with driver and hostname. |
get_components | System components — schedulers, executors, mergers, web servers with state and version. |
Write Operations
Pipeline-affecting operations — disabled by default (ZUUL_READ_ONLY=true). Set ZUUL_READ_ONLY=false to enable. Requires auth token or Kerberos. Autohold management (create/delete) is always available since it doesn't affect running pipelines.
| Tool | What it does |
|---|---|
enqueue | Enqueue a change or ref into a pipeline. Supports both change-based (check/gate) and ref-based (periodic) enqueue. |
promote | Promote changes to the top of a pipeline queue. Use for urgent fixes when gate has a long queue. |
reenqueue_buildset | Re-enqueue a buildset — reads project/pipeline/ref from a previous buildset and enqueues it again. |
dequeue | Remove a change or ref from a pipeline. Destructive. |
autohold_create | Create an autohold request — hold nodes after failure for debugging. Not gated by ZUUL_READ_ONLY. |
autohold_delete | Delete an autohold request. Not gated by ZUUL_READ_ONLY. |
Test Results & Log Analysis
| Tool | What it does |
|---|---|
get_build_test_results | Parse JUnit XML test results. Discovers test files via zuul-manifest.json, returns structured pass/fail/skip counts with failure details. Works with tempest, tobiko, and any JUnit XML output. |
get_build_anomalies | ML-based log anomaly detection via LogJuicer. Compares failed logs against successful baselines. Requires LOGJUICER_URL. |
Prompts
Pre-built prompt templates that pre-load context and guide analysis:
| Prompt | What it does |
|---|---|
debug_build | Fetches build details + structured failures, checks for flaky signal from recent history, then guides root cause analysis. |
compare_builds | Loads two builds side-by-side with inline failure data for differential analysis — "why did this start failing?" |
check_change | Determines live pipeline status or latest results for a change, with appropriate next steps. |
tenant_health | Assesses overall tenant health — components, config errors, and node pool status in one view. |
diagnose_queue_delay | Diagnoses why jobs are queued or delayed — checks nodes, semaphores, and system state. |
Resources
Browsable context that clients can attach to conversations without tool calls:
| Resource | URI Pattern |
|---|---|
| Build details | zuul://{tenant}/build/{uuid} |
| Job configuration | zuul://{tenant}/job/{name} |
| Project configuration | zuul://{tenant}/project/{org}/{repo} |
Setup
MCP client configuration
All clients use the same JSON structure. Add to your client's MCP config file:
Claude Code (~/.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 (claude_desktop_config.json), Cursor (.cursor/mcp.json), and other MCP clients use the same format. GUI-based clients don't inherit your shell PATH - use the full path to uvx (run which uvx to find it).
Or via CLI:
claude mcp add zuul \
-e ZUUL_URL=https://softwarefactory-project.io/zuul \
-e ZUUL_DEFAULT_TENANT=rdoproject.org \
-- uvx mcp-zuul
Environment variables
| Variable | Required | Default | Description |
|---|---|---|---|
ZUUL_URL | Yes | — | Zuul base URL (e.g. https://softwarefactory-project.io/zuul) |
ZUUL_DEFAULT_TENANT | No | — | Default tenant (saves passing tenant on every call) |
ZUUL_AUTH_TOKEN | No | — | Bearer token for authenticated instances |
ZUUL_USE_KERBEROS | No | false | Enable Kerberos/SPNEGO authentication |
ZUUL_TIMEOUT | No | 30 | HTTP timeout in seconds |
ZUUL_VERIFY_SSL | No | true | SSL certificate verification |
MCP_TRANSPORT | No | stdio | Transport: stdio, sse, or streamable-http |
MCP_HOST | No | 127.0.0.1 | HTTP server bind address (non-stdio transports) |
MCP_PORT | No | 8000 | HTTP server port (non-stdio transports) |
ZUUL_ENABLED_TOOLS | No | — | Comma-separated list of tools to enable (disables all others) |
ZUUL_DISABLED_TOOLS | No | — | Comma-separated list of tools to disable (mutually exclusive with above) |
ZUUL_READ_ONLY | No | true | Set to false to enable pipeline-affecting write operations (enqueue, promote, dequeue, reenqueue_buildset). Autohold management (create/delete) is always available. |
LOGJUICER_URL | No | — | LogJuicer base URL for ML-based log anomaly detection |
Token authentication
Pass ZUUL_AUTH_TOKEN via host environment — never hardcode tokens in config files (visible in ps output):
export ZUUL_AUTH_TOKEN=<your-token>
For Docker, forward without a value to inherit from host:
"args": ["run", "-i", "--rm", "-e", "ZUUL_AUTH_TOKEN", "mcp-zuul"]
Kerberos / SPNEGO
For Zuul behind OIDC + Kerberos. Requires a valid Kerberos ticket (kinit) and the gssapi package.
Linux prerequisites - gssapi has no pre-built Linux wheels and must compile from source:
# Fedora/RHEL/CentOS
sudo dnf install krb5-devel python3-devel gcc
# Debian/Ubuntu
sudo apt install libkrb5-dev python3-dev gcc
macOS and Windows have pre-built wheels - no extra packages needed.
Then install with Kerberos support:
pip install mcp-zuul[kerberos] # or: uvx --with "mcp-zuul[kerberos]" mcp-zuul
Via CLI:
claude mcp add -s user zuul-internal \
-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 \
-- uvx --with "mcp-zuul[kerberos]" mcp-zuul
Or via JSON config:
{
"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"
}
}
}
For Docker, mount the Kerberos ticket cache:
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
Multiple instances
Add separate entries per Zuul instance:
{
"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" }
}
}
}
Troubleshooting
krb5-config: not found or Python.h: No such file when installing mcp-zuul[kerberos] on Linux:
gssapi has no pre-built Linux wheels - it compiles from source. Install system packages first:
# Fedora/RHEL/CentOS
sudo dnf install krb5-devel python3-devel gcc
# Debian/Ubuntu
sudo apt install libkrb5-dev python3-dev gcc
uvx: command not found in Cursor or Claude Desktop:
GUI-based MCP clients don't inherit your shell PATH. Use the full path to uvx:
which uvx # find the path, e.g. /usr/bin/uvx or ~/.local/bin/uvx
Then use that absolute path as command in your MCP config:
"command": "/usr/bin/uvx"
Permission errors on ~/.local/share/uv/:
If uv was previously run with sudo, the cache directory may be root-owned:
sudo chown -R $(whoami) ~/.local/share/uv/
Usage Examples
Debug a build failure
"Why did the latest build of my-project fail?"
→ list_builds(project="my-project", result="FAILURE", limit=1) → get_build_failures(uuid="...") → root cause with task name, error, and return code.
Deep-dive into logs
"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) → exact error with surrounding context.
Navigate to a specific error
"Show me lines 6478-6484 of the job output"
→ get_build_log(uuid="...", start_line=6478, end_line=6484) → exactly those 7 lines.
Check live pipeline status
"Is change 54321 in any pipeline?"
→ get_change_status(change="54321") → live jobs with elapsed times and ETA, or latest completed buildset if not in pipeline.
Compare build results across a pipeline
"Show me all builds from the latest buildset"
→ list_builds to get buildset_uuid → get_buildset(uuid="...") → all sibling builds with results and durations.
Paste a Zuul URL directly
"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") → tenant and UUID auto-extracted.
Debug why a job isn't running
"My project's check pipeline seems broken — jobs aren't triggering"
→ get_config_errors(project="org/my-project") → configuration errors, missing refs, or repo access issues.
Check node availability
"Jobs are stuck in queue — are there nodes available?"
→ list_nodes() → node states with by_state summary → list_labels() → available node types.
Detect flaky jobs
"Is this job flaky? It keeps failing intermittently"
→ find_flaky_jobs(job_name="my-deploy-job", limit=30) → pass/fail stats, failure rate, flaky=true/false.
See what jobs run for a project
"What jobs are configured for openstack-operator in the check pipeline?"
→ get_freeze_jobs(pipeline="check", project="openstack-k8s-operators/openstack-operator") → resolved job graph with dependencies.
Quick log tail
"Show me the last 30 lines of the build log"
→ tail_build_log(uuid="...", lines=30) → just the tail, minimal tokens.
What nodeset does my job use after inheritance?
"What nodeset and playbooks will deploy-job actually use?"
→ get_freeze_job(pipeline="check", project="org/repo", job_name="deploy-job") → resolved nodeset, playbooks, variables, timeout after all parent inheritance.
Development
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 .
Architecture
MCP Client (Claude Code, Cursor, etc.)
│
▼
┌──────────────────────────────────────────────────┐
│ src/mcp_zuul/ │
│ │
│ server.py MCPServer instance │
│ config.py env vars, transport, filtering │
│ auth.py Kerberos/SPNEGO + OIDC │
│ errors.py @handle_errors decorator │
├──────────────────────────────────────────────────┤
│ tools/ 48 tools across 8 submodules │
│ prompts.py 5 prompt templates │
│ resources.py 3 zuul:// resources │
├──────────────────────────────────────────────────┤
│ helpers.py API client, URL parsing │
│ formatters.py token-efficient output │
│ parsers.py Ansible/JUnit/log parsing │
│ classifier.py failure classification │
├──────────────────────────────────────────────────┤
│ httpx clients API (auth) + logs (no auth) │
└────────┬─────────────────────────┬───────────────┘
▼ ▼
Zuul REST API Log file hosts
See CLAUDE.md for full architecture details.
Listings
<a href="https://glama.ai/mcp/servers/imatza-rh/mcp-zuul"> <img width="380" height="200" src="https://glama.ai/mcp/servers/imatza-rh/mcp-zuul/badge" alt="mcp-zuul MCP server" /> </a>- PyPI —
pip install mcp-zuul - Glama — Quality: A/A/A
- Conare — Marketplace listing
- PulseMCP — Server directory
- LobeHub — MCP marketplace with agent install
- HiFriendBot — AI tools directory
- pepy.tech — Download statistics
- Docker —
ghcr.io/imatza-rh/mcp-zuul
Contributing
Contributions welcome. Please open an issue first to discuss significant changes.
# 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/
License
Apache-2.0
Related MCP servers

Financial Modeling Prep MCP Server
Access 250+ financial data tools via MCP for stocks, ETFs, crypto, forex, and economic analysis.

Apple Mail MCP
Full-coverage FTS5 body search for Apple Mail — reliable on large mailboxes.

io.github.img-src-io/mcp
MCP server for img-src.io Image CDN - upload, transform, and deliver images through AI assistants
U.S. federal contract opportunities from SAM.gov. Daily updates. Public Domain.
Wine matching, pricing, auctions, exchange, merchant, critic, portfolio, and cellar intelligence.

