create_manual_run
Create a new manual test run. Specify project, name, and optionally link to a release, assign tags, or select specific test cases or suites.
Instructions
Create a new manual test run. Requires write permission. selectionMode controls which test cases are included: 'all' (default — every case in the project) or 'selected' (use testCaseIds and/or suiteIds to scope). releaseId attaches the run to a release. note accepts rich HTML. IMPORTANT: tags must be a JSON array of strings here — e.g. ["smoke","regression"] — NOT the comma-separated form that list_manual_runs accepts as a filter.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| projectId | Yes | Project ID (required). | |
| name | Yes | Run name (required). | |
| note | No | Rich HTML note. | |
| environment | No | Environment label, e.g. 'Staging'. | |
| releaseId | No | Attach run to this release. | |
| state | No | Workflow state (default 'new'). Either canonical ('in_progress') or display ('In Progress') form — server normalizes to lowercase+underscored so UI colors render correctly. | |
| selectionMode | No | Default 'all'. | |
| testCaseIds | No | ||
| suiteIds | No | ||
| includeUnsorted | No | ||
| forecast | No | ||
| tags | No | Array of tag strings, e.g. ["smoke","regression"]. NOT a comma-separated string. | |
| linkedIssues | No | Array of linked-issue objects (same shape list_manual_runs returns). | |
| attachments | No | Array of attachment objects or URLs. | |
| links | No | Array of link objects. |
Implementation Reference
- handleCreateManualRun: The handler function that creates a manual test run. It extracts the API key, validates required args (projectId, name), builds the endpoint URL, and sends a POST request with the remaining args as the body. Returns the JSON response wrapped in MCP content format.
export async function handleCreateManualRun(args?: CreateManualRunArgs) { const token = getApiKey(args); if (!token) { throw new Error( "Missing TESTDINO_PAT environment variable. Configure it in your .cursor/mcp.json under 'env'." ); } if (!args?.projectId) throw new Error("projectId is required"); if (!args?.name) throw new Error("name is required"); try { const { projectId, ...body } = args; const url = endpoints.createManualRun(String(projectId)); const response = await apiRequestJson<unknown>(url, { method: "POST", headers: { Authorization: `Bearer ${token}` }, body, }); return { content: [{ type: "text", text: JSON.stringify(response, null, 2) }], }; } catch (error) { const msg = error instanceof Error ? error.message : String(error); throw new Error(`Failed to create manual run: ${msg}`); } } - createManualRunTool: Schema registration object for the 'create_manual_run' tool. Includes the name (create_manual_run), description, and inputSchema defining all parameters: projectId (required), name (required), note, environment, releaseId, state, selectionMode, testCaseIds, suiteIds, includeUnsorted, forecast, tags, linkedIssues, attachments, links.
export const createManualRunTool = { name: "create_manual_run", description: "Create a new manual test run. Requires write permission. selectionMode controls which test cases are included: 'all' (default — every case in the project) or 'selected' (use testCaseIds and/or suiteIds to scope). releaseId attaches the run to a release. note accepts rich HTML. IMPORTANT: tags must be a JSON array of strings here — e.g. [\"smoke\",\"regression\"] — NOT the comma-separated form that list_manual_runs accepts as a filter.", inputSchema: { type: "object", properties: { projectId: { type: "string", description: "Project ID (required)." }, name: { type: "string", description: "Run name (required)." }, note: { type: "string", description: "Rich HTML note." }, environment: { type: "string", description: "Environment label, e.g. 'Staging'.", }, releaseId: { type: "string", description: "Attach run to this release." }, state: { type: "string", description: "Workflow state (default 'new'). Either canonical ('in_progress') or display ('In Progress') form — server normalizes to lowercase+underscored so UI colors render correctly.", }, selectionMode: { type: "string", enum: ["all", "selected"], description: "Default 'all'.", }, testCaseIds: { type: "array", items: { type: "string" } }, suiteIds: { type: "array", items: { type: "string" } }, includeUnsorted: { type: "boolean" }, forecast: {}, tags: { type: "array", items: { type: "string" }, description: 'Array of tag strings, e.g. ["smoke","regression"]. NOT a comma-separated string.', }, linkedIssues: { type: "array", items: {}, description: "Array of linked-issue objects (same shape list_manual_runs returns).", }, attachments: { type: "array", items: {}, description: "Array of attachment objects or URLs.", }, links: { type: "array", items: {}, description: "Array of link objects.", }, }, required: ["projectId", "name"], }, }; - src/index.ts:306-310 (registration)Tool dispatch: When the tool name equals 'create_manual_run', the server invokes handleCreateManualRun with the provided args.
if (name === "create_manual_run") { return await handleCreateManualRun( args as Parameters<typeof handleCreateManualRun>[0] ); } - src/index.ts:59-60 (registration)Imports createManualRunTool and handleCreateManualRun into the main server file from the manual-runs module.
createManualRunTool, handleCreateManualRun, - src/lib/endpoints.ts:418-421 (helper)Endpoint builder: creates the URL '/api/mcp/manual-runs/{projectId}' for the POST request when creating a manual run.
createManualRun: (projectId: string): string => { const baseUrl = getBaseUrl(); return `${baseUrl}/api/mcp/manual-runs/${projectId}`; },