内容
# 截图 MCP
English | [中文](./README_ZH.md)
使用 **Windows 图形捕获 (WGC)** 进行 OBS 类似的窗口捕获,并支持 **MCP Streamable HTTP** 远程访问。
## 功能特点
- **OBS 风格的窗口捕获** — WGC 直接读取 GPU 缓冲区,对任何窗口状态 **零干扰**
- **HDR 兼容** — BGRA8 和 FP16 格式,支持自动色调映射
- **窗口过滤** — 按进程名称、标题(精确/包含/正则表达式)过滤,支持包含/排除模式
- **MCP Streamable HTTP** — SSE 双向通道,用于远程机器人跨网络调用
- **本地标准输入输出模式** — 与 Claude Desktop / Cursor 等本地 AI 代理兼容
- **获取活动窗口** — 查询当前前景/焦点窗口信息
- **多显示器支持** — 自动检测或指定显示器索引
## 快速入门
```bash
cargo build --release
```
编译输出:`target/release/screenshot-mcp.exe`
### 启动模式
| 模式 | 命令 | 描述 |
|------|---------|-------------|
| **双击启动** | 直接运行 exe | 启动 Streamable HTTP MCP 服务器 (`http://0.0.0.0:3210`) |
| HTTP 模式 | `screenshot-mcp mcp --transport http --port 3210` | 远程访问(默认端口 3210) |
| 标准输入输出模式 | `screenshot-mcp mcp` | 本地 Claude Desktop 集成 |
> **提示:只需双击 `screenshot-mcp.exe` 即可启动服务器,无需任何参数。**
启动后,您将看到:
```
[screenshot-mcp] Listening on http://0.0.0.0:3210 (MCP Streamable HTTP)
[screenshot-mcp] Ready. SSE endpoint: http://0.0.0.0:3210/sse
[screenshot-mcp] Message endpoint: POST http://0.0.0.0:3210/message
```
---
## MCP Streamable HTTP 协议
该服务器遵循 [MCP Streamable HTTP Transport](https://modelcontextprotocol.io/specification/2025-03-26/basic/transports#streamable-http) 规范。
### 协议流程
```
┌──────────┐ GET /sse?sessionId=xxx ┌──────────┐
│ │ ──────────────────────────────────────▶ │ │
│ 客户端 │ SSE 长轮询(接收响应流)│ 服务器 │
│ │ ◀────────────────────────────────────── │ │
│ │ event: message │ │
│ │ data: {jsonrpc response} │ │
│ │ │ │
│ │ POST /message │ │
│ │ ──────────────────────────────────────▶ │ │
│ │ {jsonrpc request} │ │
│ │ ◀──────── 200 OK + sessionId ────────── │ │
└──────────┘ └──────────┘
```
### 端点
| 端点 | 方法 | 描述 |
|----------|--------|-------------|
| `/sse` | GET | SSE 事件流,返回 JSON-RPC 响应。支持 `?sessionId=xxx` 以重用会话 |
| `/message` | POST | 发送 JSON-RPC 请求。响应通过 SSE 推送,HTTP 返回 `sessionId` |
| `/` | GET | 健康检查 |
### 步骤 1:建立 SSE 连接
首先连接到 SSE 端点以监听响应:
```bash
GET http://YOUR_IP:3210/sse
# 响应(SSE 流,保持连接)
Content-Type: text/event-stream
Cache-Control: no-cache
: keepalive ping\n\n
```
> `sessionId` 包含在响应头或第一个消息中 — 在后续请求中包含它。
### 步骤 2:发送初始化请求
```bash
POST http://YOUR_IP:3210/message
Content-Type: application/json
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}
```
**HTTP 响应** (立即返回,包含 sessionId):
```json
{
"sessionId": "sess-1777477748503866700"
}
```
**SSE 响应** (异步推送到连接的 `/sse` 端点):
```json
event: message
data: {"jsonrpc":"2.0","id":1,"result":{"protocolVersion":"2024-11-05","capabilities":{"tools":{}},"serverInfo":{"name":"screenshot-mcp","version":"0.1.0"}}}
```
### 步骤 3:调用工具
#### 截图(核心功能)
```bash
POST http://YOUR_IP:3210/message
Content-Type: application/json
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "screenshot",
"arguments": {
"filters": {
"mode": "include",
"rules": [
{ "type": "process_name", "value": "NZMClient" }
]
},
"format": "png"
}
}
}
```
**SSE 推送结果** (base64 编码的 PNG 图片):
```json
event: message
data: {"jsonrpc":"2.0","id":2,"result":{"content":[{"type":"image","data":"iVBORw0KGgoAAA...","mimeType":"image/png"}]}}
```
#### 获取活动窗口
```bash
POST http://YOUR_IP:3210/message
Content-Type: application/json
{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"get_active_window","arguments":{}}}
```
**SSE 结果**:
```json
event: message
data: {"jsonrpc":"2.0","id":3,"result":{"content":[{"type":"text","text":"{\"active_window\":{\"title\":\"Visual Studio Code\",\"process_name\":\"Code.exe\",\"pid\":9112,\"position\":{\"x\":93,\"y\":148,\"width\":2026,\"height\":963},\"is_visible\":true}}"}]}}
```
#### 列出窗口 / 显示器
```bash
POST http://YOUR_IP:3210/message
Content-Type: application/json
{"jsonrpc":"2.0","id":4,"method":"tools/call","params":{"name":"list_windows","arguments":{}}}
POST http://YOUR_IP:3210/message
Content-Type: application/json
{"jsonrpc":"2.0","id":5,"method":"tools/call","params":{"name":"list_monitors","arguments":{}}}
```
### 可用工具
| 工具 | 描述 | 关键参数 |
|------|-------------|----------------|
| `screenshot` | 截取屏幕/窗口截图(WGC,零干扰) | `filters`, `monitor_index`, `format` |
| `list_windows` | 列出所有可见窗口 | `include_minimized` |
| `get_active_window` | 获取当前前景窗口 | — |
| `list_monitors` | 列出所有连接的显示器 | — |
### 过滤规则格式
```json
{
"filters": {
"mode": "include", // "include" = 只显示匹配项,"exclude" = 隐藏匹配项
"rules": [
{ "type": "process_name", "value": "NZMClient" }, // 按进程名称
{ "type": "title_contains", "value": "Chrome" }, // 标题包含
{ "type": "title_exact", "value": "Notepad" }, // 标题精确匹配
{ "type": "title_regex", "value": "^Edge.*$" } // 正则表达式
]
}
}
```
### 本地集成(Claude Desktop)
添加到 `claude_desktop_config.json`:
```json
{
"mcpServers": {
"screenshot": {
"command": "C:\\path\\to\\screenshot-mcp.exe",
"args": ["mcp"]
}
}
}
```
---
## CLI 调试命令
除了 MCP 接口外,还提供了 CLI 工具用于快速测试:
```bash
# 全屏截图
screenshot-mcp screenshot --output full.png
# 仅捕获特定进程(OBS 风格,排除其他窗口)
screenshot-mcp screenshot --filter-process "NZMClient" --output game.png
# 多个条件(OR 关系)
screenshot-mcp screenshot --filter-process "Code" --filter-title "Edge" --output both.png
# 排除模式(隐藏指定窗口)
screenshot-mcp screenshot --mode exclude --filter-process "NZMClient" --output no_game.png
# 显示当前活动窗口
screenshot-mcp active-window
# 列出所有窗口 / 显示器
screenshot-mcp list-windows
screenshot-mcp list-monitors
```
| 参数 | 描述 | 默认值 |
|-----------|-------------|---------|
| `--monitor <N>` | 显示器索引 | `0` |
| `--output <PATH>` | 输出文件路径 | `screenshot.png` |
| `--format png\|jpeg` | 图片格式 | `png` |
| `--mode include\|exclude` | 过滤模式 | `include` |
| `--filter-process` | 按进程名称过滤(可重复) | — |
| `--filter-title` | 按标题包含过滤 | — |
| `--filter-title-exact` | 按标题精确匹配过滤 | — |
| `--filter-title-regex` | 按标题正则表达式过滤 | — |
---
## 技术架构
```
┌─────────────────────────────────────────────────────┐
│ 远程 AI 机器人 │
│ │
│ ┌──────────┐ GET /sse ┌──────────────────┐ │
│ │ SSE 监听 │ ◀────────── │ │ │
│ │ (响应流)│ │ │ │
│ └──────────┘ │ │ │
│ │ │ │
│ ┌──────────┐ POST /msg │ Axum HTTP │ │
│ │ 发送 │ ───────────▶ │ (Tokio) │ │
│ │ 请求 │ │ │ │
│ └──────────┘ │ CORS + SSE │ │
│ │ /sse + /message │ │
│ 端口: 3210 │ MCP 处理器 │ │
└─────────────────────────────│──────────────────┼─────┘
│ screenshot │
│ get_active_win │
│ list_windows │
│ list_monitors │
├──────────────────┤
│ WGC(windows-capture)│
│ ├── GPU 缓冲区直接 │
│ └── DXGI 备用 │
└────────────────────────┘
```
### 为什么使用 WGC?
| 方法 | DX 内容 | 窗口干扰 | HDR 支持 | 叠加层穿透 |
|----------|-----------|--------------------|----|-----------|
| **WGC** ✅ | ✅ | ❌ 零干扰 | ✅ | ✅ 原生 |
| PrintWindow | ❌ 复合层 | ❌ | ⚠️ | ❌ |
| DXGI + SetWindowPos | ✅ | ❌ 更改 z-order | ⚠️ | ⚠️ 间隙 |
### 依赖项
| Crate | 目的 |
|-------|---------|
| `windows-capture 1.5` | Windows 图形捕获 API 包装器 |
| `windows 0.61` | Win32/DirectX 绑定 |
| `axum 0.7` + `tower-http` | HTTP 服务器(原生 SSE 支持) |
| `tokio 1` | 异步运行时 |
| `async-stream` | SSE 流生成 |
| `image 0.25` | PNG/JPEG 编码 |
**系统要求:** Windows 10 1903+(build 18362)— 由 WGC API 要求。
## 许可证
该项目在 [MIT License](LICENSE) 下许可。