list_releases
Browse releases for a project. Filter by name, type, completion status, or parent release to find specific milestones.
Instructions
Browse releases (a.k.a. milestones) for a project. Use search to match by name; type filters by free-text release type; isCompleted filters by completion state; parentReleaseId returns the direct children of a release (releases nest up to 3 levels deep). Default page size 25 (max 200).
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| projectId | Yes | Project ID (required). | |
| search | No | Match by release name. | |
| type | No | Release type. Either canonical ('iteration', 'major') or display ('Iteration', 'Major') form — server normalizes to lowercase so UI badge color matches. | |
| isCompleted | No | ||
| parentReleaseId | No | Direct children of this release. | |
| status | No | Release status (project-specific). | |
| sortBy | No | ||
| sortOrder | No | ||
| page | No | ||
| limit | No | Default 25 (max 200). |
Implementation Reference
- The main handler function that executes the list_releases tool logic. It calls the API endpoint and returns the response as tool content.
export async function handleListReleases(args?: ListReleasesArgs) { 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"); try { const { parentReleaseId, ...rest } = args; const url = endpoints.listReleases({ ...rest, ...(parentReleaseId ? { parentMilestone: parentReleaseId } : {}), }); const response = await apiRequestJson<unknown>(url, { headers: { Authorization: `Bearer ${token}` }, }); 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 list releases: ${msg}`); } } - The ListReleasesArgs interface and inputSchema property of the tool definition, defining the input parameters (projectId required, optional search, type, isCompleted, parentReleaseId, status, sortBy, sortOrder, page, limit).
interface ListReleasesArgs { projectId: string; search?: string; type?: string; isCompleted?: boolean; parentReleaseId?: string; status?: string; sortBy?: "createdAt" | "startDate" | "endDate" | "name"; sortOrder?: "asc" | "desc"; page?: number; limit?: number; } export const listReleasesTool = { name: "list_releases", description: "Browse releases (a.k.a. milestones) for a project. Use search to match by name; type filters by free-text release type; isCompleted filters by completion state; parentReleaseId returns the direct children of a release (releases nest up to 3 levels deep). Default page size 25 (max 200).", inputSchema: { type: "object", properties: { projectId: { type: "string", description: "Project ID (required)." }, search: { type: "string", description: "Match by release name." }, type: { type: "string", description: "Release type. Either canonical ('iteration', 'major') or display ('Iteration', 'Major') form — server normalizes to lowercase so UI badge color matches.", }, isCompleted: { type: "boolean" }, parentReleaseId: { type: "string", description: "Direct children of this release.", }, status: { type: "string", description: "Release status (project-specific).", }, sortBy: { type: "string", enum: ["createdAt", "startDate", "endDate", "name"], }, sortOrder: { type: "string", enum: ["asc", "desc"] }, page: { type: "number" }, limit: { type: "number", description: "Default 25 (max 200)." }, }, required: ["projectId"], }, }; - src/index.ts:273-278 (registration)The routing logic in the tool call handler that dispatches 'list_releases' to handleListReleases.
// Releases if (name === "list_releases") { return await handleListReleases( args as Parameters<typeof handleListReleases>[0] ); } - src/index.ts:113-114 (registration)The tool is registered in the tools array passed to setRequestHandler(ListToolsRequestSchema), exposing it to MCP clients.
// Releases listReleasesTool, - src/lib/endpoints.ts:332-348 (helper)The endpoint URL builder that constructs the GET /api/mcp/releases/:projectId request with query parameters.
listReleases: (params: { projectId: string; search?: string; type?: string; isCompleted?: boolean; parentMilestone?: string; status?: string; sortBy?: string; sortOrder?: string; page?: number; limit?: number; }): string => { const baseUrl = getBaseUrl(); const { projectId, ...queryParams } = params; const queryString = buildQueryString(queryParams); return `${baseUrl}/api/mcp/releases/${projectId}${queryString}`; },