zephyr-squad-server-mcp
An MCP server that lets an AI agent drive Zephyr for Jira — Server / Data Center (ZAPI), the test-management suite for Jira. It exposes the most common test-management operations (cycles, folders, executions, test steps, step results, ZQL search) as well-described tools over stdio, so it plugs into Claude Desktop, Claude Code, and any other MCP client.
This targets the Server/DC flavor (
/rest/zapi/latest). It is not for Zephyr Squad Cloud, which uses a different JWT-signed API.
Install
The server is published on PyPI and is easiest to run with uv:
uvx zephyr-squad-server-mcp # run directly, no install
# or
uv tool install zephyr-squad-server-mcp
# or, in a venv
pip install zephyr-squad-server-mcp
Configuration
The connection rides on your Jira instance's authentication (shared by ZAPI and the Jira core REST API). Configure via environment variables or a .env file (see .env.example):
| Variable | Required | Default | Description | |---|---|---|---| | JIRA_URL | ✅ | — | Jira base URL, e.g. https://jira.company.com (no /rest suffix). | | JIRA_PERSONAL_TOKEN | one of | — | Personal Access Token → Authorization: Bearer … (recommended for DC). | | JIRA_USERNAME + JIRA_PASSWORD | one of | — | Basic-auth fallback (password or API token). Used only if JIRA_PERSONAL_TOKEN is empty. | | ZEPHYR_API_PATH | | /rest/zapi/latest | ZAPI base path on the Jira host. | | ZEPHYR_TIMEOUT | | 30 | Per-request timeout (seconds). | | ZEPHYR_VERIFY_SSL | | true | Verify TLS certs. Set false only for trusted internal self-signed hosts. |
The server fails fast with a clear error if the base URL or authentication is missing.
Client configuration (stdio)
Add to your MCP client config (e.g. Claude Desktop claude_desktop_config.json or Claude Code .mcp.json):
{
"mcpServers": {
"zephyr-squad": {
"command": "uvx",
"args": ["zephyr-squad-server-mcp"],
"env": {
"JIRA_URL": "https://jira.company.com",
"JIRA_PERSONAL_TOKEN": "your-personal-access-token"
}
}
}
}
For local development against a checkout, point command at uv:
{
"mcpServers": {
"zephyr-squad": {
"command": "uv",
"args": ["run", "--directory", "/path/to/zephyr-squad-server-mcp", "zephyr-squad-server-mcp"],
"env": { "JIRA_URL": "https://jira.company.com", "JIRA_PERSONAL_TOKEN": "…" }
}
}
}
Tools
All id-bearing tools accept either a numeric id or a human-friendly key/name for project (key like SONY or its name), version (name like Version 1.0, or -1/Unscheduled), and issue (key like SONY-1386). Resolved ids are cached for the session, so the first call does the lookup and later calls reuse it.
Full reference: see
docs/tools.mdfor every tool's arguments, types, defaults, the exact ZAPI endpoint it calls, and sync/async behavior. The table below is a quick index.
| Tool | What it does | |---|---| | list_cycles | List test cycles for a project/version. | | get_cycle | Get one cycle's details (id -1 = the Ad hoc cycle). | | create_cycle | Create a test cycle. | | update_cycle | Update a cycle's fields (id is sent in the body). | | delete_cycle | Delete a cycle (async; auto-polls to completion by default). | | export_cycle | Get a CSV download link for a cycle's executions. | | copy_executions_to_cycle | Copy executions into a cycle (async; auto-polls to completion by default). | | move_executions_to_folder | Move executions from a cycle into a folder (async; auto-polls to completion by default). | | list_cycle_folders | List folders within a cycle. | | create_folder | Create a folder under a cycle. | | update_folder | Update a folder's name/description. | | delete_folder | Delete a folder from a cycle (async; auto-polls to completion by default). | | list_executions | List executions in a cycle (optionally a folder). | | update_execution | Set an execution's status (PASS/FAIL/WIP/BLOCKED/…). | | list_test_steps | List the test steps of a test issue. | | create_test_step | Add a test step to a test issue. | | list_step_results | List per-step results for an execution. | | search_executions | Run a ZQL query and return matching executions. | | get_execution_status_counts | Status-count rollup for a project/version (by cycle). | | get_execution_status_counts_by_assignee | Per-assignee status counts for cycle(s). | | list_executions_by_issue | A single test's executions across all cycles. | | list_execution_defects | Defects linked to an execution. | | get_tests_by_requirement | Tests covering requirement(s); flags orphans. | | get_executions_by_test | Executions for a test (coverage history). | | get_executions_by_defect | Executions linked to a defect. | | get_defect_statistics | Per-defect execution/req/test rollups. | | update_test_step | Edit a test step's action/data/result. | | delete_test_step | Delete a test step. | | create_execution | Schedule a test into a cycle. | | add_tests_to_cycle_from_list | Bulk-add an explicit list of tests to a cycle as new UNEXECUTED executions (async). | | add_tests_to_cycle_from_filter | Bulk-add tests matched by a saved ZQL filter to a cycle as new UNEXECUTED executions (async). | | add_tests_to_cycle_from_cycle | Add tests from another cycle as new UNEXECUTED executions (async). | | update_step_result | Set a step result's status/comment. | | link_execution_defects | Link Jira defects to executions (async). | | assign_execution | Assign an execution to a user. | | delete_execution | Delete an execution by id. | | get_job_progress (helper) | Manually poll any async job by token. | | list_projects (helper) | List projects (name → id discovery). | | list_versions (helper) | List a project's versions (name → id discovery). | | get_zephyr_test_issue_type (helper) | Discover the Zephyr Test issue-type id per project (use case 1.1). |
Dates use Jira's dd/MMM/yy format (e.g. 4/Dec/12). Execution-status codes: -1=UNEXECUTED, 1=PASS, 2=FAIL, 3=WIP, 4=BLOCKED, 5=PENDING, 6=APPROVED, 7=CANCELLED.
Development
uv sync # create venv + install deps (incl. dev group)
uv run pytest # unit tests (httpx mocked with respx — no live Jira needed)
uv run ruff check # lint
uv run mcp dev src/zephyr_squad_server_mcp/server.py # MCP Inspector smoke test
docs/getzephyr.apib is the ZAPI API Blueprint used as the reference for request/response shapes during development. It was retrieved from the official public documentation at <https://getzephyr.docs.apiary.io/> (© SmartBear Software). An older version is also available in the zfjdeveloper/zapi-docs repository.
The Inspector (mcp dev) launches the MCP Inspector via npx, so it needs Node.js / npx on your PATH. The tool list loads without any Jira config, but invoking a tool builds the client on first use — so set JIRA_URL and auth (a .env is read automatically) before running tools.
Publishing to PyPI
uv build # produces wheel + sdist in dist/
uv publish --token "$UV_PUBLISH_TOKEN" # or set UV_PUBLISH_TOKEN in the env
Test against TestPyPI first:
uv publish --publish-url https://test.pypi.org/legacy/ --token "$TESTPYPI_TOKEN"
License
MIT — see LICENSE.












