Skip to main content
Glama

list-test-cases

Retrieve test cases from a qTest module using module ID and optional filters for properties like Type, Status, or Priority.

Instructions

Test Design — fetch test cases from a qTest module with optional property filters (Type, Status, Priority, version, etc.). Requires moduleId (numeric).

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
projectIdYesNumeric project ID as string
moduleIdYesNumeric ID of the module
filtersNoFilter by fields (AND logic); omit to return all

Implementation Reference

  • The getTestCases function is the handler for the list-test-cases tool. It fetches test cases from qTest API with pagination, then optionally filters by top-level fields (e.g., version, name) or custom properties (e.g., Type, Status, Priority) using case-insensitive AND logic.
    export async function getTestCases(args: GetTestCasesArgs): Promise<QTestTestCase[]> {
      const { projectId, moduleId: resolvedModuleId, filters } = args
    
      const all: QTestTestCase[] = []
      let page = 1
    
      while (true) {
        const raw = await qtestFetch(
          config,
          projectId,
          `/test-cases?parentId=${resolvedModuleId}&parentType=module&page=${page}&size=100`,
          'GET'
        )
        const batch = extractArray<QTestTestCase>(raw)
        all.push(...batch)
        if (batch.length < 100) break
        page++
      }
    
      if (!filters || filters.length === 0) return all
    
      return all.filter((tc) =>
        filters.every((filter) => {
          const fieldNameLower = filter.field.toLowerCase()
          const filterValueLower = filter.value.toLowerCase()
    
          // Check top-level fields first (e.g. version, name, pid)
          const topLevelMatch = Object.entries(tc).find(
            ([k]) => k.toLowerCase() === fieldNameLower
          )
          if (topLevelMatch) {
            return String(topLevelMatch[1] ?? '').toLowerCase() === filterValueLower
          }
    
          // Fall back to properties array
          const prop = tc.properties?.find(
            (p: QTestProperty) => p.field_name.toLowerCase() === fieldNameLower
          )
          if (!prop) return false
    
          return prop.field_value_name.toLowerCase() === filterValueLower
        })
      )
    }
  • GetTestCasesArgs interface defines the input schema: projectId (string), moduleId (number), and an optional filters array with field/value pairs.
    export interface GetTestCasesArgs {
      projectId: string
      moduleId: number
      filters?: Array<{ field: string; value: string }>
    }
  • src/server.ts:19-42 (registration)
    Registration of the 'list-test-cases' tool using server.registerTool with Zod input schema and a handler that calls getTestCases and returns JSON text content.
    server.registerTool(
      'list-test-cases',
      {
        description:
          'Test Design — fetch test cases from a qTest module with optional property filters (Type, Status, Priority, version, etc.). Requires moduleId (numeric).',
        inputSchema: {
          projectId: z.string().describe('Numeric project ID as string'),
          moduleId: z.number().int().describe('Numeric ID of the module'),
          filters: z
            .array(
              z.object({
                field: z.string().describe('Field name — top-level (e.g. "version") or property (e.g. "Type", "Status")'),
                value: z.string().describe('Value to match (case-insensitive)'),
              })
            )
            .optional()
            .describe('Filter by fields (AND logic); omit to return all'),
        },
      },
      async ({ projectId, moduleId, filters }) => {
        const result = await getTestCases({ projectId, moduleId, filters })
        return { content: [{ type: 'text' as const, text: JSON.stringify(result, null, 2) }] }
      }
    )
  • qtestFetch helper used by getTestCases to make authenticated HTTP requests to the qTest API.
    export async function qtestFetch(
      config: QTestConfig,
      projectId: string,
      endpoint: string,
      method: 'GET' | 'POST' | 'DELETE',
      body?: unknown
    ): Promise<unknown> {
      const url = `${config.baseUrl}/api/v3/projects/${projectId}${endpoint}`
      const response = await fetch(url, {
        method,
        headers: {
          'Content-Type': 'application/json',
          'Authorization': `Bearer ${config.token}`,
        },
        body: body !== undefined ? JSON.stringify(body) : undefined,
      })
      if (!response.ok) {
        const text = await response.text()
        throw new Error(`HTTP ${response.status}: ${text}`)
      }
      if (response.status === 204 || response.headers.get('content-length') === '0') {
        return null
      }
      const text = await response.text()
      return text ? JSON.parse(text) : null
    }
  • extractArray helper used to parse the API response into an array of QTestTestCase objects.
    export function extractArray<T>(raw: unknown): T[] {
      if (Array.isArray(raw)) return raw as T[]
      if (raw && typeof raw === 'object') {
        for (const key of ['items', 'data', 'object'] as const) {
          const val = (raw as Record<string, unknown>)[key]
          if (Array.isArray(val)) return val as T[]
        }
      }
      return []
    }
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description bears the full burden of behavioral disclosure. It correctly indicates a read operation (fetch), but does not specify permissions, rate limits, pagination, or error behavior. The lack of a readOnly hint or similar annotation leaves room for ambiguity, though the action is inherently read-only.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence that immediately states the tool's purpose ('Test Design — fetch test cases'), followed by core constraints. Every word serves a purpose; there is no redundancy or fluff. It is optimally concise for an AI agent.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a list tool with three parameters and no output schema, the description covers the essential: what it fetches, required input (moduleId), and optional filtering with field examples. The schema covers the other required parameter (projectId). It does not mention return structure or pagination, but these are often implicit for list tools. The description is complete enough for typical usage.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has 100% coverage with descriptions for all three parameters. The description adds value by listing examples of filterable fields (Type, Status, Priority, version), which are not present in the schema's parameter descriptions. This helps the agent understand what values for 'field' are meaningful. The schema already explains the 'filters' array structure and AND logic.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('fetch test cases'), the source ('from a qTest module'), and the optional filtering capability. This distinguishes it from sibling tools like 'add-test-cases' (add) and 'list-modules' (different resource). The title 'Test Design' provides additional context. No ambiguity.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description mentions the required parameter 'moduleId' and optional filters, implying it should be used when retrieving test cases from a specific module. However, it does not explicitly state when not to use it (e.g., when needing to filter by user) or mention alternatives among siblings. The guidance is clear but not exhaustive.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

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/Usman-Ghani123/qtest-mcp-server'

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