MCP server by g-tiwari
@g-tiwari/mcp-testrail
MCP server for the TestRail API. Gives AI assistants full access to manage test cases, runs, results, plans, and all other TestRail resources.
107 tools covering every TestRail API endpoint, with toolset filtering for token efficiency.
Works with any TestRail setup — standard cloud/self-hosted instances (API key or password auth) and enterprise SSO deployments (SAML/OIDC cookie-based auth).
Quick Start
Add to your MCP client config (Claude Desktop, Claude Code, Kiro, Cursor, Windsurf — see IDE Configuration below):
{
"mcpServers": {
"testrail": {
"command": "npx",
"args": ["-y", "@g-tiwari/mcp-testrail"],
"env": {
"TESTRAIL_URL": "https://yourcompany.testrail.com",
"TESTRAIL_EMAIL": "your@email.com",
"TESTRAIL_API_KEY": "your-api-key"
}
}
}
}
That's it. Restart your MCP client and start asking it to manage TestRail.
Enterprise SSO? Replace the API key env vars with
"TESTRAIL_COOKIE_PATH": "~/path/to/cookies.txt"— see Authentication for all options. You can also add optional env vars likeTESTRAIL_PROJECT_IDS,TESTRAIL_TOOLSETS, andTESTRAIL_READ_ONLY_MODEto the sameenvblock — see Environment Variables.
Authentication
Option 1: API Key (Recommended for most users)
This is the standard auth method for TestRail Cloud and self-hosted instances.
- Go to My Settings in TestRail (top-right menu)
- Enable the API under API section
- Generate an API key
Set these environment variables:
TESTRAIL_URL=https://yourcompany.testrail.com
TESTRAIL_EMAIL=your@email.com
TESTRAIL_API_KEY=your-api-key
Option 2: Password
For instances where API keys are not available.
TESTRAIL_URL=https://yourcompany.testrail.com
TESTRAIL_EMAIL=your@email.com
TESTRAIL_PASSWORD=your-password
Option 3: SSO Cookie Auth (Enterprise)
For enterprise TestRail instances behind SSO providers (Okta, Azure AD, etc.). The server reads a Netscape-format cookie file, automatically completes the SAML/OIDC login flow, and obtains a TestRail session.
TESTRAIL_URL=https://testrail.yourcompany.com
TESTRAIL_COOKIE_PATH=~/path/to/sso/cookies.txt
How it works: The server loads SSO cookies from the file, hits the TestRail SSO redirect endpoint, parses the SAML response form, and submits it back to TestRail to obtain a tr_session cookie. It also hot-reloads when the cookie file changes (e.g. after re-authenticating with your SSO provider).
Note: You may need to refresh your SSO cookies periodically (e.g. re-authenticate via your SSO provider's CLI).
Option 4: SSO Cookie + API Key (Hybrid)
For enterprise setups where the SSO proxy requires cookies and TestRail also validates API key auth.
TESTRAIL_URL=https://testrail.yourcompany.com
TESTRAIL_COOKIE_PATH=~/path/to/sso/cookies.txt
TESTRAIL_EMAIL=your@email.com
TESTRAIL_API_KEY=your-api-key
IDE / AI Assistant Configuration
Claude Desktop
Add to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):
API Key auth:
{
"mcpServers": {
"testrail": {
"command": "npx",
"args": ["-y", "@g-tiwari/mcp-testrail"],
"env": {
"TESTRAIL_URL": "https://yourcompany.testrail.com",
"TESTRAIL_EMAIL": "your@email.com",
"TESTRAIL_API_KEY": "your-api-key"
}
}
}
}
SSO Cookie auth (enterprise):
{
"mcpServers": {
"testrail": {
"command": "npx",
"args": ["-y", "@g-tiwari/mcp-testrail"],
"env": {
"TESTRAIL_URL": "https://testrail.yourcompany.com",
"TESTRAIL_COOKIE_PATH": "~/path/to/sso/cookies.txt"
}
}
}
}
Claude Code (CLI)
Add to ~/.claude/settings.json or your project's .claude/settings.json:
{
"mcpServers": {
"testrail": {
"command": "npx",
"args": ["-y", "@g-tiwari/mcp-testrail"],
"env": {
"TESTRAIL_URL": "https://yourcompany.testrail.com",
"TESTRAIL_EMAIL": "your@email.com",
"TESTRAIL_API_KEY": "your-api-key"
}
}
}
}
Kiro
Add to .kiro/settings/mcp.json in your project root:
API Key auth:
{
"mcpServers": {
"testrail": {
"command": "npx",
"args": ["-y", "@g-tiwari/mcp-testrail"],
"env": {
"TESTRAIL_URL": "https://yourcompany.testrail.com",
"TESTRAIL_EMAIL": "your@email.com",
"TESTRAIL_API_KEY": "your-api-key"
}
}
}
}
SSO Cookie auth (enterprise):
{
"mcpServers": {
"testrail": {
"command": "npx",
"args": ["-y", "@g-tiwari/mcp-testrail"],
"env": {
"TESTRAIL_URL": "https://testrail.yourcompany.com",
"TESTRAIL_COOKIE_PATH": "~/path/to/sso/cookies.txt"
}
}
}
}
Cursor
Add to .cursor/mcp.json in your project root:
{
"mcpServers": {
"testrail": {
"command": "npx",
"args": ["-y", "@g-tiwari/mcp-testrail"],
"env": {
"TESTRAIL_URL": "https://yourcompany.testrail.com",
"TESTRAIL_EMAIL": "your@email.com",
"TESTRAIL_API_KEY": "your-api-key"
}
}
}
}
Windsurf
Add to ~/.codeium/windsurf/mcp_config.json:
{
"mcpServers": {
"testrail": {
"command": "npx",
"args": ["-y", "@g-tiwari/mcp-testrail"],
"env": {
"TESTRAIL_URL": "https://yourcompany.testrail.com",
"TESTRAIL_EMAIL": "your@email.com",
"TESTRAIL_API_KEY": "your-api-key"
}
}
}
}
Local Development
For local testing (not published to npm), use the absolute path to the built file:
{
"mcpServers": {
"testrail": {
"command": "node",
"args": ["/absolute/path/to/testrail-mcp/build/src/index.js"],
"env": {
"TESTRAIL_URL": "https://yourcompany.testrail.com",
"TESTRAIL_EMAIL": "your@email.com",
"TESTRAIL_API_KEY": "your-api-key"
}
}
}
}
Environment Variables
| Variable | Required | Description |
|----------|----------|-------------|
| TESTRAIL_URL | Yes | TestRail instance URL (e.g. https://yourcompany.testrail.com) |
| TESTRAIL_EMAIL | For API key/password auth | User email address |
| TESTRAIL_API_KEY | Option 1 | API key (from My Settings in TestRail) |
| TESTRAIL_PASSWORD | Option 2 | Password (if API keys are unavailable) |
| TESTRAIL_COOKIE_PATH | Option 3 | Path to Netscape-format cookie file |
| TESTRAIL_TOOLSETS | No | Comma-separated toolset names or "all" (default: core toolsets) |
| TESTRAIL_TOOLS | No | Additional individual tool names to enable |
| TESTRAIL_DENIED_TOOLS_REGEX | No | Regex pattern to exclude tools by name |
| TESTRAIL_PROJECT_IDS | No | Comma-separated project IDs to scope the server to (e.g. "5" or "1,5,12") |
| TESTRAIL_READ_ONLY_MODE | No | Set to "true" to expose only read operations |
If both TESTRAIL_API_KEY and TESTRAIL_PASSWORD are set, API key takes precedence.
Project Scoping
Use TESTRAIL_PROJECT_IDS to restrict the server to specific projects. This is useful when your TestRail instance has many projects but you only work with a few.
| Configuration | Description hints | Auto-inject project_id | Restrict |
|---|---|---|---|
| Unset | None | No | No |
| Single ID ("5") | [Project 5] appended to tool descriptions | Yes — fills missing project_id | Rejects other IDs |
| Multiple IDs ("1,5,12") | [Allowed projects: 1, 5, 12] appended | No — LLM must pick | Rejects other IDs |
# Scope to a single project (auto-injects project_id)
TESTRAIL_PROJECT_IDS="5"
# Scope to multiple projects (LLM must specify which)
TESTRAIL_PROJECT_IDS="1,5,12"
Tools like get_projects (no project_id input) and add_project (creates new) are unaffected. Entity-scoped tools like get_case (which take a case_id, not project_id) are also unaffected.
Toolsets
Tools are organized into 18 toolsets. 9 are enabled by default (54 tools) to keep token usage low. Use TESTRAIL_TOOLSETS to customize.
| Toolset | Default | Tools | Description |
|---------|---------|-------|-------------|
| projects | Yes | 5 | Project CRUD |
| suites | Yes | 5 | Suite CRUD |
| sections | Yes | 6 | Section CRUD + move |
| cases | Yes | 13 | Case CRUD + bulk + fields/types |
| runs | Yes | 6 | Run CRUD + close |
| tests | Yes | 2 | Read tests in runs |
| results | Yes | 8 | Result CRUD + bulk + fields |
| users | Yes | 5 | User lookup + roles |
| metadata | Yes | 4 | Priorities, statuses, templates |
| plans | No | 12 | Test plan management |
| milestones | No | 5 | Milestone CRUD |
| groups | No | 5 | Group management |
| attachments | No | 8 | File attachments |
| configurations | No | 7 | Test configurations |
| reports | No | 2 | Report execution |
| shared_steps | No | 5 | Shared steps |
| variables | No | 4 | Variables |
| datasets | No | 5 | Datasets |
Toolset Examples
# Only case and result management (21 tools)
TESTRAIL_TOOLSETS="cases,results"
# Everything (107 tools)
TESTRAIL_TOOLSETS="all"
# Default toolsets + specific additional tools
TESTRAIL_TOOLS="get_plan,get_plans,get_milestones"
# Block all destructive operations
TESTRAIL_DENIED_TOOLS_REGEX="^(delete_|close_)"
# Read-only mode (~40 tools)
TESTRAIL_READ_ONLY_MODE="true"
Token Efficiency
Every MCP tool definition is injected into the LLM context on every conversation turn. More tools = more tokens burned before the model even reads your message. This MCP is designed to keep that cost low.
Default config uses ~2,000 tokens for tool definitions — roughly half of what exposing all 107 tools would cost (~4,000 tokens). Over a 10-turn conversation, that's ~20,000 tokens saved.
| Configuration | Tools | ~Tokens per turn |
|---|---|---|
| Default (9 core toolsets) | 54 | ~2,000 |
| Read-only mode | 46 | ~1,700 |
| Custom (e.g. cases,results) | 21 | ~800 |
| All toolsets | 107 | ~4,000 |
How
- Toolset filtering — only 54 of 107 tools exposed by default; non-essential toolsets (plans, milestones, groups, etc.) are opt-in
- Compact descriptions — average 24 characters per tool (5-10 words), not full sentences
- Bulk operations —
add_results,update_cases,delete_casesaccept arrays, so one call replaces dozens of round-trips (each avoided round-trip saves the full tool list re-injection) - Max pagination — defaults to 250 items per page (TestRail's maximum), fewer calls needed
- Raw JSON responses — no metadata envelope or wrapper overhead; delete/close operations return just
{"success": true} - Layered filtering —
TESTRAIL_TOOLSETS→TESTRAIL_TOOLS→TESTRAIL_READ_ONLY_MODE→TESTRAIL_DENIED_TOOLS_REGEXall compose, so you can tune to exactly what you need
Rate Limiting
Automatic retry with exponential backoff on HTTP 429 responses. Respects the Retry-After header. Max 3 retries.
Available Tools (107)
Click to expand full tool list
Projects (5)
get_project— Get a project by IDget_projects— List all projectsadd_project— Create a new projectupdate_project— Update an existing projectdelete_project— Delete a project by ID
Suites (5)
get_suite— Get a test suite by IDget_suites— List suites for a projectadd_suite— Create a test suiteupdate_suite— Update a test suitedelete_suite— Delete a test suite
Sections (6)
get_section— Get a section by IDget_sections— List sections in a project/suiteadd_section— Create a sectionmove_section— Move a section to a new parentupdate_section— Update a sectiondelete_section— Delete a section
Cases (13)
get_case— Get a test case by IDget_cases— List test cases with filtersget_history_for_case— Get change history for a caseadd_case— Create a test case in a sectionupdate_case— Update a test caseupdate_cases— Bulk update multiple test casesdelete_case— Delete a test casedelete_cases— Bulk delete multiple test casescopy_cases_to_section— Copy cases to another sectionmove_cases_to_section— Move cases to another sectionget_case_fields— List available case fieldsadd_case_field— Create a custom case fieldget_case_types— List available case types
Runs (6)
get_run— Get a test run by IDget_runs— List test runs for a projectadd_run— Create a test runupdate_run— Update a test runclose_run— Close a test rundelete_run— Delete a test run
Tests (2)
get_test— Get a test by IDget_tests— List tests in a run
Results (8)
get_results— Get results for a testget_results_for_case— Get results for a case in a runget_results_for_run— Get all results for a runadd_result— Add a result for a testadd_result_for_case— Add a result for a case in a runadd_results— Bulk add results for a runadd_results_for_cases— Bulk add results by case for a runget_result_fields— List available result fields
Plans (12)
get_plan— Get a test plan by IDget_plans— List test plans for a projectadd_plan— Create a test planadd_plan_entry— Add a suite entry to a planadd_run_to_plan_entry— Add a run to a plan entryupdate_plan— Update a test planupdate_plan_entry— Update a plan entryupdate_run_in_plan_entry— Update a run in a plan entryclose_plan— Close a test plandelete_plan— Delete a test plandelete_plan_entry— Delete a plan entrydelete_run_from_plan_entry— Delete a run from a plan entry
Milestones (5)
get_milestone— Get a milestone by IDget_milestones— List milestones for a projectadd_milestone— Create a milestoneupdate_milestone— Update a milestonedelete_milestone— Delete a milestone
Users & Roles (5)
get_user— Get a user by IDget_current_user— Get the authenticated userget_user_by_email— Find a user by emailget_users— List usersget_roles— List available user roles
Groups (5)
get_group— Get a group by IDget_groups— List all groupsadd_group— Create a user groupupdate_group— Update a user groupdelete_group— Delete a user group
Attachments (8)
add_attachment_to_plan— Attach a file to a test planadd_attachment_to_result— Attach a file to a resultadd_attachment_to_run— Attach a file to a runadd_attachment_to_case— Attach a file to a caseget_attachments_for_case— List attachments for a caseget_attachments_for_run— List attachments for a runget_attachment— Get attachment metadata by IDdelete_attachment— Delete an attachment
Configurations (7)
get_configs— List configurations for a projectadd_config_group— Create a configuration groupadd_config— Add a config to a groupupdate_config_group— Update a configuration groupupdate_config— Update a configurationdelete_config_group— Delete a configuration groupdelete_config— Delete a configuration
Metadata (4)
get_priorities— List available prioritiesget_statuses— List available test statusesget_case_statuses— List available case statusesget_templates— List templates for a project
Reports (2)
get_reports— List reports for a projectrun_report— Execute a report template
Shared Steps (5)
get_shared_step— Get a shared step by IDget_shared_steps— List shared steps for a projectadd_shared_step— Create a shared stepupdate_shared_step— Update a shared stepdelete_shared_step— Delete a shared step
Variables (4)
get_variables— List variables for a projectadd_variable— Create a variableupdate_variable— Update a variabledelete_variable— Delete a variable
Datasets (5)
get_dataset— Get a dataset by IDget_datasets— List datasets for a projectadd_dataset— Create a datasetupdate_dataset— Update a datasetdelete_dataset— Delete a dataset
Troubleshooting
"Authentication failed: invalid or missing user/password or session cookie"
- API Key auth: Verify your API key is correct and the API is enabled in TestRail (Administration > Site Settings > API).
- SSO Cookie auth: Your SSO cookies may have expired. Refresh them (re-authenticate with your SSO provider) and try again. The server auto-detects cookie file changes.
"TESTRAIL_URL environment variable is required"
Ensure TESTRAIL_URL is set in your MCP config's env block. The URL should not have a trailing slash.
SSO login flow fails
- Ensure your SSO cookies are fresh and valid
- Test by opening your TestRail URL in a browser — if you can access it, the cookies should work
- Check that
TESTRAIL_COOKIE_PATHpoints to the correct Netscape-format cookie file - The server logs to stderr — check your MCP client's logs for detailed SSO flow output
Tools not appearing
Check TESTRAIL_TOOLSETS — by default only 9 core toolsets (54 tools) are enabled. Use TESTRAIL_TOOLSETS="all" for all 107 tools.
License
MIT