🚀 PyAutoGUI的MCP和HTTP服务器包装器
这是一个用于PyAutoGUI的MCP和HTTP服务器包装器,可让大语言模型(LLMs)控制你的鼠标和键盘。
🚀 快速开始
前提条件
- Python >= 3.12
- 推荐使用
uv包管理器
安装
- 克隆仓库:
git clone https://github.com/stonehill-2345/mcp-autogui-multinode.git
cd mcp-autogui-multinode
- 根据你的部署场景安装依赖:
本地全功能开发
适用于具有所有功能(GUI控制 + 测试)的本地开发:
uv sync --group gui --group dev
仅部署MCP服务器
用于部署连接到远程工具服务的MCP服务器(无需GUI依赖):
uv sync --no-group gui
仅部署工具服务
用于部署执行实际计算机控制的HTTP工具服务(需要GUI):
uv sync --group gui
运行服务
该服务支持两个独立的服务器:
1. 运行工具服务(HTTP API)
启动用于计算机控制的HTTP API服务器:
uv run python tool.py
2. 运行MCP服务器
启动可连接到远程工具服务的MCP服务器。该服务器支持两种传输模式:
HTTP传输模式:
uv run python mcp_local.py http
stdio传输模式(默认):
uv run python mcp_local.py stdio
启动后,你可以访问:
- HTTP API文档:http://localhost:8000/docs
- 健康检查:http://localhost:8000/health
- MCP端点:http://localhost:8001/mcp(如果使用HTTP传输)
✨ 主要特性
- 🚀 双协议支持:HTTP REST API和MCP(模型上下文协议)
- 🔐 API密钥认证:可选的API密钥认证,用于服务间通信
- 🌐 多种MCP传输方式:支持HTTP和stdio(标准输入/输出)传输模式
- 🖱️ 鼠标控制:移动、点击、拖动、滚动操作
- ⌨️ 键盘控制:按键、输入文本、组合键
- 📸 截图:捕获屏幕并获取Base64编码的图像
- 📊 屏幕信息:获取光标位置和屏幕分辨率
- ⚙️ 配置管理:支持环境变量的Pydantic设置
- 📝 自动文档:HTTP API的Swagger UI
- 🔧 灵活部署:可独立运行HTTP服务器或MCP服务器
- 📋 请求追踪:用于请求跟踪的请求ID中间件
- 📝 结构化日志:基于Loguru的日志记录,集成请求ID
- 🔌 远程MCP支持:可选的HTTP客户端,用于远程工具服务器集成
📦 安装指南
前提条件
- Python >= 3.12
- 推荐使用
uv包管理器
安装步骤
- 克隆仓库:
git clone https://github.com/stonehill-2345/mcp-autogui-multinode.git
cd mcp-autogui-multinode
- 根据部署场景安装依赖:
本地全功能开发
uv sync --group gui --group dev
仅部署MCP服务器
uv sync --no-group gui
仅部署工具服务
uv sync --group gui
💻 使用示例
基础用法
移动鼠标
curl -X POST "http://localhost:8000/api/computer/MoveMouse" \
-H "Content-Type: application/json" \
-H "X-API-Key: your-secret-api-key-here" \
-d '{"x": 100, "y": 200}'
点击鼠标
curl -X POST "http://localhost:8000/api/computer/ClickMouse" \
-H "Content-Type: application/json" \
-H "X-API-Key: your-secret-api-key-here" \
-d '{"x": 100, "y": 200, "button": "left"}'
截图
curl -X POST "http://localhost:8000/api/computer/TakeScreenshot" \
-H "Content-Type: application/json" \
-H "X-API-Key: your-secret-api-key-here" \
-d '{}'
获取光标位置
curl -X POST "http://localhost:8000/api/computer/GetCursorPosition" \
-H "Content-Type: application/json" \
-H "X-API-Key: your-secret-api-key-here" \
-d '{}'
注意:如果API_KEY_ENABLED=false,则X-API-Key头是可选的。如果API_KEY_ENABLED=true,则除健康检查和文档端点外的所有请求都需要该头。
📚 详细文档
API端点
基础端点
GET / - 根路径,返回API信息
GET /health - 健康检查端点
计算机控制端点
所有计算机控制操作都可通过以下端点访问:
POST /api/computer/{action} - 执行计算机控制操作
GET /api/computer/actions - 列出所有可用操作
可用操作
| 操作 |
描述 |
参数 |
MoveMouse |
移动鼠标光标 |
x, y(坐标) |
ClickMouse |
点击鼠标按钮 |
x, y, button, press, release |
PressMouse |
按下鼠标按钮(按住) |
x, y, button |
ReleaseMouse |
释放鼠标按钮 |
x, y, button |
DragMouse |
从源位置拖动鼠标到目标位置 |
source_x, source_y, target_x, target_y |
Scroll |
滚动鼠标滚轮 |
scroll_direction, scroll_amount, x, y |
PressKey |
按下键盘键 |
key(例如,"enter", "ctrl c") |
TypeText |
输入文本(使用剪贴板) |
text |
Wait |
等待一段时间 |
duration(毫秒) |
TakeScreenshot |
捕获屏幕 |
(无参数) |
GetCursorPosition |
获取鼠标位置 |
(无参数) |
GetScreenSize |
获取屏幕分辨率 |
(无参数) |
MCP工具
可用MCP工具
所有HTTP API操作都可作为MCP工具使用。MCP工具名称使用蛇形命名法,而HTTP API使用帕斯卡命名法:
move_mouse - 移动鼠标光标(HTTP: MoveMouse)
click_mouse - 点击鼠标按钮(HTTP: ClickMouse)
press_mouse - 按下鼠标按钮(HTTP: PressMouse)
release_mouse - 释放鼠标按钮(HTTP: ReleaseMouse)
drag_mouse - 拖动鼠标(HTTP: DragMouse)
scroll - 滚动鼠标滚轮(HTTP: Scroll)
press_key - 按下键盘键(HTTP: PressKey)
type_text - 输入文本(HTTP: TypeText)
wait - 等待一段时间(HTTP: Wait)
take_screenshot - 截图(HTTP: TakeScreenshot)
get_cursor_position - 获取光标位置(HTTP: GetCursorPosition)
get_screen_size - 获取屏幕大小(HTTP: GetScreenSize)
MCP传输模式
MCP服务器支持两种传输模式:
- stdio(默认):标准输入/输出传输
- 用于通过标准输入/输出进行本地通信
- 适用于与MCP客户端直接集成
- 启动命令:
python mcp_local.py stdio
- http:基于HTTP的无状态传输
- 用于通过HTTP进行远程通信
- 适用于服务间通信
- 启动命令:
python mcp_local.py http
- 访问地址:
http://localhost:8001/mcp
MCP工具注册模式
该服务支持两种MCP工具注册模式:
- 直接工具 (
register_computer_tools):直接调用本地计算机控制实现的工具。无需endpoint参数。
- 用于
mcp_local.py中的本地MCP服务器
- 工具直接执行计算机控制操作
- 基于客户端的工具 (
register_computer_tools_with_client):使用HTTP客户端调用远程工具服务器的工具。需要endpoint参数。
- 用于
mcp_server/register.py中的远程MCP服务器
- 工具通过HTTP将请求转发到远程工具服务
本地MCP服务器 (
mcp_local.py) 默认使用直接工具。远程MCP服务器使用基于客户端的工具。
代码风格
- 为所有函数参数和返回类型使用类型提示
- 遵循PEP 8风格指南
- 为所有公共函数使用描述性文档字符串
- 保持函数功能单一
🔧 技术细节
架构
该服务支持两种部署架构:
LLM -> MCP -> TOOL (远程工具服务)
此架构将MCP服务器与工具服务分离,允许MCP服务器通过HTTP连接到远程工具服务。
graph LR
LLM[LLM客户端] -->|MCP协议| MCP[MCP服务器<br/>main.py<br/>基于客户端的工具]
MCP -->|HTTP API<br/>带API密钥| TOOLA[工具服务<br/>tool.py<br/>HTTP API服务器]
MCP -->|HTTP API<br/>带API密钥| TOOLB[工具服务<br/>tool.py<br/>HTTP API服务器]
TOOLA -->|PyAutoGUI| COMPUTERA[计算机控制]
TOOLB -->|PyAutoGUI| COMPUTERB[计算机控制]
style LLM fill:#e1f5ff
style MCP fill:#fff4e1
style TOOLA fill:#ffe1f5
style COMPUTERA fill:#e1ffe1
style COMPUTERB fill:#e1ffe1
特点:
- MCP服务器使用基于客户端的工具 (
register_computer_tools_with_client)
- MCP服务器通过HTTP将请求转发到远程工具服务
- 工具服务执行实际的计算机控制操作
- 适用于MCP服务器和工具服务在不同机器上运行的分布式部署
- MCP工具调用需要
endpoint参数
架构2: LLM -> MCP (直接工具)
此架构使用直接工具,MCP服务器直接执行计算机控制操作。
graph LR
LLM[LLM客户端] -->|MCP协议<br/>stdio/http| MCP[MCP服务器<br/>mcp_local.py<br/>直接工具]
MCP -->|PyAutoGUI| COMPUTER[计算机控制]
style LLM fill:#e1f5ff
style MCP fill:#fff4e1
style COMPUTER fill:#e1ffe1
特点:
- MCP服务器使用直接工具 (
register_computer_tools)
- MCP服务器直接执行计算机控制操作
- 无需单独的工具服务
- 适用于所有组件在同一台机器上运行的本地部署
- MCP工具调用无需
endpoint参数
📄 许可证
MIT许可证
🤝 贡献
欢迎贡献代码!请随时提交拉取请求。
⚠️ 安全注意事项
本服务可直接控制计算机的鼠标和键盘,请谨慎使用:
- 仅在受信任的网络上运行
- 在生产环境中限制CORS来源(目前允许所有来源)
- 启用API密钥认证:在生产环境中设置
API_KEY_ENABLED=true并配置强API_KEY
- 注意远程计算机控制的安全影响
API密钥认证
该服务支持可选的API密钥认证,用于保护服务间通信:
- 启用认证:在
.env文件中设置API_KEY_ENABLED=true
- 设置API密钥:在
.env文件中配置API_KEY=your-secret-api-key-here
- 在请求中传递API密钥:在请求头中包含API密钥:
X-API-Key: your-secret-api-key-here(推荐)
Authorization: Bearer your-secret-api-key-here(可选)
排除路径(无需认证):
/health - 健康检查端点
/docs - API文档
/openapi.json - OpenAPI模式
/redoc - 替代API文档
使用API密钥的MCP客户端示例:
from fastmcp import Client
from fastmcp.client.transports import StreamableHttpTransport
transport = StreamableHttpTransport(
url="http://localhost:8001/mcp",
headers={"X-API-Key": "your-secret-api-key-here"}
)
client = Client(transport)
async with client:
response = await client.call_tool("move_mouse", {"x": 100, "y": 200})
📝 日志记录
该服务使用Loguru进行结构化日志记录,具有以下特点:
- 请求ID跟踪:每个请求都有一个唯一的ID,出现在所有日志条目中
- 环境感知:开发环境中输出到控制台,生产环境中记录到文件
- 结构化格式:包括时间戳、级别、请求ID、模块、函数和行号
日志文件存储在
logs/目录中:
app_YYYY-MM-DD.log:一般应用程序日志
error_YYYY-MM-DD.log:仅错误日志
在开发模式下,日志仅输出到控制台。在生产模式下,日志同时输出到控制台和文件。
🧪 测试
使用pytest运行测试:
uv pytest
uvpytest tests/test_mcp_client.py
pytest -v
测试套件包括:
test_local_mcp_client.py:使用HTTP传输的本地MCP服务器测试(直接工具)
test_stdio_mcp_client.py:使用stdio传输的本地MCP服务器测试(直接工具)
test_mcp_client.py:使用基于客户端工具的远程MCP服务器测试(需要endpoint参数)
🛠️ 故障排除
端口已被占用
如果你遇到端口已被占用的错误:
PORT=8002
MCP_PORT=8003
MCP连接问题
对于HTTP传输,确保MCP服务器正在运行且可访问:
curl http://localhost:8001/mcp
curl -H "X-API-Key: your-secret-api-key-here" http://localhost:8001/mcp
对于stdio传输,确保MCP服务器以stdio模式启动:
uv python mcp_local.py stdio
API密钥认证问题
如果你遇到认证错误:
- 验证
.env文件中API_KEY_ENABLED设置是否正确
- 检查客户端和服务器的
API_KEY是否匹配
- 确保API密钥在
X-API-Key头或Authorization: Bearer <key>头中传递
- 检查请求路径是否不在排除路径列表中
截图问题
如果截图功能失败:
- 检查Python版本兼容性(需要Python >= 3.12)
- 验证macOS/Linux上的显示权限
- 确保PyAutoGUI及其依赖项已正确安装