A comprehensive Python wrapper for the TestRail API that provides easy access to all TestRail functionalities. Now featuring a built-in MCP (Model Context Protocol) server for seamless AI assistant integration.
- NEW: MCP (Model Context Protocol) server support for AI assistants
- NEW: Comprehensive exception handling with specific error types
- NEW: Connection pooling and automatic retry logic
- NEW: Rate limiting awareness and handling
- NEW: Configurable request timeouts
- Full coverage of TestRail API endpoints
- Type hints for better IDE support
- Easy-to-use interface
- Support for both API key and password authentication
This is a major version update with breaking changes. Please read the Migration Guide before upgrading from v0.3.x.
- Enhanced Error Handling: Methods now raise specific exceptions instead of returning
None - Consistent Return Types: No more
Optionalwrappers - methods return data directly - Better Type Safety: Comprehensive type annotations throughout
- Performance Improvements: Connection pooling, retry logic, and efficient requests
- Official Compliance: Follows TestRail API best practices
This package includes a built-in MCP server that enables AI assistants (like Cursor, Claude Desktop, etc.) to interact with TestRail through a standardized interface. All TestRail API methods are automatically exposed as MCP tools.
One-click install link for Cursor:
After clicking the link:
- Cursor will prompt you to install the MCP server
- You'll need to update the environment variables in the prompt / your
mcp.jsonfile:- Replace
https://yourinstance.testrail.iowith your TestRail instance URL - Replace
Yourtestrailuser@yourcompany.comwith your TestRail username/email - Replace
Your API Key goes herewith your TestRail API key (found in your TestRail profile settings)
- Replace
- Restart Cursor to activate the MCP server
Text link (if button doesn't work):
cursor://anysphere.cursor-deeplink/mcp/install?name=testrail-mcp&config=eyJjb21tYW5kIjoidXZ4IiwiYXJncyI6WyItLWZyb20iLCJ0ZXN0cmFpbC1hcGktbW9kdWxlIiwidGVzdHJhaWwtbWNwLXNlcnZlciJdLCJlbnYiOnsiVEVTVFJBSUxfQkFTRV9VUkwiOiJodHRwczovL3lvdXJpbnN0YW5jZS50ZXN0cmFpbC5pbyIsIlRFU1RSQUlMX1VTRVJOQU1FIjoiWW91cnRlc3RyYWlsdXNlckB5b3VyY29tcGFueS5jb20iLCJURVNUUkFJTF9BUElfS0VZIjoiWW91ciBBUEkgS2V5IGdvZXMgaGVyZSJ9fQ==
⚠️ Important: You must haveuvinstalled before running the MCP server. The MCP server usesuvxto run without requiring a global package installation.
# macOS/Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"đź“‹ Click to Copy Configuration
Open or create ~/.cursor/mcp.json (or ~/.config/cursor/mcp.json on Linux) and add this configuration:
{
"mcpServers": {
"testrail": {
"command": "uvx",
"args": [
"--from",
"testrail-api-module",
"testrail-mcp-server"
],
"env": {
"TESTRAIL_BASE_URL": "https://your-instance.testrail.io",
"TESTRAIL_USERNAME": "your-username",
"TESTRAIL_API_KEY": "your-api-key"
}
}
}
}After copying:
- Replace
https://your-instance.testrail.iowith your TestRail instance URL - Replace
your-usernamewith your TestRail username/email - Replace
your-api-keywith your TestRail API key (found in your TestRail profile settings)
Restart Cursor to load the MCP server. The TestRail tools will be available in your AI assistant.
Note: This configuration runs the
testrail-mcp-serverCLI usinguvx --from testrail-api-module.uvxwill automatically download and cache the package from PyPI if needed, so you don't need a global install or a pre-created virtual environment.
Using uvx directly from GitHub (no PyPI install required):
{
"mcpServers": {
"testrail": {
"command": "uvx",
"args": [
"--from",
"git+https://github.com/trtmn/testrail_api_module",
"testrail-mcp-server"
],
"env": {
"TESTRAIL_BASE_URL": "https://your-instance.testrail.io",
"TESTRAIL_USERNAME": "your-username",
"TESTRAIL_API_KEY": "your-api-key"
}
}
}
}- Automatic Tool Discovery: All TestRail API methods are automatically exposed as MCP tools
- Module-Based Organization: Tools are organized by TestRail module (cases, runs, results, etc.)
- Full API Coverage: Access to all 22 TestRail API modules
- Environment-Based Configuration: Configure via environment variables or
.envfiles - No Installation Required: Use
uvxto run without installing the package globally
The MCP server exposes tools for all TestRail API modules:
attachments- Managing attachmentscases- Test casesconfigurations- Test configurationsmilestones- Milestonesplans- Test plansprojects- Projectsresults- Test resultsruns- Test runssuites- Test suites- And many more...
For detailed MCP usage instructions, see the MCP Usage Guide.
# Install the package with runtime dependencies only
pip install testrail-api-module# Clone the repository
git clone https://github.com/trtmn/testrail-api-module.git
cd testrail-api-module
# Create virtual environment and install dependencies using uv
uv venv .venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
# Install development dependencies (includes all dev tools like pytest, mypy, etc.)
uv sync --extra dev
# Or install all optional dependencies
uv sync --all-extrasfrom testrail_api_module import TestRailAPI, TestRailAPIError, TestRailAuthenticationError, TestRailRateLimitError
# Initialize the API client
api = TestRailAPI(
base_url='https://your-instance.testrail.io',
username='your-username',
api_key='your-api-key', # or use password='your-password'
timeout=30 # Optional: request timeout in seconds
)
try:
# Get a list of projects
projects = api.projects.get_projects()
print(f"Found {len(projects)} projects")
# Create a new test case
new_case = api.cases.add_case(
section_id=123,
title='Test Login Functionality',
type_id=1, # Functional test
priority_id=3, # Medium priority
estimate='30m', # 30 minutes
refs='JIRA-123'
)
print(f"Created case: {new_case['title']}")
# Add a test result
result = api.results.add_result(
run_id=456,
case_id=789,
status_id=1, # Passed
comment='Test executed successfully',
elapsed='15m', # Actual time taken
version='1.0.0'
)
print(f"Added result: {result['id']}")
except TestRailAuthenticationError as e:
print(f"Authentication failed: {e}")
except TestRailRateLimitError as e:
print(f"Rate limit exceeded: {e}")
except TestRailAPIError as e:
print(f"API error: {e}")
except Exception as e:
print(f"Unexpected error: {e}")try:
# Get all test cases in a project
cases = api.cases.get_cases(project_id=1)
print(f"Found {len(cases)} cases")
# Update a test case
updated_case = api.cases.update_case(
case_id=123,
title='Updated Test Case Title',
type_id=2, # Performance test
priority_id=1 # Critical priority
)
print(f"Updated case: {updated_case['title']}")
# Delete a test case
result = api.cases.delete_case(case_id=123)
print("Case deleted successfully")
except TestRailAPIError as e:
print(f"Error managing test cases: {e}")# Create a new test run
new_run = api.runs.add_run(
project_id=1,
name='Sprint 1 Regression',
description='Full regression test suite',
suite_id=2,
milestone_id=3,
include_all=True
)
# Get test run results
results = api.runs.get_run_stats(run_id=new_run['id'])
# Close a test run
api.runs.close_run(run_id=new_run['id'])# Add an attachment to a test case
api.attachments.add_attachment(
entity_type='case',
entity_id=123,
file_path='path/to/screenshot.png',
description='Screenshot of the error'
)
# Get attachments for a test case
attachments = api.attachments.get_attachments(
entity_type='case',
entity_id=123
)# Import a BDD scenario
api.bdd.add_bdd(
section_id=123,
feature_file='path/to/feature/file.feature',
description='Login feature tests'
)
# Export a BDD scenario
scenario = api.bdd.get_bdd(case_id=456)The module includes comprehensive error handling with specific exception types:
from testrail_api_module import TestRailAPI, TestRailAPIError, TestRailAuthenticationError, TestRailRateLimitError
try:
result = api.cases.get_case(case_id=999999)
print(f"Case: {result['title']}")
except TestRailAuthenticationError as e:
print(f"Authentication failed: {e}")
except TestRailRateLimitError as e:
print(f"Rate limit exceeded: {e}")
except TestRailAPIError as e:
print(f"API error: {e}")
except Exception as e:
print(f"Unexpected error: {e}")TestRailAPIError: Base exception for all API-related errorsTestRailAuthenticationError: Authentication failures (401 errors)TestRailRateLimitError: Rate limit exceeded (429 errors)TestRailAPIException: General API errors with status codes and response details
Upgrading from v0.3.x? Please read our comprehensive Migration Guide for detailed instructions on updating your code to work with v0.4.0.
- Update error handling: Wrap API calls in try/except blocks
- Remove None checks: Methods now return data directly or raise exceptions
- Import exception classes: Add
TestRailAPIError,TestRailAuthenticationError,TestRailRateLimitErrorto your imports - Update method calls: Use explicit parameters instead of
**kwargswhere applicable
For complete documentation, visit our docs.
This project uses modern Python packaging with pyproject.toml for dependency
management.
pyproject.toml- Package configuration and dependency specifications
Contributions are welcome! Please feel free to submit a Pull Request.
This project is licensed under the MIT License - see the LICENSE file for details.
- Matt Troutman
- Christian Thompson
- Andrew Tipper
If you encounter any issues or have questions, please open an issue on GitHub.