trackmcp
Back to directory

Enhanced MCP server for Windows CLI interactions with advanced configuration and security features

4 stars TypeScriptOthers Updated Aug 23, 2026

Documentation

Windows CLI MCP Server (Enhanced)

NPM Downloads
NPM Version

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.

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:

bash
# 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:custom

Bundle Size Comparison

BuildSize ReductionShells Included
FullBaselineAll 5 shells
Windows~40% smallerPowerShell, CMD, Git Bash
Git Bash Only~60% smallerGit Bash
CMD Only~65% smallerCMD
Unix~60% smallerBash

Documentation

For detailed information about the modular architecture:

Quick Start with Specialized Builds

If you only need Git Bash:

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):

bash
# Unix-only build (Bash shell)
npm run build:unix

# The output will be: dist/index.unix-only.js

Starting the Server on macOS

Start the server using npx:

bash
# 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:

json
{
  "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:

json
{
  "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:

OptionTypeDescription
`--shell`stringShell to use (use `bash` or `bash_auto` on Unix)
`--allowedDir`stringAdd an allowed directory (can be used multiple times)
`--config`stringPath to configuration file
`--initialDir`stringInitial working directory
`--allowAllDirs`flagDisable directory restrictions
`--unsafe`flagDisable all safety checks (not recommended)
`--yolo`flagDisable 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:

json
{
  "global": {
    "logging": {
      "maxOutputLines": 20,
      "enableTruncation": true
    }
  }
}

File-Based Log Storage

For persistent logging, configure a log directory:

json
{
  "global": {
    "logging": {
      "logDirectory": "./logs",
      "exposeFullPath": false
    }
  }
}

Or via CLI:

bash
npx wcli0 --shell gitbash --logDirectory ./logs

When 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

json
{
  "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`:

json
{
  "mcpServers": {
    "windows-cli": {
      "command": "npx",
      "args": ["-y", "wcli0"]
    }
  }
}

For use with a specific config file, add the `--config` flag:

json
{
  "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:

    bash
    # 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.json

    The server also accepts an `--initialDir` flag to override the initial

    working directory defined in your configuration file:

    bash
    npx wcli0 --config ./my-config.json --initialDir /path/to/start

    You can override global command limits directly from the CLI:

    bash
    npx wcli0 --config ./my-config.json \
          --maxCommandLength 5000 --commandTimeout 60

    You can configure output truncation and logging via CLI:

    bash
    npx wcli0 --shell gitbash \
          --maxOutputLines 50 \
          --enableTruncation \
          --enableLogResources \
          --maxReturnLines 1000 \
          --logDirectory ./logs
    OptionTypeDefaultDescription
    ----------------------------
    `--maxOutputLines`number20Maximum output lines before truncation
    `--enableTruncation`booleantrueEnable output truncation
    `--enableLogResources`booleantrueEnable log resources for `get_command_output`
    `--maxReturnLines`number500Maximum 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:

    bash
    npx wcli0 --blockedCommand "" --blockedArgument "" --blockedOperator ""

    Provide the flag multiple times to specify values:

    bash
    npx wcli0 --blockedCommand rm --blockedCommand del

    You can also start the server with a specific shell and allowed directories

    without a configuration file:

    bash
    npx wcli0 --shell powershell \
         --allowedDir C:\safe --allowedDir D:\projects

    For WSL shells, you can specify a custom mount location:

    bash
    npx wcli0 --shell wsl \
        --wslMountPoint /windows/

    To disable directory restrictions entirely when no allowed paths are

    configured, start the server with:

    bash
    npx wcli0 --allowAllDirs

    When 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):

    bash
    # YOLO disables all safety checks except allowed working directories
      npx wcli0 --yolo
    
      # Fully unsafe removes all safety checks, including directory limits
      npx wcli0 --unsafe

    Both 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`).

    bash
    # 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
    OptionTypeDefaultDescription
    ----------------------------
    `--transport`stringstdioTransport protocol: `stdio`, `http` (Streamable HTTP), or `sse` (legacy HTTP+SSE)
    `--http-host`string127.0.0.1Host address for the Streamable HTTP transport (`http` mode)
    `--http-port`number9444Port 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`string127.0.0.1Host address for the legacy SSE transport (`sse` mode)
    `--sse-port`number9444Port 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:

    bash
    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 \
        --debug

    CLI 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:

    json
    {
         "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

    json
    {
      "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.

    json
    {
      "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
    json
    {
      "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
    json
    {
      "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
    json
    {
      "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
    json
    {
      "shells": {
        "powershell": {
          "type": "powershell",
          "enabled": true,
          "executable": {
            "command": "powershell.exe",
            "args": ["-NoProfile", "-NonInteractive", "-Command"]
          }
        }
      }
    }
    Shell-Specific Overrides
    json
    {
      "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:

    json
    {
      "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):

    json
    {
      "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):

    json
    {
      "transport": {
        "mode": "sse",
        "sseHost": "127.0.0.1",
        "ssePort": 9444,
        "sseAllowedOrigins": ["https://app.example.com", "192.168.1.10"]
      }
    }
    FieldTypeDefaultApplies toDescription
    `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:

    json
    {
      "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:

    json
    {
      "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:

    FieldTypeRequiredDescription
    `env`objectYesMap of environment variable names to string values. Values support `${VAR}` interpolation resolved against the server's environment.
    `description`stringNoHuman-readable summary surfaced in the `execute_command` tool description.
    `allowedShells`string[]NoShells this profile may be used with (`cmd`, `powershell`, `gitbash`, `wsl`, `bash`). When omitted, the profile is allowed for every shell.
    json
    {
      "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 `--`:

      bash
      # 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.json

      Development and Testing

      This project requires Node.js 18 or later.

      Running Tests

      bash
      # 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:debug

      Cross-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

      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:

      bash
      npm test

      This 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

      Run your own MCP server? See who uses it and what to fix.

      Measure it with TrackMCP