Skip to main content
Glama
kaznak

Shell Command MCP Server

by kaznak

execute-bash-script-sync

Execute shell scripts synchronously in bash, waiting for completion before proceeding. Use when script output is required for subsequent operations.

Instructions

This tool executes shell scripts synchronously in bash. Executing each command creates a new bash process. Synchronous execution requires to wait the scripts completed. Asynchronous execution makes it possible to execute multiple scripts in parallel. You can reduce waiting time by planning in advance which shell scripts need to be executed and executing them in parallel. Avoid using this execute-bash-script-sync tool unless you really need to, and use the execute-bash-script-async tool whenever possible.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
commandYesThe bash script to execute
optionsYes

Implementation Reference

  • Core handler logic: asynchronously spawns a bash process via child_process.spawn, pipes command to stdin, collects stdout/stderr, handles timeout and process exit/error, returns CommandResult with stdout, stderr, exitCode.
    export async function executeCommand(
      command: string,
      options: CommandOptions = {},
    ): Promise<CommandResult> {
      return new Promise((resolve, reject) => {
        // 環境変数を設定
        const env = {
          ...process.env,
          ...options.env,
        };
    
        // bashプロセスを起動
        const bash = spawn(shellProgram, [], {
          cwd: options.cwd,
          env,
          stdio: ['pipe', 'pipe', 'pipe'],
        });
    
        let stdout = '';
        let stderr = '';
        let timeoutId: NodeJS.Timeout | null = null;
    
        // 標準出力の収集
        bash.stdout.on('data', (data) => {
          stdout += data.toString();
        });
    
        // 標準エラー出力の収集
        bash.stderr.on('data', (data) => {
          stderr += data.toString();
        });
    
        // タイムアウト処理
        if (options.timeout) {
          timeoutId = setTimeout(() => {
            bash.kill();
            reject(new Error(`Command timed out after ${options.timeout}ms`));
          }, options.timeout);
        }
    
        // プロセス終了時の処理
        bash.on('close', (code) => {
          if (timeoutId) clearTimeout(timeoutId);
    
          console.error('bash process exited with code', code);
          resolve({
            stdout,
            stderr,
            exitCode: code !== null ? code : 1,
          });
        });
    
        bash.on('error', (error) => {
          if (timeoutId) clearTimeout(timeoutId);
    
          console.error('Failed to start bash process:', error);
          reject(error);
        });
    
        // コマンドを標準入力に書き込み、EOF を送信
        bash.stdin.write(command + '\n');
        bash.stdin.end();
      });
    }
  • Input schema using Zod: command (string), options object with cwd (opt string), env (opt record), timeout (opt positive int).
    export const toolOptionsSchema = {
      command: z.string().describe('The bash script to execute'),
      options: z.object({
        cwd: z.string().optional().describe(`The working directory to execute the script.
    use this option argument to avoid cd command in the first line of the script.
    \`~\` and environment variable is not supported. use absolute path instead.
    `),
        env: z.record(z.string(), z.string()).optional()
          .describe(`The environment variables for the script.
    Set environment variables using this option instead of using export command in the script.
    `),
        timeout: z.number().int().positive().optional().describe(`The timeout in milliseconds.
    Set enough long timeout even if you don't need to set timeout to avoid unexpected blocking.
    `),
      }),
    };
  • Registers the 'execute-bash-script-sync' tool on the MCP server with server.tool(), providing toolName, description, schema, and inline handler that calls executeCommand and returns stdout/stderr/exitCode as text contents.
    // Execute a shell command
    export function setTool(server: McpServer) {
      server.tool(toolName, toolDescription, toolOptionsSchema, async ({ command, options }) => {
        const { stdout, stderr, exitCode } = await executeCommand(command, options);
        return {
          content: [
            {
              type: 'text',
              text: `stdout: ${stdout}`,
              resource: undefined,
            },
            {
              type: 'text',
              text: `stderr: ${stderr}`,
              resource: undefined,
            },
            {
              type: 'text',
              text: `exitCode: ${exitCode}`,
              resource: undefined,
            },
          ],
        };
      });
    }
  • src/index.ts:13-14 (registration)
    Calls setTool from execute-bash-script-sync to register the tool on the main MCP server instance.
    setSyncTool(server);
    setAsyncTool(server);
  • Tool name constant and description string used in registration.
    export const toolName = 'execute-bash-script-sync';
    
    export const toolDescription = `This tool executes shell scripts synchronously in bash.
    Executing each command creates a new bash process.
    Synchronous execution requires to wait the scripts completed.
    Asynchronous execution makes it possible to execute multiple scripts in parallel.
    You can reduce waiting time by planning in advance which shell scripts need to be executed and executing them in parallel.
    Avoid using this execute-bash-script-sync tool unless you really need to, and use the execute-bash-script-async tool whenever possible.
    `;
Behavior3/5

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

No annotations are provided, so the description carries full burden. It discloses key behavioral traits: 'Executing each command creates a new bash process' and 'Synchronous execution requires to wait the scripts completed.' However, it lacks details about error handling, output format, security implications, or system resource usage. For a potentially dangerous tool like bash script execution with no annotations, this is a moderate disclosure level.

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

Conciseness3/5

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

The description is 6 sentences with some redundancy ('synchronous execution' mentioned twice) and could be more front-loaded. The first sentence states the purpose clearly, but subsequent sentences mix behavioral details with usage guidelines in a somewhat disorganized way. It's not excessively verbose but could be more efficiently structured.

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

Completeness3/5

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

Given this is a potentially dangerous tool (bash script execution) with no annotations and no output schema, the description provides moderate context. It covers the synchronous nature and sibling comparison well, but lacks critical details like what happens on script failure, what output is returned, security warnings, or performance implications. For a tool with this complexity and risk profile, the description should do more.

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

Parameters3/5

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

Schema description coverage is 50% (2 parameters total, with 'command' well-described but 'options' object lacking overall description). The description adds no parameter semantics beyond what's in the schema - it doesn't explain what 'command' should contain or how 'options' affect execution. With moderate schema coverage, the description doesn't compensate enough, resulting in a baseline 3 score.

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 tool 'executes shell scripts synchronously in bash' with specific verb+resource. It distinguishes from the sibling tool by mentioning 'synchronous execution requires to wait the scripts completed' and contrasting with 'asynchronous execution makes it possible to execute multiple scripts in parallel.' However, it doesn't explicitly name the sibling tool in the purpose statement, keeping it at 4 rather than 5.

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

Usage Guidelines5/5

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

The description provides explicit guidance on when to use this tool vs alternatives: 'Avoid using this execute-bash-script-sync tool unless you really need to, and use the execute-bash-script-async tool whenever possible.' It also explains the trade-off: synchronous execution requires waiting, while asynchronous allows parallel execution to reduce waiting time. This is comprehensive guidance with clear alternatives.

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/kaznak/shell-command-mcp'

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