🚀 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及其依賴項已正確安裝