wcli0
Enhanced MCP server for Windows CLI interactions with advanced configuration and security features
Documentation
Windows CLI MCP Server (Enhanced)
MCP server for secure command-line interactions on Windows systems, enabling controlled access to PowerShell, CMD, Git Bash, and Bash shells.
It allows MCP clients (like Claude Desktop) to perform operations on your system, similar to Open Interpreter.
This enhanced version includes advanced configuration management, improved security features, and comprehensive testing capabilities.
>[!IMPORTANT]
> This MCP server provides direct access to your system's command line interface. When enabled, it grants access to your files, environment variables, and command execution capabilities.
>
> - Review and restrict allowed paths
> - Enable directory restrictions
> - Configure command blocks
> - Consider security implications
>
> See Configuration for more details.
- Windows CLI MCP Server (Enhanced)
Features
- Multi-Shell Support: Execute commands in PowerShell, Command Prompt (CMD), Git Bash, Bash, and WSL
- Modular Architecture: Build only the shells you need for smaller bundle sizes (30-65% reduction)
- Inheritance-Based Configuration: Global defaults with shell-specific overrides
- Shell-Specific Validation: Each shell can have its own security settings and path formats
- Flexible Path Management: Different shells support different path formats (Windows/Unix/Mixed)
- Resource Exposure: View configuration and security settings as MCP resources
- Explicit Working Directory State: The server maintains an active working directory used when `execute_command` omits `workingDir`. If the launch directory isn't allowed, this state starts unset and must be set via `set_current_directory`.
- Optional Initial Directory: Configure `initialDir` to start the server in a specific directory.
- Security Controls:
- Command blocking (full paths, case variations)
- Working directory validation
- Maximum command length limits
- Smart argument validation
- Shell-specific timeout settings
- Configurable:
- Inheritance-based configuration system
- Shell-specific security overrides
- Dynamic tool descriptions based on enabled shells
See the API section for more 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.
VS Code Extension
A companion VS Code extension in `vscode-extension/` simplifies
configuring this server. It exposes every CLI option as ordinary VS Code settings
(scoped per User and per Workspace) and registers the MCP server with
VS Code automatically via the MCP Server Definition Provider API — no hand-edited
`mcp.json` required. It can also generate a `config.json` or a `.vscode/mcp.json`
on demand. See vscode-extension/README.md.
Modular Shell Architecture
WCLI0 now supports a modular architecture that allows you to build specialized versions containing only the shells you need. This results in significantly smaller bundle sizes and faster startup times.
Build Options
Choose from several pre-configured builds:
# Full build (all shells) - default
npm run build
# Windows-only shells (PowerShell, CMD, Git Bash)
npm run build:windows
# Git Bash only (smallest Windows build)
npm run build:gitbash
# CMD only
npm run build:cmd
# Unix/Linux only (Bash)
npm run build:unix
# Custom combination
INCLUDED_SHELLS=gitbash,powershell npm run build:customBundle Size Comparison
| Build | Size Reduction | Shells Included |
|---|---|---|
| Full | Baseline | All 5 shells |
| Windows | ~40% smaller | PowerShell, CMD, Git Bash |
| Git Bash Only | ~60% smaller | Git Bash |
| CMD Only | ~65% smaller | CMD |
| Unix | ~60% smaller | Bash |
Documentation
For detailed information about the modular architecture:
- **Architecture Overview** - System design and module structure
- **User Guide** - How to build and use specialized versions
- **API Documentation** - Complete API reference for shell plugins
- **Migration Guide** - Upgrading from previous versions
- **Testing Guide** - Testing strategies for modular shells
Quick Start with Specialized Builds
If you only need Git Bash:
# Build
npm run build:gitbash
# Use in Claude Desktop config
{
"mcpServers": {
"windows-cli": {
"command": "node",
"args": ["/path/to/wcli0/dist/index.gitbash-only.js"]
}
}
}macOS and Unix/Linux Support
While wcli0 is primarily designed for Windows, it also supports Unix-based systems (macOS, Linux) with Bash shell integration.
Building for Unix Systems
To build wcli0 for Unix-based systems (macOS, Linux):
# Unix-only build (Bash shell)
npm run build:unix
# The output will be: dist/index.unix-only.jsStarting the Server on macOS
Start the server using npx:
# Start with default settings
npx wcli0 --shell bash
# Start with a configuration file
npx wcli0 --config ./config.mac.json
# Start with specific allowed directories
npx wcli0 --shell bash \
--allowedDir "/Users/$(whoami)" \
--allowedDir "/tmp"macOS Configuration Example
Here's a sample configuration for macOS:
{
"global": {
"security": {
"commandTimeout": 30,
"enableInjectionProtection": true,
"restrictWorkingDirectory": true
},
"restrictions": {
"blockedCommands": ["rm -rf /", "dd", "mkfs"],
"blockedArguments": ["--force", "-rf"],
"blockedOperators": ["&&", "||", ";", "|"]
},
"paths": {
"allowedPaths": ["/Users/$(whoami)", "/tmp"],
"initialDir": "/Users/$(whoami)"
}
},
"shells": {
"bash_auto": {
"type": "bash_auto",
"enabled": true
}
}
}Using with Claude Desktop on macOS
Configure Claude Desktop to use wcli0 on macOS:
{
"mcpServers": {
"macos-cli": {
"command": "npx",
"args": [
"-y",
"wcli0",
"--config",
"/path/to/config.mac.json"
]
}
}
}Important Notes for Unix Systems
- Path Formats: Unix systems use forward slashes (`/`) and do not support Windows drive letters
- Shell Type: Use `bash` or `bash_auto` shell types on Unix systems
- Home Directory: Use `$(whoami)` or your actual username in paths
- Security Commands: Some blocked commands in the default configuration are Windows-specific (e.g., `regedit`, `format`)
CLI Options for macOS
When running on Unix systems, use these CLI options:
| Option | Type | Description |
|---|---|---|
| `--shell` | string | Shell to use (use `bash` or `bash_auto` on Unix) |
| `--allowedDir` | string | Add an allowed directory (can be used multiple times) |
| `--config` | string | Path to configuration file |
| `--initialDir` | string | Initial working directory |
| `--allowAllDirs` | flag | Disable directory restrictions |
| `--unsafe` | flag | Disable all safety checks (not recommended) |
| `--yolo` | flag | Disable safety except directory restrictions |
Log Management
wcli0 automatically stores command execution logs and provides MCP resources for querying historical output with advanced filtering capabilities.
Output Truncation
By default, command responses show only the last 20 lines to prevent overwhelming long outputs. Full output is always stored and accessible via:
- File-based storage: When `logDirectory` is configured, logs are saved to files for persistent storage
- In-memory storage: Default behavior using MCP log resources (e.g., `cli://logs/commands/{id}`)
- The `get_command_output` tool (fallback for hosts that cannot read resources)
Configure truncation settings:
{
"global": {
"logging": {
"maxOutputLines": 20,
"enableTruncation": true
}
}
}File-Based Log Storage
For persistent logging, configure a log directory:
{
"global": {
"logging": {
"logDirectory": "./logs",
"exposeFullPath": false
}
}
}Or via CLI:
npx wcli0 --shell gitbash --logDirectory ./logsWhen file-based logging is enabled:
- Truncation messages show the file path directly (simpler output)
- Logs persist across server restarts
- No in-memory storage limits apply
- Starting the server with `--debug` automatically enables file-based logging to your OS temp directory (`/wcli0-debug-logs`) when no `logDirectory` is set, so every command and its output are persisted during debugging sessions.
> Security Note: Log files may contain sensitive command output. Ensure the log directory has appropriate permissions.
Log Resources
Access stored command output via MCP resources (in-memory mode):
- `cli://logs/list` - List all stored command execution logs
- `cli://logs/recent?n=10` - Get the N most recent logs
- `cli://logs/commands/{id}` - Access full output from a specific command
- `cli://logs/commands/{id}/range?start=1&end=100` - Query specific line ranges
- `cli://logs/commands/{id}/search?q=error&context=3` - Search logs with context
See API Documentation for detailed resource specifications and query parameters.
Example Configuration
{
"global": {
"logging": {
"maxOutputLines": 20,
"enableTruncation": true,
"maxStoredLogs": 50,
"maxLogSize": 1048576,
"enableLogResources": true,
"logRetentionMinutes": 1440,
"logDirectory": "./logs"
}
}
}Usage with Claude Desktop
Add this to your `claude_desktop_config.json`:
{
"mcpServers": {
"windows-cli": {
"command": "npx",
"args": ["-y", "wcli0"]
}
}
}For use with a specific config file, add the `--config` flag:
{
"mcpServers": {
"windows-cli": {
"command": "npx",
"args": [
"-y",
"wcli0",
"--config",
"path/to/your/config.json"
]
}
}
}Configuration Setup
To get started with configuration:
1. Use a sample configuration:
2. Create your own configuration:
# Copy and customize a sample
cp config.examples/config.sample.json my-config.json
# Or generate a default config
npx wcli0 --init-config ./my-config.jsonThe server also accepts an `--initialDir` flag to override the initial
working directory defined in your configuration file:
npx wcli0 --config ./my-config.json --initialDir /path/to/startYou can override global command limits directly from the CLI:
npx wcli0 --config ./my-config.json \
--maxCommandLength 5000 --commandTimeout 60You can configure output truncation and logging via CLI:
npx wcli0 --shell gitbash \
--maxOutputLines 50 \
--enableTruncation \
--enableLogResources \
--maxReturnLines 1000 \
--logDirectory ./logs| Option | Type | Default | Description |
|---|---|---|---|
| ------ | ---- | ------- | ----------- |
| `--maxOutputLines` | number | 20 | Maximum output lines before truncation |
| `--enableTruncation` | boolean | true | Enable output truncation |
| `--enableLogResources` | boolean | true | Enable log resources for `get_command_output` |
| `--maxReturnLines` | number | 500 | Maximum lines returned by `get_command_output` |
| `--logDirectory` | string | - | Directory for file-based log storage (instead of in-memory) |
When `--logDirectory` is configured, command output logs are saved to files instead of in-memory storage.
Truncation messages will show the file path for easy access to full output.
> Security Note: Log files may contain sensitive data from command output. Ensure the log directory
> has appropriate permissions and consider implementing log rotation.
You can override blocked restrictions directly from the CLI. Pass the option with
an empty string to clear defaults:
npx wcli0 --blockedCommand "" --blockedArgument "" --blockedOperator ""Provide the flag multiple times to specify values:
npx wcli0 --blockedCommand rm --blockedCommand delYou can also start the server with a specific shell and allowed directories
without a configuration file:
npx wcli0 --shell powershell \
--allowedDir C:\safe --allowedDir D:\projectsFor WSL shells, you can specify a custom mount location:
npx wcli0 --shell wsl \
--wslMountPoint /windows/To disable directory restrictions entirely when no allowed paths are
configured, start the server with:
npx wcli0 --allowAllDirsWhen started this way, `restrictWorkingDirectory` is forced on and
`enableInjectionProtection` is disabled to ensure the allowed paths apply
without shell injection checks.
If you need to disable safety checks that block command execution for
experimentation, you can start the server in unsafe or YOLO modes
(not recommended for production):
# YOLO disables all safety checks except allowed working directories
npx wcli0 --yolo
# Fully unsafe removes all safety checks, including directory limits
npx wcli0 --unsafeBoth modes clear blocked commands/arguments/operators and turn off injection
protection. YOLO mode leaves working directory restrictions active, while
fully unsafe mode disables those restrictions as well. These two flags are
mutually exclusive; using both at once will fail.
You can start the server with an HTTP-based transport instead of the default
stdio transport, so remote and web-based MCP clients can connect over HTTP.
Two HTTP transports are available:
- `http` -- the modern Streamable HTTP transport (MCP protocol revision
2025-03-26), serving a single `/mcp` endpoint. This is what current MCP
clients default to and is the recommended HTTP transport.
- `sse` -- the legacy HTTP+SSE transport (MCP protocol revision
2024-11-05), using two endpoints (`GET /sse`, `POST /messages`). It is
deprecated by the MCP spec in favor of Streamable HTTP and is kept only for
compatibility with older clients.
The modes are mutually exclusive (selected by `--transport`) and use separate
bind settings (`--http-*` for `http`, `--sse-*` for `sse`).
# Streamable HTTP on the default host/port (127.0.0.1:9444), serving /mcp
npx wcli0 --transport http
# Custom port, still bound to localhost
npx wcli0 --transport http --http-host 127.0.0.1 --http-port 3000
# Legacy HTTP+SSE transport
npx wcli0 --transport sse --sse-host 127.0.0.1 --sse-port 3000| Option | Type | Default | Description |
|---|---|---|---|
| ------ | ---- | ------- | ----------- |
| `--transport` | string | stdio | Transport protocol: `stdio`, `http` (Streamable HTTP), or `sse` (legacy HTTP+SSE) |
| `--http-host` | string | 127.0.0.1 | Host address for the Streamable HTTP transport (`http` mode) |
| `--http-port` | number | 9444 | Port for the Streamable HTTP transport (`http` mode) |
| `--http-allowed-origins` | string | (none) | Comma-separated browser origins allowed for `http` mode, in addition to loopback hosts and the bind host (e.g. `https://app.example.com,192.168.1.10`). Only the host component is compared. Required for browser clients on a wildcard (`0.0.0.0`) bind. |
| `--sse-host` | string | 127.0.0.1 | Host address for the legacy SSE transport (`sse` mode) |
| `--sse-port` | number | 9444 | Port for the legacy SSE transport (`sse` mode) |
| `--sse-allowed-origins` | string | (none) | Comma-separated browser origins allowed for `sse` mode, in addition to loopback hosts and the bind host. Only the host component is compared. Required for browser clients on a wildcard (`0.0.0.0`) bind. |
When `http` mode is active, clients use a single `/mcp` endpoint:
- `POST /mcp` carries client-to-server JSON-RPC messages. An `initialize`
request with no session id starts a new session; the server returns the
assigned id in the `Mcp-Session-Id` response header, and the client must
send that header on every subsequent request.
- `GET /mcp` opens the optional server-to-client SSE stream for an existing
session.
- `DELETE /mcp` terminates an existing session.
Sessions are stateful and isolated: each session has its own active working
directory, so one client's `set_current_directory` cannot affect another.
Requests carrying an unknown or terminated `Mcp-Session-Id` are rejected with
`404 Not Found`. The server logs the bind address and port on startup (with
`--debug`).
When `sse` mode is active, clients instead connect via `GET /sse` to open an
SSE stream and send messages via `POST /messages?sessionId=`.
Configuring Streamable HTTP entirely with CLI parameters (no config file).
Every transport and operational setting can be supplied as an input parameter,
so the server can run as a Streamable HTTP server without any config file:
npx wcli0 \
--transport http \
--http-host 127.0.0.1 \
--http-port 9444 \
--http-allowed-origins "https://app.example.com,192.168.1.10" \
--shell gitbash \
--allowedDir "D:/work/project" \
--commandTimeout 60 \
--debugCLI parameters also take precedence over a config file, so the same `--http-*`
flags override the corresponding `transport` fields when a `--config` file is
also passed (see the transport config section).
Both HTTP transports validate the request `Origin` header to mitigate
DNS-rebinding attacks: requests whose `Origin` is not a loopback host, the
configured bind host, or one of the configured allowed origins
(`--http-allowed-origins` / `--sse-allowed-origins`) are rejected with
`403 Forbidden`, while non-browser clients that send no `Origin` are allowed.
Allowed browser origins receive CORS headers, and `OPTIONS` preflight requests
are answered with `204`.
> Security: Neither HTTP transport has built-in authentication, and both
> expose command-execution tools. Keep the server bound to `127.0.0.1` (the
> default) for local use. Binding to `0.0.0.0` or any non-loopback address
> exposes those tools to every host that can reach the port; only do so behind
> an authenticated reverse proxy or equivalent access control. Origin
> validation alone does not authenticate non-browser clients.
>
> Wildcard binds and browser origins: When binding to a wildcard address
> (`0.0.0.0` / `::`), the bind host is not a usable origin to compare against,
> so browser clients reaching the server through its real LAN address (or a
> reverse proxy whose public hostname differs from the bind host) are rejected
> unless their origin is listed in `--http-allowed-origins` /
> `--sse-allowed-origins` (or the `transport.httpAllowedOrigins` /
> `transport.sseAllowedOrigins` config arrays). Non-browser clients are
> unaffected, since they send no `Origin`.
1. Update your Claude Desktop configuration to use your config file:
{
"mcpServers": {
"windows-cli": {
"command": "npx",
"args": [
"-y",
"wcli0",
"--config",
"./my-config.json"
]
}
}
}After configuring, you can:
- Execute commands directly using the available tools
- View server configuration and security settings in the Resources section
- Access shell-specific configurations and capabilities
Configuration
The server uses an inheritance-based configuration system where global defaults can be overridden by shell-specific settings.
Configuration Structure
{
"global": {
"security": {
"maxCommandLength": 2000,
"commandTimeout": 30,
"enableInjectionProtection": true,
"restrictWorkingDirectory": true
},
"restrictions": {
"blockedCommands": ["format", "shutdown"],
"blockedArguments": ["--exec", "-e"],
"blockedOperators": ["&", "|", ";", "`"]
},
"paths": {
"allowedPaths": ["/home/user", "/tmp"],
"initialDir": "/home/user"
}
},
"shells": {
"powershell": {
"type": "powershell",
"enabled": true,
"executable": {
"command": "powershell.exe",
"args": ["-NoProfile", "-NonInteractive", "-Command"]
},
"overrides": {
"security": {
"commandTimeout": 45
},
"restrictions": {
"blockedCommands": ["Remove-Item", "Format-Volume"]
}
}
},
"wsl": {
"type": "wsl",
"enabled": true,
"executable": {
"command": "wsl.exe",
"args": ["-e"]
},
"wslConfig": {
"mountPoint": "/mnt/",
"inheritGlobalPaths": true
}
}
}
}Configuration Locations
The server looks for configuration files in the following order:
1. Path specified via `--config` command line argument
2. `win-cli-mcp.config.json` in the current working directory
3. `~/.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.
For a complete reference of all default values, see docs/defaults.md.
{
"global": {
"security": {
"maxCommandLength": 2000,
"commandTimeout": 30,
"enableInjectionProtection": true,
"restrictWorkingDirectory": true
},
"restrictions": {
"blockedCommands": [
"rm", "del", "rmdir", "format", "shutdown", "restart",
"reg", "regedit", "net", "netsh", "takeown", "icacls"
],
"blockedArguments": [
"--exec", "-e", "/c", "-enc", "-encodedcommand",
"-command", "--interactive", "-i", "--login", "--system"
],
"blockedOperators": ["&", "|", ";", "`"]
},
"paths": {
"initialDir": null
}
},
"shells": {
"powershell": {
"type": "powershell",
"enabled": true,
"executable": {
"command": "powershell.exe",
"args": ["-NoProfile", "-NonInteractive", "-Command"]
}
},
"cmd": {
"type": "cmd",
"enabled": true,
"executable": {
"command": "cmd.exe",
"args": ["/c"]
}
},
"gitbash": {
"type": "gitbash",
"enabled": true,
"executable": {
"command": "C:\\Program Files\\Git\\bin\\bash.exe",
"args": ["-c"]
}
}
}
}Configuration Settings
The configuration file uses an inheritance system with two main sections: `global` and `shells`.
Global Settings
Global settings provide defaults that apply to all shells unless overridden.
Security Settings
{
"global": {
"security": {
// Maximum allowed length for any command
"maxCommandLength": 2000,
// Command execution timeout in seconds
"commandTimeout": 30,
// Enable protection against command injection
"enableInjectionProtection": true,
// Restrict commands to allowed working directories
"restrictWorkingDirectory": true
}
}
}Restriction Settings
{
"global": {
"restrictions": {
// Commands to block - blocks both direct use and full paths
"blockedCommands": ["rm", "format", "shutdown"],
// Arguments to block across all commands
"blockedArguments": ["--exec", "-e", "/c"],
// Operators to block in commands
"blockedOperators": ["&", "|", ";", "`"]
}
}
}Path Settings
{
"global": {
"paths": {
// Directories where commands can be executed
"allowedPaths": ["/home/user", "/tmp", "C:\\Users\\username"],
// Initial working directory (null = use launch directory)
"initialDir": "/home/user",
// Whether to restrict working directories
"restrictWorkingDirectory": true
}
}
}If the `allowedPaths` array is omitted from your configuration file, no default
directories are automatically allowed. When `restrictWorkingDirectory` is
enabled, only the `initialDir` (if specified) will be added to the allowed paths
list.
Use the `--allowAllDirs` flag when launching the server to automatically
disable `restrictWorkingDirectory` if no allowed paths or `initialDir` are set.
Shell Configuration
Each shell can be individually configured and can override global settings.
Each shell entry must include a `type` field indicating the shell. Valid values are `powershell`, `cmd`, `gitbash`, `bash`, and `wsl`.
Basic Shell Configuration
{
"shells": {
"powershell": {
"type": "powershell",
"enabled": true,
"executable": {
"command": "powershell.exe",
"args": ["-NoProfile", "-NonInteractive", "-Command"]
}
}
}
}Shell-Specific Overrides
{
"shells": {
"powershell": {
"type": "powershell",
"enabled": true,
"executable": {
"command": "powershell.exe",
"args": ["-NoProfile", "-NonInteractive", "-Command"]
},
"overrides": {
"security": {
"commandTimeout": 45,
"maxCommandLength": 3000
},
"restrictions": {
"blockedCommands": ["Remove-Item", "Format-Volume"],
"blockedOperators": ["|", "&"]
}
}
}
}
}WSL Configuration
WSL shells have additional configuration options for path mapping:
{
"shells": {
"wsl": {
"type": "wsl",
"enabled": true,
"executable": {
"command": "wsl.exe",
"args": ["-e"]
},
"wslConfig": {
"mountPoint": "/mnt/",
"inheritGlobalPaths": true
}
}
}
}You can override the mount point at startup using the `--wslMountPoint` CLI flag.
Configuration Inheritance
The transport section can also be set in the config file. For the Streamable
HTTP transport (`http` mode):
{
"transport": {
"mode": "http",
"httpHost": "127.0.0.1",
"httpPort": 9444,
"httpAllowedOrigins": ["https://app.example.com", "192.168.1.10"]
}
}For the legacy HTTP+SSE transport (`sse` mode):
{
"transport": {
"mode": "sse",
"sseHost": "127.0.0.1",
"ssePort": 9444,
"sseAllowedOrigins": ["https://app.example.com", "192.168.1.10"]
}
}| Field | Type | Default | Applies to | Description |
|---|---|---|---|---|
| `mode` | string | `stdio` | all | `stdio`, `http`, or `sse` |
| `httpHost` | string | `127.0.0.1` | `http` | Bind host for the Streamable HTTP transport |
| `httpPort` | number | `9444` | `http` | Bind port for the Streamable HTTP transport (integer `1..65535`) |
| `httpAllowedOrigins` | string[] | `[]` | `http` | Browser origins allowed in addition to loopback hosts and `httpHost` |
| `sseHost` | string | `127.0.0.1` | `sse` | Bind host for the legacy SSE transport |
| `ssePort` | number | `9444` | `sse` | Bind port for the legacy SSE transport (integer `1..65535`) |
| `sseAllowedOrigins` | string[] | `[]` | `sse` | Browser origins allowed in addition to loopback hosts and `sseHost` |
The `*AllowedOrigins` lists are optional and default to an empty list. Each
entry is an origin URL or a bare host; only the host component is compared
(case-insensitively).
CLI flags override config-file values: `--transport`, `--http-host`,
`--http-port`, `--http-allowed-origins`, `--sse-host`, `--sse-port`, and
`--sse-allowed-origins`.
The inheritance system works as follows:
1. Global defaults are applied to all shells
2. Shell-specific overrides replace or extend global settings
3. Array settings (like `blockedCommands`) override defaults when provided.
Specifying an empty array removes all default entries for that setting.
4. Object settings are deep-merged
5. Primitive settings are replaced
Example of inheritance in action:
{
"global": {
"security": { "commandTimeout": 30 },
"restrictions": { "blockedCommands": ["rm", "format"] }
},
"shells": {
"powershell": {
"type": "powershell",
"overrides": {
"security": { "commandTimeout": 45 },
"restrictions": { "blockedCommands": ["Remove-Item"] }
}
}
}
}Results in PowerShell having:
- `commandTimeout`: 45 (overridden)
- `blockedCommands`: ["Remove-Item"] (overrides defaults)
To completely remove defaults for a given restriction, provide an empty array:
{
"global": {
"restrictions": {
"blockedCommands": [],
"blockedArguments": [],
"blockedOperators": []
}
},
"shells": {
"powershell": {
"type": "powershell",
"overrides": {
"restrictions": { "blockedCommands": [] }
}
}
}
}Environment Profiles
Named environment profiles let a single server instance run the same CLI tool under different environment variable sets, selected per call via the optional `profile` parameter on `execute_command`. A common use case is testing the same SQL against different `sqlplus` versions, where each version needs its own `ORACLE_HOME`, `TNS_ADMIN`, and a `PATH` that points at that version's `bin`.
Profiles are defined under an optional top-level `profiles` map. Each entry accepts:
| Field | Type | Required | Description |
|---|---|---|---|
| `env` | object | Yes | Map of environment variable names to string values. Values support `${VAR}` interpolation resolved against the server's environment. |
| `description` | string | No | Human-readable summary surfaced in the `execute_command` tool description. |
| `allowedShells` | string[] | No | Shells this profile may be used with (`cmd`, `powershell`, `gitbash`, `wsl`, `bash`). When omitted, the profile is allowed for every shell. |
{
"profiles": {
"ora19": {
"description": "Oracle 19c sqlplus client",
"allowedShells": ["cmd", "powershell"],
"env": {
"ORACLE_HOME": "C:\\oracle\\product\\19.0.0\\client",
"TNS_ADMIN": "C:\\oracle\\product\\19.0.0\\client\\network\\admin",
"PATH": "C:\\oracle\\product\\19.0.0\\client\\bin;${PATH}"
}
}
}
}Behavior:
- When a profile is selected, its `env` map is merged over the server's environment (`{ ...process.env, ...profileEnv }`) before the command runs.
- `${VAR}` is replaced with the server environment value of `VAR`; an undefined reference resolves to an empty string. This is how `PATH` is prepended (`"C:\\oracle\\product\\19.0.0\\client\\bin;${PATH}"`).
- Profiles are validated at load time: `env` must be a non-empty string-to-string map and every `allowedShells` entry must be a known shell. Invalid profiles abort startup with a descriptive error.
- Selecting an unknown profile, or a profile whose `allowedShells` excludes the requested shell, returns an `InvalidParams` error.
- When no `profiles` are configured, behavior is unchanged and the `profile` parameter is not exposed.
A complete example is provided in `config.examples/profiles.json`. See Configuration Examples for more.
API
Tools
- execute_command
- get_current_directory
- Get the server's active working directory
- If the directory is not set, returns a message explaining how to set it
- set_current_directory
- Set the server's active working directory
- Inputs:
- `path` (string): Path to set as current working directory
- Returns confirmation message with the new directory path, or error message if the change fails
- get_config
- Get the windows CLI server configuration
- Returns the server configuration as a JSON string (excluding sensitive data)
- validate_directories
- Check if specified directories are within allowed paths
- Only available when `restrictWorkingDirectory` is enabled in configuration
- Inputs:
- `directories` (array of strings): List of directory paths to validate
- Returns success message if all directories are valid, or error message detailing which directories are outside allowed paths
Resources
- cli://config
- Returns the main CLI server configuration (excluding sensitive data like blocked command details if security requires it).
- cli://logs/list
- List all stored command execution logs with metadata
- cli://logs/recent?n={count}
- Get the N most recent command logs (default: 5)
- cli://logs/commands/{id}
- Access full output from a specific command execution
- cli://logs/commands/{id}/range?start={n}&end={m}
- Query specific line ranges from a log (supports negative indices)
- cli://logs/commands/{id}/search?q={pattern}&context={n}&occurrence={n}
- Search logs with regex patterns and context lines
Security Considerations
This server allows external tools to execute commands on your system. Exercise extreme caution when configuring and using it.
Built-in Security Features
- Path Restrictions: Commands can only be executed in specified directories (`allowedPaths`) if `restrictWorkingDirectory` is true.
- Command Blocking: Defined commands and arguments are blocked to prevent potentially dangerous operations (`blockedCommands`, `blockedArguments`).
- Injection Protection: Common shell injection characters (`;`, `&`, `|`, `` ` ``) are blocked in command strings if `enableInjectionProtection` is true.
- Timeout: Commands are terminated if they exceed the configured timeout (`commandTimeout`).
- Input validation: All user inputs are validated before execution
- Shell process management: Processes are properly terminated after execution or timeout
Configurable Security Features (Active by Default)
- Working Directory Restriction (`restrictWorkingDirectory`): HIGHLY RECOMMENDED. Limits command execution to safe directories.
- Injection Protection (`enableInjectionProtection`): Recommended to prevent bypassing security rules.
Best Practices
- Minimal Allowed Paths: Only allow execution in necessary directories.
- Restrictive Blocklists: Block any potentially harmful commands or arguments.
- Regularly Review Logs: Check the command history for suspicious activity.
- Keep Software Updated: Ensure Node.js, npm, and the server itself are up-to-date.
Using the MCP Inspector for Testing
Use the Inspector to interactively test this server with a custom config file. Pass any server flags after `--`:
# Inspect with built server and test config
npx @modelcontextprotocol/inspector -- node dist/index.js --config tests/config.json
# Or test the published package
npx @modelcontextprotocol/inspector wcli0 -- --config tests/config.jsonDevelopment and Testing
This project requires Node.js 18 or later.
Running Tests
# Install dependencies
npm install
# Run all tests
npm test
# Run specific test suites
npm run test:validation # Path validation tests
npm run test:wsl # WSL emulation tests
npm run test:integration # Integration tests
npm run test:async # Async operation tests
# Run tests with coverage
npm run test:coverage
# Debug open handles
npm run test:debugCross-Platform Testing
The project uses a Node.js-based WSL emulator (`scripts/wsl-emulator.js`) to enable testing of WSL functionality on all platforms. This allows the test suite to run successfully on both Windows and Linux environments.
Acknowledgments
This project is based on the excellent work by SimonB97 in the win-cli-mcp-server repository. Due to significant configuration differences and architectural changes that made merging back to the source repository challenging, this has been maintained as a separate fork with enhanced features and extensive modifications.
Key enhancements in this version:
- Enhanced inheritance-based configuration system
- Improved WSL support with cross-platform testing
- Advanced security features and path validation
- Comprehensive test coverage with Node.js-based WSL emulation
- Extended documentation and configuration examples
We gratefully acknowledge SimonB97's foundational work that made this project possible.
Development Environment using Dev Containers
This project includes a Dev Container configuration, which allows you to use a Docker container as a fully-featured development environment. This ensures consistency and makes it easy to get started with development and testing.
Prerequisites
- Docker Desktop installed and running.
- Visual Studio Code installed.
- The Dev Containers extension installed in VS Code.
Getting Started
1. Clone this repository to your local machine.
2. Open the repository in Visual Studio Code.
3. When prompted "Reopen in Container", click the button. (If you don't see a prompt, you can open the Command Palette (Ctrl+Shift+P or Cmd+Shift+P) and select "Dev Containers: Reopen in Container".)
4. VS Code will build the dev container image (as defined in `.devcontainer/devcontainer.json` and `Dockerfile`) and start the container. This might take a few minutes the first time.
5. Once the container is built and started, your VS Code will be connected to this environment. The `postCreateCommand` (`npm install`) will ensure all dependencies are installed.
Running Tests in the Dev Container
After opening the project in the dev container:
1. Open a new terminal in VS Code (it will be a terminal inside the container).
2. Run the tests using the command:
npm testThis setup mirrors the environment used in GitHub Actions for tests, ensuring consistency between local development and CI.
License
This project is licensed under the MIT License. See the LICENSE file for details.
Frequently asked questions
What is wcli0?
wcli0 is Enhanced MCP server for Windows CLI interactions with advanced configuration and security features
How do I install wcli0?
Open the GitHub repository and follow its README. Most MCP servers are added to your client's MCP config, then called by your agent.
Is wcli0 open source?
Yes — it is hosted on GitHub at https://github.com/s2005/wcli0 and has 4 stars.
Related MCP tools
Model Context Protocol Servers
The Open-Source Multimodal AI Agent Stack: Connecting Cutting-Edge AI Models and Agent Infra
A MCP for Claude Desktop / Claude Code / Windsurf / Cursor to build n8n workflows for you
MCP server to provide Figma layout information to AI coding agents like Cursor
The world's best AI personal assistant for email. Open source app to help you reach inbox zero fast.
Instant is the best backend for AI-coded apps. You get auth, permissions, storage, presence, and streams — everything you need to ship apps your users will love.
Run your own MCP server? See who uses it and what to fix.
Measure it with TrackMCP