zephyr-scale-mcp
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| JIRA_PAT | No | Personal access token for Jira DC (required if JIRA_AUTH is 'pat' or not set) | |
| JIRA_AUTH | No | Authentication type: 'pat' for personal access token, 'basic' for username/password | pat |
| JIRA_BASE_URL | Yes | Base URL of Jira without trailing slash (e.g., https://jira.example.com) | |
| JIRA_PASSWORD | No | Jira password (required if JIRA_AUTH is 'basic') | |
| JIRA_USERNAME | No | Jira username (required if JIRA_AUTH is 'basic') | |
| JIRA_TIMEOUT_MS | No | Timeout per HTTP request in milliseconds | 30000 |
| ZEPHYR_READONLY | No | When true, write tools return an error | false |
| JIRA_MAX_RETRIES | No | Max retries for GET and 429/503 responses | 2 |
| ZEPHYR_LOG_LEVEL | No | Log level: debug, info, warn, or error | info |
| ZEPHYR_DEFAULT_PROJECT_KEY | No | Default project key to use when not provided in tool calls | |
| JIRA_TLS_REJECT_UNAUTHORIZED | No | Set to false to allow self-signed certificates (disables TLS verification) | true |
Capabilities
Features and capabilities supported by this server
| Capability | Details |
|---|---|
| tools | {
"listChanged": true
} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| create_test_caseA | Create a Zephyr Scale test case (POST /testcase). Returns { key, url } with a key like PROJ-T123. Constraints: the folder, if given, MUST already exist — the API never creates folders (use create_folder first); status and priority are case-sensitive internal names (defaults 'Draft'/'Approved'/'Deprecated' and 'High'/'Normal'/'Low'; instances may define custom ones); owner is a Jira user key like JIRAUSER10000 (resolve with find_jira_user); estimatedTime is in milliseconds. testScript formats: STEP_BY_STEP with steps (a step carrying testCaseKey is a 'Call to Test' that inlines another test case), PLAIN_TEXT with text, or BDD with text holding ONLY Gherkin step lines (Given/When/Then/And/But, stored verbatim) — do NOT include 'Feature:'/'Scenario:' headers, the API rejects them with 400 'Invalid BDD Script'. |
| get_test_caseA | Read a Zephyr Scale test case by key (GET /testcase/{testCaseKey}). Optionally restrict the payload with fields. STEP_BY_STEP scripts come back with per-step ids — those ids are required to edit steps safely via update_test_case (add_test_steps handles them automatically). |
| search_test_cases | Search Zephyr Scale test cases with a TQL query (GET /testcase/search). Returns { startAt, maxResults, count, isLast, values }; isLast is the heuristic count < maxResults. Paginate with startAt (default 0) and maxResults (default 50; the API server-side default is 200). TQL quick reference:
Note: queries longer than 1500 characters (typically large IN lists) are automatically sent via POST /testcase/search, which is RESTRICTED to the fields projectKey, key and name, and to at most 2500 values in an IN list. |
| update_test_caseA | Update a Zephyr Scale test case (PUT /testcase/{testCaseKey}). PARTIAL update: only the fields you pass are changed; omitted fields keep their current values — never send empty placeholders. projectKey cannot be changed. STEP_BY_STEP step synchronization: when testScript.steps is passed, steps are matched by id — a step WITHOUT an id is CREATED, a step WITH an id is UPDATED, and any existing step MISSING from the list is DELETED. Therefore always pass the COMPLETE final list of steps, carrying over the ids of steps to keep (read them with get_test_case). To merely add steps, prefer add_test_steps, which performs that read-merge-write safely. Returns { key, url }. |
| add_test_stepsA | Add steps to a STEP_BY_STEP test case without losing the existing ones. Composite operation: reads the test case, merges the new steps at the requested position while preserving existing step ids (so nothing is deleted), and writes the full list back. position: 'append' (default) adds after the last step, 'prepend' before the first, an integer inserts at that 0-based index (clamped to the current length). Only valid when the current script is STEP_BY_STEP or the test case has no script yet (a step-by-step script is then created); for a PLAIN_TEXT or BDD script use set_test_script instead. Returns { key, totalSteps }. |
| set_test_scriptA | Replace a test case's ENTIRE script or change its format (PUT /testcase/{testCaseKey} with a full testScript). WARNING — destructive: switching a STEP_BY_STEP script to PLAIN_TEXT or BDD irreversibly deletes all existing steps, and a STEP_BY_STEP replacement deletes every existing step omitted from the list. Pass text for PLAIN_TEXT/BDD (for BDD only Gherkin step lines Given/When/Then/And/But, stored verbatim — no 'Feature:'/'Scenario:' headers, the API rejects them); pass steps for STEP_BY_STEP. Returns { key, url }. |
| delete_test_case | Permanently delete a Zephyr Scale test case (DELETE /testcase/{testCaseKey}). This cannot be undone. Returns { deleted: true, key }. |
| create_test_cases_bulk | Create multiple Zephyr Scale test cases in one call (POST /testcase/bulk). Each item accepts the same fields as create_test_case; an item without its own projectKey uses the shared projectKey parameter (or ZEPHYR_DEFAULT_PROJECT_KEY). The same constraints apply: folders must already exist, status/priority values are case-sensitive, owner is a Jira user key. Returns an array of { key, url } for the created test cases. Some Zephyr Scale Server builds lack a working bulk endpoint (it answers HTTP 500 with an empty body) — the tool then automatically falls back to creating the cases one by one via POST /testcase and returns { note, created, failed? } instead, so partial progress is never lost. |
| link_issues_to_test_cases | Link Jira issues to Zephyr Scale test cases in bulk (POST /testcase/link-issues). Each entry links one test case (testCaseKey, e.g. PROJ-T123) to one Jira issue (issueKey, e.g. PROJ-123); repeat a test case key across entries to link it to several issues. API limit: at most 2500 UNIQUE test case keys per call — validated locally before any request is sent. |
| get_test_cases_linked_to_issue | List the Zephyr Scale test cases linked to a Jira issue (GET /issuelink/{issueKey}/testcases). Useful for traceability from a requirement or bug to its tests. |
| clone_test_caseA | Clone a Zephyr Scale test case within its project — composite read+create: reads the source test case and creates a copy with the same objective, precondition, status, priority, owner, labels, custom fields, parameters and (by default) test script. Step ids are never carried over (the copy gets fresh steps), and execution history/attachments are NOT copied. The copy's name defaults to ' (copy)'; folder defaults to the source folder. Returns { key, url, sourceKey }. |
| get_issue_test_coverageA | Traceability report for a Jira issue: lists the Zephyr Scale test cases linked to the issue together with the latest execution result of each (composite read-only: GET /issuelink/{issueKey}/testcases, then per case GET /testcase/{key} and GET /testcase/{key}/testresult/latest). lastResult is null when the case has never been executed. Makes up to 2 HTTP calls per case — cap the volume with maxCases (default 50). |
| create_folderA | Create a Zephyr Scale folder for test cases, test plans or test runs (test cycles). |
| rename_folderA | Rename an existing Zephyr Scale folder by its numeric id (and optionally update its custom fields). |
| create_test_runA | Create a Zephyr Scale test run (test cycle; key like PROJ-R123). IMPORTANT API v1 limitation: a test run is IMMUTABLE after creation — there is no PUT /testrun/{key}. A run cannot be renamed, moved to another folder, and test cases cannot be added to or removed from it later; the set of items is fixed ONLY at creation time. The run status is computed automatically from the statuses of its items and cannot be set directly. Therefore pass the COMPLETE list of test cases in |
| get_test_runA | Read a Zephyr Scale test run (test cycle) by key, including its items. IMPORTANT API v1 limitation: a test run is IMMUTABLE after creation — there is no PUT /testrun/{key}. A run cannot be renamed, moved to another folder, and test cases cannot be added to or removed from it later; the set of items is fixed ONLY at creation time. The run status is computed automatically from the statuses of its items and cannot be set directly. Use get_test_run_results to page through the execution results of the run. |
| search_test_runs | Search Zephyr Scale test runs (test cycles) with TQL. For test runs TQL supports ONLY the fields |
| delete_test_run | Permanently delete a Zephyr Scale test run (test cycle) together with all its execution results. Since runs are immutable after creation, deleting and re-creating a run (create_test_run with the full desired |
| get_test_run_results | Page through the execution results of a Zephyr Scale test run (test cycle) via the paginated endpoint GET /testrun/{key}/testresults/page (the flat non-paginated variant is deprecated and used only as a fallback: older Zephyr Scale versions lack the /page endpoint, in which case the flat endpoint is read and paginated client-side — the response then carries a |
| get_test_run_summary | Aggregated execution summary of a Zephyr Scale test run (test cycle): counts the LAST execution of every run item grouped by status. Statuses are counted verbatim (case-sensitive, instance-specific custom sets included) in |
| create_test_result | Create a NEW execution (test result) for a test case that is already an item of a test run (test cycle). Appends a new result to the item's execution history — to amend the latest result instead, use update_last_test_result. This tool CANNOT add a test case to a run: the run's item list is fixed when the run is created, and the call fails if the case is not among the run's items. Only the fields you pass are sent. Default statuses: 'Not Executed', 'In Progress', 'Pass', 'Fail', 'Blocked' — case-sensitive internal names; instances may define custom ones. Durations (executionTime) are in milliseconds; dates are ISO 8601. scriptResults record per-step outcomes for STEP_BY_STEP scripts as { index (0-based), status, comment? }. If the same test case is included in the run as several items, disambiguate with matchEnvironment / matchUserKey. Returns { id } of the created result. |
| update_last_test_resultA | Update the LAST (most recent) test result of a run item. Partial update: ONLY the fields you pass are changed, everything else is preserved — do not send fields you do not want to modify. Older executions cannot be targeted; to record a new execution use create_test_result. The test case must already be one of the run's items (the run's composition is fixed at creation). Default statuses: 'Not Executed', 'In Progress', 'Pass', 'Fail', 'Blocked' — case-sensitive internal names; instances may define custom ones. Durations (executionTime) are in milliseconds; dates are ISO 8601. scriptResults record per-step outcomes as { index (0-based), status, comment? }. If the same test case is included in the run as several items, disambiguate with matchEnvironment / matchUserKey. |
| create_test_results_bulkA | Create NEW executions (test results) for several test cases of one test run in a single call. Every element's testCaseKey must already be one of the run's items — the run's item list is fixed when the run is created and this tool cannot extend it. In each element only the fields you pass are sent. Default statuses: 'Not Executed', 'In Progress', 'Pass', 'Fail', 'Blocked' — case-sensitive internal names; instances may define custom ones. Durations (executionTime) are in milliseconds; dates are ISO 8601. scriptResults record per-step outcomes as { index (0-based), status, comment? }. matchEnvironment / matchUserKey apply to the whole batch and disambiguate run items when the same test case is included in the run several times. Returns the array of created result ids. |
| get_latest_result_for_test_caseA | Get the latest (most recent) execution result of a test case across ALL test runs (cycles). Use get_test_run_results to read the results of one specific run instead. |
| create_test_planA | Create a Zephyr Scale test plan (POST /testplan). Returns { key } with a key like PROJ-P123 (no UI url — it cannot be built reliably for test plans). Constraints: the folder, if given, MUST be an existing folder of type TEST_PLAN — the API never creates folders (use create_folder with type TEST_PLAN first); status is a case-sensitive internal name (defaults 'Draft'/'Approved'/'Deprecated'; instances may define custom ones); owner is a Jira user key like JIRAUSER10000 (resolve with find_jira_user). |
| get_test_planA | Read a Zephyr Scale test plan by key (GET /testplan/{testPlanKey}). Optionally restrict the payload with fields. The response includes linked test runs and issues when present. |
| update_test_planA | Update a Zephyr Scale test plan (PUT /testplan/{testPlanKey}). PARTIAL update: only the fields you pass are changed; omitted fields keep their current values — never send empty placeholders. projectKey cannot be changed. The same constraints as create_test_plan apply: the folder must be an existing TEST_PLAN folder, status is case-sensitive, owner is a Jira user key. Returns { key }. |
| delete_test_planA | Permanently delete a Zephyr Scale test plan (DELETE /testplan/{testPlanKey}). This cannot be undone. Returns { deleted: true, key }. |
| search_test_plansA | Search Zephyr Scale test plans with a TQL query (GET /testplan/search). Returns { startAt, maxResults, count, isLast, values }; isLast is the heuristic count < maxResults. Paginate with startAt (default 0) and maxResults (default 50; the API server-side default is 200). TQL syntax is strict: spaces around operators are mandatory, string values go in double quotes, and the only logical connector is AND (no OR). Commonly supported test plan fields are projectKey, folder, name and status (e.g. projectKey = "PROJ" AND status = "Approved") — the exact set varies by Zephyr Scale version. |
| upload_attachmentA | Upload a file as an attachment to a Zephyr Scale test case, test run (cycle) or test result — optionally to a single step (POST multipart/form-data to /testcase/{key}[/step/{i}]/attachments, /testrun/{key}/attachments or /testresult/{id}[/step/{i}]/attachments). Addressing: target 'test_case' requires testCaseKey (stepIndex optional to address a specific step); target 'test_run' requires testRunKey (no step addressing — the API has no per-step endpoint for runs); target 'test_result' requires testResultId (stepIndex optional). Pass ONLY the identifier that matches the chosen target. filePath must be an absolute path of a file ON THE MACHINE RUNNING THIS MCP SERVER (the file is read from local disk). Returns the attachment metadata reported by the API, or { uploaded, fileName, size } when the API responds with an empty body. |
| list_attachmentsA | List the attachments of a Zephyr Scale test case, test run (cycle) or test result — optionally of a single step (GET /testcase/{key}[/step/{i}]/attachments, /testrun/{key}/attachments or /testresult/{id}[/step/{i}]/attachments). Addressing: target 'test_case' requires testCaseKey (stepIndex optional to address a specific step); target 'test_run' requires testRunKey (no step addressing — the API has no per-step endpoint for runs); target 'test_result' requires testResultId (stepIndex optional). Pass ONLY the identifier that matches the chosen target. Returns the attachment list as reported by the API; the numeric ids can be passed to delete_attachment. |
| download_attachmentA | Download a Zephyr Scale attachment to a local file. Address it either by attachmentId (from list_attachments or an upload response) or by the exact |
| delete_attachment | Permanently delete a Zephyr Scale attachment by its numeric id (DELETE /attachments/{id}). This cannot be undone. Attachment ids come from list_attachments or from upload_attachment responses. Returns { deleted: true, id }. |
| upload_automation_results | Publish automated test execution results to Zephyr Scale by uploading a ZIP archive. The archive must contain result files in the Zephyr Scale custom results format (JSON files listing executed test cases with their statuses, script results, etc.). The server processes the archive and creates a new test cycle (test run) holding the results; the API response describing that cycle is returned as-is. Pass autoCreateTestCases=true to let the server create test cases that appear in the results but do not exist in the project yet. filePath must point to a .zip file readable on the machine where this MCP server runs. |
| upload_cucumber_results | Publish Cucumber test execution results to Zephyr Scale by uploading a ZIP archive. The archive must contain Cucumber JSON report files (the output of Cucumber's built-in json formatter); scenario names/tags are matched to BDD test cases. The server processes the archive and creates a new test cycle (test run) holding the results; the API response describing that cycle is returned as-is. Pass autoCreateTestCases=true to let the server create test cases that appear in the results but do not exist in the project yet. filePath must point to a .zip file readable on the machine where this MCP server runs. |
| download_feature_files | Export BDD test cases from Zephyr Scale as Gherkin .feature files. The server returns a ZIP archive containing one .feature file per exported BDD test case; the archive is written to outputPath on the machine running this MCP server (the parent directory must already exist). The tql query is REQUIRED by the API and selects which test cases to export; this endpoint uses the testCase.-prefixed TQL dialect, e.g. 'testCase.projectKey = "PROJ"' or 'testCase.key IN ("PROJ-T1", "PROJ-T2")'. Returns { savedTo, bytes }. Reads from Zephyr Scale only (also available in ZEPHYR_READONLY mode); the sole side effect is writing the local file. |
| recreate_test_run_with_items | Composite workaround for a hard API v1 limitation: a Zephyr Scale test run (test cycle) is IMMUTABLE after creation — there is no PUT /testrun, so a run cannot be renamed, moved to another folder, and test cases cannot be added or removed. This tool is the ONLY way to change a run's composition, name or folder: it reads the source run, builds a new items list (kept source items in their original order, minus removeTestCaseKeys, plus addItems appended), creates a NEW run and returns its NEW key — references to the old key are not updated anywhere. Header fields not passed explicitly (name, folder, testPlanKey, issueLinks, iteration, version, owner, plannedStartDate, plannedEndDate, customFields) default to the source run's values. With copyResults=true the LAST execution of each kept item is carried over as the initial result of the new run (status, comment, executedBy, executionTime, actual dates, per-step scriptResults, …); when the same test case is included as several items, each of them receives that case's latest execution while keeping its own environment/assignee. The source run is KEPT unless deleteOriginal=true, and it is never deleted when creating the new run failed. Returns { key, originalKey, itemCount, copiedResults, deletedOriginal }. |
| list_environments | List Zephyr Scale environments configured for a Jira project. Environment names are case-sensitive and are referenced by name in test run items and test results. |
| create_environment | Create a Zephyr Scale environment in a Jira project. The name must be unique within the project. |
| find_jira_user | Search Jira users by username, display name or e-mail. Use it to resolve the Jira user key (e.g. 'JIRAUSER10000') required by the owner / executedBy / assignedTo fields of other tools. |
| health_check | Check connectivity and credentials: calls Jira /rest/api/2/myself and, when a default project key is configured, verifies that the Zephyr Scale plugin answers at /rest/atm/1.0. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/vilaabo/zephyr-scale-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server