返回 MCP 目录
public公开dns本地运行

mcp-autogui-multinode

一个基于PyAutoGUI的MCP和HTTP服务器包装器,允许LLM通过远程或本地连接控制计算机的鼠标和键盘操作,支持分布式部署和多种传输协议。

article

README

🚀 PyAutoGUI的MCP和HTTP服务器包装器

这是一个用于PyAutoGUI的MCP和HTTP服务器包装器,可让大语言模型(LLMs)控制你的鼠标和键盘。

🚀 快速开始

前提条件

  • Python >= 3.12
  • 推荐使用uv包管理器

安装

  1. 克隆仓库:
git clone https://github.com/stonehill-2345/mcp-autogui-multinode.git
cd mcp-autogui-multinode
  1. 根据你的部署场景安装依赖:

本地全功能开发

适用于具有所有功能(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包管理器

安装步骤

  1. 克隆仓库:
git clone https://github.com/stonehill-2345/mcp-autogui-multinode.git
cd mcp-autogui-multinode
  1. 根据部署场景安装依赖:

本地全功能开发

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服务器支持两种传输模式:

  1. stdio(默认):标准输入/输出传输
    • 用于通过标准输入/输出进行本地通信
    • 适用于与MCP客户端直接集成
    • 启动命令:python mcp_local.py stdio
  2. http:基于HTTP的无状态传输
    • 用于通过HTTP进行远程通信
    • 适用于服务间通信
    • 启动命令:python mcp_local.py http
    • 访问地址:http://localhost:8001/mcp

MCP工具注册模式

该服务支持两种MCP工具注册模式:

  1. 直接工具 (register_computer_tools):直接调用本地计算机控制实现的工具。无需endpoint参数。
    • 用于mcp_local.py中的本地MCP服务器
    • 工具直接执行计算机控制操作
  2. 基于客户端的工具 (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密钥认证,用于保护服务间通信:

  1. 启用认证:在.env文件中设置API_KEY_ENABLED=true
  2. 设置API密钥:在.env文件中配置API_KEY=your-secret-api-key-here
  3. 在请求中传递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

# 创建带API密钥的传输
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参数)

🛠️ 故障排除

端口已被占用

如果你遇到端口已被占用的错误:

# 在.env文件中更改端口
PORT=8002
MCP_PORT=8003

MCP连接问题

对于HTTP传输,确保MCP服务器正在运行且可访问:

# 测试MCP端点
curl http://localhost:8001/mcp

# 使用API密钥测试(如果启用)
curl -H "X-API-Key: your-secret-api-key-here" http://localhost:8001/mcp

对于stdio传输,确保MCP服务器以stdio模式启动:

# 以stdio模式启动MCP服务器
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及其依赖项已正确安装
help

运行方式说明

cloud

托管运行

托管运行通常表示这个 MCP Server 由服务方环境承载,用户一般按页面提供的连接方式或授权流程接入,不需要在本地长期启动一个 MCP 进程

  1. 打开服务方连接页
  2. 完成授权或复制端点
  3. 在 MCP 客户端中连接
terminal

本地运行 / 其它方式

本地运行通常需要用户在自己的电脑或服务器上安装依赖,把 server_config 复制到 MCP 客户端,并按 env_schema 补齐环境变量、密钥或其它配置

  1. 复制 server_config
  2. 安装所需依赖
  3. 补齐环境变量后重启客户端