QaseSAFE
An official Qase MCP server
Overview
From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.
Official Model Context Protocol (MCP) server for Qase Test Management Platform — connect AI assistants to your test cases, runs, defects, and more.
[](https://www.npmjs.com/package/@qase/mcp-server) [](https://opensource.org/licenses/MIT) [](https://registry.modelcontextprotocol.io/v0/servers?search=io.qase%2Fmcp-server)
Table of Contents
- Overview
- Use Cases
- Quick Start
- Use the hosted Qase MCP (recommended)
- Run it yourself
- Building on top of this server
- Upgrading from v1
- Tools
- Documentation
- Contributing
- License
- Support
- Links
Overview
The Qase MCP Server lets AI assistants (Claude, Cursor, Codex, and any other MCP client) read and write Qase test cases, runs, results, defects, suites, milestones, and more — through a standardized protocol, with no custom integration code.
Features:
- 40 task-oriented tools (41 total, including
qase_discover_tools) — consolidated from 83 v1 tools for lower token usage and better LLM accuracy - Composite tools — multi-step workflows in a single call: CI reporting, defect triage, regression run setup
- QQL support — Qase Query Language for advanced searches across cases, runs, results, defects, and plans
- Project context bootstrap — one call returns full project structure (suites, milestones, environments, users, custom fields)
- Test case review — propose new cases or changes for review, assign reviewers, and track status (approving and merging remain
41c50729eeeeOBSERVED · 2026-10-08Connect
Built from this server's own package name, version and transport as found in its source — not copied from anyone's documentation, so it cannot drift against a page we do not control. Replace the environment placeholders with a token scoped to the least it needs.
claude mcp add mcp-server --env QASE_API_TOKEN=${QASE_API_TOKEN} -- npx -y @qase/[email protected]Exposed tools (70)
30 read · 26 write · 14 destructive. Blast radius: 14 tools can delete or overwrite — an agent that can be talked into calling a tool can be talked into calling this one.
| Tool | Risk | Description |
|---|---|---|
a | read | a |
b | read | b |
ci_integration | write | Report CI/CD test results to Qase: create a run, record results, and get a summary. |
complex_tool | read | A complex tool |
core_a | read | a |
core_c | read | c |
core_tool | read | core |
disc_b | read | b |
duplicate_tool | read | First |
explicit_core | read | core |
hidden | read | h |
hidden_tool | read | hidden |
milestone | read | Milestone name or ID |
my_tool | read | desc |
onboard_project | read | Get a comprehensive overview of a Qase project for a new team member: |
probe_secondary_tool | read | A probe tool used to verify discovery activation. |
project | read | Project code (e.g. DEMO) |
qase_api | read | Call any Qase REST endpoint directly, for the few things no dedicated tool covers. Pass the |
qase_attachment_delete | destructive | Delete an attachment by its hash. Anything referencing it — a case, a result, a defect — |
qase_attachment_upload | write | Upload files and get back the hashes that other tools reference them by — screenshots, |
qase_case_bulk_create | write | Create up to ${MAX_CASES} test cases in one request — the batch form of qase_case_upsert, |
qase_case_delete | destructive | Delete a test case by project code and case ID. The case goes, and so does its execution |
qase_case_upsert | write | Create or update a single test case. With |
qase_ci_report | write | Report a whole CI run in one call: creates the run, records every result, and completes it. |
qase_custom_field_delete | destructive | Delete a custom field by ID. The field disappears from every project it applies to, and the |
qase_custom_field_upsert | write | Create or update a custom field. With |
qase_defect_delete | destructive | Delete a defect by project code and defect ID. The defect and its links to results |
qase_defect_upsert | write | Create or update a defect — a tracked problem found by testing. Without |
qase_discover_tools | read | Find and switch on tools that are hidden by default. Only core tools appear in the tool |
qase_environment_delete | destructive | Delete an environment by project code and environment ID. Runs that referenced it are not |
qase_environment_upsert | write | Create or update an environment — a named target that runs can be attributed to, such as |
qase_external_issue_link | read | Link or unlink test cases and test runs to issues in an external tracker — Jira Cloud or |
qase_get | write | Fetch one known record by type and ID: case, suite, run, result, plan, defect, milestone, |
qase_milestone_delete | destructive | Delete a milestone by project code and milestone ID. The milestone disappears and runs and |
qase_milestone_upsert | write | Create or update a milestone — a dated marker that runs and cases can be grouped under, |
qase_plan_delete | destructive | Delete a test plan by project code and plan ID. Only the plan is removed — the cases it |
qase_plan_upsert | write | Create or update a test plan — a named, reusable set of cases to run together, such as a |
qase_project_context | read | Seed everything about a project in one call: project details, the full suite tree, |
qase_project_create | write | Create a new project. The code must be unique in the workspace and may contain letters only |
qase_project_delete | destructive | Delete an entire project by its code. This removes every test case, suite, run, result, |
qase_regression_run | write | Build and start a test run from a suite, a test plan, or an explicit list of case IDs, in |
qase_result_delete | destructive | Delete a single result from a run, addressed by run ID and result hash. Use it to remove one |
qase_result_record | write | Record up to ${MAX_RESULTS} results into an existing run. A case says what should be tested; |
qase_review_bulk_create | write | Open several test case reviews in one request — the batch form of qase_review_create, and |
qase_review_create | write | Open a test case review — the pull-request flow for test cases. Pass |
qase_review_delete | destructive | Delete a review by ID. This removes the proposal entirely — it does not decline it, and |
qase_review_list | read | List the reviews in a project, with their current state, so you can see what is waiting on a |
qase_review_update | write | Update an open review: change the proposed case fields, reassign reviewers, or both. |
qase_run_complete | write | Mark a test run as complete so it reports as finished rather than in progress. Call it once |
qase_run_delete | destructive | Delete a test run by project code and run ID. This removes the run together with every |
qase_run_upsert | write | Create or update a test run. Without |
qase_shared_step_delete | destructive | Delete a shared step by project code and hash. Every case that referenced it loses those |
qase_shared_step_upsert | write | Create or update a shared step — a block of steps written once and reused across many cases, |
qase_suite_delete | destructive | Delete a test suite by project code and suite ID. WARNING: the cases inside are deleted with |
qase_suite_upsert | write | Create or update a test suite — the folder cases live in. Without |
qase_triage_defect | write | Create a defect from a test failure, with the failure context written into it. Requires |
qql_help | read | Read the QQL reference before writing a query. Pass a |
qql_search | read | Search any entity with Qase Query Language: filtering, cross-project queries, sorting, and |
regression_workflow | write | Create and manage a full regression test cycle: set up a run from a plan or suites, |
release_readiness | read | Check release readiness for a milestone: test coverage, pass rate, open defects, blocking issues. |
results_json | read | JSON array of results: [{ |
run_id | write | Test run ID to triage |
source | read | Source of test cases: plan ID, suite IDs (comma-separated), or |
test_tool | read | A test tool |
title | write | Regression run title (e.g. |
to_remove | destructive | x |
tool1 | read | Tool 1 |
tool2 | read | Tool 2 |
triage_failed_run | write | Analyze a failed test run: show all failed results grouped by error pattern, |
whoami | read | reports the integration marker |
Trust audit
SAFEgrade B · trust 88/100 Nothing in the source contradicts what it says it does. Grade A is reserved for packages that have also passed the behavioural sandbox.
| Layer | What it checks | Result |
|---|---|---|
| L0 | Provenance & inventory | PASS |
| L1 | Static analysis of the code | PASS |
| L2 | Instruction surface (what it tells the agent) | PASS |
| L3 | Class-specific surface | WARN |
| L4 | Behavioural (sandbox) | SKIPPED |
What the source does
- Filesystem
- declared (2 observation(s))
- Network
- declared (6 observation(s))
- Shell
- none-observed
- Dependencies
- not all pinned
- Secrets in source
- none-found
Findings (16)
qase_attachment_delete, qase_case_delete, qase_custom_field_delete, qase_defect_delete, qase_environment_delete, qase_milestone_delete, qase_plan_delete, qase_project_delete, qase_result_delete, qase_
await client.request('/v1/../../v1/project');import { setTestEnv } from '../../utils/test-helpers.js';jest.mock('../../client/index.js', () => ({import { toolRegistry } from '../../utils/registry.js';import { getApiClient } from '../../client/index.js';host = `http://127.0.0.1:${(server.address() as AddressInfo).port}`;const sseUrl = new URL(`http://127.0.0.1:${(httpServer.address() as AddressInfo).port}/sse`);const sseUrl = new URL(`http://127.0.0.1:${(httpServer.address() as AddressInfo).port}/sse`);baseUrl = new URL(`http://127.0.0.1:${address.port}/mcp`);sudo mv mcp-publisher /usr/local/bin/
@modelcontextprotocol/node, @modelcontextprotocol/server, @modelcontextprotocol/server-legacy, axios, express, express-rate-limit, form-data, jose
- **An unparsable request body leaked a stack trace on network transports.** `express.json()` is mounted before the auth guard, so a POST with malformed JSON never reached the guard: it fell through t
- **Each SSE client gets its own session.** The transport kept one connection per process, so the second client to open `/sse` took over the first one's stream and the original session silently stoppe
Over HTTP transports the marker can also travel per request instead of per process — send an `X-Qase-Integration: <name>/<version>` header, or add `?integration=<name>/<version>` to the MCP endpoint U
2. 2.6.0 also fixes notification delivery on the HTTP transports, where only the most recently opened session used to be notified — if several sessions or clients share one server process, older sessi
Gates applied: no_behavioural_pass.
41c50729eeeefull audit observations/trust-audit/mcp-server/qase-tms__qase-1.json · Report an issue / request a re-scanAudit history
Every audit this server has had. A grade with a past is a grade somebody is still checking.
| Date | Source | Verdict | Grade | Score | Change |
|---|---|---|---|---|---|
| 2026-10-08 | 41c50729eeee | SAFE | B | 88 | first audit |
Questions
What is the Qase MCP server?
An official Qase MCP server
What tools does Qase expose?
70 in total: 30 read-only, 26 that write, and 14 that can delete or overwrite (qase_attachment_delete, qase_case_delete, qase_custom_field_delete, qase_defect_delete, qase_environment_delete). Every one is listed on this page with its risk.
Is Qase safe to connect to an agent?
The audit found nothing in the source that contradicts what it says it does, and graded it B (88/100). Grade A is held back for packages that have also passed a sandboxed behavioural run, which is why a clean server reads B. Separately from the audit: 14 of its tools can destroy data, so scope the token you give it to what you actually need.
What credentials does Qase need?
It reads DUMP_TOKEN, QASE_API_TOKEN, QASE_OAUTH_AUDIENCE, QASE_OAUTH_ENABLED, QASE_OAUTH_ISSUER, QASE_OAUTH_JWT_ALGORITHMS, QASE_OAUTH_PUBLIC_URL, QASE_OAUTH_RESOURCE_URL and QASE_OAUTH_REVOCATION_URL from the environment. Give it a token scoped to the least it needs — an agent that can be talked into calling a tool can be talked into calling it with your credentials.
How does Qase run?
It speaks sse, stdio and streamable-http, so it runs as a local process your client starts. It is published on npm as @qase/mcp-server at 2.7.5.
How current is this page?
The grade is for one exact copy of the source (41c50729eeee), read on 2026-10-08. The repository is watched and re-audited when it changes.