Skip to main content
Glama

mcp-beaker

PyPI Version PyPI Downloads CI License Python

MCP server for Beaker lab automation -- system provisioning, job management, distro discovery, and failure diagnosis.

Works with any Beaker server instance. Built on FastMCP v3 and designed for use with AI coding assistants (Cursor, Claude Desktop, etc.).

Features

  • 27 tools covering the full Beaker lifecycle: systems, jobs, distros, tasks

  • Hostname filter: list or search systems by FQDN substring (e.g. ampere-mtsnow), combined with availability presets (free/available/all)

  • Beaker Py3 compatible: works with both legacy and modernized Beaker REST APIs

  • Flexible auth: Kerberos (native GSSAPI/SPNEGO or bkr CLI fallback) and password (XML-RPC)

  • Job XML validation: auto-fills missing fields, infers distro families

  • Failure diagnosis: deep analysis with auto-retry on correctable failures

  • 10 documentation topics exposed as MCP resources

  • 2 workflow prompts for common tasks (reserve system, diagnose job)

  • Generic: works with any Beaker URL, configurable SSL/CA settings

Related MCP server: zuul-mcp

Installation

The container image bundles everything -- no host dependencies beyond podman (or docker). Kerberos authentication happens inside the container via KRB5_PRINCIPAL and KRB5_PASSWORD environment variables.

# Pull the pre-built image from GHCR
podman pull ghcr.io/faizbawa/mcp-beaker:latest

# Or build locally from the repo
podman build -t mcp-beaker:latest -f Containerfile .

Pip / uvx

# Using uv (recommended)
pip install uv
uvx mcp-beaker

# Using pip
pip install mcp-beaker
mcp-beaker

# With native Kerberos support (no bkr CLI needed -- requires krb5-devel on host)
pip install mcp-beaker[kerberos]

# Local development
uv run --directory /path/to/mcp-beaker mcp-beaker

Configuration

Cursor / VS Code

Add to your .cursor/mcp.json (or .vscode/mcp.json):

{
  "mcpServers": {
    "beaker": {
      "command": "podman",
      "args": [
        "run", "--rm", "-i", "--network=host",
        "-e", "BEAKER_URL=https://beaker.example.com",
        "-e", "KRB5_PRINCIPAL=your-user@YOUR.REALM",
        "-e", "KRB5_PASSWORD=your-kerberos-password",
        "ghcr.io/faizbawa/mcp-beaker:latest"
      ]
    }
  }
}

The container runs kinit internally -- no volume mounts, no host dependencies. Use --network=host so the container can reach your Kerberos KDC and Beaker server (especially over VPN).

Container with mounted ticket cache (no password in config)

Instead of storing your Kerberos password in mcp.json, you can mount a pre-existing ticket cache from the host:

Step 1 -- Create a file-based ticket on the host:

kinit -c FILE:/tmp/krb5cc_beaker your-user@YOUR.REALM

Re-run this whenever the ticket expires (typically every 10 hours).

Step 2 -- Mount the ticket into the container:

{
  "mcpServers": {
    "beaker": {
      "command": "podman",
      "args": [
        "run", "--rm", "-i", "--network=host",
        "-v", "/tmp/krb5cc_beaker:/tmp/krb5cc_0:ro,Z",
        "-e", "BEAKER_URL=https://beaker.example.com",
        "ghcr.io/faizbawa/mcp-beaker:latest"
      ]
    }
  }
}

The container detects the valid ticket and skips kinit entirely. No KRB5_PRINCIPAL or KRB5_PASSWORD needed. The :ro,Z mount flags ensure read-only access with proper SELinux labeling.

Note: The host typically uses KCM (D-Bus) for credential storage, which containers cannot access. That's why you need kinit -c FILE:... to create a file-based cache that can be bind-mounted.

SSL certificates: Many Beaker servers use internal CA certificates that are not in the container's default trust store. You have three options:

  1. Disable verification (simplest, fine on a trusted corporate network):

"-e", "BEAKER_SSL_VERIFY=false",
  1. Pass CA cert inline via BEAKER_CA_CERT_DATA (no volume mount needed):

"-e", "BEAKER_CA_CERT_DATA=-----BEGIN CERTIFICATE-----\nMIID...your-ca-cert...\n-----END CERTIFICATE-----",
  1. Mount a CA bundle (single file):

"-v", "/path/to/ca-bundle.crt:/tmp/ca-bundle.crt:ro",
"-e", "BEAKER_CA_CERT=/tmp/ca-bundle.crt",

Pip / uvx

{
  "mcpServers": {
    "beaker": {
      "command": "uvx",
      "args": ["mcp-beaker[kerberos]"],
      "env": {
        "BEAKER_URL": "https://beaker.example.com",
        "BEAKER_AUTH_METHOD": "kerberos",
        "BEAKER_KERBEROS_BACKEND": "http"
      }
    }
  }
}

Streamable HTTP mode

uvx mcp-beaker --transport streamable-http --port 8000
{
  "mcpServers": {
    "beaker": {
      "url": "http://localhost:8000/mcp",
      "type": "streamableHttp"
    }
  }
}

Environment Variables

Variable

Required

Default

Description

BEAKER_URL

Yes

--

Base URL of your Beaker server

BEAKER_AUTH_METHOD

No

kerberos

kerberos or password

BEAKER_KERBEROS_BACKEND

No

http

http (native SPNEGO) or bkr (bkr CLI)

BEAKER_USERNAME

For password auth

--

Beaker username

BEAKER_PASSWORD

For password auth

--

Beaker password

BEAKER_OWNER

No

$USER

Default owner for job queries

BEAKER_SSL_VERIFY

No

true

Verify SSL certificates

BEAKER_CA_CERT

No

--

Path to CA certificate bundle

KRB5_PRINCIPAL

Container only

--

Kerberos principal for kinit inside container

KRB5_PASSWORD

Container only

--

Kerberos password for kinit inside container

BEAKER_CA_CERT_DATA

Container only

--

PEM-encoded CA certificate written to file at startup

CLI Options

mcp-beaker [OPTIONS]

Options:
  --transport [stdio|sse|streamable-http]  Transport type (default: stdio)
  --port INTEGER                           Port for HTTP transports (default: 8000)
  --host TEXT                              Host for HTTP transports (default: 0.0.0.0)
  --path TEXT                              Path for streamable-http (default: /mcp)
  --beaker-url TEXT                        Beaker server URL
  --ssl-verify / --no-ssl-verify           Verify SSL certs (default: verify)
  --ca-cert TEXT                           CA certificate bundle path
  --auth-method [kerberos|password]        Authentication method
  --kerberos-backend [http|bkr]            Kerberos backend (default: http)
  --read-only                              Disable all write tools
  --enabled-tools TEXT                     Comma-separated tools to enable
  -v, --verbose                            Increase verbosity (-v info, -vv debug)
  --version                                Show version
  --help                                   Show this message

Tools

Read Tools (15)

Tool

Description

list_systems

List systems by availability (all/available/free) and optional hostname substring

search_systems

Search systems by hostname, CPU, architecture, memory, pool, and other hardware attributes

get_system_details

Hardware specs, CPU info, pool membership, ownership, status for a system

get_system_status

Current condition, reservation, and loan status for a system

get_system_history

Activity history for a system

get_system_arches

Supported OS families and architectures

list_jobs

Filter jobs by owner, status, whiteboard

get_job_status

Job status with failure diagnosis

get_job_results_xml

Export job results as XML

get_job_logs

List log files for a job/recipe/task

list_distro_trees

Search distros by name, family, arch, tags

list_os_families

List all known OS families

whoami

Show authenticated user info

list_lab_controllers

List all lab controllers

search_tasks

Search the task library

Write Tools (12)

Tool

Description

submit_job

Submit a job from XML (with validation and auto-fill)

clone_job

Clone and resubmit an existing job

cancel_job

Cancel a running/queued job

watch_job

Poll until completion with failure analysis and auto-retry

reserve_system

Manually reserve a system

release_system

Release a manually reserved system

loan_system

Grant a loan for a system to a user

return_loan

Return a current system loan

power_system

Power on/off/reboot a system

provision_system

Provision a reserved system with a distro

extend_watchdog

Extend a running task's watchdog timer

set_job_response

Ack/nak (waive) a recipe set result

Authentication

Ensure you have a valid ticket:

kinit your-username@YOUR.REALM

The server supports two Kerberos backends, controlled by BEAKER_KERBEROS_BACKEND:

Value

Backend

Install

http (default)

Native GSSAPI/SPNEGO -- lightweight, pip-installable

pip install mcp-beaker[kerberos]

bkr

bkr CLI subprocesses -- traditional, requires RPM

yum install beaker-client

Both backends use the same Kerberos ticket from kinit.

Password

Set BEAKER_AUTH_METHOD=password along with BEAKER_USERNAME and BEAKER_PASSWORD. The server authenticates via the XML-RPC auth.login_password() method. Note: this requires server-side LDAP to be enabled.

Architecture

src/mcp_beaker/
  __init__.py           # Click CLI entry point
  config.py             # BeakerConfig dataclass
  exceptions.py         # Custom exceptions
  client.py             # BeakerClient (XML-RPC + REST)
  models/               # Pydantic response models
  servers/
    __init__.py         # FastMCP server, lifespan, DI helper
    systems.py          # System tools (6 read + 6 write)
    jobs.py             # Job tools (4 read + 6 write)
    distros.py          # Distro tools (2 read)
    tasks.py            # Task tools (1 read)
    general.py          # General tools (2 read)
    prompts.py          # Workflow prompt templates
    resources.py        # Beaker documentation resources
  utils/
    xml_validation.py   # Job XML validation/auto-fill
    diagnosis.py        # Failure analysis engine
    formatting.py       # Human-readable formatters
    bkr_cli.py          # bkr CLI helpers
    parsing.py          # ID parsing utilities

Development

cd mcp-beaker
uv sync --dev
uv run pytest
uv run ruff check src/

License

MIT

Available Tools

27 tools
cancel_jobCancel JobA

Cancel a running or queued Beaker job.

Note: cancelling any part of a job (recipe, recipe set) cancels the entire job. The reason is recorded in the job history.

Inputs: task_id (required), reason. Returns: result

clone_jobClone JobA

Clone (re-submit) an existing Beaker job.

Fetches the original job's XML in clone mode, then submits it as a new job. Useful for retrying failed jobs or running the same test again.

Inputs: job_id (required). Returns: result

extend_watchdogExtend WatchdogA

Extend the watchdog timer for a running Beaker task.

Use this to extend a Beaker reservation and prevent the system from being reclaimed. Beaker's watchdog automatically aborts recipes that exceed their timeout — this tool pushes that deadline forward.

Provide either a task_id directly, or a job_id and the tool will find the currently running task for you.

Inputs: seconds (required), job_id, task_id. Returns: result

get_job_logsGet Job LogsA
Read-only

List all log files for a Beaker job, recipe, or task.

Returns URLs to log files including console.log, anaconda logs, and task output. Critical for debugging installation failures.

Inputs: task_id (required). Returns: result

get_job_results_xmlGet Job Results XMLA
Read-only

Export Beaker job results as XML.

Returns the XML representation of a job component including its current state. Use clone=true to get XML suitable for resubmission.

Inputs: task_id (required), clone. Returns: result

get_job_statusGet Job StatusA
Read-only

Check the status of a Beaker job and diagnose any failures.

Fetches detailed job information including recipe sets, recipes, and tasks, then highlights any problems found with failure analysis.

Inputs: job_id (required). Returns: result

get_system_archesGet System ArchitecturesA
Read-only

Get supported OS families and architectures for a Beaker system.

Returns a mapping of distro family names to their supported architecture list for the given system.

Inputs: fqdn (required). Returns: result

get_system_detailsGet System DetailsA
Read-only

Get detailed information about a specific Beaker system.

Returns hardware specs, ownership, status, architectures, and lab controller assignment for the given system FQDN.

Inputs: fqdn (required). Returns: result

get_system_historyGet System HistoryB
Read-only

Get activity history for a Beaker system.

Shows who used the system, what changed, and when. Useful for investigating system state changes and usage patterns.

Inputs: fqdn (required), since. Returns: result

get_system_statusGet System StatusA
Read-only

Get the current status of a Beaker system: who has it loaned and who is using it.

Returns the system condition (Automated/Manual/Broken/Removed), current loan details (recipient and comment), and current reservation details (user and recipe).

Inputs: fqdn (required). Returns: result

list_distro_treesList Distro TreesA
Read-only

Search available distro trees on the Beaker server.

Query the distro library to discover which distros are available before submitting a job. At least one search criterion is required.

Inputs: arch, name, tags, limit, +1 more. Returns: result

list_jobsList JobsA
Read-only

List Beaker jobs filtered by owner and other criteria.

Uses XML-RPC jobs.filter() to find matching job IDs, then optionally fetches full details for each via the REST API.

Inputs: limit, owner, max_id, min_id, +3 more. Returns: result

list_lab_controllersList Lab ControllersA
Read-only

List all lab controllers attached to the Beaker server.

Lab controllers manage system provisioning in specific labs. Useful for troubleshooting distro availability issues.

Inputs: no named parameters. Returns: result

list_os_familiesList OS FamiliesA
Read-only

List all distro families (OS major versions) known to Beaker.

Returns family names like 'RedHatEnterpriseLinux10', 'Fedora41', etc. Optionally filter to families that have distros with specific tags.

Inputs: tags. Returns: result

list_systemsList SystemsA
Read-only

List Beaker systems matching the filter criteria.

Returns a list of system FQDNs filtered by availability status and optional hostname substring. Use 'available' for systems you can reserve, 'free' for idle ones, or 'all' for the complete inventory.

Inputs: limit, hostname, filter_type. Returns: result

loan_systemLoan SystemA

Grant a loan for a Beaker system.

The loan recipient gets full permissions to reserve, provision, and schedule jobs on the system. While loaned, only the recipient and the system owner can use it. You must have permission to loan the system (typically the owner or an admin).

Inputs: fqdn (required), comment, recipient. Returns: result

power_systemPower SystemA

Control power for a Beaker system (on, off, or reboot).

Power control is not normally permitted when the system is in use by someone else. Use force=true to override this safety check.

Inputs: fqdn (required), action (required), force. Returns: result

provision_systemProvision SystemA

Provision a reserved Beaker system with a specific distro.

The system must be in 'Manual' condition and already reserved by you. Use list_distro_trees to find the distro_tree_id first.

Inputs: fqdn (required), distro_tree_id (required), reboot, ks_meta, +3 more. Returns: result

release_systemRelease SystemA

Release a manually reserved Beaker system.

You must be the current user of the system (i.e. you reserved it).

Inputs: fqdn (required). Returns: result

reserve_systemReserve SystemA

Manually reserve a Beaker system.

The system must be in 'Manual' condition and not currently in use. You must have permission to use the system. After reserving, you can provision it at will.

Inputs: fqdn (required). Returns: result

return_loanReturn System LoanA

Return a current loan on a Beaker system.

Either the loan recipient or a user with permission to loan the system can return it. The system reverts to its normal access policy.

Inputs: fqdn (required). Returns: result

search_systemsSearch SystemsA
Read-only

Search Beaker systems by hardware attributes and ownership.

Find systems matching hostname, CPU, architecture, memory, pool, owner, and other criteria. All filters are combined with AND logic.

Inputs: arch, pool, user, limit, +10 more. Returns: result

search_tasksSearch TasksA
Read-only

Search the Beaker task library for available test tasks.

Find tasks compatible with a given OS, distro, or package list. Returns task names and their excluded architectures.

Inputs: types, osmajor, packages, distro_name. Returns: result

set_job_responseSet Job ResponseA

Set the response (ack/nak) for a Beaker recipe set or job.

Used to acknowledge or waive recipe set results. Setting 'nak' is equivalent to waiving the result.

Inputs: task_id (required), response (required). Returns: result

submit_jobSubmit JobA

Submit a Beaker job from a complete job XML document.

The XML is validated before submission. Missing optional fields are auto-filled with sensible defaults. Uses Kerberos auth via the bkr CLI if available, otherwise falls back to XML-RPC password auth.

Inputs: job_xml (required), force. Returns: result

watch_jobWatch JobA

Watch a Beaker job until completion, with failure analysis and auto-retry.

Polls the job continuously. On success, returns a report. On failure, performs deep analysis (failure reasons, constraints, suggestions) and can auto-generate a corrected XML and resubmit up to max_retries times. Also works on already-finished jobs for post-mortem analysis.

Inputs: job_id (required), max_retries, poll_interval. Returns: result

whoamiWho Am IA
Read-only

Show the currently authenticated Beaker user.

Verifies that credentials are working and returns the username and email associated with the current session.

Inputs: no named parameters. Returns: result

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.7/5.0

    Scored across 27 tools

    Disambiguation3/5

    Several tools occupy adjacent territory: list_systems/search_systems, get_system_details/get_system_status, and get_job_status/watch_job can all be selected for similar intents. Most actions are still distinct after reading descriptions, but the 27-tool surface makes misselection possible.

    Naming Consistency4/5

    The set overwhelmingly uses a clear verb_noun snake_case pattern (submit_job, cancel_job, list_systems, reserve_system, provision_system). Minor inconsistencies such as return_loan versus loan_system, the extra _xml suffix on get_job_results_xml, and one-word whoami prevent a perfect score.

    Tool Count2/5

    At 27 tools, the set exceeds the 25+ threshold and feels heavier than necessary for the two core workflows of job management and system management. Some list/search/detail/status tools are close enough that consolidation would improve the surface.

    Completeness4/5

    Job and system lifecycles are well represented: jobs can be submitted, cloned, canceled, watched, inspected, logged, and acked, while systems can be discovered, reserved, provisioned, powered, loaned, and released. The only gap is the lack of destructive/admin operations such as deleting jobs or editing system metadata, but primary workflows have no dead ends.

    Maintenance

    ActivityInactive
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      B
      maintenance
      MCP server for Zuul CI/CD with 25 tools for builds, pipelines, queue management (enqueue/dequeue/promote), infrastructure visibility, and autohold management. Supports stdio, HTTP, and SSE transports.
      MIT
    • A
      license
      Not graded
      quality
      D
      maintenance
      MCP server for infrastructure discovery and remote management, enabling SSH command execution, file transfer, log tailing, and machine/service inventory with a companion web dashboard.
      2
      MIT