testrails-mcp

adakh3/testrails-mcp
0 starsMITCommunity

Install to Claude Code

This server doesn't publish a one-line install command. Follow the setup in the source repository.

Summary

MCP server for TestRail that enables AI agents to manage test cases, runs, and results, plus a bundled skill to convert Jira tickets into TestRail test cases.

README.md

testrails-mcp

An MCP (Model Context Protocol) server that exposes TestRail CRUD operations to agentic coding tools like Claude Code and Codex CLI, plus a bundled agent skill for turning Jira tickets into TestRail cases.

What it does

testrails-mcp is a thin, async wrapper around the TestRail API v2. Once registered with your agent, it lets the model:

  • Navigate your TestRail instance — list projects, suites, and sections.
  • Manage test cases — list, read, create, update, and (soft-)delete cases.
  • Manage runs — list, read, create, and close test runs; list the tests

inside a run.

  • Record results — add and read results for cases within a run.

It speaks stdio (the standard MCP transport for local tools), authenticates with TestRail via HTTP Basic auth using your email and API key, and reads credentials from environment variables or a local .env file.

The repo also ships a portable agent skill (skills/jira-to-testrail/) that auto-triggers when a user asks to convert a Jira ticket into TestRail cases. The skill orchestrates a Jira MCP (any vendor) + this MCP to produce one case per acceptance criterion, with a confirmation gate before anything is created.

Requirements

  • Python 3.11+
  • A TestRail account with API access enabled (admin → Site Settings → API)
  • A TestRail API key — generate one at My Settings → API Keys → Add Key
  • An agent runtime that speaks MCP — Claude Code, Codex CLI, Claude Desktop,

or any other MCP-compatible client

Setup

git clone <this-repo> testrails-mcp
cd testrails-mcp

uv venv
uv pip install -e .

cp .env.example .env
# then edit .env with your TestRail URL, email, and API key

.env shape:

TESTRAIL_URL=https://yourcompany.testrail.io
TESTRAIL_USER=you@example.com
TESTRAIL_API_KEY=...

Verify it launches:

.venv/bin/testrails-mcp
# (should sit silently waiting on stdin; Ctrl+C to exit)

Confirm the protocol surface:

echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | .venv/bin/testrails-mcp

For an interactive smoke test with form inputs for every tool:

npx @modelcontextprotocol/inspector .venv/bin/testrails-mcp

Register with your agent

Claude Code

claude mcp add testrails -- /absolute/path/to/.venv/bin/testrails-mcp

Or add to ~/.claude.json (user-scope) or .mcp.json (project-scope):

{
  "mcpServers": {
    "testrails": {
      "command": "/absolute/path/to/.venv/bin/testrails-mcp"
    }
  }
}

Codex CLI

Add to ~/.codex/config.toml:

[mcp_servers.testrails]
command = "/absolute/path/to/.venv/bin/testrails-mcp"

Other clients (Claude Desktop, etc.)

Use the standard MCP server entry: command = /absolute/path/to/.venv/bin/testrails-mcp, no args.

Tools

Navigation

  • list_projects()
  • list_suites(project_id)
  • list_sections(project_id, suite_id?)

Cases (CRUD)

  • list_cases(project_id, suite_id?, section_id?, limit?, offset?)
  • get_case(case_id)
  • add_case(section_id, title, type_id?, priority_id?, estimate?, refs?, custom_fields?)
  • update_case(case_id, title?, type_id?, priority_id?, estimate?, refs?, custom_fields?)
  • delete_case(case_id, soft=True)soft=True previews; pass soft=False to actually delete

Runs

  • list_runs(project_id)
  • get_run(run_id)
  • add_run(project_id, name, suite_id?, description?, case_ids?, include_all?)
  • close_run(run_id)
  • list_tests(run_id)

Results

  • add_result_for_case(run_id, case_id, status_id, comment?, version?, elapsed?, defects?)
  • get_results_for_case(run_id, case_id)

TestRail default status IDs: 1=Passed, 2=Blocked, 3=Untested, 4=Retest, 5=Failed.

custom_fields on add_case / update_case accepts any TestRail custom field the instance has configured — commonly custom_steps, custom_preconds, custom_expected, or custom_steps_separated.

Skills

This repo ships one bundled skill — a portable SKILL.md that works in both Claude Code and Codex CLI. Skills are auto-loaded by the agent based on their description and activate when the user's prompt matches.

jira-to-testrail

Converts a Jira ticket into TestRail test cases. Triggers on phrases like:

  • "Turn PROJ-1234 into test cases"
  • "Create TestRail cases from this ticket"
  • "Generate QA coverage for <ticket>"

What it does:

  1. Verifies both a Jira MCP and this TestRail MCP are connected.
  2. Reads the ticket, extracts acceptance criteria (refuses to invent any).
  3. Auto-discovers the instance's custom-field shape by sampling an existing

case in the target section.

  1. Drafts one case per AC with behavior-focused titles and mapped priority.
  2. Shows you the plan and waits for confirmation before creating.
  3. Creates the cases and reports IDs + URLs as a table.
  4. On partial failure, asks how to proceed rather than auto-retrying.

Requires a Jira MCP to also be installed (e.g. Atlassian's official MCP, or mcp-atlassian) — the skill is vendor-agnostic about which one.

Installing the skill

Skills live in a directory the agent watches. Symlink the bundled skill into your agent's skills location so git pull keeps it up to date:

Claude Code

mkdir -p ~/.claude/skills
ln -s "$(pwd)/skills/jira-to-testrail" ~/.claude/skills/jira-to-testrail

Codex CLI

mkdir -p ~/.agents/skills
ln -s "$(pwd)/skills/jira-to-testrail" ~/.agents/skills/jira-to-testrail

Project-scoped (Codex only)

If you'd rather scope the skill to a single repo, drop a copy into that repo's .agents/skills/ directory — Codex walks up from the cwd to find skills.

Prefer a copy over a symlink:

cp -r skills/jira-to-testrail ~/.claude/skills/   # or ~/.agents/skills/

Verifying the skill loaded

  • Claude Code: run /skills and look for jira-to-testrail in the list.
  • Codex CLI: start a new session and ask "what skills do you have?" — it

should mention jira-to-testrail (Codex loads skill names/descriptions at session start).

If it doesn't show up, double-check:

  1. The symlink target exists (ls -la ~/.claude/skills/jira-to-testrail).
  2. SKILL.md is directly inside that folder, not nested further.
  3. The frontmatter (name, description) is present and valid YAML.

Project layout

testrails_mcp/
├── pyproject.toml
├── README.md
├── .env.example
├── .gitignore
├── src/testrails_mcp/
│   ├── __init__.py
│   ├── client.py          # async httpx client (Basic auth)
│   └── server.py          # FastMCP tools, stdio entrypoint
└── skills/
    └── jira-to-testrail/
        └── SKILL.md       # portable Claude/Codex skill

Troubleshooting

  • Missing TestRail credentials on startup.env not found or missing a

key. The server reads .env from the cwd it's launched in; if your agent spawns it from a different directory, set the vars in your shell profile or agent config instead.

  • TestRail API 401 — wrong email or API key. Confirm the key in *My

Settings → API Keys* and that the user has API access on the instance.

  • TestRail API 403 on create/update/delete — the user lacks write

permission on the project, suite, or section.

  • delete_case returns a preview — that's the default (soft=True). Pass

soft=False to actually delete.

  • Skill doesn't trigger — descriptions are matched fuzzily, but very short

prompts may miss. Try a phrase closer to the examples in the skill's description. As a fallback you can invoke it explicitly (/skill jira-to-testrail in Codex; mention the skill name directly in Claude Code).

Roadmap

Phase 1 (current): Cases, Runs, Results, plus the Jira → TestRail skill.

Likely next:

  • Sections CRUD (so the skill can create new sections if needed).
  • Milestones and Plans.
  • A bulk_add_result_for_cases tool (TestRail has a native batch endpoint).
  • A second skill for bug report → regression case flows.

License

MIT.

Related MCP servers

Browse all →