Skip to main content
Glama

list_environments

Display all active QIT test environments for WordPress/WooCommerce plugin testing with compact output format.

Instructions

List all running QIT test environments with compact output.

⚠️ QIT CLI not detected. QIT CLI not found. Please install it using one of these methods:

  1. Via Composer (recommended): composer require woocommerce/qit-cli --dev

  2. Set QIT_CLI_PATH environment variable: export QIT_CLI_PATH=/path/to/qit

  3. Ensure 'qit' is available in your system PATH

For more information, visit: https://github.com/woocommerce/qit-cli

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

Implementation Reference

  • The handler function executes the QIT CLI 'env:list' command, parses its verbose output by splitting into blocks separated by dashed lines, extracts key-value pairs using regex for each environment's details (env_id, created_at, php_version, woocommerce_version, site_url, status), filters out PHP deprecation warnings, and formats the results as a compact Markdown table.
    handler: async () => {
      const cmdArgs = ["env:list"];
      const result = await executeQitCommand(cmdArgs);
    
      // Combine stdout and stderr, filter PHP warnings
      const rawOutput = (result.stdout + "\n" + result.stderr)
        .split("\n")
        .filter(line => !line.includes("Deprecated:") && !line.includes("PHP Deprecated:"))
        .join("\n");
    
      if (!result.success && !rawOutput.includes("Environment")) {
        return {
          content: result.stderr || result.stdout || "Failed to list environments",
          isError: true,
        };
      }
    
      // Parse the verbose output into compact format
      // The output has blocks separated by dashed lines, each block has key-value pairs
      const environments: Array<{
        env_id: string;
        created_at: string;
        php_version: string;
        woo_version: string;
        site_url: string;
        status: string;
      }> = [];
    
      // Split by environment blocks (each starts with "Extra" or similar header)
      const blocks = rawOutput.split(/\s+-{20,}\s+/).filter(block => block.includes("Env_id"));
    
      for (const block of blocks) {
        const lines = block.split("\n");
        const env: Record<string, string> = {};
    
        for (const line of lines) {
          // Match key-value pairs like "Env_id                    qitenv01ed18d948bfe5cc"
          const match = line.match(/^\s*([A-Za-z_]+)\s{2,}(.+?)\s*$/);
          if (match) {
            env[match[1].toLowerCase()] = match[2].trim();
          }
        }
    
        if (env.env_id) {
          environments.push({
            env_id: env.env_id || "",
            created_at: env.created_at || "",
            php_version: env.php_version || "",
            woo_version: env.woocommerce_version || "",
            site_url: env.site_url || "",
            status: env.status || "",
          });
        }
      }
    
      if (environments.length === 0) {
        return {
          content: "No running environments found.",
          isError: false,
        };
      }
    
      // Format as compact table
      const header = "| Env ID | Created | PHP | WooCommerce | URL | Status |";
      const separator = "|--------|---------|-----|-------------|-----|--------|";
      const rows = environments.map(env =>
        `| ${env.env_id} | ${env.created_at} | ${env.php_version} | ${env.woo_version} | ${env.site_url} | ${env.status} |`
      );
    
      return {
        content: `Running environments (${environments.length}):\n${header}\n${separator}\n${rows.join("\n")}`,
        isError: false,
      };
    },
  • Input schema defining no required parameters for the list_environments tool.
    inputSchema: z.object({}),
  • Tool definition object for 'list_environments' including name, description, schema, and handler reference.
    list_environments: {
      name: "list_environments",
      description: "List all running QIT test environments with compact output.",
      inputSchema: z.object({}),
      handler: async () => {
        const cmdArgs = ["env:list"];
        const result = await executeQitCommand(cmdArgs);
    
        // Combine stdout and stderr, filter PHP warnings
        const rawOutput = (result.stdout + "\n" + result.stderr)
          .split("\n")
          .filter(line => !line.includes("Deprecated:") && !line.includes("PHP Deprecated:"))
          .join("\n");
    
        if (!result.success && !rawOutput.includes("Environment")) {
          return {
            content: result.stderr || result.stdout || "Failed to list environments",
            isError: true,
          };
        }
    
        // Parse the verbose output into compact format
        // The output has blocks separated by dashed lines, each block has key-value pairs
        const environments: Array<{
          env_id: string;
          created_at: string;
          php_version: string;
          woo_version: string;
          site_url: string;
          status: string;
        }> = [];
    
        // Split by environment blocks (each starts with "Extra" or similar header)
        const blocks = rawOutput.split(/\s+-{20,}\s+/).filter(block => block.includes("Env_id"));
    
        for (const block of blocks) {
          const lines = block.split("\n");
          const env: Record<string, string> = {};
    
          for (const line of lines) {
            // Match key-value pairs like "Env_id                    qitenv01ed18d948bfe5cc"
            const match = line.match(/^\s*([A-Za-z_]+)\s{2,}(.+?)\s*$/);
            if (match) {
              env[match[1].toLowerCase()] = match[2].trim();
            }
          }
    
          if (env.env_id) {
            environments.push({
              env_id: env.env_id || "",
              created_at: env.created_at || "",
              php_version: env.php_version || "",
              woo_version: env.woocommerce_version || "",
              site_url: env.site_url || "",
              status: env.status || "",
            });
          }
        }
    
        if (environments.length === 0) {
          return {
            content: "No running environments found.",
            isError: false,
          };
        }
    
        // Format as compact table
        const header = "| Env ID | Created | PHP | WooCommerce | URL | Status |";
        const separator = "|--------|---------|-----|-------------|-----|--------|";
        const rows = environments.map(env =>
          `| ${env.env_id} | ${env.created_at} | ${env.php_version} | ${env.woo_version} | ${env.site_url} | ${env.status} |`
        );
    
        return {
          content: `Running environments (${environments.length}):\n${header}\n${separator}\n${rows.join("\n")}`,
          isError: false,
        };
      },
    },
  • Includes environmentTools (containing list_environments) in the central allTools registry by spreading the object.
    ...environmentTools,
  • src/server.ts:25-87 (registration)
    Registers all tools from allTools for MCP server: handles ListToolsRequest by providing tool metadata and CallToolRequest by looking up the tool by name, validating input with schema, and invoking the handler.
    server.setRequestHandler(ListToolsRequestSchema, async () => {
      // Check if QIT CLI is available
      const cliInfo = detectQitCli();
    
      const tools = Object.entries(allTools).map(([_, tool]) => ({
        name: tool.name,
        description: cliInfo
          ? tool.description
          : `${tool.description}\n\n⚠️ QIT CLI not detected. ${getQitCliNotFoundError()}`,
        inputSchema: zodToJsonSchema(tool.inputSchema),
      }));
    
      return { tools };
    });
    
    // Handle tool calls
    server.setRequestHandler(CallToolRequestSchema, async (request) => {
      const { name, arguments: args } = request.params;
    
      const tool = allTools[name as ToolName];
    
      if (!tool) {
        return {
          content: [
            {
              type: "text",
              text: `Unknown tool: ${name}`,
            },
          ],
          isError: true,
        };
      }
    
      try {
        // Validate input
        const validatedArgs = tool.inputSchema.parse(args);
    
        // Execute tool
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        const result = await (tool.handler as (args: any) => Promise<{ content: string; isError: boolean }>)(validatedArgs);
    
        return {
          content: [
            {
              type: "text",
              text: result.content,
            },
          ],
          isError: result.isError,
        };
      } catch (error) {
        const message = error instanceof Error ? error.message : String(error);
        return {
          content: [
            {
              type: "text",
              text: `Error: ${message}`,
            },
          ],
          isError: true,
        };
      }
    });
Behavior2/5

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

No annotations are provided, so the description carries the full burden. It discloses that the tool lists environments with 'compact output', which hints at the return format, but doesn't describe behavioral traits such as whether it's read-only, potential errors, or how it interacts with the system. The warning about QIT CLI installation adds some context but is more about prerequisites than tool behavior.

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

Conciseness2/5

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

The description is not appropriately sized or front-loaded. The first sentence states the purpose, but the majority of the text is a lengthy warning about QIT CLI installation that repeats information and includes installation instructions, which doesn't earn its place in a tool description. This reduces clarity and efficiency.

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

Completeness2/5

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

Given the complexity (a tool with no parameters but no output schema), the description is incomplete. It lacks details on what the output looks like (e.g., format of 'compact output'), error handling, or dependencies beyond the CLI warning. Without annotations or output schema, more context is needed for effective use.

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 0 parameters with 100% coverage, so no parameter documentation is needed. The description appropriately doesn't discuss parameters, which is efficient. A baseline of 4 is applied since it avoids redundancy and focuses on other aspects.

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

Purpose4/5

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

The description clearly states the verb 'List' and resource 'all running QIT test environments' with the qualifier 'with compact output', which specifies what the tool does. However, it doesn't explicitly differentiate from sibling tools like 'get_test_report' or 'list_tests', which might also list related resources, so it doesn't fully distinguish from siblings.

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

Usage Guidelines2/5

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

The description provides no guidance on when to use this tool versus alternatives. It mentions prerequisites (QIT CLI installation) but doesn't specify contexts or exclusions relative to sibling tools like 'list_tests' or 'get_test_report'. This lack of comparative usage advice limits its effectiveness.

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/woocommerce/qit-mcp'

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