# wsl-exec-mcp **Repository Path**: agstar/wsl-exec-mcp ## Basic Information - **Project Name**: wsl-exec-mcp - **Description**: 基于Rust开发的用于在WSL中执行命令的MCP,可以在 Windows中通过该MCP操作WSL中的文件和命令。不需要通过wsl.exe,不需要命令转义 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-09-04 - **Last Updated**: 2026-09-04 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # wsl-exec-mcp `wsl-exec-mcp` 是运行在 WSL Ubuntu 中的单例本地命令执行 MCP 服务。多个 Windows Codex 客户端通过 Streamable HTTP 连接同一服务,并共享同一个全局命令执行器和并发限制器。 ```text 多个 Windows Codex 客户端 ↓ http://localhost:18765/mcp ↓ WSL 中的 wsl-exec-mcp ↓ /bin/bash -lc ``` 服务只提供一个命令工具 `wsl_bash`,没有普通 REST 命令执行接口。另有 `GET /healthz` 用于健康检查。 ## 特性 - 使用官方 Rust MCP SDK `rmcp 3.1.4` 和 Streamable HTTP Transport。 - 默认只监听 `127.0.0.1:18765`。 - 所有 MCP Session 共享全局 `Semaphore`,默认最多同时运行 5 条命令;超出的命令异步排队。 - 命令直接通过唯一一层 `/bin/bash -lc` 执行,工作目录由 `current_dir()` 设置。 - 默认超时 1800 秒;超时、请求取消或服务关闭时终止整个 Linux 进程组。 - stdout 和 stderr 持续并行读取,合计默认最多保留 20 MiB,非法 UTF-8 使用有损转换。 - 非零退出码是正常工具结果,不会转换为 MCP 协议错误。 - 支持 SIGINT、SIGTERM 和 Ctrl+C 优雅关闭。 - 服务启动时加载 `~/.bashrc` 和 `~/.zshrc` 中通过 `export` 导出的环境变量;普通同名变量以 `.zshrc` 为准,`PATH` 合并两者的绝对路径项。 ## 编译与直接运行 需要 Rust stable;`rmcp 3.1.4` 要求 Rust 1.88 或更高版本。 ```bash cargo build --release cargo run --release ``` 也可以直接运行: ```bash ./target/release/wsl-exec-mcp ``` 默认端点: - MCP:`http://localhost:18765/mcp` - 健康检查:`http://localhost:18765/healthz` 验证健康状态: ```bash curl --fail --silent http://localhost:18765/healthz ``` 正常响应: ```json {"status":"ok"} ``` ## 配置 命令行参数的优先级高于环境变量,环境变量的优先级高于默认值。 | 配置 | 命令行参数 | 环境变量 | 默认值 | |---|---|---|---:| | 监听地址 | `--listen-address` | `WSL_EXEC_LISTEN_ADDRESS` | `127.0.0.1:18765` | | 全局最大并发数 | `--max-concurrency` | `WSL_EXEC_MAX_CONCURRENCY` | `5` | | 命令超时秒数 | `--command-timeout-seconds` | `WSL_EXEC_COMMAND_TIMEOUT_SECONDS` | `1800` | | 合计最大输出字节数 | `--max-output-bytes` | `WSL_EXEC_MAX_OUTPUT_BYTES` | `20971520` | 示例: ```bash WSL_EXEC_MAX_CONCURRENCY=8 \ ./target/release/wsl-exec-mcp \ --max-concurrency 10 \ --command-timeout-seconds 3600 ``` 此时最终并发数是 10。并发数、超时和输出上限必须是正整数,设置为 `0` 或无效值时服务会输出清晰错误并拒绝启动。若非必要,不要将监听地址改为 `0.0.0.0`;此工具没有认证和命令审批机制。 ## MCP 工具 `wsl_bash` 只接受两个参数: ```json { "cwd": "/home/agstar/workspace/ai/ae/skills-management", "command": "go test ./..." } ``` `cwd` 必须是 WSL 内存在的绝对目录。`command` 是完整 Bash 命令,可包含引号、管道、重定向和多行脚本。不要把 `cwd` 写成 `C:\...`,也不要从 Windows Shell 再调用 `wsl.exe`。 成功执行、非零退出和超时都会返回同一结构: ```json { "exit_code": 0, "stdout": "ok example/project\n", "stderr": "", "timed_out": false, "truncated": false, "duration_ms": 1250 } ``` `duration_ms` 不包括等待全局并发许可的时间。参数校验失败、无法启动 Bash 或内部错误才会返回 MCP 工具调用错误。 ### 用户 Shell 环境变量 服务启动时会显式运行交互式 Bash 和 Zsh,依次读取 `~/.bashrc`、`~/.zshrc`,并将其中最终通过 `export` 导出的环境变量注入所有 `wsl_bash` 命令。普通同名变量按以下顺序覆盖: ```text systemd 服务环境 → ~/.bashrc → ~/.zshrc ``` `PATH` 不采用整体覆盖,而是合并 Bash 与 Zsh 的结果,展开残留的 `$VAR` 和 `${VAR}`,去除重复项,并丢弃空项、相对路径及未能展开为绝对路径的错误项。 alias、未导出的普通 Shell 变量、Shell 函数和 zsh 专用选项不会注入 Bash 命令。修改 rc 文件后需要重启服务: ```bash systemctl --user restart wsl-exec-mcp.service ``` ## Codex 配置 先在 WSL 中启动服务,然后在 Windows Codex 配置文件中加入: ```toml [mcp_servers.wsl_exec] url = "http://localhost:18765/mcp" tool_timeout_sec = 1800 required = true ``` `tool_timeout_sec` 是 Codex 客户端等待时间,通常应不小于服务端的命令超时。配置后可用以下任一方式检查连接状态: ```bash codex mcp list ``` 或在 Codex 中输入: ```text /mcp ``` 建议在需要操作的 WSL 项目 `AGENTS.md` 中加入: ```markdown ## WSL 命令执行 本项目的所有构建、测试、Git、包管理和文件系统命令都必须通过 `wsl_bash` MCP 工具执行。 当 `wsl_bash` 可用时,不要通过 PowerShell 或 CMD 调用 `wsl.exe`。 `cwd` 参数必须使用绝对 Linux 路径。 ``` ## systemd 用户服务 这是可选的单例常驻运行方式。用户服务天然以当前普通用户身份运行,不需要也不应使用 root。 先安装二进制和服务文件: ```bash cargo build --release install -Dm755 target/release/wsl-exec-mcp "$HOME/bin/wsl-exec-mcp" install -Dm644 packaging/wsl-exec-mcp.service \ "$HOME/.config/systemd/user/wsl-exec-mcp.service" systemctl --user daemon-reload ``` 启动并设置登录后自动运行: ```bash systemctl --user enable --now wsl-exec-mcp.service ``` 查看状态和日志: ```bash systemctl --user status wsl-exec-mcp.service journalctl --user -u wsl-exec-mcp.service -f ``` 停止或取消自动启动: ```bash systemctl --user stop wsl-exec-mcp.service systemctl --user disable wsl-exec-mcp.service ``` 修改服务文件中的 `Environment=` 后,运行 `systemctl --user daemon-reload` 和 `systemctl --user restart wsl-exec-mcp.service`。WSL 必须已启用 systemd;若希望退出 WSL 登录会话后用户服务仍运行,可按系统策略启用 linger:`loginctl enable-linger "$USER"`。 ## 开发验证 ```bash cargo fmt --all -- --check cargo clippy --all-targets --all-features -- -D warnings cargo test --all cargo build --release ``` 测试覆盖正常执行、非零退出、工作目录、特殊字符、管道、多行命令、超时进程组清理、全局并发排队、配置优先级、输出截断、非法 UTF-8 和标准 Streamable HTTP MCP 初始化/工具发现/调用流程。 ## 限制与安全说明 - 仅支持 Linux/WSL,不执行 Windows 原生命令。 - 不提供认证、审批、命令或目录白名单;应保持环回地址监听。 - 不保存任务历史,服务重启后没有持久状态。 - 输出限制按 stdout 与 stderr 合计计算;达到上限后仍会排空管道,但不再保留后续字节。 - Linux 信号只能保证进程组内的进程被终止;命令若主动创建新的会话或脱离原进程组,可能不再属于该组。