Allure Testops Mcp

io.github.mshegolevPublished by GitHub account mshegolevv0.9.5Updated Nov 3, 2026

Allure TestOps MCP — projects, launches, test cases, test results via REST API.

VerifiedSTDIODesktop onlyDeveloper ToolsData & Analytics

Overview

AI-generated overview

Local MCP server that lets an assistant browse and manage Allure TestOps projects, launches, test results and test cases through the Allure REST API.

What you can do
  • List projects and read project statistics such as test-case count and automation rate
  • List launches and read individual test results, including a search for failed and broken tests in the latest or a given launch
  • List, read and inspect test cases, including full scenario steps and custom-field values
  • Look up project reference data: statuses, layers, custom-field schema, defect categories and regex category matchers
  • With writes enabled, create, partially update and permanently delete test cases, categories and category matchers
When to use it
Useful when a team keeps its test management in Allure TestOps and wants an assistant to answer questions about runs, triage failures, review test cases or draft new ones without switching to the web UI. One connection covers every project on the instance, so cross-project comparisons work in a single session.
Requirements
Runs locally as a Python 3.10+ stdio process, typically launched with uvx or pipx. Needs network access to an Allure TestOps instance (SaaS or self-hosted) and two environment variables: ALLURE_URL and ALLURE_TOKEN, an API token created under Profile, API tokens. Optional ALLURE_SSL_VERIFY (default true) and ALLURE_ENABLE_WRITE (default false).
Before you install
The API token in ALLURE_TOKEN carries the issuing account's permissions, so scope it to a least-privileged account. Write tools stay unregistered unless ALLURE_ENABLE_WRITE is set to true; once enabled, delete tools remove test cases, categories and matchers permanently and require confirm=true. Setting ALLURE_SSL_VERIFY to false disables certificate checks and should be limited to trusted corporate instances. Proxy environment variables are deliberately ignored.

Installation

In SourceWeft

  1. Open Allure Testops Mcp in the dashboard and add it to a workspace.
  2. Enable the server for the chats that should use its tools.

Desktop only via STDIO. STDIO servers start a local process, so they need the SourceWeft desktop host.

Other MCP clients

Follow the launch instructions in the repository.

README

allure-testops-mcp

[PyPI] [Python] [License: MIT] [Tests] [Allure TestOps MCP server]

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

bash
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.

ToolKindPurpose
allure_list_projectsreadAll projects (id, name, abbreviation)
allure_get_project_statisticsreadTC count, automation rate, last-launch summary
allure_list_launchesreadRecent launches with pass/fail stats
allure_get_test_resultsreadTest results in a launch (filter by status)
allure_search_failed_testsreadFAILED/BROKEN tests in the last or a given launch
allure_list_test_casesreadTest cases (automated/manual + owner filters)
allure_get_test_casereadOne test case's full detail + scenario steps
allure_get_test_case_custom_fieldsreadA test case's custom-field values
allure_list_statusesreadA project's statuses (id, name, color)
allure_list_layersreadA project's test layers (id, name)
allure_list_custom_fieldsreadA project's custom-field schema
allure_list_categoriesreadDefect categories (named/coloured buckets)
allure_list_category_matchersreadRegex automation rules (message/trace → category)
allure_create_test_casewrite ⚑Create a test case
allure_update_test_casewrite ⚑Partial update of a test case
allure_delete_test_casewrite ⚑Permanent delete (destructive — needs confirm=true)
allure_create_categorywrite ⚑Create a defect category
allure_delete_categorywrite ⚑Permanent delete (destructive — needs confirm=true)
allure_create_category_matcherwrite ⚑Create + attach a regex automation rule
allure_delete_category_matcherwrite ⚑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 verb — allure_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.

bash
# run on demand via uvx (recommended)uvx --from allure-testops-mcp allure-testops-mcp
# or install with pipxpipx install allure-testops-mcp

Configuration

Claude Code — one command:

bash
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.:

json
{  "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:

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

Environment variables

VariableRequiredDefaultDescription
ALLURE_URLyes—Allure TestOps URL (e.g. https://allure.example.com)
ALLURE_TOKENyes—API token (Allure → Profile → API tokens)
ALLURE_SSL_VERIFYnotruetrue/false. Set false for self-signed corp certs
ALLURE_ENABLE_WRITEnofalsetrue 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:

bash
uvx --refresh --from allure-testops-mcp allure-testops-mcp   # force latest on next runuv 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:

jsonc
// 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

bash
git clone https://github.com/mshegolev/allure-testops-mcp.gitcd allure-testops-mcppip 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):

bash
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:

bash
export ALLURE_URL=https://allure.example.comexport ALLURE_TOKEN=...                 # token from an account with write accessexport ALLURE_ENABLE_WRITE=trueexport ALLURE_TEST_PROJECT_ID=63        # a throwaway project you can write topytest -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

Source: README.md at commit f222646

Tools

13

allure_list_projects

List Projects

List all projects in the Allure TestOps instance. Use this first to discover which project IDs exist — all other tools take a ``project_id`` that you can look up here. Returns: dict with keys: - ``count`` (int): number of projects in this response - ``projects`` (list): each item has ``id``, ``name``, ``abbreviation`` Examples: - "Which projects exist in Allure?" -> default call, take the names/ids - "Find project by abbreviation" -> iterate ``projects`` and match Don't use when: - You already know the project id (skip discovery, go straight to the target tool).

Parameterspagesize

allure_get_project_statistics

Get Project Statistics

Get summary statistics for an Allure project. Returns TC count, automation rate, and the last closed launch's pass/fail breakdown. Performs 3-4 API calls — progress is reported via MCP Context (visible as progress updates in compatible clients). Args: project_id: Allure project ID (see ``allure_list_projects``). ctx: MCP Context injected by FastMCP (used for progress reporting; never supplied by the agent directly). Returns: dict with keys: - ``project_id`` (int) - ``total_test_cases`` (int) - ``automated_test_cases`` (int) - ``manual_test_cases`` (int) - ``automation_rate_pct`` (float) - ``last_launch_id`` (int | None): latest *closed* launch - ``last_launch_name`` (str | None) - ``last_launch_passed`` / ``last_launch_failed`` / ``last_launch_broken`` (int) - ``last_launch_total`` (int) - ``recent_launches_count`` (int): launches examined to find the latest closed one Examples: - "How automated is project 63?" -> ``project_id=63``, read ``automation_rate_pct`` - "What was the last passing run for project 175?" -> read ``last_launch_passed`` Don't use when: - You need per-test detail (use ``allure_get_test_results``). - You need the full launch history (use ``allure_list_launches``).

Parametersproject_idrequired

allure_list_launches

List Launches

List recent launches for a project, newest first. Each launch carries a pass/fail/broken/skipped breakdown from Allure's ``statistic`` field. Pagination info is returned in the ``pagination`` block (use ``next_page`` to continue). Args: project_id: Allure project ID. page: 0-based page index. size: Items per page (1-100; 20 is usually enough for triage). Returns: dict with keys: - ``project_id`` (int) - ``count`` (int): items in this response - ``pagination`` (dict): ``page`` / ``size`` / ``total`` / ``total_pages`` / ``has_more`` / ``next_page`` - ``launches`` (list): each with ``id`` / ``name`` / ``status`` / ``created_date`` / ``passed`` / ``failed`` / ``broken`` / ``skipped`` / ``total`` Examples: - "Last 10 launches for project 63" -> ``project_id=63, size=10`` - "Older launches beyond page 1" -> repeat with ``page=1`` Don't use when: - You need test results inside a launch (``allure_get_test_results``). - You need just the latest FAILED/BROKEN tests (``allure_search_failed_tests``).

Parameterspagesizeproject_idrequired

allure_get_test_results

Get Test Results

Get individual test results inside a launch, optionally filtered by status. The Allure server may ignore the ``status`` query parameter and return mixed-status pages. When ``status`` is set, this tool enforces the filter client-side (case-insensitive comparison) so the returned ``results`` always contain only rows matching the requested status. Args: launch_id: Allure launch ID (from ``allure_list_launches``). status: Filter — ``PASSED`` / ``FAILED`` / ``BROKEN`` / ``SKIPPED``. ``None`` returns all. page: 0-based page index. size: Items per page (1-200; default 50). Returns: dict with keys: - ``launch_id`` (int) - ``count`` (int): number of results after client-side status filter - ``pagination`` (dict) - ``results`` (list): each with ``id`` / ``name`` / ``status`` / ``duration_ms`` / ``error`` (first 300 chars of ``statusMessage``) Examples: - "FAILED tests in launch 12345" -> ``launch_id=12345, status="FAILED"`` - "All results in launch X, second page" -> ``launch_id=X, page=1`` Don't use when: - You want only FAILED+BROKEN (``allure_search_failed_tests`` does both in one call).

Parameterspagesizestatuslaunch_idrequired

allure_search_failed_tests

Search Failed Tests

Find FAILED and BROKEN tests in the most recent (or given) launch. Useful for triage: _"what's broken in the latest run"_ without listing every test. Performs up to 3 API calls; progress reported via MCP Context. Args: project_id: Allure project ID. launch_id: Specific launch ID. If ``None``, the latest launch is used. limit: Max failures per status (so up to ``2 * limit`` total). ctx: MCP Context (auto-injected). Returns: dict with keys: - ``launch_id`` (int): the resolved launch (latest if not passed in) - ``failed_count`` (int) - ``results`` (list): ``id`` / ``name`` / ``status`` / ``duration_ms`` / ``error`` Examples: - "What's failing in project 63 right now?" -> ``project_id=63`` - "Failures in launch 98765" -> ``project_id=N, launch_id=98765`` Don't use when: - You need PASSED tests too (use ``allure_get_test_results`` without status filter).

Parameterslimitlaunch_idproject_idrequired

allure_list_test_cases

List Test Cases

List test cases for a project with optional automation and ownership filters. Each TC carries ``id``, ``name``, ``automated``, ``status``, ``layer`` (e.g. ``UNIT``, ``API``, ``E2E``), the ``createdBy`` / ``lastModifiedBy`` audit usernames, and a flat list of tag names. **Caveat:** the audit fields and ``tags`` are only populated when ``owner`` is set, because Allure's plain ``/testcase`` endpoint returns a compact projection that omits them — the ``owner`` path uses ``__search`` which returns the full projection. Args: project_id: Allure project ID. ctx: MCP Context (auto-injected by FastMCP for progress reporting). automated: ``True`` — only automated, ``False`` — only manual, ``None`` — both. owner: Optional Allure username. When set, the response is narrowed to TCs where ``createdBy = owner OR lastModifiedBy = owner`` (case-sensitive, exact match), enforced **server-side** via Allure's RQL ``__search`` endpoint. The username must match ``[A-Za-z0-9._@-]+`` — anything else is rejected at the MCP input layer (Pydantic ``pattern``) to prevent RQL injection. **Why "creator/modifier" and not "owner".** Allure TestOps does not expose a separate ``owner`` field in RQL on most deployments — the closest stable proxy for "TCs I touched" is the union of ``createdBy`` and ``lastModifiedBy``. **Trade-off when ``owner`` is set.** ``__search`` does not accept the ``automated`` query parameter, so an ``automated`` filter combined with ``owner`` is applied **client-side after the page is fetched**. ``pagination`` then reflects the raw owner-filtered set, not the further automation-filtered view — a fetched page of 50 may shrink. Raise ``size`` (max 200) or iterate ``page`` for full coverage. page: 0-based

Parameterspagesizeownerautomatedproject_idrequired

allure_list_statuses

List Statuses

List the test-case statuses defined in a project (id, name, color). Use this to discover valid status names/ids before setting a status on ``allure_create_test_case`` / ``allure_update_test_case``. Built-in statuses use negative ids (e.g. Draft = -1). Returns: dict with ``project_id``, ``count`` and ``statuses`` (each: ``id``, ``name``, ``color``).

Parametersproject_idrequired

allure_list_layers

List Layers

List the test layers defined in a project (id, name). Use this to discover valid layer names/ids before setting a layer on ``allure_create_test_case`` / ``allure_update_test_case``. Built-in layers use negative ids (e.g. API Tests = -3). Returns: dict with ``project_id``, ``count`` and ``layers`` (each: ``id``, ``name``).

Parametersproject_idrequired

allure_get_test_case

Get Test Case

Get one test case's full detail — fields, status/layer, tags, and steps. Unlike ``allure_list_test_cases`` (summaries), this returns the body of a single test case: description, precondition, expected result, and the manual scenario steps (flattened with a ``depth`` marker). Use it to read or review the actual content of a test case. Scenario steps are loaded from ``GET /testcase/{id}/scenario`` (nested tree). If that returns no steps, falls back to ``GET /testcase/{id}/step`` (normalized ``root`` + ``scenarioSteps`` map used by some Allure versions). Returns: dict with ``id``, ``name``, ``project_id``, ``automated``, ``description``, ``precondition``, ``expected_result``, ``status``, ``layer``, ``tags`` and ``steps`` (each: ``depth``, ``keyword``, ``name``, ``expected_result``). ``steps`` is empty when ``include_scenario`` is false or the case has none.

Parameterstest_case_idrequiredinclude_scenario

allure_get_test_case_custom_fields

Get Test Case Custom Fields

List the custom-field values set on a test case. Returns each value flattened to ``field_id`` / ``field_name`` (the custom field) and ``value_id`` / ``value_name`` (the chosen value) — e.g. field "Priority" → value "High". These are not included in ``allure_get_test_case``; fetch them here when you need a test case's custom-field assignments.

Parameterstest_case_idrequired

allure_list_custom_fields

List Custom Fields

List the custom fields defined on a project (its schema). Returns each field's ``field_id``, ``name``, ``single_select`` and ``required``. Use it to discover which custom fields a project has before reading a test case's values with ``allure_get_test_case_custom_fields``. Built-in metadata fields (Epic/Feature/Story/Component/Suite) use negative ids; project-specific custom fields use positive ids.

Parametersproject_idrequired

allure_list_categories

List Defect Categories

List the defect categories configured for a project. Categories are the named, coloured buckets shown on the project's *Categories* settings page (``name`` / ``color`` / ``description``). They are inert on their own — the regex rules that auto-assign failures live in ``allure_list_category_matchers``. Args: project_id: Allure project ID. page: 0-based page index. size: Items per page (1-500). Returns: dict with keys: - ``project_id`` (int) - ``count`` (int): items in this response - ``pagination`` (dict) - ``categories`` (list): each ``id`` / ``name`` / ``color`` / ``description`` Examples: - "What defect categories does project 175 have?" -> ``project_id=175`` Don't use when: - You want the regex automation rules (use ``allure_list_category_matchers``).

Parameterspagesizeproject_idrequired

allure_list_category_matchers

List Category Matchers

List the regex automation rules (matchers) for a project. Each matcher carries a ``message_regex`` / ``trace_regex`` (Java regex) and the ``category_id`` / ``category_name`` it feeds. This is the project's *automation schema* — what makes failing results land in a category automatically at result-ingest time. Args: project_id: Allure project ID. page: 0-based page index. size: Items per page (1-500). Returns: dict with keys: - ``project_id`` (int) - ``count`` (int) - ``pagination`` (dict) - ``matchers`` (list): each ``id`` / ``name`` / ``message_regex`` / ``trace_regex`` / ``category_id`` / ``category_name`` Examples: - "Show the auto-classification rules for project 175" -> ``project_id=175`` Don't use when: - You only need the bucket names/colours (use ``allure_list_categories``).

Parameterspagesizeproject_idrequired

Version history

2
  1. v0.9.5LatestOct 29, 2026
  2. v0.9.3Sep 16, 2026

Score

90% of the applicable checks met

How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.

  • Reached in the last 30 days25 pts
  • Auth declared10 pts

    Declare the credential headers in the registry entry, or keep the endpoint answering the probe so its auth can be classified.

  • Tools listedRequired15 pts
  • DescriptionRequired15 pts
  • Logo10 pts
  • Documentation15 pts
  • License10 pts