Skip to content

Repository files navigation

VMware Guest Terminal MCP Slim

精简高效地让 AI 通过一个终端入口操作 VMware Windows 虚拟机,就像操作本机终端一样。

VMware Guest Terminal MCP Slim 是一个面向 VMware Windows Guest 的极简 MCP Server。它不暴露大量 VM 管理 API,也不把文件、进程、VM 管理能力拆成一堆工具。默认只给 AI 两个工具:

Tool Purpose
vm_exec(command) 在 VMware Windows Guest 的终端里执行或输入一行命令。
vm_check() 检查 Host MCP Server 与 Guest Agent 是否连通。

核心目标只有一个:把虚拟机当作一台远程 Windows 终端来用。


当前版本

6.3.6-slim-terminal

这个版本的重点是:

  • vm_exec 对 AI 只暴露 一个参数:command
  • 默认使用持久化 PowerShell 终端。
  • 支持交互式输入,例如 Read-Hostcmd set /p、Python REPL。
  • 默认返回干净命令输出,隐藏内部 wrapper、marker 和 shell prompt。
  • 修复 live 测试暴露的 Unicode 输出、CMD set /p 命令 echo、截断标记和布局检查问题。
  • 项目自带开发测试 .env,默认 token 为 0f0a4871befc47e290bc9ff2bc4887f6
  • PowerShell 脚本统一保存为 带 BOM 的 UTF-8,兼容 Windows PowerShell 5.1。
  • MCP 工具面保持极简:只有 vm_execvm_check

架构

Codex / MCP Client
        |
        | HTTP MCP: http://127.0.0.1:18765/mcp
        v
Host MCP Server
        |
        | VMware Shared Folder
        v
Guest Agent inside Windows VM
        |
        v
Persistent Windows terminal session

Host 和 Guest 通过 VMware 共享文件夹交换请求和响应。Guest Agent 在虚拟机内维护持久化终端 session,因此 cd、PowerShell 变量、环境变量、REPL 状态都可以跨多次 vm_exec 调用保留。


前置条件

Host 侧

  • Windows Host
  • VMware Workstation / Player
  • Python 环境,建议 Python 3.10+
  • 已安装依赖:
pip install -r requirements.txt

Guest 侧

  • Windows Guest VM
  • VMware Shared Folders 已启用
  • Guest 能访问类似下面的共享目录:
\\vmware-host\Shared Folders\vmware_mcp_shared

目录结构

.
├─ host/
│  ├─ vmware_mcp_server.py      # Host MCP Server
│  └─ start_server.ps1          # Host 启动脚本
├─ guest/
│  ├─ guest_vm_agent.ps1        # Guest Agent
│  └─ start_agent.ps1           # Guest 启动脚本
├─ scripts/
│  ├─ new_token.ps1             # 生成 token
│  └─ clean_queues.ps1          # 清理请求/响应队列
├─ tests/
│  └─ smoke_test_runner.py      # 目标验收测试
├─ run_server.ps1               # Host 一键启动入口
├─ run_tests.ps1                # 测试入口
├─ requirements.txt
├─ .env                         # 开发测试默认配置,含固定测试 token
├─ .env.example
└─ README.md

快速开始

下面假设项目解压在 Host:

D:\Pyhton_AllEnglish\vmware_mcp

你可以按自己的实际路径替换。


1. 创建 Host 共享目录

在 Host 项目目录下创建:

agent_shared

并把它通过 VMware Shared Folders 共享给 Guest,建议共享名为:

vmware_mcp_shared

Guest 里应能访问:

\\vmware-host\Shared Folders\vmware_mcp_shared

2. 使用默认开发 token

项目根目录已经包含 .env,开发测试阶段默认 token 固定为:

VM_AGENT_TOKEN=0f0a4871befc47e290bc9ff2bc4887f6

这样 Host 和 Guest 测试时不需要每次重新生成、复制和粘贴 token。

如果以后要换 token,仍然可以在 Host 项目目录运行:

powershell.exe -ExecutionPolicy Bypass -File .\scripts\new_token.ps1

然后把 Host 和 Guest 使用的 VM_AGENT_TOKEN 同步改成新值。


3. 配置 Host .env

默认 .env 已可用于开发测试;通常只需要确认共享目录路径符合你的 Host 项目位置:

VM_AGENT_HOST_ROOT=D:\Pyhton_AllEnglish\vmware_mcp\agent_shared
VM_AGENT_TOKEN=0f0a4871befc47e290bc9ff2bc4887f6
VM_AGENT_TIMEOUT_SECONDS=120
VM_AGENT_RESPONSE_GRACE_SECONDS=5
VM_AGENT_POLL_INTERVAL_MS=25
VM_AGENT_MAX_OUTPUT_CHARS=50000
VM_AGENT_KEEP_FILES=0
VM_AGENT_DEFAULT_SESSION=default
VM_AGENT_PERSIST_CWD=1
VM_AGENT_PERSIST_ENV=1

Host 和 Guest 必须使用同一个 VM_AGENT_TOKEN


4. 启动 Guest Agent

Windows Guest VM 内运行:

cd C:\path\to\vmware_mcp

powershell.exe -ExecutionPolicy Bypass -File .\guest\start_agent.ps1 `
  -Root "\\vmware-host\Shared Folders\vmware_mcp_shared" `
  -AllowedRoots "C:\Users\Public;C:\Users\gynzhli;\\vmware-host\Shared Folders\vmware_mcp_shared"

start_agent.ps1 会自动读取项目根目录 .env 里的 VM_AGENT_TOKEN;如果你显式传入 -Token,则以命令行参数为准。

AllowedRoots 用于限制内部文件辅助能力可访问的路径。Slim 模式下 AI 默认看不到文件工具,但仍建议保留限制。


5. 启动 Host MCP Server

Host 项目目录运行:

cd D:\Pyhton_AllEnglish\vmware_mcp

powershell.exe -ExecutionPolicy Bypass -File .\run_server.ps1 `
  -PythonExe "C:\Users\86177\miniconda3\envs\py312\python.exe"

默认 MCP endpoint:

http://127.0.0.1:18765/mcp

6. 配置 Codex MCP

在 Codex 的 config.toml 中添加:

[mcp_servers.vm-terminal]
url = "http://127.0.0.1:18765/mcp"
enabled = true
startup_timeout_sec = 20
tool_timeout_sec = 120

重启 Codex CLI 后检查:

/mcp

应能看到 vm-terminal


使用方式

检查连通性

{}

调用工具:

vm_check

返回中应看到:

{
  "ok": true,
  "server_version": "6.3.6-slim-terminal",
  "agent_version": "6.3.6-slim-terminal"
}

如果 Host 和 Guest 版本不一致,建议完整覆盖两侧文件并重启 Host MCP Server 和 Guest Agent。


vm_exec(command)

vm_exec 就是一个远程 Windows 终端输入框。

最简单用法

{
  "command": "ipconfig"
}

返回示例:

Windows IP Configuration

Ethernet adapter ...

   IPv4 Address. . . . . . . . . . . : 192.168.244.129
   Subnet Mask . . . . . . . . . . . : 255.255.255.0
   Default Gateway . . . . . . . . . : 192.168.244.2

默认不会返回内部 PowerShell wrapper、base64、marker 或 prompt。


终端语义

输入 含义
ipconfig 执行一条命令。
cd C:\Windows 切换目录,状态会保留。
空字符串 "" 读取当前终端已有输出。
^C 中断当前任务;实现上会重置当前 terminal session。
:reset 重启当前 terminal session。

常用示例

PowerShell 命令

{
  "command": "Get-ChildItem C:\\ | Select-Object -First 5"
}

目录保持

{
  "command": "cd C:\\Windows"
}

然后:

{
  "command": "pwd"
}

变量保持

{
  "command": "$x = 123"
}

然后:

{
  "command": "$x"
}

返回:

123

运行 CMD 命令

临时执行一条 CMD 命令:

{
  "command": "cmd /c dir C:\\"
}

进入持久 CMD:

{
  "command": "cmd"
}

然后可以继续输入:

{
  "command": "dir"
}

退出 CMD:

{
  "command": "exit"
}

PowerShell 交互输入

第一次输入:

{
  "command": "$name = Read-Host 'Name'; 'Hello ' + $name"
}

如果返回:

Name:
[waiting]

继续输入:

{
  "command": "Alice"
}

返回:

Hello Alice

CMD set /p

{
  "command": "cmd"
}
{
  "command": "set /p NAME=Name: & echo Hello %NAME%"
}

返回等待输入后:

{
  "command": "Bob"
}

返回:

Hello Bob

Python REPL

{
  "command": "python"
}
{
  "command": "print(1 + 1)"
}

返回:

2

退出:

{
  "command": "exit()"
}

输出规则

默认返回 clean output

会隐藏:

$__vm_mcp_cmd_b64
Invoke-Expression
__VM_MCP_DONE
__VM_MCP_READY
PS C:\...>
C:\...>

正常命令成功时,只返回命令输出。

如果命令返回非 0 exit code,会追加:

[exit code: 1]

如果命令还在运行或等待输入,会追加:

[waiting]

如果命令超时但进程仍在运行,会追加:

[waiting]

测试

确保 Host MCP Server 和 Guest Agent 都已启动,然后在 Host 项目目录运行:

powershell.exe -ExecutionPolicy Bypass -File .\run_tests.ps1 `
  -PythonExe "C:\Users\86177\miniconda3\envs\py312\python.exe"

成功时应看到类似:

=== Summary ===
PASS: 25
WARN: 0
FAIL: 0
ERROR: 0
SKIP: 0

测试报告会写入:

reports/

新版测试脚本是目标验收测试,不只验证已有小功能。它会覆盖:工具面是否只有 vm_exec(command) / vm_check()、Host/Guest 版本一致性、干净输出、PowerShell/CMD 状态保持、多轮交互输入、静默 stdin 等待、空命令读取、^C 中断恢复、Unicode、非零退出码、路径带空格的文件操作、输出截断,以及可选 Python REPL。

离线包检查会用轻量 FastMCP stub 导入 Host 模块,因此不需要先启动 VMware;完整运行 MCP Server 仍需先执行 pip install -r requirements.txt

只做静态/离线包检查时可运行:

powershell.exe -ExecutionPolicy Bypass -File .\run_tests.ps1 `
  -PythonExe "C:\Users\86177\miniconda3\envs\py312\python.exe" `
  -Offline

清理队列

如果请求/响应目录里堆积了旧文件,可以停止 Host 和 Guest 后运行:

powershell.exe -ExecutionPolicy Bypass -File .\scripts\clean_queues.ps1

如果共享目录不在默认位置:

powershell.exe -ExecutionPolicy Bypass -File .\scripts\clean_queues.ps1 `
  -SharedRoot "D:\Pyhton_AllEnglish\vmware_mcp\agent_shared"

升级说明

升级时建议 Host 和 Guest 两侧都覆盖到同一版本。

最容易遗漏的是 Guest 侧:

  1. 覆盖 VM 里的 guest/guest_vm_agent.ps1
  2. 重启 Guest Agent。
  3. 重启 Host MCP Server。
  4. 调用 vm_check() 确认:
{
  "server_version": "6.3.6-slim-terminal",
  "agent_version": "6.3.6-slim-terminal"
}

如果 server_versionagent_version 不一致,说明还有一侧没更新。


故障排查

现象 可能原因 处理方式
/mcp 看不到服务 Codex 没配置 [mcp_servers.vm-terminal],或 Host Server 未启动 检查 Codex 配置和 run_server.ps1
vm_check 返回 token 错误 Host 和 Guest token 不一致 重新设置同一个 VM_AGENT_TOKEN
vm_check 连接不上 Guest VMware Shared Folders 未启用,或路径不一致 确认 Guest 可访问 \\vmware-host\Shared Folders\vmware_mcp_shared
输出里出现 $__vm_mcp / Invoke-Expression 运行的不是 6.3.0 clean output 版本,或 Host/Guest 没重启 覆盖完整包并重启 Host 与 Guest。
命令一直显示 [waiting] 程序在等待输入或长时间运行 继续 vm_exec("") 读输出,输入下一行,或 vm_exec("^C") 中断。
Read-Host 没有继续 没有用下一次 vm_exec 提供输入 再调用一次 vm_exec("你的输入")
中文路径显示异常 控制台编码或原生命令输出编码差异 优先使用 PowerShell 命令;必要时设置 VM 控制台编码。
Guest Agent 启动即 ParserError 且出现乱码字符 .ps1 被 Windows PowerShell 5.1 按 ANSI 解析 确认 .ps1 是带 BOM 的 UTF-8;本包默认已这样保存。

安全说明

  • MCP endpoint 默认绑定 127.0.0.1,不要暴露到公网。
  • Host 与 Guest 必须配置相同 token。
  • Guest 的 AllowedRoots 应尽量限制在必要目录。
  • 这个工具让 AI 可以在 VM 内执行命令,请只在可信项目和隔离 VM 中使用。
  • 删除、写文件等能力不作为 MCP 工具暴露;如需操作文件,请通过终端命令完成。

已知限制

这个项目追求“精简高效”,不是完整 VM 管理平台,也不是完整 ConPTY 终端模拟器。

适合:

  • PowerShell / CMD 命令
  • Python、Node 等 REPL 的基础交互
  • 需要输入确认的 CLI 程序
  • 构建、测试、脚本执行、排查问题

不保证完美支持:

  • vimless 这类全屏 TUI
  • 复杂 ANSI 控制序列
  • 依赖真实窗口尺寸、方向键、鼠标事件的程序
  • 图形安装器或 GUI 程序

设计原则

  1. 工具少:AI 只看到 vm_execvm_check
  2. 参数少vm_exec 只需要一个 command
  3. 输出干净:默认只返回命令结果。
  4. 状态持久:像终端一样保留目录、变量和 REPL 状态。
  5. 失败可诊断:保留测试、日志和队列清理工具。

最小心智模型

把它当成一个远程 Windows 终端:

{"command": "ipconfig"}

要输入什么,就继续发什么:

{"command": "Alice"}

要读输出,发空字符串:

{"command": ""}

要重置,发:

{"command": ":reset"}

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages