Skip to main content
Glama
VaniTTC

qTest On-Premise MCP Server

by VaniTTC
README.md
# qTest On-Premise MCP Server

> **Disclaimer:** This is an unofficial, community-built [MCP (Model Context Protocol)](https://modelcontextprotocol.io) server for **qTest Manager (On-Premise)**. It is not affiliated with or endorsed by Tricentis. Inspired by, and a substantial enhancement of, [Usman-Ghani123/qtest-mcp-server](https://github.com/Usman-Ghani123/qtest-mcp-server).

An MCP server that lets AI assistants (Claude Desktop, Claude Code, and any MCP-compatible client) drive a **self-hosted qTest Manager** instance through natural language — manage projects, modules, test cases, test steps, requirements, **requirement↔test-case traceability links**, test cycles, suites, runs, and execution results.

It is written in **TypeScript**, talks to qTest over the standard `/api/v3` REST API, and communicates with clients over **stdio**.

---

## What's new vs. the reference server

The reference project covered projects, modules, test cases, and execution scaffolding. This server keeps that surface and adds:

- **On-prem first**: configurable base URL, optional self-signed TLS tolerance, and tolerant base-URL parsing.
- **Dual authentication**: a static bearer/API token **or** username/password login that fetches and auto-refreshes a token (with 401 retry).
- **Requirements management**: full CRUD for requirements.
- **Traceability**: link / unlink test cases to requirements, read requirement coverage, a generic artifact-linking tool, and the requirement **traceability matrix** report.
- **Richer test design**: create test cases *with* ordered steps, add steps, update test cases, list/discover **fields** (so the model can populate custom fields by ID).
- **Execution & results**: cycles, suites, add runs from test cases, list/get runs, and **submit test logs** (pass/fail results).
- **QQL search** across artifact types, **attachments**, and an optional **raw request** escape hatch.
- **Production hardening**: timeouts, retry with backoff on 429/5xx, structured stderr logging, destructive-action gating, and friendly, LLM-readable error messages.

---

## Prerequisites

- Node.js 18+ (developed and tested on Node 22).
- A qTest Manager On-Premise instance reachable from where the server runs.
- Either a qTest **API token**, or a **username/password** with API access.

---

## Installation

```bash
git clone <your-fork-url> qtest-onprem-mcp
cd qtest-onprem-mcp
npm install
npm run build
```

```powershell
# Windows PowerShell equivalent
git clone <your-fork-url> qtest-onprem-mcp
cd qtest-onprem-mcp
npm install
npm run build
```

This produces `dist/index.js`, the compiled entry point your MCP client will launch (`dist/` is not committed — you must build it locally, or run `npm run dev` below).

For local development without building, use `npm run dev` (watch mode via `tsx`).

---

## Configuration

All configuration is via environment variables. Copy `.env.example` to `.env` for local runs, or set them in your MCP client config (recommended).

```bash
cp .env.example .env        # macOS/Linux
```
```powershell
Copy-Item .env.example .env # Windows PowerShell
```

| Variable | Required | Default | Description |
| --- | --- | --- | --- |
| `QTEST_BASE_URL` | **Yes** | – | Base URL of your on-prem qTest, e.g. `https://qtest.mycompany.internal`. A trailing `/api/v3` is tolerated and stripped. |
| `QTEST_TOKEN` | One of token *or* user/pass | – | Static bearer/API token. Generate in qTest under **Profile → API & SDK**. |
| `QTEST_USERNAME` | – | – | Username for password-grant login (used only when `QTEST_TOKEN` is empty). |
| `QTEST_PASSWORD` | – | – | Password for password-grant login. |
| `QTEST_LOGIN_CLIENT` | No | `qtest` | Basic-auth seed used on the `/oauth/token` request. Override if your admin configured a specific client id. |
| `QTEST_ENABLE_DESTRUCTIVE` | No | `false` | When `true`, registers the `delete-*` tools. |
| `QTEST_ENABLE_RAW_REQUEST` | No | `false` | When `true`, registers the generic `qtest_request` tool. |
| `QTEST_TIMEOUT_MS` | No | `30000` | Per-request timeout in milliseconds. |
| `QTEST_INSECURE_TLS` | No | `false` | When `true`, disables TLS certificate verification (for internal self-signed certs only). |
| `QTEST_LOG_LEVEL` | No | `info` | `error` \| `warn` \| `info` \| `debug`. All logs go to **stderr**. |

> **Auth precedence:** if `QTEST_TOKEN` is set it is always used. Otherwise the server logs in with `QTEST_USERNAME`/`QTEST_PASSWORD`, caches the token, refreshes it ~60s before expiry, and retries once on a `401`.

### Connect your MCP client

A ready-to-edit example lives in `.mcp.example.json`. Minimal Claude Desktop / Claude Code entry:

```json
{
  "mcpServers": {
    "qtest-onprem": {
      "command": "node",
      "args": ["dist/index.js"],
      "env": {
        "QTEST_BASE_URL": "https://qtest.mycompany.internal",
        "QTEST_TOKEN": "your-personal-access-token"
      }
    }
  }
}
```

Use an **absolute path** to `dist/index.js` if your client does not run from the project root.

---

## Available tools

Most tools require a numeric `projectId` — call **`qtest_list_projects`** first to discover it.

### Projects
| Tool | Description |
| --- | --- |
| `qtest_list_projects` | List accessible projects (optionally only those assigned to you). |
| `qtest_get_project` | Get a single project by ID. |

### Test Design — Modules
| Tool | Description |
| --- | --- |
| `qtest_list_modules` | List root / child modules, or filter by name. |
| `qtest_create_module` | Create a module or sub-module. |
| `qtest_update_module` | Rename/update a module or its custom fields. |
| `qtest_delete_module` † | Delete a module (cascades). |

### Test Design — Test Cases & Steps
| Tool | Description |
| --- | --- |
| `qtest_list_test_cases` | List test cases (optionally scoped to a module, name-filtered). |
| `qtest_get_test_case` | Get one test case with its steps. |
| `qtest_create_test_case` | Create a test case, optionally with ordered steps and custom fields. |
| `qtest_update_test_case` | Update name/description/precondition/fields (new version). |
| `qtest_add_test_step` | Append a step to a test case. |
| `qtest_delete_test_case` † | Delete a test case. |

### Requirements
| Tool | Description |
| --- | --- |
| `qtest_list_requirements` | List requirements (optionally scoped to a module). |
| `qtest_get_requirement` | Get one requirement. |
| `qtest_create_requirement` | Create a requirement under a module. |
| `qtest_update_requirement` | Update or move a requirement. |
| `qtest_delete_requirement` † | Delete a requirement. |

### Traceability & Linking
| Tool | Description |
| --- | --- |
| `qtest_link_test_cases_to_requirement` | **Link** one or more test cases as coverage of a requirement. |
| `qtest_unlink_test_cases_from_requirement` | Remove those coverage links. |
| `qtest_get_requirement_coverage` | List the test cases covering a requirement. |
| `qtest_link_artifacts` | Generic link/unlink between any two artifact types (test-cases, requirements, defects, test-runs). |
| `qtest_get_traceability_matrix` | Requirement traceability matrix report. |

### Test Execution
| Tool | Description |
| --- | --- |
| `qtest_list_test_cycles` | List root/child test cycles. |
| `qtest_create_test_cycle` | Create a cycle (root or nested). |
| `qtest_delete_test_cycle` † | Delete a cycle (cascades). |
| `qtest_list_test_suites` | List suites under a cycle/release. |
| `qtest_create_test_suite` | Create a suite. |
| `qtest_add_test_runs` | Create runs in a suite from test case IDs. |
| `qtest_list_test_runs` | List runs under a parent. |
| `qtest_get_test_run` | Get a run with its latest status. |
| `qtest_submit_test_log` | Record an execution result (Passed/Failed/…). |

### Cross-cutting
| Tool | Description |
| --- | --- |
| `qtest_search` | Search artifacts with qTest Query Language (QQL). |
| `qtest_list_fields` | Discover field IDs/allowed values for an artifact type. |
| `qtest_get_current_user` | Verify auth / identity. |
| `qtest_add_attachment` | Attach a base64 file to an artifact. |
| `qtest_request` ‡ | Raw authenticated API call (advanced). |

† Registered only when `QTEST_ENABLE_DESTRUCTIVE=true`.  ‡ Registered only when `QTEST_ENABLE_RAW_REQUEST=true`.

---

## Usage examples (natural language)

Once connected, you can prompt your assistant like this:

**Discover and browse**
```
List all my qTest projects.
List the modules in project 100001.
Show test cases in module 60000001 of project 100001.
```

**Author test design**
```
In project 100001, create a test case named "Login with valid credentials"
under module 60000001 with steps:
  1. Open the login page — login page is shown
  2. Enter valid username and password — fields accept input
  3. Click Sign In — user lands on the dashboard
```

**Requirements & traceability (the headline workflow)**
```
Create a requirement "User can reset password" under module 70000002 in project 100001.
List test cases in module 60000001 whose name contains "password".
Link test cases 130000045 and 130000046 to requirement 88000123 in project 100001.
Show me the coverage for requirement 88000123.
Give me the traceability matrix for project 100001.
```

**Execution & results**
```
Create a test cycle "Release 3.0" in project 100001.
Add a suite "Smoke" under that cycle, then add test runs for test cases 130000045 and 130000046.
Mark test run 220000099 as Passed with the note "verified on build 3.0.12".
```

**Search**
```
Search project 100001 for test cases where Status = 'Approved' and Priority = 'High'.
```

---

## Safety model

- **Destructive tools are off by default.** Deleting modules, test cases, requirements, and cycles cascades in qTest, so those tools only appear when you explicitly set `QTEST_ENABLE_DESTRUCTIVE=true`.
- **The raw request tool is off by default.** Enable it only if you need endpoints not yet wrapped by a dedicated tool.
- **Secrets stay in env vars** and are never logged. Set `QTEST_LOG_LEVEL=debug` only for troubleshooting.

---

## Development

```bash
npm run dev        # watch mode (tsx), no build needed
npm run build      # compile TypeScript to dist/
npm run typecheck  # type-only check
npm start          # run the compiled server
```

### Smoke test
With the server built, any MCP client can connect and call `tools/list`. The `tools/list` response should report **31 tools by default**, or **36** when both `QTEST_ENABLE_DESTRUCTIVE` and `QTEST_ENABLE_RAW_REQUEST` are `true` (adds 4 delete tools + the raw request tool).

> **No automated test suite yet.** This project currently has no unit/integration tests (`npm test` is not defined). Verification is manual: build, connect an MCP client (or the [MCP Inspector](https://modelcontextprotocol.io/docs/tools/inspector)), and exercise `tools/list` / `tools/call` against a real or sandboxed qTest instance.

---

## Troubleshooting

| Symptom | Likely cause / fix |
| --- | --- |
| `FATAL: QTEST_BASE_URL is required` | Set the base URL env var. |
| `Authentication not configured` | Provide `QTEST_TOKEN`, or both `QTEST_USERNAME` and `QTEST_PASSWORD`. |
| `401` errors | Token expired/invalid, or wrong `QTEST_LOGIN_CLIENT` for password grant. |
| `fetch failed` / TLS errors on-prem | Self-signed cert — set `QTEST_INSECURE_TLS=true` on a trusted network. |
| `404` on a known ID | Verify the `projectId` and artifact IDs; IDs are project-scoped. |
| A `delete-*` or `qtest_request` tool is missing | Enable it via the corresponding env flag. |

See **[ARCHITECTURE.md](./ARCHITECTURE.md)** for the internal design.

---

## License

MIT — see [LICENSE](./LICENSE).
"# soco-qtest-mcp" 

TDQS

A3.7/5.0

Scored across 31 tools

Disambiguation5/5

Each tool targets a distinct resource and action (e.g., get vs list vs create vs update). The two coverage-related tools are clearly differentiated: one for a single requirement, the other for a full traceability matrix. No two tools appear to do the same thing.

Naming Consistency5/5

All tool names follow the qtest_<verb>_<noun> pattern. Verbs are consistent (get/list/create/update/add/submit/link/unlink/search), and plural forms are used for list operations while singular is used for single-item fetches. No mixed conventions or style inconsistencies exist.

Tool Count3/5

The server exposes 31 tools, which is heavier than the typical sweet spot. While the breadth of qTest's test management API justifies many of them, there is some conceptual overlap (e.g., qtest_get_requirement_coverage vs qtest_get_traceability_matrix) that could be consolidated. The count is borderline but not chaotic.

Completeness2/5

The tool set covers create, read, and update for many artifact types, but lacks delete operations entirely (no delete for modules, test cases, requirements, cycles, suites, or runs). Update is also missing for cycles and suites. This creates lifecycle dead ends and limits cleanup ability, a significant gap in a comprehensive test management tool.

Maintenance

ActivitySlowing
ResponsivenessNo issues