Metadata-Version: 2.4
Name: cvm-vnc
Version: 0.3.0
Summary: Tencent Cloud CVM VNC browser control via agent-browser with MCP server support
Author: Curu
License: MIT
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Provides-Extra: dotenv
Requires-Dist: python-dotenv; extra == "dotenv"
Provides-Extra: mcp
Requires-Dist: mcp[cli]>=1.0.0; extra == "mcp"

# cvm-vnc

通过 `agent-browser` 对 Web VNC 页面进行程序化控制的 Python 工具，支持屏幕截图、文本输入、图片 OCR 和页面状态检测，并提供 MCP (Model Context Protocol) Server 供 AI Agent 集成。

## 功能特性

- **VNC 页面控制** — 打开并操作 Web VNC 界面，兼容腾讯云临时 VNC URL 和 Workbench VNC 页面
- **屏幕截图** — 将 VNC Canvas 捕获为 PNG 图片
- **智能文本输入** — 自动识别输入方式（远程命令对话框 / noVNC 键盘 / Canvas 直接输入等）
- **LLM OCR** — 通过 `cvm-vnc ocr-read` 调用 OpenAI 兼容视觉模型，从本地图片提取文本
- **MCP Server** — 以 stdio 模式运行，供 AI Agent 调用
- **登录检测** — 自动识别 VNC 页面跳转至登录页的场景
- **终端网格估算** — 根据 Canvas 尺寸启发式推算终端行列数

## 安装

### 从 PyPI 安装

```bash
# 基础安装（CLI 功能：open / capture / type / close / ocr-read 等）
pip install cvm-vnc

# 安装 MCP Server 支持（AI Agent 集成必需）
pip install cvm-vnc[mcp]

# 安装全部可选依赖
pip install cvm-vnc[mcp,dotenv]
```

### 从源码安装（开发模式）

```bash
git clone <repo-url>
cd cvm-vnc
pip install -e '.[mcp]'
```

`-e`（editable）模式会将当前源码目录链接为已安装包，修改代码后无需重新安装即可生效。

### 可选依赖说明

| Extra | 包 | 说明 |
|-------|-----|------|
| `mcp` | `mcp[cli]>=1.0.0` | MCP Server 功能（`cvm-vnc mcp` / `cvm-vnc-mcp` 命令必需） |
| `dotenv` | `python-dotenv` | 从 `.env` 文件自动加载环境变量 |

> **注意**：不安装 `mcp` extra 时，CLI 基础命令（`open`、`capture`、`type`、`type-sequence`、`close`、`ocr-read`）仍可正常使用，无需任何第三方依赖。

### 前置依赖

需要系统中安装 [agent-browser](https://www.npmjs.com/package/agent-browser)（Node.js CLI 工具）：

```bash
npm install -g agent-browser
```

## 使用方式

### CLI 命令

```bash
# 打开 VNC 页面
cvm-vnc open <url> [--wait-ms MS] [--session NAME] [--headed]

# 截取 VNC 屏幕
cvm-vnc capture [output] [--session NAME] [--headed]

# 发送文本输入
cvm-vnc type <text> [--enter] [--session NAME] [--headed]

# 批量顺序输入（避免 AI 思考间隙导致登录超时）
cvm-vnc type-sequence --steps-json '<JSON>' [--mode MODE] [--session NAME]

# 关闭浏览器会话
cvm-vnc close [--session NAME]

# 从本地图片读取文本（OpenAI 兼容视觉模型）
cvm-vnc ocr-read <image>

# 启动 MCP Server
cvm-vnc mcp [--session-default NAME] [--mode-default MODE] [--headed]
```

### OCR 识图命令

`ocr-read` 会自动加载当前目录下的 `.env`，然后从以下环境变量读取 LLM 配置：

- `LLM_OCR_BASE_URL`
- `LLM_OCR_API_KEY`
- `LLM_OCR_MODEL`

若缺少 Base URL、API Key 或模型名中的任意一项，命令会在发起请求前直接报错。

```bash
# 方式一：直接导出环境变量
export LLM_OCR_BASE_URL="https://api.example.com"
export LLM_OCR_API_KEY="<your-key>"
export LLM_OCR_MODEL="gpt-4.1-mini"

cvm-vnc ocr-read ./invoice.png

# 方式二：写入 .env 后直接执行
cat > .env <<'EOF'
LLM_OCR_BASE_URL=https://api.example.com
LLM_OCR_API_KEY=<your-key>
LLM_OCR_MODEL=gpt-4.1-mini
EOF

cvm-vnc ocr-read ./screenshot.png
```

成功时只会在 stdout 输出 OCR 文本，便于管道串联；失败时会在 stderr 输出简洁错误信息。

也可通过独立入口直接启动 MCP Server：

```bash
cvm-vnc-mcp
```

### MCP Server Tools

MCP Server 对外暴露以下工具：

| 工具 | 说明 |
|------|------|
| `vnc_open(url, wait_ms, session)` | 打开 VNC 页面 |
| `vnc_status(session)` | 检查页面状态（Canvas 元数据、登录检测等） |
| `vnc_capture(output_path, session)` | 截取 Canvas 为 PNG |
| `vnc_type(text, press_enter, session, mode)` | 发送文本输入 |
| `vnc_type_sequence(steps, session, mode)` | 批量顺序输入（适合系统登录等需要连续输入的场景） |
| `vnc_close(session)` | 关闭浏览器会话，释放资源 |
| `vnc_ocr_read(image_path)` | 读取本地图片文字，返回 OCR 文本 |

### 示例

```bash
# 打开 VNC 并等待页面加载
cvm-vnc open https://vnc.example.com --wait-ms 3000

# 截图保存到文件
cvm-vnc capture /tmp/screen.png

# 执行命令
cvm-vnc type "ls -la" --enter

# 一次性完成系统登录（用户名 + 密码）
cvm-vnc type-sequence --steps-json '[{"text":"root","press_enter":true,"wait_ms":500},{"text":"password","press_enter":true}]'

# 关闭浏览器会话
cvm-vnc close

# 从图片中提取文本
export LLM_OCR_BASE_URL="https://api.example.com"
export LLM_OCR_API_KEY="<your-key>"
export LLM_OCR_MODEL="gpt-4.1-mini"
cvm-vnc ocr-read ./receipt.png
```

## 项目结构

```
src/cvm_vnc/
├── __init__.py        # 版本信息
├── __main__.py        # CLI 入口
├── llm_ocr.py         # OCR 核心实现（配置解析、图片编码、兼容接口调用）
└── vnc_browser.py     # 核心实现（浏览器控制、CLI 分发、MCP Server、JS 注入脚本）
```

## MCP Server 配置

使用 MCP 功能前，请确保已安装 mcp extra：`pip install cvm-vnc[mcp]`

安装完成后，可将 cvm-vnc 作为 MCP Server 接入 AI 客户端。

### Claude Code

```bash
claude mcp add cvm-vnc -- cvm-vnc-mcp
```

添加后可通过以下命令验证：

```bash
claude mcp list
```

### Codebuddy

```bash
codebuddy mcp add cvm-vnc -- cvm-vnc-mcp
```

或手动编辑 `~/.codebuddy/settings.json`：

```json
{
  "mcpServers": {
    "cvm-vnc": {
      "command": "cvm-vnc-mcp"
    }
  }
}
```

> **提示**：如果 `cvm-vnc-mcp` 不在 PATH 中，需使用完整路径，例如 `/path/to/venv/bin/cvm-vnc-mcp`。

## 配置

| 环境变量 | 说明 | 默认值 |
|----------|------|--------|
| `AGENT_BROWSER_BIN` | agent-browser 可执行文件路径 | 自动查找 |
| `LOCK_TIMEOUT` | 会话锁超时时间（秒） | 120 |
| `LLM_OCR_BASE_URL` | `ocr-read` 使用的 OpenAI 兼容接口地址 | 无 |
| `LLM_OCR_API_KEY` | `ocr-read` 使用的 API Key | 无 |
| `LLM_OCR_MODEL` | `ocr-read` 使用的视觉模型名 | 无 |

## Changelog

### v0.3.0

- **兼容 Workbench VNC 页面** — 同时支持腾讯云临时 VNC URL（`img.qcloud.com`）和 Workbench VNC 页面（`workbench.cloud.tencent.com`），两种模式均支持粘贴（快速）输入
- **修复粘贴模式选择器** — 远程命令对话框启动链接选择器从硬编码 `a.copyBtn` 改为通用选择器，适配不同页面变体
- **修复 Shift 符号字符输入** — Canvas 键盘输入路径中 `!@#$%^&*()` 等 Shift 组合符号不再丢失
- **重构粘贴命令模式** — 解决 canvas 渲染未完成就返回的问题，通过 canvas 指纹轮询等待稳定
- **新增 LLM OCR** — 通过 `cvm-vnc ocr-read` 调用 OpenAI 兼容视觉模型从图片提取文本

## License

MIT
