Skip to main content
Glama
deepsuthar496

Remote Command MCP Server

execute_remote_command

Execute shell commands on remote host machines across different operating systems, automatically handling platform-specific differences between Windows and Unix-like systems.

Instructions

Execute a command on the host machine

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
commandYesCommand to execute
cwdNoWorking directory for command execution

Implementation Reference

  • Handler for CallToolRequestSchema that specifically handles 'execute_remote_command': validates args, sanitizes/normalizes command, executes it, and returns stdout/stderr or error.
    this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
      if (request.params.name !== 'execute_remote_command') {
        throw new McpError(
          ErrorCode.MethodNotFound,
          `Unknown tool: ${request.params.name}`
        );
      }
    
      if (!isValidExecArgs(request.params.arguments)) {
        throw new McpError(
          ErrorCode.InvalidParams,
          'Invalid command execution arguments'
        );
      }
    
      try {
        // Sanitize and normalize the command
        const sanitizedCmd = sanitizeCommand(request.params.arguments.command);
        const normalizedCmd = normalizeCommand(sanitizedCmd);
    
        const { stdout, stderr } = await this.executeCommand(
          normalizedCmd,
          request.params.arguments.cwd
        );
    
        // Combine stdout and stderr in the response
        const output = [];
        
        if (stdout.trim()) {
          output.push(stdout.trim());
        }
        
        if (stderr.trim()) {
          output.push('STDERR:', stderr.trim());
        }
    
        return {
          content: [
            {
              type: 'text',
              text: output.join('\n') || 'Command completed successfully (no output)',
            },
          ],
        };
      } catch (error: any) {
        // Enhanced error handling with more details
        const errorMessage = [
          'Command execution error:',
          `Command: ${request.params.arguments.command}`,
          `Error: ${error?.message || 'Unknown error'}`
        ];
    
        console.error('Command failed:', error);  // Debug log
    
        return {
          content: [
            {
              type: 'text',
              text: errorMessage.join('\n'),
            },
          ],
          isError: true,
        };
      }
    });
  • Input schema definition for the execute_remote_command tool, specifying command (required) and optional cwd.
    inputSchema: {
      type: 'object',
      properties: {
        command: {
          type: 'string',
          description: 'Command to execute',
        },
        cwd: {
          type: 'string',
          description: 'Working directory for command execution',
        },
      },
      required: ['command'],
    },
  • src/index.ts:148-169 (registration)
    Registration of the execute_remote_command tool in the ListTools response.
    this.server.setRequestHandler(ListToolsRequestSchema, async () => ({
      tools: [
        {
          name: 'execute_remote_command',
          description: 'Execute a command on the host machine',
          inputSchema: {
            type: 'object',
            properties: {
              command: {
                type: 'string',
                description: 'Command to execute',
              },
              cwd: {
                type: 'string',
                description: 'Working directory for command execution',
              },
            },
            required: ['command'],
          },
        },
      ],
    }));
  • Core helper method that executes the sanitized command using exec or spawn, handles pipes, timeouts, stdout/stderr capture, cross-platform.
    private executeCommand(command: string, cwd?: string): Promise<{ stdout: string; stderr: string }> {
      return new Promise((resolve, reject) => {
        let timeout: NodeJS.Timeout | null = null;
    
        // Set timeout
        timeout = setTimeout(() => {
          reject(new Error(`Command timed out after ${COMMAND_TIMEOUT/1000} seconds`));
        }, COMMAND_TIMEOUT);
    
        // Use exec for commands with pipes, spawn for simple commands
        if (command.includes('|')) {
          execPromise(command, {
            cwd,
            shell: isWindows ? 'cmd.exe' : '/bin/sh',
            timeout: COMMAND_TIMEOUT,
            windowsHide: true
          }).then(({ stdout, stderr }) => {
            if (timeout) clearTimeout(timeout);
            resolve({ stdout, stderr });
          }).catch((error) => {
            if (timeout) clearTimeout(timeout);
            reject(error);
          });
        } else {
          const shell = isWindows ? 'cmd.exe' : '/bin/sh';
          const args = isWindows ? ['/c', command] : ['-c', command];
          
          console.error(`Executing command: ${command} (${shell} ${args.join(' ')})`);  // Debug log
    
          const child = spawn(shell, args, {
            cwd,
            shell: true,
            windowsHide: true
          });
    
          let stdout = '';
          let stderr = '';
    
          child.stdout.on('data', (data) => {
            stdout += data.toString();
          });
    
          child.stderr.on('data', (data) => {
            stderr += data.toString();
          });
    
          child.on('error', (error) => {
            if (timeout) clearTimeout(timeout);
            reject(error);
          });
    
          child.on('close', (code) => {
            if (timeout) clearTimeout(timeout);
            if (code === 0 || stdout.length > 0) { // Consider command successful if there's output even with non-zero exit code
              resolve({ stdout, stderr });
            } else {
              reject(new Error(`Command failed with exit code ${code}${stderr ? ': ' + stderr : ''}`));
            }
          });
        }
      });
  • Helper to sanitize the command by removing null bytes, semicolons (unix), and || operators to prevent injection.
    const sanitizeCommand = (command: string): string => {
      // Remove any null bytes that could be used for command injection
      command = command.replace(/\0/g, '');
      
      // Only remove malicious command chaining while preserving pipes
      if (isWindows) {
        command = command.replace(/\|\|/g, '');  // Remove OR operator but keep pipes
      } else {
        command = command.replace(/;/g, '').replace(/\|\|/g, '');  // Remove semicolon and OR operator
      }
      
      return command;
    };
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/deepsuthar496/Remote-Command-MCP'

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