Windows Command Line MCP Server

by alxspiker
Verified
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { z } from "zod"; import { execSync } from "child_process"; import { platform } from "os"; // Detect operating system const isWindows = platform() === 'win32'; // Create server instance const server = new McpServer({ name: "windows-command-line", version: "0.3.0", }); // Helper function to handle command execution based on platform function executeCommand(command: string, options: any = {}) { if (isWindows) { return execSync(command, options); } else { // Log warning for non-Windows environments console.error(`Warning: Running in a non-Windows environment (${platform()}). Windows commands may not work.`); // For testing purposes on non-Windows platforms try { // For Linux/MacOS, we'll strip cmd.exe and powershell.exe references let modifiedCmd = command; // Replace cmd.exe /c with empty string modifiedCmd = modifiedCmd.replace(/cmd\.exe\s+\/c\s+/i, ''); // Replace powershell.exe -Command with empty string or a compatible command modifiedCmd = modifiedCmd.replace(/powershell\.exe\s+-Command\s+("|')/i, ''); // Remove trailing quotes if we removed powershell -Command if (modifiedCmd !== command) { modifiedCmd = modifiedCmd.replace(/("|')$/, ''); } console.error(`Attempting to execute modified command: ${modifiedCmd}`); return execSync(modifiedCmd, options); } catch (error) { console.error(`Error executing modified command: ${error}`); return Buffer.from(`This tool requires a Windows environment. Current platform: ${platform()}`); } } } // Register the list_running_processes tool server.tool( "list_running_processes", "List all running processes on the system. Can be filtered by providing an optional filter string that will match against process names.", { filter: z.string().optional().describe("Optional filter string to match against process names"), }, async ({ filter }) => { try { let cmd; if (isWindows) { cmd = "powershell.exe -Command \"Get-Process"; if (filter) { // Add filter if provided cmd += ` | Where-Object { $_.ProcessName -like '*${filter}*' }`; } cmd += " | Select-Object Id, ProcessName, CPU, WorkingSet, Description | Format-Table -AutoSize | Out-String\""; } else { // Fallback for Unix systems cmd = "ps aux"; if (filter) { cmd += ` | grep -i ${filter}`; } } const stdout = executeCommand(cmd); return { content: [ { type: "text", text: stdout.toString(), }, ], }; } catch (error) { return { isError: true, content: [ { type: "text", text: `Error listing processes: ${error}`, }, ], }; } } ); // Register the get_system_info tool server.tool( "get_system_info", "Retrieve system information including OS, hardware, and user details. Can provide basic or full details.", { detail: z.enum(["basic", "full"]).default("basic").describe("Level of detail"), }, async ({ detail }) => { try { let cmd; if (isWindows) { cmd = "powershell.exe -Command \""; if (detail === "basic") { cmd += "$OS = Get-CimInstance Win32_OperatingSystem; " + "$CS = Get-CimInstance Win32_ComputerSystem; " + "$Processor = Get-CimInstance Win32_Processor; " + "Write-Output 'OS: ' $OS.Caption $OS.Version; " + "Write-Output 'Computer: ' $CS.Manufacturer $CS.Model; " + "Write-Output 'CPU: ' $Processor.Name; " + "Write-Output 'Memory: ' [math]::Round($OS.TotalVisibleMemorySize/1MB, 2) 'GB'"; } else { cmd += "$OS = Get-CimInstance Win32_OperatingSystem; " + "$CS = Get-CimInstance Win32_ComputerSystem; " + "$Processor = Get-CimInstance Win32_Processor; " + "$Disk = Get-CimInstance Win32_LogicalDisk -Filter 'DriveType=3'; " + "$Network = Get-CimInstance Win32_NetworkAdapterConfiguration | Where-Object {$_.IPAddress -ne $null}; " + "Write-Output '=== OPERATING SYSTEM ==='; " + "Write-Output ('OS: ' + $OS.Caption + ' ' + $OS.Version); " + "Write-Output ('Architecture: ' + $OS.OSArchitecture); " + "Write-Output ('Install Date: ' + $OS.InstallDate); " + "Write-Output ('Last Boot: ' + $OS.LastBootUpTime); " + "Write-Output (''; '=== HARDWARE ==='); " + "Write-Output ('Manufacturer: ' + $CS.Manufacturer); " + "Write-Output ('Model: ' + $CS.Model); " + "Write-Output ('Serial Number: ' + (Get-CimInstance Win32_BIOS).SerialNumber); " + "Write-Output ('Processor: ' + $Processor.Name); " + "Write-Output ('Cores: ' + $Processor.NumberOfCores); " + "Write-Output ('Logical Processors: ' + $Processor.NumberOfLogicalProcessors); " + "Write-Output ('Memory: ' + [math]::Round($OS.TotalVisibleMemorySize/1MB, 2) + ' GB'); " + "Write-Output (''; '=== STORAGE ==='); " + "foreach($drive in $Disk) { " + "Write-Output ('Drive ' + $drive.DeviceID + ' - ' + [math]::Round($drive.Size/1GB, 2) + ' GB (Free: ' + [math]::Round($drive.FreeSpace/1GB, 2) + ' GB)') " + "}; " + "Write-Output (''; '=== NETWORK ==='); " + "foreach($adapter in $Network) { " + "Write-Output ('Adapter: ' + $adapter.Description); " + "Write-Output (' IP Address: ' + ($adapter.IPAddress[0])); " + "Write-Output (' MAC Address: ' + $adapter.MACAddress); " + "Write-Output (' Gateway: ' + ($adapter.DefaultIPGateway -join ', ')); " + "}"; } cmd += "\""; } else { // Fallback for Unix systems if (detail === "basic") { cmd = "uname -a && lscpu | grep 'Model name' && free -h | head -n 2"; } else { cmd = "uname -a && lscpu && free -h && df -h && ip addr"; } } const stdout = executeCommand(cmd); return { content: [ { type: "text", text: stdout.toString(), }, ], }; } catch (error) { return { isError: true, content: [ { type: "text", text: `Error retrieving system info: ${error}`, }, ], }; } } ); // Register the get_network_info tool server.tool( "get_network_info", "Retrieve network configuration information including IP addresses, adapters, and DNS settings. Can be filtered to a specific interface.", { networkInterface: z.string().optional().describe("Optional interface name to filter results"), }, async ({ networkInterface }) => { try { let cmd; if (isWindows) { cmd = "powershell.exe -Command \""; if (networkInterface) { cmd += "$adapters = Get-NetAdapter | Where-Object { $_.Name -like '*" + networkInterface + "*' }; "; } else { cmd += "$adapters = Get-NetAdapter; "; } cmd += "foreach($adapter in $adapters) { " + "Write-Output ('======== ' + $adapter.Name + ' (' + $adapter.Status + ') ========'); " + "Write-Output ('Interface Description: ' + $adapter.InterfaceDescription); " + "Write-Output ('MAC Address: ' + $adapter.MacAddress); " + "Write-Output ('Link Speed: ' + $adapter.LinkSpeed); " + "$ipconfig = Get-NetIPConfiguration -InterfaceIndex $adapter.ifIndex; " + "Write-Output ('IP Address: ' + ($ipconfig.IPv4Address.IPAddress -join ', ')); " + "Write-Output ('Subnet: ' + ($ipconfig.IPv4Address.PrefixLength -join ', ')); " + "Write-Output ('Gateway: ' + ($ipconfig.IPv4DefaultGateway.NextHop -join ', ')); " + "Write-Output ('DNS Servers: ' + ($ipconfig.DNSServer.ServerAddresses -join ', ')); " + "Write-Output ''; " + "}\""; } else { // Fallback for Unix systems if (networkInterface) { cmd = `ip addr show ${networkInterface}`; } else { cmd = "ip addr"; } } const stdout = executeCommand(cmd); return { content: [ { type: "text", text: stdout.toString(), }, ], }; } catch (error) { return { isError: true, content: [ { type: "text", text: `Error retrieving network info: ${error}`, }, ], }; } } ); // Register the get_scheduled_tasks tool server.tool( "get_scheduled_tasks", "Retrieve information about scheduled tasks on the system. Can query all tasks or get detailed status of a specific task.", { action: z.enum(["query", "status"]).default("query").describe("Action to perform"), taskName: z.string().optional().describe("Name of the specific task (optional)"), }, async ({ action, taskName }) => { if (!isWindows) { return { content: [ { type: "text", text: "The scheduled tasks tool is only available on Windows. Current platform: " + platform(), }, ], }; } try { let cmd = "powershell.exe -Command \""; if (action === "query") { if (taskName) { cmd += "Get-ScheduledTask -TaskName '" + taskName + "' | Format-List TaskName, State, Description, Author, LastRunTime, NextRunTime, LastTaskResult"; } else { cmd += "Get-ScheduledTask | Select-Object TaskName, State, Description | Format-Table -AutoSize | Out-String"; } } else if (action === "status" && taskName) { cmd += "Get-ScheduledTask -TaskName '" + taskName + "' | Format-List *; " + "Get-ScheduledTaskInfo -TaskName '" + taskName + "' | Format-List *"; } else { return { isError: true, content: [ { type: "text", text: "For 'status' action, taskName parameter is required", }, ], }; } cmd += "\""; const stdout = executeCommand(cmd); return { content: [ { type: "text", text: stdout.toString(), }, ], }; } catch (error) { return { isError: true, content: [ { type: "text", text: `Error retrieving scheduled tasks: ${error}`, }, ], }; } } ); // Register the get_service_info tool server.tool( "get_service_info", "Retrieve information about Windows services. Can query all services or get detailed status of a specific service.", { action: z.enum(["query", "status"]).default("query").describe("Action to perform"), serviceName: z.string().optional().describe("Service name to get info about (optional)"), }, async ({ action, serviceName }) => { if (!isWindows) { return { content: [ { type: "text", text: "The service info tool is only available on Windows. Current platform: " + platform(), }, ], }; } try { let cmd = "powershell.exe -Command \""; if (action === "query") { if (serviceName) { cmd += "Get-Service -Name '" + serviceName + "' | Format-List Name, DisplayName, Status, StartType, Description"; } else { cmd += "Get-Service | Select-Object Name, DisplayName, Status, StartType | Format-Table -AutoSize | Out-String"; } } else if (action === "status" && serviceName) { cmd += "Get-Service -Name '" + serviceName + "' | Format-List *; " + "Get-CimInstance -ClassName Win32_Service -Filter \"Name='" + serviceName + "'\" | Format-List *"; } else { return { isError: true, content: [ { type: "text", text: "For 'status' action, serviceName parameter is required", }, ], }; } cmd += "\""; const stdout = executeCommand(cmd); return { content: [ { type: "text", text: stdout.toString(), }, ], }; } catch (error) { return { isError: true, content: [ { type: "text", text: `Error retrieving service info: ${error}`, }, ], }; } } ); // Register the list_allowed_commands tool server.tool( "list_allowed_commands", "List all commands that are allowed to be executed by this server. This helps understand what operations are permitted.", {}, async () => { try { if (isWindows) { return { content: [ { type: "text", text: "The following commands are allowed to be executed by this server:\n\n" + "- powershell.exe: Used for most system operations\n" + "- cmd.exe: Used for simple command execution\n\n" + "Note: All commands are executed with the same privileges as the user running this server." }, ], }; } else { return { content: [ { type: "text", text: "Running on non-Windows platform: " + platform() + "\n\n" + "Standard Unix/Linux commands are available, but Windows-specific commands like powershell.exe and cmd.exe are not available in this environment.\n\n" + "The following commands should work:\n" + "- ls: List directory contents\n" + "- ps: List processes\n" + "- uname: Print system information\n" + "- ip: Show network information\n\n" + "Note: All commands are executed with the same privileges as the user running this server." }, ], }; } } catch (error) { return { isError: true, content: [ { type: "text", text: `Error listing allowed commands: ${error}`, }, ], }; } } ); // Register the execute_command tool server.tool( "execute_command", "Execute a Windows command and return its output. Only commands in the allowed list can be executed. This tool should be used for running simple commands like 'dir', 'echo', etc.", { command: z.string().describe("The command to execute"), workingDir: z.string().optional().describe("Working directory for the command"), timeout: z.number().default(30000).describe("Timeout in milliseconds"), }, async ({ command, workingDir, timeout }) => { try { // Security check: Ensure only allowed commands are executed const commandLower = command.toLowerCase(); // Block potentially dangerous commands const dangerousPatterns = [ 'net user', 'net localgroup', 'netsh', 'format', 'rd /s', 'rmdir /s', 'del /f', 'reg delete', 'shutdown', 'taskkill', 'sc delete', 'bcdedit', 'cacls', 'icacls', 'takeown', 'diskpart', 'cipher /w', 'schtasks /create', 'rm -rf', 'sudo', 'chmod', 'chown', 'passwd', 'mkfs', 'dd' ]; // Check for dangerous patterns if (dangerousPatterns.some(pattern => commandLower.includes(pattern.toLowerCase()))) { return { isError: true, content: [ { type: "text", text: "Command contains potentially dangerous operations and cannot be executed.", }, ], }; } const options: any = { timeout }; if (workingDir) { options.cwd = workingDir; } let cmdToExecute; if (isWindows) { cmdToExecute = `cmd.exe /c ${command}`; } else { // For non-Windows, try to execute the command directly cmdToExecute = command; } const stdout = executeCommand(cmdToExecute, options); return { content: [ { type: "text", text: stdout.toString() || 'Command executed successfully (no output)', }, ], }; } catch (error) { return { isError: true, content: [ { type: "text", text: `Error executing command: ${error}`, }, ], }; } } ); // Register the execute_powershell tool server.tool( "execute_powershell", "Execute a PowerShell script and return its output. This allows for more complex operations and script execution. PowerShell must be in the allowed commands list.", { script: z.string().describe("PowerShell script to execute"), workingDir: z.string().optional().describe("Working directory for the script"), timeout: z.number().default(30000).describe("Timeout in milliseconds"), }, async ({ script, workingDir, timeout }) => { if (!isWindows) { return { content: [ { type: "text", text: "The PowerShell execution tool is only available on Windows. Current platform: " + platform(), }, ], }; } try { // Security check: Ensure no dangerous operations const scriptLower = script.toLowerCase(); // Block potentially dangerous commands const dangerousPatterns = [ 'new-user', 'add-user', 'remove-item -recurse -force', 'format-volume', 'reset-computer', 'stop-computer', 'restart-computer', 'stop-process -force', 'remove-item -force', 'set-executionpolicy', 'invoke-webrequest', 'start-bitstransfer', 'set-location', 'invoke-expression', 'iex', '& {', 'invoke-command', 'new-psdrive', 'remove-psdrive', 'enable-psremoting', 'new-service', 'remove-service', 'set-service' ]; // Check for dangerous patterns if (dangerousPatterns.some(pattern => scriptLower.includes(pattern.toLowerCase()))) { return { isError: true, content: [ { type: "text", text: "Script contains potentially dangerous operations and cannot be executed.", }, ], }; } const options: any = { timeout }; if (workingDir) { options.cwd = workingDir; } const stdout = executeCommand(`powershell.exe -Command "${script}"`, options); return { content: [ { type: "text", text: stdout.toString() || 'PowerShell script executed successfully (no output)', }, ], }; } catch (error) { return { isError: true, content: [ { type: "text", text: `Error executing PowerShell script: ${error}`, }, ], }; } } ); // Start the server async function main() { // Log platform information on startup console.error(`Starting Windows Command Line MCP Server on platform: ${platform()}`); if (!isWindows) { console.error("Warning: This server is designed for Windows environments. Some features may not work on " + platform()); } const transport = new StdioServerTransport(); await server.connect(transport); console.error("Windows Command Line MCP Server running on stdio"); } main().catch((error) => { console.error("Fatal error in main():", error); process.exit(1); });
ID: 976txj1j30