Skip to main content

MCP server for Allure TestOps — projects, launches, test cases, test results, defect categories

Project description

allure-testops-mcp

PyPI Python License: MIT Tests

An MCP server for Allure TestOps. It lets an LLM agent (Claude Code, Cursor, OpenCode, …) explore and manage projects, launches, test cases, test results and reference data through the Allure REST API.

  • Stack: Python 3.10+, FastMCP, stdio transport.
  • Compatibility: any Allure TestOps instance — SaaS qameta.io or self-hosted / on-prem (API at /api/rs).
  • Instance-wide — all projects at once: one connection serves every project on the instance. The server isn't pinned to a single project — discover them with allure_list_projects, then pass any project_id. No reconfiguration to switch or compare projects.
  • Corporate-friendly: API-token auth, optional SSL-verify toggle, deliberate proxy bypass.
  • Safe by default: 13 read-only tools; the 7 write tools are off unless you opt in.

Quick start

claude mcp add allure -s user \
  --env ALLURE_URL=https://allure.example.com \
  --env ALLURE_TOKEN=your-api-token \
  -- uvx --from allure-testops-mcp allure-testops-mcp

Then ask your agent: "List all Allure projects" or "Show failed tests in the last launch for project 175". Get an API token in Allure TestOps under Profile → API tokens. See Configuration for other clients and Environment variables for all options.

Tools at a glance

20 tools — 13 read-only (always on) and 7 write tools (opt-in via ALLURE_ENABLE_WRITE=true). Every tool carries MCP annotations and returns both a typed structuredContent payload and a markdown summary.

Tool Kind Purpose
allure_list_projects read All projects (id, name, abbreviation)
allure_get_project_statistics read TC count, automation rate, last-launch summary
allure_list_launches read Recent launches with pass/fail stats
allure_get_test_results read Test results in a launch (filter by status)
allure_search_failed_tests read FAILED/BROKEN tests in the last or a given launch
allure_list_test_cases read Test cases (automated/manual + owner filters)
allure_get_test_case read One test case's full detail + scenario steps
allure_get_test_case_custom_fields read A test case's custom-field values
allure_list_statuses read A project's statuses (id, name, color)
allure_list_layers read A project's test layers (id, name)
allure_list_custom_fields read A project's custom-field schema
allure_list_categories read Defect categories (named/coloured buckets)
allure_list_category_matchers read Regex automation rules (message/trace → category)
allure_create_test_case write ⚑ Create a test case
allure_update_test_case write ⚑ Partial update of a test case
allure_delete_test_case write ⚑ Permanent delete (destructive — needs confirm=true)
allure_create_category write ⚑ Create a defect category
allure_delete_category write ⚑ Permanent delete (destructive — needs confirm=true)
allure_create_category_matcher write ⚑ Create + attach a regex automation rule
allure_delete_category_matcher write ⚑ Permanent delete (destructive — needs confirm=true)

⚑ Registered only when ALLURE_ENABLE_WRITE=true. Without the flag they are never imported, so the agent never sees them — see Security considerations.

Write tools — status & layer by name or id

allure_create_test_case / allure_update_test_case accept status and layer as either a name (status / layer) or a numeric id (status_id / layer_id). Names are auto-resolved to ids against the project's status/layer lists (GET /api/rs/status, GET /api/rs/testlayer) — an unknown name returns an actionable error listing the valid options. Update is partial (only the fields you pass change), and allure_delete_test_case is irreversible: it carries destructiveHint: True (compliant clients prompt) and additionally requires an explicit confirm=true argument.

Design highlights

  • Full tool annotations — read tools are readOnlyHint: True / openWorldHint: True so clients don't prompt; allure_delete_test_case is destructiveHint: True.
  • Structured output on every tool — each tool declares a TypedDict return type, so FastMCP auto-generates an outputSchema and every result carries both structuredContent and a markdown block.
  • Actionable errors — auth / 400 / 403 / 404 / 409 / 429 / 5xx / missing-env errors are converted to specific, next-step messages (e.g. "Authentication failed — verify ALLURE_TOKEN has API scope").
  • Pydantic input validation — every argument has typed constraints (ranges, lengths, literals), exposed as JSON Schema; usernames are alphabet-restricted to prevent RQL injection.
  • Pagination — list tools return a pagination block with page, total, has_more, next_page.
  • Progress reporting — multi-call tools emit ctx.report_progress + ctx.info events.
  • Version-agnostic update verballure_update_test_case issues PATCH and falls back to PUT on HTTP 405, so it works across Allure deployments that expose only one verb.
  • Single source of truth for version__version__ derives from installed package metadata, and a test asserts pyproject.toml matches both server.json version fields, so the published version can't drift.

Installation

Requires Python 3.10+. No manual install needed if you use uvx (recommended) — your MCP client runs it.

# run on demand via uvx (recommended)
uvx --from allure-testops-mcp allure-testops-mcp

# or install with pipx
pipx install allure-testops-mcp

Configuration

Claude Code — one command:

claude mcp add allure -s user \
  --env ALLURE_URL=https://allure.example.com \
  --env ALLURE_TOKEN=your-api-token \
  --env ALLURE_SSL_VERIFY=true \
  -- uvx --from allure-testops-mcp allure-testops-mcp

Any MCP client — add to ~/.claude.json, a project .mcp.json, Cursor's mcp.json, etc.:

{
  "mcpServers": {
    "allure": {
      "type": "stdio",
      "command": "uvx",
      "args": ["--from", "allure-testops-mcp", "allure-testops-mcp"],
      "env": {
        "ALLURE_URL": "https://allure.example.com",
        "ALLURE_TOKEN": "${ALLURE_TOKEN}",
        "ALLURE_SSL_VERIFY": "true"
      }
    }
  }
}

See .env.example for a template. Verify the connection:

claude mcp list
# allure: uvx --from allure-testops-mcp allure-testops-mcp - ✓ Connected

Environment variables

Variable Required Default Description
ALLURE_URL yes Allure TestOps URL (e.g. https://allure.example.com)
ALLURE_TOKEN yes API token (Allure → Profile → API tokens)
ALLURE_SSL_VERIFY no true true/false. Set false for self-signed corp certs
ALLURE_ENABLE_WRITE no false true registers the 7 write tools; default is a read-only server

ALLURE_TEST_PROJECT_ID (plus optional ALLURE_TEST_STATUS / ALLURE_TEST_LAYER) are used only by the opt-in live integration tests — see Development.

Updating

The server is a stdio process your client respawns each session, so the running version is decided by the uvx invocation. uvx caches the resolved environment under ~/.cache/uv, so an older version sticks until you refresh:

uvx --refresh --from allure-testops-mcp allure-testops-mcp   # force latest on next run
uv cache clean allure-testops-mcp                            # or drop the cached env

Then reconnect the server (/mcp → reconnect, or restart the session). To control the version from config, edit args — pin for stability, or always-latest for currency:

// Pin a version (deterministic; bump consciously)
"args": ["--from", "allure-testops-mcp==0.8.0", "allure-testops-mcp"]

// Always latest on every start (adds a PyPI lookup per launch)
"args": ["--refresh", "--from", "allure-testops-mcp", "allure-testops-mcp"]

Example prompts

Read-only:

  • "List all Allure projects"
  • "Show the last 10 launches for project 63"
  • "Failed tests in the last launch for project 175"
  • "What's the automation rate for project 842?"
  • "Compare the automation rate of project 63 and project 842" — works across projects in one session
  • "Show me the steps of test case 641012"
  • "Which custom fields does project 1664 have?"

With ALLURE_ENABLE_WRITE=true, drive test-case CRUD in natural language:

  • "Create a Draft manual TC named 'Login flow' in project 63"
  • "Add an automated smoke TC in project 63 tagged smoke, layer E2E"
  • "Rename test case 555 to 'Login (rewritten)' and set its status to Active"
  • "Delete test case 555" — the agent passes confirm=true, and a compliant client prompts you first

Security considerations

  • API token is read from ALLURE_TOKEN only — never passed on the command line, never written to logs.
  • Secrets are never echoed back in tool responses (no header dumps, no auth reflection).
  • Self-signed SSL is opt-in via ALLURE_SSL_VERIFY=false (default true). Disabling verification on a public network is a risk; use only for trusted corporate instances.
  • Proxy discovery is disabled (session.trust_env = False) — the server ignores HTTP_PROXY / HTTPS_PROXY so it can't be silently routed through an unintended proxy.
  • Writes are opt-in and least-privilege — without ALLURE_ENABLE_WRITE=true the server registers only the 13 read-only tools and cannot create, modify, or delete anything, even with a write-scoped token. When enabled, the destructive tools (allure_delete_test_case / allure_delete_category / allure_delete_category_matcher) carry destructiveHint: True and require confirm=true.
  • Input validation via Pydantic — every argument is typed and bounded; usernames are alphabet-restricted to prevent RQL injection through the search endpoint.
  • A token is never more privileged than its account — Allure Api-Token auth inherits the issuing user's role, so a read-only (guest) account yields a read-only server regardless of the ALLURE_ENABLE_WRITE flag.

Rate limits

Allure TestOps enforces per-instance rate limits (typically ~60 requests/minute per token). On HTTP 429 the server returns an actionable error suggesting you wait 30–60s, reduce size, or paginate with smaller pages. Two tools make multiple API calls internally — allure_get_project_statistics (3) and allure_search_failed_tests (2–3) — and report per-step progress via MCP Context.

Development

git clone https://github.com/mshegolev/allure-testops-mcp.git
cd allure-testops-mcp
pip install -e '.[dev]'
pytest          # unit suite (all HTTP mocked)
ruff check src tests && ruff format --check src tests

Run the server directly (stdio transport — waits on stdin for MCP messages):

ALLURE_URL=... ALLURE_TOKEN=... allure-testops-mcp

Live-instance integration tests

An opt-in suite runs a real create → update → delete lifecycle against a live Allure project. It is deselected by default and skips itself unless credentials are present, so a normal pytest stays green:

export ALLURE_URL=https://allure.example.com
export ALLURE_TOKEN=...                 # token from an account with write access
export ALLURE_ENABLE_WRITE=true
export ALLURE_TEST_PROJECT_ID=63        # a throwaway project you can write to
pytest -m integration tests/integration -v

Contributing

Issues and PRs welcome. Keep the unit suite green (pytest) and the linter clean (ruff check, ruff format); CI runs both on Python 3.10 / 3.11 / 3.12. See CHANGELOG.md for the release history.

License

MIT © Mikhail Shchegolev

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

allure_testops_mcp-0.9.0.tar.gz (71.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

allure_testops_mcp-0.9.0-py3-none-any.whl (37.2 kB view details)

Uploaded Python 3

File details

Details for the file allure_testops_mcp-0.9.0.tar.gz.

File metadata

  • Download URL: allure_testops_mcp-0.9.0.tar.gz
  • Upload date:
  • Size: 71.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for allure_testops_mcp-0.9.0.tar.gz
Algorithm Hash digest
SHA256 b141b00b651e5c87a041bcd13572769a01eda4f54d2367b872e6b3f217318ca0
MD5 e79b06a52e9a3ff84b8a6fe88f868b54
BLAKE2b-256 fb630489f8caed3b938c45f6ce0ca738186ba5bd15b970b6b5d1d0eea938b498

See more details on using hashes here.

Provenance

The following attestation bundles were made for allure_testops_mcp-0.9.0.tar.gz:

Publisher: publish.yml on mshegolev/allure-testops-mcp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file allure_testops_mcp-0.9.0-py3-none-any.whl.

File metadata

File hashes

Hashes for allure_testops_mcp-0.9.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f780fefb5acba02e90456cafdd4332656f4efebefd5bc28aaa2e7d13106b67ef
MD5 e05989b99aac73389b99bdaaf381df20
BLAKE2b-256 1557bd2e5bcf8008aaae26e040a27daf0c70d88562295e048c40866b6b57cf8e

See more details on using hashes here.

Provenance

The following attestation bundles were made for allure_testops_mcp-0.9.0-py3-none-any.whl:

Publisher: publish.yml on mshegolev/allure-testops-mcp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page