Skip to main content
Glama

create_list_from_shell

Generate lists by executing shell commands and parsing their output, enabling batch processing of files or data from command-line operations.

Instructions

Creates a list by running a shell command and parsing its newline-delimited output.

WHEN TO USE:

  • When you need to create a list from command output (e.g., find, ls, grep, git ls-files)

  • When the list of items to process is determined by a shell command

  • As an alternative to manually specifying items in create_list

EXAMPLES:

  • "find src -name '*.ts'" to get all TypeScript files

  • "git ls-files '*.tsx'" to get all tracked TSX files

  • "ls *.json" to get all JSON files in current directory

  • "grep -l 'TODO' src/**/*.ts" to get files containing TODO

WORKFLOW:

  1. Call create_list_from_shell with your command

  2. The command's stdout is split by newlines to create list items

  3. Empty lines are filtered out

  4. Use the returned list_id with run_shell_across_list or run_agent_across_list

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
commandYesShell command to run. Its stdout will be split by newlines to create list items. Example: 'find src -name "*.ts"' or 'git ls-files'

Implementation Reference

  • The handler function for the 'create_list_from_shell' tool. It spawns a shell process with the provided command, captures stdout and stderr, parses non-empty lines from stdout into an array of items, generates a unique list ID using generateListId(), stores the list in the global 'lists' Map, and returns a success message containing the list ID. Handles errors if the command fails or produces no output.
    async ({ command }) => { return new Promise((resolve) => { const child = spawn("sh", ["-c", command], { stdio: ["ignore", "pipe", "pipe"], }); // Track the child process for cleanup on shutdown activeProcesses.add(child); let stdout = ""; let stderr = ""; child.stdout.on("data", (data: Buffer) => { stdout += data.toString(); }); child.stderr.on("data", (data: Buffer) => { stderr += data.toString(); }); child.on("close", (code) => { activeProcesses.delete(child); if (code !== 0 && stderr) { resolve({ content: [ { type: "text", text: `Error: Command exited with code ${code}.\n\nstderr:\n${stderr}`, }, ], isError: true, }); return; } // Split by newlines and filter out empty lines const items = stdout .split("\n") .map((line) => line.trim()) .filter((line) => line.length > 0); if (items.length === 0) { resolve({ content: [ { type: "text", text: `Warning: Command produced no output. No list was created.${stderr ? `\n\nstderr:\n${stderr}` : ""}`, }, ], }); return; } const id = generateListId(); lists.set(id, items); resolve({ content: [ { type: "text", text: `Successfully created a list with ${items.length} items from command output. The list ID is "${id}". You can now use this ID with run_shell_across_list or run_agent_across_list to process each item in parallel.${stderr ? `\n\nNote: Command produced stderr output:\n${stderr}` : ""}`, }, ], }); }); child.on("error", (err) => { activeProcesses.delete(child); resolve({ content: [ { type: "text", text: `Error: Failed to execute command: ${err.message}`, }, ], isError: true, }); }); }); },
  • The Zod input schema for the tool, defining a single 'command' parameter as a string with description providing usage examples.
    inputSchema: { command: z .string() .describe( "Shell command to run. Its stdout will be split by newlines to create list items. Example: 'find src -name \"*.ts\"' or 'git ls-files'", ), },
  • src/index.ts:199-308 (registration)
    The server.registerTool call that registers the 'create_list_from_shell' tool with its description, input schema, and handler function.
    server.registerTool( "create_list_from_shell", { description: `Creates a list by running a shell command and parsing its newline-delimited output. WHEN TO USE: - When you need to create a list from command output (e.g., find, ls, grep, git ls-files) - When the list of items to process is determined by a shell command - As an alternative to manually specifying items in create_list EXAMPLES: - "find src -name '*.ts'" to get all TypeScript files - "git ls-files '*.tsx'" to get all tracked TSX files - "ls *.json" to get all JSON files in current directory - "grep -l 'TODO' src/**/*.ts" to get files containing TODO WORKFLOW: 1. Call create_list_from_shell with your command 2. The command's stdout is split by newlines to create list items 3. Empty lines are filtered out 4. Use the returned list_id with run_shell_across_list or run_agent_across_list`, inputSchema: { command: z .string() .describe( "Shell command to run. Its stdout will be split by newlines to create list items. Example: 'find src -name \"*.ts\"' or 'git ls-files'", ), }, }, async ({ command }) => { return new Promise((resolve) => { const child = spawn("sh", ["-c", command], { stdio: ["ignore", "pipe", "pipe"], }); // Track the child process for cleanup on shutdown activeProcesses.add(child); let stdout = ""; let stderr = ""; child.stdout.on("data", (data: Buffer) => { stdout += data.toString(); }); child.stderr.on("data", (data: Buffer) => { stderr += data.toString(); }); child.on("close", (code) => { activeProcesses.delete(child); if (code !== 0 && stderr) { resolve({ content: [ { type: "text", text: `Error: Command exited with code ${code}.\n\nstderr:\n${stderr}`, }, ], isError: true, }); return; } // Split by newlines and filter out empty lines const items = stdout .split("\n") .map((line) => line.trim()) .filter((line) => line.length > 0); if (items.length === 0) { resolve({ content: [ { type: "text", text: `Warning: Command produced no output. No list was created.${stderr ? `\n\nstderr:\n${stderr}` : ""}`, }, ], }); return; } const id = generateListId(); lists.set(id, items); resolve({ content: [ { type: "text", text: `Successfully created a list with ${items.length} items from command output. The list ID is "${id}". You can now use this ID with run_shell_across_list or run_agent_across_list to process each item in parallel.${stderr ? `\n\nNote: Command produced stderr output:\n${stderr}` : ""}`, }, ], }); }); child.on("error", (err) => { activeProcesses.delete(child); resolve({ content: [ { type: "text", text: `Error: Failed to execute command: ${err.message}`, }, ], isError: true, }); }); }); }, );
  • Helper function used by the handler to generate a unique list ID using EFF diceware passphrases, ensuring no collisions in the 'lists' Map.
    function generateListId(): string { const words = generatePassphrase(3); let id = words.join("-"); // Ensure uniqueness by appending more words if needed while (lists.has(id)) { const extraWord = generatePassphrase(1)[0]; id = `${id}-${extraWord}`; } return id; }

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/jrandolf/par5-mcp'

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