Skip to main content
Glama
TCSoftInc

TestCollab MCP Server

by TCSoftInc

move_suite

Relocate test suites within TestCollab by moving them to different parent suites or to the root level for better test organization.

Instructions

Move a test suite to a different parent suite, or to root level. Tip: Call get_project_context first to see the current suite tree.

Required: id (suite ID), parent (new parent ID, title, or null for root) Optional: project_id

Examples: Move under a parent: { "id": 10, "parent": "Authentication" } Move to root level: { "id": 10, "parent": null }

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
idYesSuite ID to move (required)
project_idNoProject ID (optional if TC_DEFAULT_PROJECT is set)
parentYesNew parent suite ID, title, or null to move to root level (required)

Implementation Reference

  • The handler function `handleMoveSuite` for the `move_suite` tool. It handles resolving the project, resolving the target parent suite (by ID or title), performing safety checks, calling the API, and clearing the cache.
    export async function handleMoveSuite(args: {
      id: number;
      project_id?: number;
      parent: number | string | null;
    }): Promise<{ content: Array<{ type: "text"; text: string }> }> {
      try {
        const projectId = resolveProjectId(args.project_id);
        if (!projectId) {
          return {
            content: [
              {
                type: "text" as const,
                text: JSON.stringify({
                  error: {
                    code: "MISSING_PROJECT_ID",
                    message:
                      "No project_id provided and no default project configured. Set TC_DEFAULT_PROJECT or pass project_id.",
                  },
                }),
              },
            ],
          };
        }
    
        // Resolve parent
        let parentId: number | null = null;
        if (args.parent !== null) {
          if (typeof args.parent === "number") {
            parentId = args.parent;
          } else {
            const resolved = resolveSuiteByTitle(args.parent, projectId);
            if (resolved === null) {
              return {
                content: [
                  {
                    type: "text" as const,
                    text: JSON.stringify({
                      error: {
                        code: "PARENT_SUITE_NOT_FOUND",
                        message: `Could not find parent suite with title "${args.parent}". Call get_project_context to see available suites.`,
                      },
                    }),
                  },
                ],
              };
            }
            parentId = resolved;
          }
        }
    
        // Prevent moving a suite under itself
        if (parentId === args.id) {
          return {
            content: [
              {
                type: "text" as const,
                text: JSON.stringify({
                  error: {
                    code: "CIRCULAR_REFERENCE",
                    message: "Cannot move a suite under itself.",
                  },
                }),
              },
            ],
          };
        }
    
        const client = getApiClient();
        const result = await client.updateSuite(args.id, {
          projectId,
          parentId,
        });
    
        // Invalidate project context cache
        clearProjectContextCache();
    
        return {
          content: [
            {
              type: "text" as const,
              text: JSON.stringify({
                success: true,
                suite: result,
                moved_to_parent: parentId,
              }),
            },
          ],
        };
      } catch (error) {
        return {
          content: [
            {
              type: "text" as const,
              text: JSON.stringify({
                error: {
                  code: "MOVE_SUITE_FAILED",
                  message:
                    error instanceof Error ? error.message : "Unknown error",
                },
              }),
            },
          ],
        };
      }
    }
  • Zod schema definition for `move_suite` arguments.
    export const moveSuiteSchema = z.object({
      id: z.number().describe("Suite ID to move (required)"),
      project_id: z
        .number()
        .optional()
        .describe("Project ID (optional if TC_DEFAULT_PROJECT is set)"),
      parent: z
        .union([z.number(), z.string(), z.null()])
        .describe(
          "New parent suite ID, title, or null to move to root level (required)"
        ),
    });
  • Tool definition object for `move_suite`.
    export const moveSuiteTool = {
      name: "move_suite",
      description: `Move a test suite to a different parent suite, or to root level.
    Tip: Call get_project_context first to see the current suite tree.
    
    Required: id (suite ID), parent (new parent ID, title, or null for root)
    Optional: project_id
    
    Examples:
      Move under a parent: { "id": 10, "parent": "Authentication" }
      Move to root level: { "id": 10, "parent": null }`,
    };
  • Helper function to resolve a suite ID by its title within the project context.
    function resolveSuiteByTitle(
      title: string,
      projectId: number
    ): number | null {
      const context = getCachedProjectContext(projectId);
      if (!context) return null;
    
      const search = (
        nodes: Array<{ id: number; title: string; children: unknown[] }>
      ): number | null => {
        for (const node of nodes) {
          if (node.title.toLowerCase() === title.toLowerCase()) {
            return node.id;
          }
          const childResult = search(
            node.children as Array<{ id: number; title: string; children: unknown[] }>
          );
          if (childResult !== null) return childResult;
        }
        return null;
      };
    
      return search(context.suites as Array<{ id: number; title: string; children: unknown[] }>);
    }
Behavior3/5

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

With no annotations provided, the description carries the full burden. It establishes the hierarchy change behavior but lacks disclosure of side effects (e.g., whether child suites move with parent), permission requirements, or error conditions (e.g., invalid parent ID). The workflow tip partially compensates.

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?

Excellent structure with clear visual separation: purpose statement, workflow tip, required/optional parameter summary, and formatted examples. Every sentence conveys distinct information with zero redundancy.

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?

Appropriately complete for a 3-parameter tool with no output schema. Covers the core move scenarios (parent vs root) and provides prerequisite context (get_project_context). Minor gap: doesn't clarify behavior regarding child suites or test cases contained within the moved suite.

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?

While the schema has 100% coverage, the description adds valuable semantic context through examples—specifically demonstrating that 'parent' accepts a title string ('Authentication') for lookup, not just numeric IDs, and clarifying the required vs optional parameters in prose.

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 opens with a specific verb ('Move') + resource ('test suite') + scope ('to a different parent suite, or to root level'), clearly distinguishing it from sibling tools like create_suite, delete_suite, or reorder_suites.

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?

Provides explicit workflow guidance ('Tip: Call get_project_context first') and concrete JSON examples for both moving under a parent and moving to root. Could improve by explicitly contrasting with reorder_suites to clarify when to use each.

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/TCSoftInc/testcollab-mcp-server'

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