Skip to main content
Glama
Faucet94

Super Windows CLI MCP Server

by Faucet94

execute_command

Run shell commands in Windows using PowerShell, CMD, or Git Bash. Specify the shell, command, and working directory for precise system control and automation.

Instructions

Execute a command in the specified shell (powershell, cmd, or gitbash)

Example usage (PowerShell):

{
  "shell": "powershell",
  "command": "Get-Process | Select-Object -First 5",
  "workingDir": "C:\Users\username"
}

Example usage (CMD):

{
  "shell": "cmd",
  "command": "dir /b",
  "workingDir": "C:\Projects"
}

Example usage (Git Bash):

{
  "shell": "gitbash",
  "command": "ls -la",
  "workingDir": "/c/Users/username"
}

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
commandYesCommand to execute
shellYesShell to use for command execution
workingDirNoWorking directory for command execution (optional)

Implementation Reference

  • Core handler logic for the 'execute_command' tool. Validates and parses input using Zod, checks security constraints, spawns the shell process using child_process.spawn, captures stdout/stderr, handles process events, timeouts, errors, logs to command history, and returns structured response with output, isError flag, and metadata.
    case "execute_command": {
      const args = z.object({
        shell: z.enum(Object.keys(this.config.shells).filter(shell => 
          this.config.shells[shell as keyof typeof this.config.shells].enabled
        ) as [string, ...string[]]),
        command: z.string(),
        workingDir: z.string().optional()
      }).parse(request.params.arguments);
    
      // Validate command
      this.validateCommand(args.shell as keyof ServerConfig['shells'], args.command);
    
      // Validate working directory if provided
      let workingDir = args.workingDir ? 
        path.resolve(args.workingDir) : 
        process.cwd();
    
      const shellKey = args.shell as keyof typeof this.config.shells;
      const shellConfig = this.config.shells[shellKey];
      
      if (this.config.security.restrictWorkingDirectory) {
        const isAllowedPath = Array.from(this.allowedPaths).some(
          allowedPath => workingDir.startsWith(allowedPath)
        );
    
        if (!isAllowedPath) {
          throw new McpError(
            ErrorCode.InvalidRequest,
            `Working directory (${workingDir}) outside allowed paths. Consult the server admin for configuration changes (config.json - restrictWorkingDirectory, allowedPaths).`
          );
        }
      }
    
      // Execute command
      return new Promise((resolve, reject) => {
        let shellProcess: ReturnType<typeof spawn>;
        
        try {
          shellProcess = spawn(
            shellConfig.command,
            [...shellConfig.args, args.command],
            { cwd: workingDir, stdio: ['pipe', 'pipe', 'pipe'] }
          );
        } catch (err) {
          throw new McpError(
            ErrorCode.InternalError,
            `Failed to start shell process: ${err instanceof Error ? err.message : String(err)}. Consult the server admin for configuration changes (config.json - shells).`
          );
        }
    
        if (!shellProcess.stdout || !shellProcess.stderr) {
          throw new McpError(
            ErrorCode.InternalError,
            'Failed to initialize shell process streams'
          );
        }
    
        let output = '';
        let error = '';
    
        shellProcess.stdout.on('data', (data) => {
          output += data.toString();
        });
    
        shellProcess.stderr.on('data', (data) => {
          error += data.toString();
        });
    
        shellProcess.on('close', (code) => {
          // Prepare detailed result message
          let resultMessage = '';
          
          if (code === 0) {
            resultMessage = output || 'Command completed successfully (no output)';
          } else {
            resultMessage = `Command failed with exit code ${code}\n`;
            if (error) {
              resultMessage += `Error output:\n${error}\n`;
            }
            if (output) {
              resultMessage += `Standard output:\n${output}`;
            }
            if (!error && !output) {
              resultMessage += 'No error message or output was provided';
            }
          }
    
          // Store in history if enabled
          if (this.config.security.logCommands) {
            this.commandHistory.push({
              command: args.command,
              output: resultMessage,
              timestamp: new Date().toISOString(),
              exitCode: code ?? -1
            });
    
            // Trim history if needed
            if (this.commandHistory.length > this.config.security.maxHistorySize) {
              this.commandHistory = this.commandHistory.slice(-this.config.security.maxHistorySize);
            }
          }
    
          resolve({
            content: [{
              type: "text",
              text: resultMessage
            }],
            isError: code !== 0,
            metadata: {
              exitCode: code ?? -1,
              shell: args.shell,
              workingDirectory: workingDir
            }
          });
        });
    
        // Handle process errors (e.g., shell crashes)
        shellProcess.on('error', (err) => {
          const errorMessage = `Shell process error: ${err.message}`;
          if (this.config.security.logCommands) {
            this.commandHistory.push({
              command: args.command,
              output: errorMessage,
              timestamp: new Date().toISOString(),
              exitCode: -1
            });
          }
          reject(new McpError(
            ErrorCode.InternalError,
            errorMessage
          ));
        });
    
        // Set configurable timeout to prevent hanging
        const timeout = setTimeout(() => {
          shellProcess.kill();
          const timeoutMessage = `Command execution timed out after ${this.config.security.commandTimeout} seconds. Consult the server admin for configuration changes (config.json - commandTimeout).`;
          if (this.config.security.logCommands) {
            this.commandHistory.push({
              command: args.command,
              output: timeoutMessage,
              timestamp: new Date().toISOString(),
              exitCode: -1
            });
          }
          reject(new McpError(
            ErrorCode.InternalError,
            timeoutMessage
          ));
        }, this.config.security.commandTimeout * 1000);
    
        shellProcess.on('close', () => clearTimeout(timeout));
      });
    }
  • src/index.ts:124-175 (registration)
    Tool registration in the ListTools response, defining name, detailed usage description with shell examples, and inputSchema JSON Schema for validation (shell enum from enabled config shells, required command, optional workingDir).
            {
              name: "execute_command",
              description: `Execute a command in the specified shell (powershell, cmd, or gitbash)
    
    Example usage (PowerShell):
    \`\`\`json
    {
      "shell": "powershell",
      "command": "Get-Process | Select-Object -First 5",
      "workingDir": "C:\\Users\\username"
    }
    \`\`\`
    
    Example usage (CMD):
    \`\`\`json
    {
      "shell": "cmd",
      "command": "dir /b",
      "workingDir": "C:\\Projects"
    }
    \`\`\`
    
    Example usage (Git Bash):
    \`\`\`json
    {
      "shell": "gitbash",
      "command": "ls -la",
      "workingDir": "/c/Users/username"
    }
    \`\`\``,
              inputSchema: {
                type: "object",
                properties: {
                  shell: {
                    type: "string",
                    enum: Object.keys(this.config.shells).filter(shell => 
                      this.config.shells[shell as keyof typeof this.config.shells].enabled
                    ),
                    description: "Shell to use for command execution"
                  },
                  command: {
                    type: "string",
                    description: "Command to execute"
                  },
                  workingDir: {
                    type: "string",
                    description: "Working directory for command execution (optional)"
                  }
                },
                required: ["shell", "command"]
              }
            },
  • Runtime input validation schema using Zod, mirroring the inputSchema from registration, parsing arguments from CallToolRequest.
    const args = z.object({
      shell: z.enum(Object.keys(this.config.shells).filter(shell => 
        this.config.shells[shell as keyof typeof this.config.shells].enabled
      ) as [string, ...string[]]),
      command: z.string(),
      workingDir: z.string().optional()
    }).parse(request.params.arguments);
Behavior2/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 describes what the tool does (executes commands) but lacks critical behavioral details: security implications, permission requirements, whether commands run synchronously/asynchronously, timeout behavior, error handling, or output format. For a command execution tool with zero annotation coverage, this is a significant gap in behavioral disclosure.

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 front-loaded with the core purpose, but the extensive examples (three full JSON blocks) dominate the text. While examples are helpful, they could be more concise or structured as a single example with variations. The description is appropriately sized but could be more efficiently organized.

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?

For a command execution tool with no annotations and no output schema, the description is incomplete. It doesn't explain what the tool returns (stdout, stderr, exit codes), security considerations, or error conditions. Given the complexity and potential risks of command execution, more contextual information is needed for safe and 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?

Schema description coverage is 100%, providing good baseline documentation. The description adds value through concrete examples showing how parameters work together in different shells, illustrating shell-specific command syntax and working directory formats. This enhances understanding beyond the schema's technical definitions.

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's purpose: 'Execute a command in the specified shell (powershell, cmd, or gitbash)'. It provides a specific verb ('execute') and resource ('command'), but doesn't explicitly differentiate from sibling tools like 'ssh_execute' which likely executes commands over SSH. The purpose is clear but lacks sibling differentiation.

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 like 'ssh_execute' or 'get_command_history'. It shows example usage but doesn't specify contexts, prerequisites, or exclusions. Without any usage guidelines, the agent must infer when this tool is appropriate.

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

Related 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/Faucet94/super-win-cli-mcp-server'

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