add_run
Create a test run by specifying a project and including specific test cases. Use the returned run ID to retrieve test IDs for result submission.
Instructions
Create a new test run in TestRail
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| project_id | Yes | The ID of the project. Use get_projects to find available projects | |
| name | No | The name of the test run | |
| description | No | The description of the test run | |
| case_ids | Yes | Array of case IDs to include in the run. After creating the run, use get_tests with the returned run_id to retrieve test IDs for result submission |
Implementation Reference
- src/tools/add_run.ts:6-23 (handler)Tool definition and handler for add_run. Fetches case data to determine suite_id, constructs params with include_all=false, calls client.addRun, and parses result through RunSchema.
const parameters = { project_id: z.number().describe("The ID of the project. Use get_projects to find available projects"), name: z.string().optional().describe("The name of the test run"), description: z.string().optional().describe("The description of the test run"), case_ids: z.array(z.number()).min(1).describe("Array of case IDs to include in the run. After creating the run, use get_tests with the returned run_id to retrieve test IDs for result submission") } export const addRunTool: ToolDefinition<typeof parameters, TestRailClient> = { name: "add_run", description: "Create a new test run in TestRail", parameters, handler: async ({ project_id, ...fields }, client: TestRailClient) => { const caseData = await client.getCase(fields.case_ids[0]); const params = { suite_id: caseData.suite_id, include_all: false, ...fields }; const run = await client.addRun(project_id, params); return RunSchema.parse(run); }, - src/tools/add_run.ts:6-11 (schema)Input schema for add_run: project_id (required), name, description (optional), case_ids (required array of numbers)
const parameters = { project_id: z.number().describe("The ID of the project. Use get_projects to find available projects"), name: z.string().optional().describe("The name of the test run"), description: z.string().optional().describe("The description of the test run"), case_ids: z.array(z.number()).min(1).describe("Array of case IDs to include in the run. After creating the run, use get_tests with the returned run_id to retrieve test IDs for result submission") } - src/types/testrail.ts:100-113 (schema)RunSchema - output validation schema defining the shape of a TestRail Run object
export const RunSchema = z.object({ id: z.number(), name: z.string(), description: z.string().nullable(), suite_id: z.number().nullable(), project_id: z.number(), is_completed: z.boolean(), passed_count: z.number(), blocked_count: z.number(), untested_count: z.number(), retest_count: z.number(), failed_count: z.number(), url: z.string(), }); - src/index.ts:16-68 (registration)Import of addRunTool in main index.ts
import { addRunTool } from "./tools/add_run.js"; import { getStatusesTool } from "./tools/get_statuses.js"; import { getPrioritiesTool } from "./tools/get_priorities.js"; import { getTestsTool } from "./tools/get_tests.js"; import { addResultsTool } from "./tools/add_results.js"; import { addAttachmentToRunTool } from "./tools/add_attachment_to_run.js"; import { addResultsForCasesTool } from "./tools/add_results_for_cases.js"; import { getLabelsTool } from "./tools/get_labels.js"; import { getSharedStepsTool } from "./tools/shared_steps/get_shared_steps.js"; import { getSharedStepTool } from "./tools/shared_steps/get_shared_step.js"; import { getSharedStepHistoryTool } from "./tools/shared_steps/get_shared_step_history.js"; import { addSharedStepTool } from "./tools/shared_steps/add_shared_step.js"; import { updateSharedStepTool } from "./tools/shared_steps/update_shared_step.js"; import { deleteSharedStepTool } from "./tools/shared_steps/delete_shared_step.js"; import { removeNullish } from "./utils/sanitizer.js"; import z from "zod"; const EnvSchema = z.object({ TESTRAIL_INSTANCE_URL: z.url('Must be a valid TestRail URL'), TESTRAIL_USERNAME: z.email('Must be a valid email address'), TESTRAIL_API_KEY: z.string().min(1, 'API key is required'), TESTRAIL_ENABLE_SHARED_STEPS: z.string().optional().transform(val => val === 'true') }); const parseResult = EnvSchema.safeParse(process.env); if (!parseResult.success) { console.error( "Invalid TestRail environment configuration:", JSON.stringify(z.treeifyError(parseResult.error), null, 2)); process.exit(1); } const { TESTRAIL_INSTANCE_URL, TESTRAIL_USERNAME, TESTRAIL_API_KEY, TESTRAIL_ENABLE_SHARED_STEPS } = parseResult.data; const server = new McpServer({ name: "TestRail MCP Server", version: "1.9.0", }); const client = new TestRailClient(TESTRAIL_INSTANCE_URL, TESTRAIL_USERNAME, TESTRAIL_API_KEY); const tools = [ getProjectsTool, getCaseTool, getCasesTool, getCaseFieldsTool, getTemplatesTool, getSectionsTool, updateCaseTool, updateCasesTool, addCaseTool, addRunTool, - src/index.ts:68-68 (registration)Registration of addRunTool in the tools array, which gets registered via server.registerTool in the loop at line 87
addRunTool, - src/client/testrail.ts:150-152 (helper)TestRailClient.addRun - calls the TestRail API to create a new run
async addRun(projectId: number, fields: Record<string, any>): Promise<Run> { return this.post<Run>(`${API_BASE_V2}/add_run/${projectId}`, fields); }