testrail-mcp
Allows fetching Confluence page content to prepare test cases from Confluence pages.
Allows fetching Jira tickets (summary, description, comments, subtasks) to prepare test cases from Jira issues.
Provides CRUD operations on TestRail projects, suites, sections, test cases, and test runs, as well as tools to generate test cases from specifications and push them back to TestRail.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@testrail-mcp prepare test cases from Jira ticket ABC-123"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
testrail-mcp
An MCP server for TestRail that goes beyond CRUD: it prepares everything an MCP client needs to generate real test cases from Jira tickets, Confluence pages, or any free-form spec — and pushes them back to TestRail.
Built on the official Python MCP SDK (FastMCP). Designed to plug into Claude Desktop, Claude Code, Cursor, or any other MCP-capable client.
No ANTHROPIC_API_KEY required. The server never calls an LLM. It fetches data (Jira/Confluence/TestRail), bundles in house-style anchors, and returns it with instructions for your MCP client. The LLM work happens in your client (Claude Desktop / Cursor / etc.) on your existing subscription — you pay once.
What it gives you
CRUD over TestRail
list_projects— projects visible to the userlist_suites— suites under a projectsearch_test_cases— list cases under a project / suite / section, optionally filter by title substringget_test_case— fetch one case by IDcreate_test_case— create a case in a sectionget_or_create_section— resolve a path likeAuth > Login > Edge Cases, creating missing nodes
Preparation tools — fetch + bundle data, hand off to your MCP client's LLM
prepare_cases_from_text— feed any spec/PRD/bug-report text → returns spec + house-style anchors + schema + instructions for the client to generate cases.prepare_cases_from_jira— pass a Jira issue key (e.g.ABC-123); server fetches summary, description, comments, subtasks, walks the ADF tree.prepare_cases_from_confluence— pass a Confluence page ID; HTML body stripped to plain text.preview_house_style— see the 5 sibling cases the server will use as in-context style anchors.add_test_cases_bulk— once the LLM has the cases array, push them all into TestRail in one call (with auto section-hierarchy creation).
All three prepare_cases_* tools pull a few existing cases from the target section as house-style examples by default, so generated cases match local title casing, step granularity, and expected-result phrasing. Override with house_style_section_id to draw style from a different "golden" section, or set house_style=False to skip.
Related MCP server: qa-mcp
Quick start
Run with uvx (recommended — no clone, no venv)
Once the package is on PyPI:
uvx testrail-mcp-serverFor local development from a checkout:
git clone https://github.com/Sergey-Bl/testrail-mcp
cd testrail-mcp
uv venv --python 3.12
uv pip install -e .
cp .env.example .env # fill in TestRail / Jira / Anthropic keysInspect interactively (recommended first step)
npx @modelcontextprotocol/inspector python server.pyThis opens a local web UI where each tool can be called by hand. Use it to verify auth and tool wiring before you plug into a client.
Use in Claude Desktop
Add to ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"testrail": {
"command": "uvx",
"args": ["testrail-mcp-server"],
"env": {
"TESTRAIL_BASE_URL": "https://your-org.testrail.io",
"TESTRAIL_USER": "you@example.com",
"TESTRAIL_API_KEY": "...",
"TESTRAIL_PROJECT_ID": "1",
"TESTRAIL_SUITE_ID": "1",
"JIRA_BASE_URL": "https://your-org.atlassian.net",
"JIRA_USER": "you@example.com",
"JIRA_API_TOKEN": "..."
}
}
}
}Restart Claude Desktop. The testrail server should appear in the tools menu.
Use in Claude Code
claude mcp add testrail -- uvx testrail-mcp-server(You'll still need to provide env vars — either via claude mcp add --env KEY=VALUE flags or a .env in the working directory.)
Use in Cursor
In ~/.cursor/mcp.json:
{
"mcpServers": {
"testrail": {
"command": "uvx",
"args": ["testrail-mcp-server"],
"env": { "TESTRAIL_BASE_URL": "...", "TESTRAIL_USER": "...", "TESTRAIL_API_KEY": "..." }
}
}
}Configuration
Env var | Required | Purpose |
| yes | e.g. |
| yes | TestRail account email |
| yes | from My Settings → API Keys |
| optional | default project ID for tools that take it |
| optional | default suite ID |
| optional | default template (2 = "Test Case (Steps)") |
| optional | default case type |
| optional | default priority (3 = Medium) |
| optional | only for |
| optional | Jira account email |
| optional | |
| optional | only for |
| optional | defaults to |
| optional | defaults to |
Example: from a Jira ticket straight into TestRail
In Claude Code or Claude Desktop, after the server is registered:
Generate test cases from
ABC-123and put them underAuth > Login > Smoke.
The server walks the section path (creating missing nodes), pulls the Jira ticket, generates ~15-30 cases, then bulk-creates them with house-style defaults (template 2, type 7, priority 3). Reply contains every new case ID.
Tool reference
In addition to the basics above:
Test-case authoring & QA
prepare_feature_bootstrap— one-shot: ingest a Confluence page / Jira ticket / raw spec, plan the suite + section, fetch house-style anchors. Hand it all back to the client LLM with step-by-step instructions for generation + push.dedupe_against_section— flag generated cases that look like duplicates of cases already in a target section (title-token containment; configurablethreshold).prepare_lint— return the case batch + lint instructions; the client LLM reviews and reports vague titles, generic expecteds, combined steps, etc.prepare_coverage_gaps— return the spec + case titles + instructions; the client LLM lists testable behaviours not covered.list_sections,find_populated_section,create_suite,update_case— CRUD helpers.
Test-run management & reporting
list_runs,get_run,get_tests_in_run,get_results_for_run— read-side access.create_run,update_run,close_run— write-side. Pair with CI to auto-create a run per build.add_result,add_bulk_results— post results back from automation. Status accepts either a string ("passed","failed","blocked","retest") or a TestRail status_id.prepare_run_summary— fetch run metadata + statuses + failure comments; client LLM writes the ship-ready Markdown report.prepare_runs_diff(run_a, run_b)— regression/fix delta between two runs; client LLM narrates the diff as Markdown.flaky_test_detector(case_id, last_n_runs)— pull a case's status across recent runs and flag flakiness when it flips between pass/fail. Pure data, no LLM needed.
Roadmap
SSE / HTTP transport for hosted use
Embedding-based dedupe (semantic, not just token overlap)
update_case— patch existing cases when the spec changesSuite cloning across projects
License
MIT
Available Tools
31 toolsadd_bulk_resultsA
Post many results in one TestRail call (much faster than looping add_result).
Each entry in results must have at least case_id and status (string or id).
Optional per-entry fields: comment, defects, elapsed, version, assignedto_id.
Inputs: run_id (required), results (required).
add_resultA
Post a single test result by case_id (TestRail looks up the test inside the run).
status accepts a string ("passed" | "failed" | "blocked" | "retest" | "untested")
or a raw TestRail status_id (1..5 by default).
elapsed is a TestRail time string ("30s", "1m 30s", "1h 5m").
defects is a comma-separated list of bug-tracker IDs ("BUG-1, BUG-2").
Inputs: run_id (required), status (required), case_id (required), comment, +3 more.
add_test_cases_bulkA
Push a batch of test cases to TestRail in one call. Returns the IDs created.
cases items are in the shape returned by prepare_cases_* — each has
{title, preconditions, steps:[{step, expected}]}. The server maps that into
TestRail's payload format (custom_steps_separated etc.).
Targeting: either section_id directly, or section_hierarchy like
'Auth > Login > Smoke' — missing nodes are created.
Inputs: cases (required), suite_id, project_id, section_id, +1 more.
close_runC
Mark a test run as completed/archived. This is irreversible in TestRail.
Inputs: run_id (required).
create_runC
Create a new test run.
By default includes every case in the suite (include_all=True). Pass an
explicit case_ids list and set include_all=False to scope the run.
Inputs: name (required), refs, case_ids, suite_id, +4 more.
create_suiteB
Create a new TestRail suite in a project (only works on multi-suite projects).
project_id defaults to TESTRAIL_PROJECT_ID from env.
Inputs: name (required), project_id, description.
create_test_caseC
Create a single test case in a TestRail section.
case should look like:
{
"title": "...",
"preconditions": "...",
"steps": [{"step": "...", "expected": "..."}, ...]
}
Inputs: case (required), section_id (required).
dedupe_against_sectionA
Check generated cases against what's already in a TestRail section.
Uses title-token overlap (no embeddings) — fast, deterministic. Returns:
kept: list of {case, reason} that look newduplicates: list of {case, existing_id, existing_title, overlap}thresholdis the minimum token-overlap (0..1) to flag as duplicate.
Inputs: cases (required), section_id (required), suite_id, threshold, +1 more.
find_populated_sectionA
Find a section that has at least min_cases real cases — useful as a
house-style anchor when bootstrapping a new feature. Returns the first
section meeting the threshold (sections are scanned in TestRail order).
Inputs: suite_id, min_cases, project_id, scan_limit. Returns: result
flaky_test_detectorA
Pull this case's result across the last N runs and flag flakiness.
A test is "flaky" if it has BOTH passes and failures in the window AND flips between them at least twice. Returns the run-by-run trace.
Inputs: case_id (required), project_id, last_n_runs.
get_or_create_sectionA
Resolve a section hierarchy like Auth > Login > Edge Cases,
creating missing parents as needed. Returns {"section_id": int, "path": str}.
Defaults to TESTRAIL_PROJECT_ID / TESTRAIL_SUITE_ID from env when not provided.
Inputs: hierarchy (required), suite_id, project_id.
get_results_for_runC
All result entries for a run — includes comments, defects, who tested when.
Inputs: run_id (required), limit. Returns: result
get_runC
Fetch the full metadata of a single test run.
Inputs: run_id (required).
get_test_caseB
Fetch a single test case by its TestRail ID.
Inputs: case_id (required).
get_tests_in_runC
Tests in a run with their current status (current = latest result).
Inputs: run_id (required), limit. Returns: result
list_projectsA
List all TestRail projects visible to the configured user.
Inputs: no named parameters. Returns: result
list_runsC
List test runs in a project.
Filters:
suite_id— only runs of this suiteis_completed— True for closed/archived runs only, False for open only
Inputs: limit, suite_id, project_id, is_completed. Returns: result
list_sectionsB
List sections in a suite, returning {id, name, parent_id}.
Defaults to TESTRAIL_PROJECT_ID / TESTRAIL_SUITE_ID from env when omitted.
Inputs: limit, suite_id, project_id. Returns: result
list_suitesA
List suites under a TestRail project.
project_id defaults to TESTRAIL_PROJECT_ID from env when omitted or 0.
Inputs: project_id. Returns: result
prepare_cases_from_confluenceB
Fetch a Confluence page + house-style anchors. Returns the context the
calling Claude needs to generate TestRail cases. page_id is the numeric ID
from the page URL: /wiki/spaces/X/pages/<page_id>.
Inputs: page_id (required), suite_id, project_id, section_id, +4 more.
prepare_cases_from_jiraC
Fetch a Jira ticket + house-style anchors. Returns the context the calling Claude needs to generate TestRail cases. Example: issue_key='ABC-123'.
Inputs: issue_key (required), suite_id, project_id, section_id, +4 more.
prepare_cases_from_textA
Fetch the inputs needed to generate TestRail cases from a free-form spec.
This is an MCP-native pattern: the server doesn't call an LLM. It returns the
spec, the house-style anchors, the target section, and an instructions block
that tells the calling Claude how to generate cases and where to push them.
Targeting modes:
section_id— push into an existing section ID latersection_hierarchy— likeAuth > Login; missing nodes will be created when you calladd_test_cases_bulk. Defaults come from TESTRAIL_PROJECT_ID and TESTRAIL_SUITE_ID env.
House-style matching (default on): the server pulls a few existing cases from
the target section (or a fallback populated section) so the calling Claude can
match the local tone, naming, and step granularity. Override the style source
with house_style_section_id to pull anchors from a different "golden" section.
Inputs: text (required), suite_id, project_id, section_id, +5 more.
prepare_coverage_gapsB
Return the spec and the existing case titles, plus instructions for the calling Claude to find missing coverage. No LLM call happens server-side.
Inputs: cases (required), spec_text (required), feature_title.
prepare_feature_bootstrapA
Prepare a feature-import workflow: fetch the spec, pull house-style anchors, and return everything the calling Claude needs to drive generation and push.
No LLM call happens server-side. Claude in the client generates cases (with the
instructions and style examples this tool returns) and then calls
add_test_cases_bulk to commit them.
Required:
source_type: "confluence" | "jira" | "text"source_value: page_id / issue_key / raw texteither
new_suite_name(creates a new suite when you push) orexisting_suite_idsection_name— hierarchy allowed: "A > B > C"
Optional:
style_from_suite_id— pull style anchors from a populated suite. Recommended when you're bootstrapping a brand-new empty suite that has no cases yet.
Inputs: source_type (required), source_value (required), project_id, section_name, +3 more.
prepare_lintB
Return the case batch alongside lint instructions for the calling Claude to evaluate.
No LLM call happens server-side — the client Claude reviews the cases using its own context and reports back, paid for by the user's subscription.
Inputs: cases (required), feature_title.
prepare_runs_diffA
Compute the regression / fix / coverage delta between two runs and return the structured data + narrate instructions for the calling Claude.
A is the baseline (older), B is the newer run. No LLM call happens server-side.
Inputs: run_id_a (required), run_id_b (required).
prepare_run_summaryA
Pull run metadata, statuses, and failure comments — return the structured payload + report instructions for the calling Claude to synthesise into Markdown.
No LLM call happens server-side. Claude in the client writes the report.
include_passed_titles=False (default) keeps the payload compact for big runs.
Set True only for tiny runs (<50 tests) when full granularity is useful.
Inputs: run_id (required), include_passed_titles.
preview_house_styleC
Return up to N existing cases from the target section in style-example format.
Use this to preview what Claude will see as "house style" before generating.
Inputs: n, suite_id, project_id, section_id, +1 more.
search_test_casesA
List test cases in a project, optionally filtered by suite, section, or title substring.
Both project_id and suite_id fall back to env defaults
(TESTRAIL_PROJECT_ID / TESTRAIL_SUITE_ID) when omitted or 0.
Inputs: limit, suite_id, project_id, section_id, +1 more. Returns: result
update_caseA
Patch an existing test case. fields is forwarded to TestRail as-is.
Common keys: title, custom_preconds, custom_steps_separated, priority_id, type_id, refs. To rewrite steps, pass a list under custom_steps_separated: [{"content": "...", "expected": "..."}, ...].
Inputs: fields (required), case_id (required).
update_runA
Patch an existing test run's metadata. Pass only fields you want to change.
Inputs: run_id (required), name, refs, description, +1 more.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 31 tools
Most tools have clearly distinct purposes, but the high number of 'prepare_*' tools (prepare_cases_from_confluence, prepare_cases_from_jira, prepare_coverage_gaps, etc.) could cause confusion for an agent trying to select the right one, despite detailed descriptions.
The naming convention is predominantly verb_noun in snake_case, but there are minor inconsistencies such as 'add_test_cases_bulk' (should be 'add_bulk_test_cases') and 'flaky_test_detector' (noun phrase instead of verb_noun).
With 31 tools, the server exceeds the recommended range for well-scoped MCP servers. While TestRail is a complex domain, several tools could be merged or omitted to reduce cognitive load.
The server covers core CRUD for runs, cases, and results, and adds valuable analysis tools. However, it lacks deletion capabilities (delete_case, delete_run) and project creation, which are notable gaps for full lifecycle coverage.
Maintenance
Related MCP Connectors
Official MCP server for Qase — manage test cases, runs, suites, defects via AI tools.
Free test management over MCP: projects, test cases, plans, runs, environments and tasks.
MCP server for AI access to SmartBear tools, including BugSnag, Reflect, Swagger, PactFlow, QTM4J.
MCP Server for JFrog, providing tools for development and artifact management.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceMCP server for TestRail that enables AI assistants to interact with TestRail's test management platform. It can query and manage projects, test cases, runs, results, plans, milestones, and more.MIT
- FlicenseNot gradedqualityNot gradedmaintenanceAn MCP server that enables Claude to create and manage TestRail test cases directly from Jira or Azure DevOps user stories. It provides tools for section management and automated test case creation with built-in format enforcement and traceability links.-
- AlicenseNot gradedqualityDmaintenanceAn MCP server that automates Playwright-based UI and API testing, supporting test case generation from requirements or API specs, and execution with detailed reports.12 npm1MIT
- AlicenseCqualityDmaintenanceMCP server for TestRail API, providing AI assistants with 107 tools to manage test cases, runs, results, plans, and more. Supports API key, password, and SSO cookie authentication.5417 npm2MIT