Skip to main content
Glama
Derrbal
by Derrbal

get_suites

Retrieve all test suites for a specific TestRail project using the project ID to organize and access test case collections within your test management system.

Instructions

Get all test suites for a specific TestRail project by ID.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
project_idYesTestRail project ID

Implementation Reference

  • src/server.ts:277-317 (registration)
    Registers the MCP 'get_suites' tool with input schema (project_id) and handler that delegates to testrailService.getSuites(project_id), formats result as JSON text content, and handles errors.
    server.registerTool( 'get_suites', { title: 'Get TestRail Suites', description: 'Get all test suites for a specific TestRail project by ID.', inputSchema: { project_id: z.number().int().positive().describe('TestRail project ID'), }, }, async ({ project_id }) => { logger.debug(`Get suites tool called with project_id: ${project_id}`); try { const result = await getSuites(project_id); logger.debug(`Get suites tool completed successfully for project_id: ${project_id}. Found ${result.length} suites`); return { content: [ { type: 'text', text: JSON.stringify(result, null, 2), }, ], }; } catch (err) { logger.error({ err }, `Get suites tool failed for project_id: ${project_id}`); const e = err as { type?: string; status?: number; message?: string }; let message = 'Unexpected error'; if (e?.type === 'auth') message = 'Authentication failed: check TESTRAIL_USER/API_KEY'; else if (e?.type === 'not_found') message = `Project ${project_id} not found`; else if (e?.type === 'rate_limited') message = 'Rate limited by TestRail; try again later'; else if (e?.type === 'server') message = 'TestRail server error'; else if (e?.type === 'network') message = 'Network error contacting TestRail'; else if (e?.message) message = e.message; return { content: [ { type: 'text', text: message }, ], isError: true, }; } },
  • MCP tool handler function for get_suites: calls service layer, returns JSON suites or error message.
    async ({ project_id }) => { logger.debug(`Get suites tool called with project_id: ${project_id}`); try { const result = await getSuites(project_id); logger.debug(`Get suites tool completed successfully for project_id: ${project_id}. Found ${result.length} suites`); return { content: [ { type: 'text', text: JSON.stringify(result, null, 2), }, ], }; } catch (err) { logger.error({ err }, `Get suites tool failed for project_id: ${project_id}`); const e = err as { type?: string; status?: number; message?: string }; let message = 'Unexpected error'; if (e?.type === 'auth') message = 'Authentication failed: check TESTRAIL_USER/API_KEY'; else if (e?.type === 'not_found') message = `Project ${project_id} not found`; else if (e?.type === 'rate_limited') message = 'Rate limited by TestRail; try again later'; else if (e?.type === 'server') message = 'TestRail server error'; else if (e?.type === 'network') message = 'Network error contacting TestRail'; else if (e?.message) message = e.message; return { content: [ { type: 'text', text: message }, ], isError: true, }; }
  • Tool metadata and input schema validation using Zod for project_id parameter.
    { title: 'Get TestRail Suites', description: 'Get all test suites for a specific TestRail project by ID.', inputSchema: { project_id: z.number().int().positive().describe('TestRail project ID'), },
  • Service layer getSuites: fetches raw suites from client, normalizes custom fields into SuiteSummary[]
    export async function getSuites(projectId: number): Promise<SuiteSummary[]> { const suites: TestRailSuiteDto[] = await testRailClient.getSuites(projectId); return suites.map((suite) => { const { id, name, description, project_id, url, is_baseline, is_master, is_completed, completed_on, created_on, created_by, updated_on, updated_by, ...rest } = suite; const custom: Record<string, unknown> = {}; for (const [key, value] of Object.entries(rest)) { if (key.startsWith('custom_')) custom[key] = value; } return { id, name, description, project_id, url, is_baseline, is_master, is_completed, completed_on, created_on, created_by, updated_on, updated_by, custom: Object.keys(custom).length ? custom : undefined, }; }); }
  • HTTP client implementation: GET /get_suites/{projectId}, handles direct/paginated responses, error normalization.
    async getSuites(projectId: number): Promise<TestRailSuiteDto[]> { try { const res = await this.http.get(`/get_suites/${projectId}`); logger.info({ status: res.status, dataType: typeof res.data, dataIsArray: Array.isArray(res.data), projectId }, 'TestRail getSuites response info'); if (res.status >= 200 && res.status < 300) { // Handle both direct array and paginated response formats let suites: TestRailSuiteDto[]; if (Array.isArray(res.data)) { // Direct array format (most common) suites = res.data as TestRailSuiteDto[]; } else if (res.data && typeof res.data === 'object' && 'suites' in res.data) { // Paginated format (if TestRail supports it) const paginatedResponse = res.data as { suites: TestRailSuiteDto[] }; if (!Array.isArray(paginatedResponse.suites)) { throw Object.assign(new Error('API returned paginated response with non-array suites field'), { response: { status: 200 } // Make it look like a server error }); } suites = paginatedResponse.suites; logger.info({ returnedSuites: suites.length }, 'TestRail paginated suites response'); } else { logger.error({ status: res.status, responseData: res.data, dataType: typeof res.data }, 'TestRail getSuites returned unexpected response format'); throw Object.assign(new Error('API returned unexpected response format'), { response: { status: 200 } // Make it look like a server error }); } return suites; } throw Object.assign(new Error(`HTTP ${res.status}`), { response: res }); } catch (err) { const normalized = this.normalizeError(err); const safeDetails = this.getSafeErrorDetails(err); logger.error({ err: normalized, details: safeDetails, projectId }, 'TestRail getSuites failed'); throw normalized; }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Derrbal/testrail-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server