TESSA MCP Skill (Claude Code)
TESSA is a SaaS platform that generates AI-driven test cases and executes them via MCP-connected agents. This skill teaches you how to use the TESSA MCP server correctly.
When this skill activates
Any of these user intents:
- "Run test case N" / "Ejecutá el caso de prueba N en [URL]"
- "List my TESSA tests / projects"
- "What are the steps of case N?"
- "Run the happy path of [project]"
- "Upload these screenshots to process N" / "Report the results"
- Any mention of TESSA, QualisLab, or automated test cases.
Server
- Production URL:
https://agent.qualis-lab.com/mcp
- Auth: Bearer token with
qai_ prefix (TESSA API token).
- Tools auto-discovered via
tools/list on connection.
- Ensure the MCP server is configured in
~/.claude.json or project .mcp.json.
The 6 tools
1. list_projects
Paginated list of the projects the user can access (server-enforced: only projects of their company where they're a member).
- Input:
{ page: number, pageSize: number }
- Output:
{ projects: [{id, name}], pagination: {...} }
- Use first when no specific
caseId is mentioned — pick a project, then list its cases.
2. list_test_cases
Paginated list of the test cases of a project the user can access.
- Input:
{ projectId: number, page: number, pageSize: number }
- Output:
{ projectId, projectName, cases: [{caseId, title, status}], pagination: {...} }
- Requires
projectId (from list_projects). Returns cases in all statuses (DRAFT, INICIADO, AWAITING_APPROVAL, PROCESADO, ERROR), each with its status field. Only PROCESADO cases are ready to execute — the rest let you see what state each generation ended up in. The caseId feeds the other tools.
- To monitor a generation just triggered with
generate_analysis, poll this tool and watch the status until it becomes PROCESADO.
3. fetch_cases
Fetch the generated cases of a process (happy path, additional cases, Gherkin scenarios and UX/UI analysis) in a single call. Replaces the old fetch_test_case and fetch_additional_cases. By default returns happy path + additionals; enable includeGherkin/includeUxUi to add them, or set includeHappyPath/includeAdditionals to false to filter them out.
- Input:
{ processId: number, includeHappyPath?: boolean, includeAdditionals?: boolean, includeGherkin?: boolean, includeUxUi?: boolean } — all include* are optional; includeHappyPath/includeAdditionals default true, includeGherkin/includeUxUi default false. Only processId is required.
- Output:
{ processId, happyPath, additionals, totalAdditionalCases }. With includeGherkin: true adds gherkin: [{ name, classification, steps: { given, when[], then[] } }]; with includeUxUi: true adds uxUi: { summary, payload } (or null if the process has no UX/UI analysis). Fields whose flag is false are omitted.
- Happy-path
steps are natural language descriptions. You translate them to concrete browser actions.
- To execute only the happy path, request
{ processId, includeAdditionals: false }. For "run all cases", keep the default (happy + additionals).
4. get_presigned_url
Generate a pre-signed S3 URL for uploading a screenshot. Use this for every screenshot — never inline base64.
- Input:
{ fileName: string, contentType: string, caseId?: string }
- Allowed contentType:
image/png, image/jpeg, image/jpg, image/webp only.
- Output:
{ uploadUrl, publicUrl } — PUT the binary to uploadUrl with correct Content-Type, then save publicUrl.
- Always pass
caseId when available — it organizes uploads and validates project access.
5. submit_test_result
Final execution report.
- Input:
{ caseId, status, executedUrl, totalDurationMs?, steps: [{stepNumber, description, status, durationMs?, screenshotUrl?, errorMessage?}] }
- status: one of
PASS | FAIL | ERROR | SKIPPED.
- Global status rule: if any step isn't PASS, global status can't be PASS (use worst: FAIL > ERROR > SKIPPED > PASS).
screenshotUrl must come from get_presigned_url.publicUrl.
6. generate_analysis
Generate test cases asynchronously from the text of a functional document, in a single call: it creates the process and triggers generation. You pass the document content as plain text in documentText — no file is uploaded (no base64, no presigned URLs). (MCP-only tool: no REST equivalent.)
- Input:
{ projectId: number, documentText: string, prompt?: string (≤5000), industry?: string, functionality?: string, platform?: string, additionals?: boolean, gherkin?: boolean, uxUi?: boolean }
projectId and documentText are required. documentText: plain text of the document (max 2 MB). If you have a PDF/docx, extract its text and pass it here.
additionals/gherkin/uxUi default to false. industry/functionality/platform have sensible defaults.
- Output:
{ processId, message } — generation is async. Poll afterwards with list_test_cases({ projectId }) and watch the case status until it becomes PROCESADO (or ERROR).
- Validates project access + the
CREATE_EXECUTIONS permission server-side. Uses the company's active LLM provider.
Recommended end-to-end flow
1. [If no caseId given]
→ list_projects
→ list_test_cases({ projectId }) (cases of the chosen project)
→ show to user, ask which one to run
2. → fetch_cases({ processId }) (happy path + additionals by default)
(for happy path only: fetch_cases({ processId, includeAdditionals: false }))
4. PRE-EXECUTION CHECK
Confirm with user: target URL, credentials if any, approval to run.
DO NOT proceed without explicit "yes".
5. FOR EACH STEP:
a. Translate step.action into concrete browser actions (navigate/click/fill/wait).
b. Execute. Measure durationMs.
c. Take screenshot.
d. get_presigned_url → PUT binary to uploadUrl → save publicUrl.
e. Record step status + publicUrl + error if any.
6. → submit_test_result with full steps array.
7. Summarize to user: global status, failed steps, screenshot links.
Document-based generation flow
1. If you have a PDF/docx, extract its content as plain text.
2. generate_analysis({ projectId, documentText, prompt?, ...flags }) → { processId, message } (ASYNC generation)
3. Poll list_test_cases({ projectId }) and watch the case status until it becomes PROCESADO (or ERROR)
4. fetch_cases({ processId }) to read the generated cases
The document travels as plain text in documentText — there is no S3 upload step.
Anti-failure patterns
Always confirm before executing
Test cases can hit real systems (payments, account creation, etc.). Always ask for explicit confirmation with target URL and side-effects summary.
"I'm going to run case 375 'Test QR Payment' on staging.example.com, which includes a simulated $500 payment. Confirm?"
No execution without an explicit "yes".
Execution URL is mandatory
Never assume https://example.com or any placeholder. If the user didn't provide the target URL, ask for it.
Screenshots via presigned URL, never base64
- ❌ Embed base64 inline in
submit_test_result.
- ✅
get_presigned_url → PUT to S3 → pass publicUrl to submit_test_result.
Error handling in steps
When a step fails:
- Screenshot the error state (not the expected state).
- Set
status: "FAIL" or "ERROR" with a meaningful errorMessage.
- Decide whether to continue or abort:
- Assertive failure (value mismatch): continue, next steps might pass.
- Structural failure (element not found, timeout, network): abort remaining steps as
SKIPPED.
Project access is enforced server-side
You only see and act on projects you're a member of. Errors like "Project not accessible" or "Test case (process) not accessible" mean the projectId/caseId isn't reachable with your token. No workarounds — ask user to verify with list_projects → list_test_cases({ projectId }).
Common errors
| Error |
Cause |
Action |
401 Invalid API token |
Token invalid/revoked |
Ask user to regenerate in TESSA → Settings → API Tokens |
Authentication required |
Call arrived without an authenticated user |
Ensure the API token is sent as Authorization: Bearer qai_... |
Project not found |
projectId doesn't exist |
Call list_projects for valid IDs |
Project not accessible |
Not a member of that project (or other company) |
Use only projectIds from list_projects |
Invalid caseId |
Non-numeric or missing process |
Call list_test_cases({ projectId }) |
Invalid content type |
Screenshot not png/jpeg/webp |
Convert to PNG |
Test case (process) not found / not accessible |
Case missing or in a project you can't see |
Verify caseId with list_test_cases({ projectId }) |
Example conversation
User: Ejecutá el caso 375 en staging.example.com
You (internally):
- Call
fetch_cases({ processId: 375, includeAdditionals: false }) → happy path (5 steps) returned.
- Respond: "Voy a ejecutar 'Test QR Payment' (5 pasos) en staging.example.com. Incluye pago simulado de $500. ¿Confirmás?"
- User confirms.
- For each step: browser action → screenshot →
get_presigned_url → PUT.
submit_test_result(...) with all 5 steps.
- Respond: "Ejecución OK. Status: PASS. 8.4s. Screenshots: ..."
Boundaries
steps[] max ~100 items.
- Screenshots ideally <2MB each.
- Don't run 50 executions in parallel — no rate limiting yet server-side.
- Never log real passwords in
errorMessage. Redact as pass=***.
See README.md at the project root or in the installation package for configuration details.
1---2name: tessa-mcp3description: Use when the user asks to run, list, inspect, or report test cases via the TESSA MCP server (at https://agent.qualis-lab.com/mcp). Orchestrates the 6 tools (list_projects, list_test_cases, fetch_cases, get_presigned_url, submit_test_result, generate_analysis) in the correct order. Triggers on mentions of TESSA, QualisLab, "test case N", "ejecutá el caso N", "happy path", "generá casos desde este documento", "generate cases from this document", or similar testing workflows.4---56# TESSA MCP Skill (Claude Code)78TESSA is a SaaS platform that generates AI-driven test cases and executes them via MCP-connected agents. This skill teaches you how to use the TESSA MCP server correctly.910## When this skill activates1112Any of these user intents:1314- "Run test case N" / "Ejecutá el caso de prueba N en [URL]"15- "List my TESSA tests / projects"16- "What are the steps of case N?"17- "Run the happy path of [project]"18- "Upload these screenshots to process N" / "Report the results"19- Any mention of TESSA, QualisLab, or automated test cases.2021## Server2223- **Production URL**: `https://agent.qualis-lab.com/mcp`24- **Auth**: Bearer token with `qai_` prefix (TESSA API token).25- Tools auto-discovered via `tools/list` on connection.26- Ensure the MCP server is configured in `~/.claude.json` or project `.mcp.json`.2728## The 6 tools2930### 1. `list_projects`31Paginated list of the **projects** the user can access (server-enforced: only projects of their company where they're a member).32- **Input**: `{ page: number, pageSize: number }`33- **Output**: `{ projects: [{id, name}], pagination: {...} }`34- **Use first** when no specific `caseId` is mentioned — pick a project, then list its cases.3536### 2. `list_test_cases`37Paginated list of the **test cases** of a project the user can access.38- **Input**: `{ projectId: number, page: number, pageSize: number }`39- **Output**: `{ projectId, projectName, cases: [{caseId, title, status}], pagination: {...} }`40- Requires `projectId` (from `list_projects`). Returns cases in **all statuses** (`DRAFT`, `INICIADO`, `AWAITING_APPROVAL`, `PROCESADO`, `ERROR`), each with its `status` field. Only `PROCESADO` cases are ready to execute — the rest let you see what state each generation ended up in. The `caseId` feeds the other tools.41- To monitor a generation just triggered with `generate_analysis`, poll this tool and watch the `status` until it becomes `PROCESADO`.4243### 3. `fetch_cases`44Fetch the generated cases of a process (happy path, additional cases, Gherkin scenarios and UX/UI analysis) in **a single call**. Replaces the old `fetch_test_case` and `fetch_additional_cases`. By default returns **happy path + additionals**; enable `includeGherkin`/`includeUxUi` to add them, or set `includeHappyPath`/`includeAdditionals` to `false` to filter them out.45- **Input**: `{ processId: number, includeHappyPath?: boolean, includeAdditionals?: boolean, includeGherkin?: boolean, includeUxUi?: boolean }` — all `include*` are optional; `includeHappyPath`/`includeAdditionals` default `true`, `includeGherkin`/`includeUxUi` default `false`. Only `processId` is required.46- **Output**: `{ processId, happyPath, additionals, totalAdditionalCases }`. With `includeGherkin: true` adds `gherkin: [{ name, classification, steps: { given, when[], then[] } }]`; with `includeUxUi: true` adds `uxUi: { summary, payload }` (or `null` if the process has no UX/UI analysis). Fields whose flag is `false` are omitted.47- Happy-path `steps` are **natural language descriptions**. You translate them to concrete browser actions.48- To execute only the happy path, request `{ processId, includeAdditionals: false }`. For "run all cases", keep the default (happy + additionals).4950### 4. `get_presigned_url`51Generate a pre-signed S3 URL for uploading a screenshot. **Use this for every screenshot — never inline base64.**52- **Input**: `{ fileName: string, contentType: string, caseId?: string }`53- **Allowed contentType**: `image/png`, `image/jpeg`, `image/jpg`, `image/webp` only.54- **Output**: `{ uploadUrl, publicUrl }` — PUT the binary to `uploadUrl` with correct `Content-Type`, then save `publicUrl`.55- **Always pass `caseId`** when available — it organizes uploads and validates project access.5657### 5. `submit_test_result`58Final execution report.59- **Input**: `{ caseId, status, executedUrl, totalDurationMs?, steps: [{stepNumber, description, status, durationMs?, screenshotUrl?, errorMessage?}] }`60- **status**: one of `PASS | FAIL | ERROR | SKIPPED`.61- **Global status rule**: if any step isn't PASS, global status can't be PASS (use worst: FAIL > ERROR > SKIPPED > PASS).62- `screenshotUrl` must come from `get_presigned_url.publicUrl`.6364### 6. `generate_analysis`65Generate test cases **asynchronously** from the **text** of a functional document, in **a single call**: it creates the process and triggers generation. You pass the document content as plain text in `documentText` — **no file is uploaded** (no base64, no presigned URLs). (MCP-only tool: no REST equivalent.)66- **Input**: `{ projectId: number, documentText: string, prompt?: string (≤5000), industry?: string, functionality?: string, platform?: string, additionals?: boolean, gherkin?: boolean, uxUi?: boolean }`67- `projectId` and `documentText` are **required**. `documentText`: plain text of the document (max 2 MB). If you have a PDF/docx, extract its text and pass it here.68- `additionals`/`gherkin`/`uxUi` default to **false**. `industry`/`functionality`/`platform` have sensible defaults.69- **Output**: `{ processId, message }` — generation is **async**. Poll afterwards with `list_test_cases({ projectId })` and watch the case `status` until it becomes `PROCESADO` (or `ERROR`).70- Validates project access + the `CREATE_EXECUTIONS` permission server-side. Uses the company's active LLM provider.7172## Recommended end-to-end flow7374```751. [If no caseId given]76 → list_projects77 → list_test_cases({ projectId }) (cases of the chosen project)78 → show to user, ask which one to run79802. → fetch_cases({ processId }) (happy path + additionals by default)81 (for happy path only: fetch_cases({ processId, includeAdditionals: false }))82834. PRE-EXECUTION CHECK84 Confirm with user: target URL, credentials if any, approval to run.85 DO NOT proceed without explicit "yes".86875. FOR EACH STEP:88 a. Translate step.action into concrete browser actions (navigate/click/fill/wait).89 b. Execute. Measure durationMs.90 c. Take screenshot.91 d. get_presigned_url → PUT binary to uploadUrl → save publicUrl.92 e. Record step status + publicUrl + error if any.93946. → submit_test_result with full steps array.957. Summarize to user: global status, failed steps, screenshot links.96```9798## Document-based generation flow99100```1011. If you have a PDF/docx, extract its content as plain text.1022. generate_analysis({ projectId, documentText, prompt?, ...flags }) → { processId, message } (ASYNC generation)1033. Poll list_test_cases({ projectId }) and watch the case status until it becomes PROCESADO (or ERROR)1044. fetch_cases({ processId }) to read the generated cases105```106107The document travels as **plain text** in `documentText` — there is no S3 upload step.108109## Anti-failure patterns110111### Always confirm before executing112Test cases can hit real systems (payments, account creation, etc.). **Always** ask for explicit confirmation with target URL and side-effects summary.113114> "I'm going to run case 375 'Test QR Payment' on staging.example.com, which includes a simulated $500 payment. Confirm?"115116No execution without an explicit "yes".117118### Execution URL is mandatory119Never assume `https://example.com` or any placeholder. If the user didn't provide the target URL, **ask for it**.120121### Screenshots via presigned URL, never base64122- ❌ Embed base64 inline in `submit_test_result`.123- ✅ `get_presigned_url` → PUT to S3 → pass `publicUrl` to `submit_test_result`.124125### Error handling in steps126When a step fails:1271. Screenshot the **error state** (not the expected state).1282. Set `status: "FAIL"` or `"ERROR"` with a meaningful `errorMessage`.1293. Decide whether to continue or abort:130 - Assertive failure (value mismatch): continue, next steps might pass.131 - Structural failure (element not found, timeout, network): abort remaining steps as `SKIPPED`.132133### Project access is enforced server-side134You only see and act on projects you're a member of. Errors like `"Project not accessible"` or `"Test case (process) not accessible"` mean the `projectId`/`caseId` isn't reachable with your token. No workarounds — ask user to verify with `list_projects` → `list_test_cases({ projectId })`.135136## Common errors137138| Error | Cause | Action |139|---|---|---|140| `401 Invalid API token` | Token invalid/revoked | Ask user to regenerate in TESSA → Settings → API Tokens |141| `Authentication required` | Call arrived without an authenticated user | Ensure the API token is sent as `Authorization: Bearer qai_...` |142| `Project not found` | `projectId` doesn't exist | Call `list_projects` for valid IDs |143| `Project not accessible` | Not a member of that project (or other company) | Use only `projectId`s from `list_projects` |144| `Invalid caseId` | Non-numeric or missing process | Call `list_test_cases({ projectId })` |145| `Invalid content type` | Screenshot not png/jpeg/webp | Convert to PNG |146| `Test case (process) not found` / `not accessible` | Case missing or in a project you can't see | Verify `caseId` with `list_test_cases({ projectId })` |147148## Example conversation149150**User**: Ejecutá el caso 375 en staging.example.com151152**You (internally)**:1531. Call `fetch_cases({ processId: 375, includeAdditionals: false })` → happy path (5 steps) returned.1542. Respond: "Voy a ejecutar 'Test QR Payment' (5 pasos) en staging.example.com. Incluye pago simulado de $500. ¿Confirmás?"1553. User confirms.1564. For each step: browser action → screenshot → `get_presigned_url` → PUT.1575. `submit_test_result(...)` with all 5 steps.1586. Respond: "Ejecución OK. Status: PASS. 8.4s. Screenshots: ..."159160## Boundaries161162- `steps[]` max ~100 items.163- Screenshots ideally <2MB each.164- Don't run 50 executions in parallel — no rate limiting yet server-side.165- **Never log real passwords** in `errorMessage`. Redact as `pass=***`.166167---168169See `README.md` at the project root or in the installation package for configuration details.