Local Computer Agent MCP
by AblazeGHR
README.md
# Local Computer Agent MCP
**中文 | [English](README.en.md)**
把本机文件、命令行和持久终端通过私人 MCP 连接提供给 ChatGPT Chat,让 Chat 能直接读取代码、修改文件、运行命令、查看结果并继续工作。
面向 **Windows 10 1809+ / Windows 11**。默认使用 **Windows PowerShell 5.1(`powershell.exe`)**,可选择 PowerShell 7 和 Git Bash。复用官方 MCP SDK、官方 filesystem server 和 Microsoft `node-pty`,增加独立会话 worker 与 Cloudflare Access OAuth 接入。项目采用 [MIT License](LICENSE)。
> 想让 agent 帮你配置?复制 [中文一键配置提示词](docs/AGENT_SETUP.zh.md) 给能够操作本机的 coding agent。它会检查环境、收集域名/邮箱、完成部署与验证,最后集中交给你完成浏览器授权。“一键”表示一个任务入口,不承诺绕过 Cloudflare 开户、域名准备或本人登录。
## 能做什么
| 能力 | 说明 |
|---|---|
| 文件读写与编辑 | 读取、覆盖写入、精确替换、目录浏览、文件名搜索、移动、文件属性 |
| 命令结果 | 返回真实输出与退出码;等待超时不会杀命令 |
| 后台命令 | 立即返回会话 ID,之后可继续读输出、发送 stdin |
| 持久交互终端 | 保留变量、cwd、REPL 和交互程序,支持 Ctrl+C 和 resize |
| 独立生命周期 | Chat 断开或 MCP 网关重启后仍可重连原会话 |
| 私人远程接入 | Cloudflare Tunnel + Access Managed OAuth,只允许指定邮箱 |
| 后台自启与恢复 | 当前用户登录后隐藏启动;网关/tunnel 意外退出后自动重启 |
没有鼠标、键盘或截图控制。MCP 提供执行工具;后台任务结束不会主动唤醒 Chat 开始新的推理轮次。
## 完整方案
```mermaid
flowchart LR
Chat[ChatGPT Chat] --> Access[Cloudflare Access / Managed OAuth]
Access --> Tunnel[专用 Cloudflare Tunnel]
Tunnel --> Gateway[本机 Streamable HTTP MCP /mcp]
Gateway --> Files[官方 filesystem server]
Gateway --> Worker[每个会话的独立后台 worker]
Worker --> Shell[PowerShell 5.1 / 7 / Git Bash]
Worker --> Logs[本机状态与分段输出日志]
Login[Windows 用户登录] --> Supervisor[隐藏后台管理器]
Supervisor --> Gateway
Supervisor --> Tunnel
```
Cloudflare 提供公网 HTTPS 和用户 OAuth;真正执行命令的是你的 Windows 用户进程。网关监听 loopback,并验证 Access JWT 的签名、issuer、audience、有效期和允许邮箱。每个终端的 worker 单独运行,网关根据会话 ID 重连,而不是把 shell 生命周期绑定到 Chat 的一次 HTTP 请求。
## 安装前准备
1. 准备 Windows、Node.js **22 或 24**、Git for Windows、cloudflared。PowerShell 5.1 随 Windows 提供;配置脚本需要 **PowerShell 7**,它不改变默认工具 shell。完整集成测试需要这三种 shell。
2. 有一个由 Cloudflare DNS 管理的域名/zone,并选一个未被其他服务使用的子域名,例如 `agent.example.com`。不要直接使用本文示例域名。
3. 在 Cloudflare Zero Trust 中完成组织初始化,得到 `your-team.cloudflareaccess.com` 团队域名,并配置 One-time PIN 邮箱登录或已有身份提供方。脚本检查这些前提,不会代你购买域名、选择付费套餐或修改已有组织。
4. 你的 ChatGPT 账户当前界面支持私人远程 MCP / 自定义 app。先检查是否有相应创建入口;产品套餐和客户端支持以当前账户为准。
官方资料:[cloudflared 下载](https://developers.cloudflare.com/cloudflare-one/networks/connectors/cloudflare-tunnel/downloads/)、[Tunnel 入门](https://developers.cloudflare.com/cloudflare-one/networks/connectors/cloudflare-tunnel/get-started/)、[邮箱 PIN 登录](https://developers.cloudflare.com/cloudflare-one/integrations/identity-providers/one-time-pin/)、[ChatGPT 接入](https://developers.openai.com/plugins/deploy/connect-chatgpt)。本项目不需要模型 API key;域名和账户可能有各自费用,部署脚本不创建付费云计算资源。
### 访问范围
本方案允许被授权的 Chat 使用**当前 Windows 用户的文件与命令权限**。默认文件 roots 是本机可访问的盘符;任意 shell 不受这些 roots 限制。不要把文件目录白名单理解为命令沙箱。建议用普通用户运行;项目不会自动提升到管理员。
## 从零配置
以下命令在 **PowerShell 7** 中执行。将邮箱与域名替换成你自己的值。
### 1. 获取代码与依赖
```powershell
git clone https://github.com/AblazeGHR/chat-local-agent-mcp.git
cd chat-local-agent-mcp
npm ci
node scripts/detect-windows.mjs
npm test
```
测试无需 Cloudflare token、真实域名或 `config.local.json`。它使用独立端口/测试目录,调用真实文件 MCP、Windows shell 和 ConPTY。非 Windows 环境只运行可移植的认证测试,不代表 Windows 功能已验收。
### 2. 准备 Cloudflare API token
创建一个只作用于目标账户和 zone 的自定义 token,赋予:
| 范围 | 权限 |
|---|---|
| Account | `Cloudflare Tunnel Edit` |
| Account | `Access: Apps and Policies Edit` |
| Account | `Access: Organizations Read`、`Access: Identity Providers Read`,或对应的组合 Read 权限 |
| Zone | `Zone Read`、`DNS Edit` |
权限名称和组合选项参见 [Cloudflare 权限表](https://developers.cloudflare.com/fundamentals/api/reference/permissions/)。脚本会读取 zone、Access 应用/策略、组织、身份提供方、tunnel、DNS,并创建专用应用、策略、tunnel、DNS。无需全局 API key 或全账户管理员 token。
用遮蔽输入设置用户环境变量;不要把 token 粘贴进 Chat、源码或命令历史:
```powershell
$secureToken = Read-Host 'Cloudflare API token' -AsSecureString
$plainToken = [System.Net.NetworkCredential]::new('', $secureToken).Password
[Environment]::SetEnvironmentVariable('CLOUDFLARE_API_TOKEN', $plainToken, 'User')
Remove-Variable plainToken, secureToken
```
脚本读取当前进程环境,缺失时读取用户环境。Token 只用于部署,不是 ChatGPT 的登录令牌;配置完成后若不再管理云端资源,可以移除或撤销它,已有 tunnel 运行使用独立凭据。
### 3. 检查并创建云端资源
```powershell
# 只读检查,不创建云端资源、不写入运行配置
./scripts/provision-cloudflare.ps1 -Hostname agent.example.com -AllowedEmails you@example.com
# 正式创建/复用本 checkout 拥有的资源
./scripts/provision-cloudflare.ps1 -Hostname agent.example.com -AllowedEmails you@example.com -Apply
```
脚本先建立仅允许指定邮箱的 Access 应用与 Managed OAuth,再建立专用本地管理 tunnel 和代理 CNAME。默认 MCP/control 端口为 **9752/9753**;被占用时选择其他相邻端口,例如加 `-Port 9852`。新部署的 tunnel 名由 hostname 派生。
已有简单 email-only Access 策略时,可以用 `-ExistingAppName 'Your existing app'` **替代** `-AllowedEmails`,复制允许邮箱;不依赖 Pan,不修改来源应用。
生成的本机文件:
| 文件 | 内容 |
|---|---|
| `config.local.json` | hostname、Access issuer/AUD、允许邮箱、shell 路径与端口 |
| `runtime/tunnel.yml` | hostname → loopback MCP 的 ingress,末尾默认 404 |
| `runtime/tunnel-credentials.json` | 专用 tunnel 凭据 |
| `runtime/cloudflare-resources.json` | 本 checkout 的云端资源 ID,用于识别所有权 |
重复执行同一参数会识别并复用本 checkout 的资源,保留本地运行偏好。若资源属于别的应用、身份策略变化或本机配置不同,脚本拒绝自动覆盖。丢失所有权记录/凭据时不要强行接管;先核对 Cloudflare 资源。多个独立部署请使用独立 clone 与子域名。
脚本目前读取前 50 个可访问 zone、前 100 个 Access 应用与 tunnel;个人账户通常足够,较大账户需扩展分页后使用。中途失败可能留下已创建资源,记录在 `runtime/cloudflare-resources.json`;先检查记录和云端状态再重试。
### 4. 启动与登录自启
```powershell
npm run service:start
npm run status
./scripts/install-autostart.ps1
```
管理器、网关与 tunnel 隐藏后台运行,关闭启动终端不会停止它们。当前用户 Startup 目录的 `ChatLocalAgentMCP.vbs` 在**用户登录后**启动管理器;这不是未登录时的系统级开机服务。管理器在子进程退出后等待 3 秒重新启动。
### 5. 在 ChatGPT 创建私人连接
1. 在 **ChatGPT 网页端**找到自定义 app/MCP 创建入口,按账户界面要求启用 Developer mode。
2. 名称填 `Local Computer Agent`,URL 填 `https://agent.example.com/mcp`,认证选 **OAuth**。完整 URL 必须包含 `/mcp`。
3. 完成本人邮箱/身份提供方登录与授权。支持动态客户端注册的流程不需要手工 Client ID/Secret;不要填 Cloudflare API token。
4. 创建新 Chat 并选中连接,发送:
> 调用 computer_info,然后用默认 shell 执行 `$PSVersionTable.PSVersion.ToString()` 和 `Write-Output 'MCP 中文验收成功'`,报告真实输出与退出码。再后台执行 `Start-Sleep -Seconds 5; Write-Output '后台完成'; exit 7`,用会话 ID 读至结束并报告退出码。
网页接入完成后再核对桌面客户端是否能选择连接。看到连接名称不等于工具已发现;本人授权、`tools/list` 和实际调用才是客户端证据。
## Cloudflare 配置细节与手工核对
方案使用命名的**本地管理 tunnel**,不运行 quick tunnel,也不复用其他服务的 tunnel。`runtime/tunnel.yml` 指向 `127.0.0.1:9752`,不会开放本机 LAN 端口。公网 hostname 有独立 Access 应用、email Allow 策略和 AUD。
Managed OAuth 配置启用 DCR,允许 ChatGPT 回调:
```text
https://chatgpt.com/connector_platform_oauth_redirect
https://chatgpt.com/connector/oauth/*
```
还允许 localhost/loopback 客户端;Access token lifetime 为 15 分钟,grant session 为 24 小时。回调和产品支持会变化,出错时核对 [当前 Managed OAuth 文档](https://developers.cloudflare.com/cloudflare-one/access-controls/applications/http-apps/managed-oauth/) 与实际客户端请求,不直接放开所有回调或删除认证。
客户拿到的是 OAuth token;Cloudflare 校验后向 origin 注入签名 `Cf-Access-Jwt-Assertion`。网关验证该 JWT 的 RS256、公钥、issuer、AUD、expiry、subject 与邮箱。仅存在 header 不算身份通过。
## 工具与使用
共 **19 个工具**:
| 工具 | 用途 |
|---|---|
| `computer_info` | 发现平台、shell、cwd、访问范围与生命周期 |
| `read` / `read_multiple_files` | 读取 UTF-8 文件;`read` 支持 `head`、`tail` |
| `write` | 覆盖写入 UTF-8 文件 |
| `edit` | 精确替换,校验匹配次数/可选 SHA-256,保留 BOM/CRLF |
| `list_directory` / `directory_tree` | 目录与目录树 |
| `create_directory` / `move_file` | 创建目录、移动/重命名 |
| `search_files` / `get_file_info` | 文件名模式搜索、属性 |
| `shell` | 一次性命令,等待或后台返回,保留 stdin/output |
| `terminal_start` | 保留变量/cwd 的交互 PTY |
| `session_read` / `session_write` | 分页读输出、继续发送输入 |
| `session_list` | 找回跨 Chat/网关重启会话 |
| `session_interrupt` / `session_resize` | Ctrl+C、调整尺寸 |
| `session_close` | 终止该会话进程树,保留记录 |
文件工具使用绝对路径。`search_files` 搜索文件名;内容搜索用 shell 的 `rg` 或 `Select-String`。`edit` 的 oldText 必须精确匹配,默认预期 1 次;匹配不唯一时不写入。
```json
{"command":"Write-Output '你好'; exit 0","shell":"powershell","mode":"wait","waitMs":1000}
```
`shell` 可选 `powershell`(5.1)、`powershell7`、`git-bash`。`waitMs` 最多 20 秒;超时返回 `running` 和会话 ID,不终止进程。显式用 `exit N` 设定退出码;PowerShell 原生程序若需传播其状态,使用 `exit $LASTEXITCODE`。
```json
{"command":"Start-Sleep -Seconds 10; Write-Output '完成'; exit 7","mode":"detach","requestId":"task-001"}
```
detach 立即返回 ID,随后用 `session_read` 获取结果。重试相同启动请求时复用 `requestId`;不同请求复用同一 ID 会被拒绝,省略 ID 则每次新建进程。
保留变量、cwd、Read-Host、SSH 或 REPL 时,使用 `terminal_start` → `session_write` → `session_read`。输入默认 `newline=true`;原始键输入设为 `false`。PTY 有 ANSI 控制符、回显和提示符,安静不代表命令完成;PTY 的 exitCode 是整个终端的退出码,单命令验收宜用 `shell`。更多约定见 [CHAT_INSTRUCTIONS.md](CHAT_INSTRUCTIONS.md)。
## 生命周期、管理与卸载
| 情况 | 结果 |
|---|---|
| Chat 关闭、HTTP 断开、网关重启/崩溃 | 独立会话继续运行,可以重连 |
| `service:stop` | 停管理器/网关/tunnel,保留会话 |
| `session_close` | 结束该会话进程树,保留日志 |
| Windows 注销/重启、worker 被终止 | 原进程与变量不保留,已保存输出仍在 |
`session_read` 的 offset/nextOffset 是 **UTF-8 字节游标**。每次下一页使用返回的 nextOffset。默认每会话保留最近约 64 MiB;旧段淘汰后返回 baseOffset/outputEvicted。默认一页 64 KiB,最多 256 KiB。无法联系 worker 时报告 unreachable,不伪报完成、不猜测 PID 并终止它。
默认最多 32 个可联系的活跃会话。完成记录、测试夹具和服务日志不自动清理;关闭闲置终端,确认历史会话结束后手工归档。代码更新后旧 worker 使用创建时版本,worker 更新需新建会话。
```powershell
npm run status
npm run service:start
npm run service:stop
npm run service:restart
node src/manage.mjs restart-gateway
./scripts/install-autostart.ps1 -Remove
```
最后一条仅移除自启,不停止服务。要卸载:先关闭所需会话,移除自启并停止服务,再根据所有权记录手工删除专用 Cloudflare 应用、DNS 和 tunnel。不要删除其他服务的资源。移动安装目录前先移除旧自启入口,之后在新目录重新安装。前台调试 `npm start` 前先停止管理器,避免端口竞争。
## 验证与排错
```powershell
npm test
# 部署后的完整生命周期检查:会短暂停止/重启本项目服务,需要已安装自启
node scripts/verify-live.mjs
```
集成测试覆盖文件编辑、三种 shell 中文与退出码、交互输入、输出轮转、启动去重、网关死亡后恢复、Ctrl+C 与关闭进程树。`verify-live.mjs` 额外检查管理器停止/启动、实际 VBS 自启入口、watchdog 和公网 OAuth 发现;使用本机管理令牌,**不代表 ChatGPT 本人 OAuth 已通过**。它写入忽略的 `runtime/live-acceptance.json`。
| 现象 | 检查 |
|---|---|
| 缺少 token/403 | token 是否在 process/User 环境,权限是否覆盖目标账户/zone |
| 缺少 Zero Trust/登录方式 | 完成组织与邮箱 PIN/IdP 前置设置 |
| 端口占用 | 查监听所属进程,选择新的端口对;不要直接杀其他服务 |
| tunnel 进程有但公网不通 | 看 `runtime/tunnel.stderr.log` 中 Registered tunnel connection、DNS、ingress、本机 `/health` |
| 公网未授权 401 | 预期行为;应带 OAuth resource_metadata challenge |
| OAuth 元数据错误 | 核对 `https://你的域名/.well-known/oauth-authorization-server` 和应用 Managed OAuth |
| 授权成功、工具发现失败 | 检查网关日志、Host/Origin、完整 `/mcp` URL、initialize/tools/list |
| 中文乱码 | 使用正确 shell 和 UTF-8,PowerShell 5.1 脚本含 BOM;PTY 回显有控制符 |
| 登录后没自启 | 核对 Startup VBS、目录是否移动、Windows 是否允许 WScript;检查 supervisor 日志 |
| worker unreachable | 使用保存输出诊断;重启/注销不能恢复原进程 |
运行状态 `npm run status` 不等于公网或 Chat 可用,逐层核验。没有进行 Windows 注销/重启测试时,不把执行 VBS 的证明称为真实重启证明。
## 开源与隐私
`config.local.json`、`runtime/`、`.env`、node_modules 不入 Git。runtime ACL 限制到当前用户、SYSTEM 与 Administrators。审计只记录工具名/时间/耗时/失败标志,命令本身与输出可能保存在会话目录。发布前检查暂存内容;不要把日志、真实域名/邮箱、token 或 tunnel secret 放入 issues。详见 [SECURITY.md](SECURITY.md)。
项目选型与源码调查见 [RESEARCH.md](RESEARCH.md)。欢迎提交带复现步骤的 issue/PR;说明 Windows、Node、shell 版本与脱敏日志。GitHub Actions 在 Windows 上运行 Node 22/24 测试,不使用个人 Cloudflare 凭据。
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues