Enables execution of Git commands through Git Bash shell on Windows systems for version control operations.
Windows CLI MCP Server
This is a fork of the originalwin-cli-mcp-server by Simon Benedict. This fork includes additional security fixes, API improvements, and new tools for enhanced functionality.
v0.3.0 - Active development with security improvements and enhanced stability.
MCP server for secure command-line interactions on Windows systems, enabling controlled access to PowerShell, CMD, Git Bash shells, and remote systems via SSH. It allows MCP clients (like Claude Desktop) to perform operations on your system.
What's New in v0.3.0
New Capabilities:
SFTP file transfer operations (upload, download, list, delete)
WSL path support for SFTP tools (converts /mnt/c/ and \wsl.localhost\ paths)
Background job execution with streaming output
Batch command execution
System monitoring (CPU usage, disk space)
Network diagnostics (DNS lookup, connectivity testing)
Environment variable access with security filtering
Configuration value retrieval
Security Improvements:
Fixed path traversal, command injection, and race condition vulnerabilities
SSH host key verification with Trust On First Use (TOFU)
Error message sanitization
Remote shell type auto-detection with validation
Connection pool limits with automatic cleanup
Secure configuration merge that preserves security settings
This MCP server provides direct access to your system's command line interface and remote systems via SSH. When enabled, it grants access to your files, environment variables, command execution capabilities, and remote server management. Review and restrict allowed paths and SSH connections, enable directory restrictions, and configure command blocks. SeeConfiguration for details.
Features
Multi-shell support: Execute commands in PowerShell, Command Prompt (CMD), and Git Bash
SSH support: Execute commands on remote systems via SSH
Resource exposure: View SSH connections, current directory, and configuration as MCP resources
Security controls:
SSH host key verification (prevents MITM attacks)
Command and SSH command blocking (full paths, case variations)
Working directory validation
Maximum command length limits
Command logging and history tracking
Smart argument validation
Configurable:
Custom security rules
Shell-specific settings
SSH connection profiles
Path restrictions
Blocked command lists
See the API section for details on the tools and resources the server provides to MCP clients.
Note: The server will only allow operations within configured directories, with allowed commands, and on configured SSH connections.
Architecture
The server uses a layered architecture with dependency injection for maintainability and testability:
Foundation Layer:
ServiceContainer: Lightweight dependency injection with singleton, transient, and instance lifecycles
ToolRegistry: Manages tool registration, discovery, and execution
Service Layer:
ConfigManager: Configuration loading and validation
SecurityManager: Multi-stage command validation pipeline
CommandExecutor: Process spawning and timeout management
HistoryManager: Command history tracking with size limits
EnvironmentManager: Secure environment variable access with blocklist/allowlist
JobManager: Background job execution with lifecycle management
SSHConnectionPool: SSH connection management with LRU eviction
Presentation Layer:
34 MCP tools organized by category (command execution, SSH operations, diagnostics, system info)
All tools extend BaseTool abstract class
Tools use dependency injection to access services
This architecture provides separation of concerns, making the codebase easier to maintain and extend. For detailed architecture documentation, see CLAUDE.md.
Usage with Claude Desktop
Add this to your claude_desktop_config.json:
For use with a specific config file, add the --config flag:
After configuring, you can:
Execute commands directly using the available tools
View configured SSH connections and server configuration in the Resources section
Manage SSH connections through the provided tools
Configuration
The server uses a JSON configuration file to customize its behavior. You can specify settings for security controls, shell configurations, and SSH connections.
To create a default config file, either:
a) copy config.json.example to config.json, or
b) run:
Then set the
--configflag to point to your config file as described in the Usage with Claude Desktop section.
Configuration Locations
The server looks for configuration in the following locations (in order):
Path specified by
--configflag./config.json in current directory
~/.win-cli-mcp/config.json in user's home directory
If no configuration file is found, the server will use a default (restricted) configuration:
Default Configuration
Note: The default configuration is designed to be restrictive and secure. Find more details on each setting in the Configuration Settings section.
Configuration Settings
The configuration file is divided into three main sections: security, shells, and ssh.
Security Settings
Shell Configuration
WSL Path Support
The SFTP tools (sftp_download, sftp_upload) support downloading and uploading files to Windows Subsystem for Linux (WSL) paths:
Supported path formats:
\\wsl.localhost\Ubuntu\home\user\file- WSL network path (recommended)\\wsl$\Ubuntu\home\user\file- WSL legacy network path/home/user/file- Unix absolute path (uses default distribution)/mnt/c/Users/user/file- WSL mount path format
Requirements:
WSL must be installed:
wsl --installAt least one distribution must be configured
Include WSL paths in
allowedPathsconfiguration
Example configuration:
Troubleshooting WSL paths:
If you get "WSL is not installed" error, run
wsl --installand restartIf you get "Path not allowed" error, add the WSL path to
allowedPathsUse
\\wsl.localhost\paths for better compatibility with Windows tools
SSH Configuration
API
Tools
The server provides 34 MCP tools organized into 4 categories:
Command Execution (6 tools)
execute_command - Execute a command in PowerShell, CMD, or Git Bash
read_command_history - Get history of executed commands with outputs and exit codes
start_background_job - Start a command as a background job (async execution)
get_job_status - Get status and metadata for a background job
get_job_output - Retrieve output from a background job with streaming support
execute_batch - Execute multiple commands sequentially with stop-on-error mode
SSH Operations (12 tools)
ssh_execute - Execute command on remote SSH host
ssh_disconnect - Close SSH connection
create_ssh_connection - Add new SSH connection to config
read_ssh_connections - List all configured SSH connections
update_ssh_connection - Modify existing SSH connection
delete_ssh_connection - Remove SSH connection from config
read_ssh_pool_status - Get SSH connection pool status and health
validate_ssh_connection - Test SSH config and connectivity
sftp_upload - Upload file to remote host via SFTP
sftp_download - Download file from remote host via SFTP
sftp_list_directory - List files/directories on remote host
sftp_delete - Delete file or directory on remote host
Diagnostics & Configuration (12 tools)
check_security_config - Inspect security rules (commands, paths, operators, limits, environment)
test_connection - Test shell connectivity and basic functionality
validate_command - Dry-run validation without execution
explain_exit_code - Get detailed explanation for exit codes
validate_config - Validate configuration file syntax
read_environment_variable - Read single environment variable (with security filtering)
list_environment_variables - List accessible environment variables
get_config_value - Get specific config value by dot notation path
reload_config - Validate and preview config reload
dns_lookup - Perform DNS lookups (A, AAAA, MX, TXT, NS, CNAME records)
test_connectivity - Test network connectivity with SSRF protection
System Info & Monitoring (4 tools)
read_current_directory - Get current working directory
get_cpu_usage - Get CPU usage with configurable sampling interval
get_disk_space - Get disk space for specific drives or all drives
list_processes - List running processes (disabled by default for security)
Resources
The server exposes 5 MCP resources for configuration and status monitoring:
ssh://{connectionId} - Individual SSH connection details (passwords masked)
ssh://config - Complete SSH configuration with all connections
cli://currentdir - Current working directory of the CLI server
cli://config - CLI server configuration (sensitive data excluded)
cli://background-jobs - Status of all background command execution jobs
Troubleshooting
This section covers common issues and their solutions when using the Windows CLI MCP Server.
Understanding Exit Codes
The server uses specific exit codes to indicate the result of command execution:
0: Success - Command executed successfully
-1: Execution failure - Command failed to run, timed out, or encountered a process error
-2: Validation failure - Command was blocked by security rules before execution
When you see a non-zero exit code, check the error message to understand what went wrong.
Issue: "Command is blocked" or "Command contains blocked command"
Symptoms:
Command execution returns exit code
-2Error message: "Command contains blocked command: [command]"
Commands like
del,rm,shutdown, orregfail immediately
Cause:
The command or one of its arguments matches an entry in the security.blockedCommands or security.blockedArguments list. The server blocks these commands to prevent potentially dangerous operations.
Solution:
First, verify which commands are blocked using the diagnostic tool:
{ "tool": "check_security_config", "arguments": { "category": "commands" } }If you need to allow a specific command, create or edit your
config.json:{ "security": { "blockedCommands": [ // Remove the command you want to allow from this list // Or create a minimal list with only commands you want to block "format", "shutdown", "reg", "regedit" ] } }Important: If you're using a custom config file, remember that the server uses secure merge logic:
Blocked commands and arguments use UNION: Both default blocks AND your custom blocks are combined
To completely override the defaults, you must explicitly list ONLY the commands you want to block
Restart the MCP server after changing the configuration (restart Claude Desktop or your MCP client)
Prevention:
Review the Default Configuration section to understand which commands are blocked by default
Use the
validate_commandtool to test commands before running themConsider using alternative commands (e.g.,
Remove-Itemin PowerShell instead ofrm)
Related Configuration:
See Security Settings for details on blockedCommands and blockedArguments.
Issue: "Path not allowed" or "Working directory outside allowed paths"
Symptoms:
Command execution returns exit code
-2Error message: "Working directory is outside allowed paths"
Commands fail even though they seem safe
Cause:
You're trying to execute a command in a directory that's not in the security.allowedPaths list, and security.restrictWorkingDirectory is set to true.
CRITICAL: Understanding Config Merge Behavior
The server uses a security-first merge strategy for allowedPaths:
allowedPaths uses INTERSECTION (not union!)
Only paths that appear in BOTH the default config AND your custom config are allowed
This prevents accidentally weakening security by adding overly broad paths
Example of INCORRECT configuration:
Example of CORRECT configuration:
Solution:
Check which paths are currently allowed:
{ "tool": "check_security_config", "arguments": { "category": "paths" } }Identify your current working directory:
{ "tool": "read_current_directory" }Update your
config.jsonto include BOTH the defaults AND your new paths:{ "security": { "allowedPaths": [ "C:\\Users\\YourUsername", // Include existing defaults! "C:\\Development\\Projects", // Include existing defaults! "C:\\YourNewPath" // Add your new path ], "restrictWorkingDirectory": true } }Alternative: Disable path restrictions entirely (NOT recommended for security):
{ "security": { "restrictWorkingDirectory": false } }Restart the MCP server
Prevention:
Always include existing allowed paths when adding new ones
Use absolute paths (e.g.,
C:\Users\Namenot~or relative paths)Test path validation before running important commands using
validate_commandUse forward slashes
/or escaped backslashes\\in JSON config files
Related Configuration:
See Security Settings for details on allowedPaths and restrictWorkingDirectory.
Issue: SSH Connection Failed
Symptoms:
ssh_executeorvalidate_ssh_connectionreturns an errorError messages like "Connection refused", "Authentication failed", "Connection timeout", or "Host not found"
SSH commands work from terminal but fail through MCP
Common Causes:
Network/Firewall Issues:
Firewall blocking port 22 (or custom SSH port)
Host is unreachable or hostname resolution fails
VPN required but not connected
Authentication Issues:
Incorrect username or password
Private key file not found or has wrong permissions
Private key requires passphrase (not supported)
SSH key not authorized on remote server
Configuration Issues:
Wrong hostname or IP address
Wrong port number
SSH not enabled in server config
Connection ID doesn't exist
Solution:
Verify SSH is enabled in your config:
{ "ssh": { "enabled": true, // Must be true! "connections": { // Your connections here } } }Test the SSH connection configuration:
{ "tool": "validate_ssh_connection", "arguments": { "connectionConfig": { "host": "your-server.example.com", "port": 22, "username": "your-username", "password": "your-password" // Or use privateKeyPath } } }For authentication failures:
Password authentication:
{ "ssh": { "enabled": true, "connections": { "my-server": { "host": "server.example.com", "port": 22, "username": "admin", "password": "your-password" // Ensure password is correct } } } }Key-based authentication:
{ "ssh": { "enabled": true, "connections": { "my-server": { "host": "server.example.com", "port": 22, "username": "admin", "privateKeyPath": "C:\\Users\\YourName\\.ssh\\id_rsa" // Use full path } } } }Important for key authentication:
Ensure the private key file exists at the specified path
Private key must NOT require a passphrase (passphrase-protected keys are not supported)
Public key must be added to
~/.ssh/authorized_keyson the remote serverPrivate key file permissions should be restrictive (read-only for owner)
For connection timeouts:
Increase timeout values in your config:
{ "ssh": { "enabled": true, "readyTimeout": 30000, // 30 seconds to establish connection "connections": { "my-server": { "host": "server.example.com", "port": 22, "username": "admin", "password": "your-password", "readyTimeout": 60000 // Override global timeout for this connection } } } }Check connection pool status:
{ "tool": "read_ssh_pool_status" }Test from command line first:
# Test if you can connect via standard SSH ssh username@server.example.com # Test specific port ssh -p 2222 username@server.example.comFor "Host not found" errors:
Use IP address instead of hostname if DNS resolution is failing
Verify hostname is correct and accessible from your network
Check if VPN connection is required
Prevention:
Use
validate_ssh_connectionbefore adding connections to verify configurationTest SSH access from command line before configuring in MCP
Use key-based authentication for better security (ensure keys don't require passphrase)
Keep connection credentials up to date
Monitor connection pool status if managing many SSH connections
Related Configuration: See SSH Configuration for details on SSH settings.
Issue: Command Times Out
Symptoms:
Command execution returns exit code
-1Error message: "Command execution timed out"
Long-running commands are killed before completion
Cause:
The command took longer than the configured commandTimeout (default: 30 seconds) to complete.
Solution:
For individual commands, override the timeout in the tool call:
{ "tool": "execute_command", "arguments": { "shell": "powershell", "command": "your-long-running-command", "timeout": 120 // 120 seconds for this command only } }For all commands, increase the default timeout in your
config.json:{ "security": { "commandTimeout": 120 // 120 seconds default for all commands } }For SSH commands, configure SSH-specific timeout:
{ "ssh": { "enabled": true, "defaultTimeout": 120, // 120 seconds for all SSH commands "connections": { "slow-server": { "host": "server.example.com", "port": 22, "username": "admin", "password": "password" // This connection will use the defaultTimeout of 120 seconds } } } }Restart the MCP server after changing configuration
Prevention:
Set appropriate timeout values for your use case
Break long-running operations into smaller commands
Use background jobs or scheduled tasks for very long operations
Monitor command execution time using
read_command_history
Using Custom Environment Variables
You can pass custom environment variables to commands for encoding, locale, or other settings:
Security notes:
Sensitive variables (AWS keys, passwords, tokens) are blocked by default
PATH and LD_PRELOAD are blocked to prevent privilege escalation
Use
check_security_configwith"category": "environment"to see blocked variablesIn allowlist mode, only explicitly allowed variables can be set
PowerShell Unicode Display Limitation:
PowerShell's default console encoding may not display Unicode characters correctly (showing ?? instead of emojis/special characters). This is a PowerShell console limitation, not a server issue - the environment variables ARE set correctly.
Workarounds:
Use GitBash for Unicode-heavy workflows - it handles UTF-8 natively:
{ "shell": "gitbash", "command": "/c/path/to/python.exe -c \"import os; print(os.environ.get('MESSAGE'))\"", "env": { "MESSAGE": "Hello 世界 🎉", "PYTHONIOENCODING": "utf-8" } }Set PowerShell encoding at the start of your command:
{ "shell": "powershell", "command": "[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; Write-Output $env:MESSAGE", "env": { "MESSAGE": "Hello 世界 🎉" } }Configure shell defaultEnv to always set UTF-8 encoding (see Shell Configuration)
Related Configuration:
See Security Settings for commandTimeout and SSH Configuration for defaultTimeout.
Issue: Shell Operators Blocked (Pipes, Redirects, Command Chaining)
Symptoms:
Command execution returns exit code
-2Error message: "Command contains blocked operator: &" (or |, ;, >, <, etc.)
Commands with pipes, redirects, or command chaining fail
Error mentions Unicode variants or zero-width characters
Cause:
The server blocks shell operators (&, |, ;, `, >, <, >>, 2>, 2>&1) and their Unicode homoglyphs to prevent command injection attacks. This is a security feature enabled by default.
Solution:
For PowerShell users, use PowerShell cmdlets instead of pipes:
# Instead of: dir | findstr "test" # Use: Get-ChildItem | Where-Object { $_.Name -like "*test*" } # Instead of: command1 && command2 # Use: command1; if ($?) { command2 }For simple output redirection, capture output programmatically instead:
The MCP server already captures and returns stdout/stderr
Use
read_command_historyto review output from previous commands
For complex operations, break into multiple separate commands:
// Instead of one command with pipes: // "dir | findstr test > output.txt" // Execute as separate commands: // Command 1: { "tool": "execute_command", "arguments": { "shell": "powershell", "command": "Get-ChildItem | Where-Object { $_.Name -like '*test*' } | Out-String" } } // Then save the result programmatically if neededIf you absolutely must use operators (NOT recommended for security):
You can modify blocked operators per shell in your
config.json:{ "shells": { "powershell": { "enabled": true, "command": "powershell.exe", "args": ["-NoProfile", "-NonInteractive", "-Command"], "blockedOperators": [";", "`"] // Only block some operators (RISKY!) } } }Warning: Removing operator blocks significantly increases security risk. Only do this if you fully understand the implications.
Test before running:
{ "tool": "validate_command", "arguments": { "shell": "powershell", "command": "your-command-here" } }
Prevention:
Use PowerShell cmdlets and native command features instead of shell operators
Learn PowerShell piping syntax (
|) which is safer within PowerShell contextBreak complex operations into multiple commands
Understand that operator blocking is a critical security feature
Related Configuration:
See Shell Configuration for blockedOperators setting.
Using Diagnostic Tools
The server provides built-in diagnostic tools to help troubleshoot issues:
validate_command - Test Commands Before Running
Validate a command without executing it to see if it would be blocked:
Returns when valid:
Returns when invalid:
Use cases:
Test commands before running to avoid validation failures
Debug why specific commands are being blocked
Verify path and operator restrictions
Check command length limits
check_security_config - Inspect Security Rules
View current security configuration to understand what's blocked:
Categories:
"commands": Shows blocked commands and arguments"paths": Shows allowed paths and directory restriction status"operators": Shows blocked operators for each shell"limits": Shows max command length and timeout settings"all": Shows everything
Use cases:
Understand which commands are blocked and why
Verify allowed paths are configured correctly
Check timeout and length limits
Audit security configuration
read_command_history - Review Past Executions
Review command history to see exit codes and outputs:
Returns: Array of command history entries with:
command: The command that was executedtimestamp: When it was executedoutput: Combined stdout/stderrexitCode: Result code (0, -1, or -2)
Use cases:
Track which commands succeeded or failed
Identify patterns in command failures
Review command outputs for debugging
Monitor command execution over time
validate_ssh_connection - Test SSH Configuration
Test SSH connection configuration before using it:
Returns:
isValid: Whether connection was successfulshellType: Detected shell type on remote server (bash, zsh, powershell, fish, etc.)error: Error message if connection failed
Use cases:
Test SSH credentials before adding to config
Verify network connectivity to remote hosts
Detect remote shell type for compatibility
Debug SSH authentication issues
Getting Help
If you're still experiencing issues after trying these solutions:
Check the command history to see exact error messages and exit codes
Use diagnostic tools to validate your configuration and commands
Review the configuration merge behavior - especially for
allowedPaths(intersection) vsblockedCommands(union)Check the GitHub repository for known issues and updates: https://github.com/quanticsoul4772/win-cli-mcp-server
Report bugs with:
Error messages and exit codes
Configuration file (sanitized - remove passwords!)
Steps to reproduce
Output from
check_security_configdiagnostic tool
License
This project is licensed under the MIT License - see the LICENSE file for details.