เครื่องมือควบคุมและจัดการหน้าจอระบบ Windows ผ่าน Antigravity (AI Agent) โดยออกแบบสถาปัตยกรรม Daemon-Client เพื่อความปลอดภัย ความโปร่งใส และให้การควบคุมทั้งหมดอยู่ภายใต้สิทธิ์ของผู้ใช้อย่างสมบูรณ์
Local Windows GUI automation for AI agents via MCP (Cursor / Antigravity) or CLI. A visible overlay daemon (127.0.0.1:8000) must be started manually before any control. 33 MCP tools — screenshot, click, web (Playwright), OCR, window/a11y, launch_app, etc.
Quick start: clone → uv sync → edit MCP config --directory to your clone path → uv run src/daemon.py → configure .cursor/mcp.json from mcp_config/cursor.example.json.
Thai guides: USAGE_GUIDE.md · Security: SECURITY.md · Maintainer checklist: docs/PUBLISHING.md
| อยากรู้ / ทำอะไร | อ่านไฟล์ |
|---|---|
| กฎก่อนให้ AI แก้โปรเจกต์ | RULES.md |
| ติดตั้ง, คำสั่ง CLI/MCP ครบ | ไฟล์นี้ (README.md) |
| สั่ง AI: "อยากทำ X ใช้ tool อะไร" | USAGE_GUIDE.md |
| AI ควบคุมจอ (daemon, MCP, sensitive) | SKILL.md |
| แก้ปัญหา / พฤติกรรมระบบ | TROUBLESHOOTING.md |
| ความปลอดภัย (local / localhost) | SECURITY.md |
| Checklist ก่อน push GitHub | docs/PUBLISHING.md |
| แผนงานปัจจุบัน + backlog | implementation_plan.md |
| ประวัติ CP1–CP7 (archive) | docs/archive/implementation_plan_cp1-cp7.md |
| ประวัติ CP8–CP12 (archive) | docs/archive/implementation_plan_cp8-cp12.md |
เริ่มจาก RULES.md ถ้าจะให้ AI แก้โปรเจกต์ · สั่งงานประจำวันดู USAGE_GUIDE.md
- Daemon-Client Architecture:
- Daemon (
src/daemon.py): รันหน้าต่างเตือนภัยโปร่งแสง (Always on top) แสดงให้เห็นชัดเจนว่ากำลังควบคุมหน้าจออยู่ และเป็น HTTP API Server (bind เฉพาะ127.0.0.1เพื่อความปลอดภัย — ไม่เปิดให้เครื่องอื่นในเครือข่ายเข้ามา) - CLI Client (
src/cli.py): เครื่องมือคอมมานไลน์สำหรับส่งคำสั่งจาก AI หรือ Terminal เข้ามาประมวลผลที่ Daemon
- Daemon (
- Visual Overlay & Emergency Control:
- แถบสถานะลอยตัวบนหน้าจอสีแดงเด่นชัดเตือนว่า "หน้าจอถูกควบคุม"
- ปุ่ม STOP บนหน้าต่าง และการดักจับปุ่ม Escape (Esc) ค้างประมาณ 0.5 วินาที จะตัดการเชื่อมต่อและปิดการทำงานของระบบควบคุมทันที (Emergency Abort) — การกด Esc สั้นๆ ตามปกติเพื่อปิด modal/ออกจาก search ไม่กระทบ การทำงานของ daemon
- Precision Grid Overlay:
- สามารถจับภาพหน้าจอและสร้างภาพซ้อนเส้นพิกัด X, Y (Grid Lines) ช่วยให้ AI ประเมินพิกัดปุ่มและตำแหน่งที่จะคลิกได้แม่นยำ 100%
- รองรับ Windows Display Scaling > 100% โดยอัตโนมัติ (Per-Monitor-V2 DPI Awareness) ภาพที่จับมากับพิกัดที่ AI สั่งคลิกจะตรงกันเสมอ
- Sensitive Action Filter:
- ระบบคัดกรองคำสั่งความเสี่ยงสูง (เช่น การเงิน การซื้อสินค้า ลบไฟล์ รหัสผ่าน) โดยจะหยุดรอและแสดงป๊อปอัปให้ผู้ใช้คลิก "อนุญาต" หรือ "ปฏิเสธ" บนหน้าจอก่อนลงมือจริงเสมอ
- หากผู้ใช้ไม่ตอบภายใน 110 วินาที ระบบจะถือว่าปฏิเสธโดยปริยายและคืน 403
- Activity Log:
- บันทึกการทำงานและผลลัพธ์ทุกคำสั่งในรูปแบบ JSON Lines ที่อ่านเข้าใจง่ายในไฟล์
logs/activity_log.jsonl - เพื่อความปลอดภัย เนื้อหาของข้อความที่พิมพ์ (
type) และคำค้น (web_play_music) จะถูกแทนที่ด้วยtext_lengthใน metadata เพื่อไม่ให้รหัสผ่านรั่วลงไฟล์ log
- บันทึกการทำงานและผลลัพธ์ทุกคำสั่งในรูปแบบ JSON Lines ที่อ่านเข้าใจง่ายในไฟล์
computer-control/ # โฟลเดอร์ที่ clone (path ใดก็ได้)
├── logs/
│ └── activity_log.jsonl # สร้างตอนรัน (ไม่ commit — ดู .gitignore)
├── screenshots/
│ ├── screen_xxxx.png # ไฟล์จับภาพหน้าจอ + ภาพ Grid
│ ├── _latest.png # screenshot ล่าสุดสำหรับ MCP inline image
│ └── window_xxxx.png # screenshot เฉพาะ window (CP4)
├── src/
│ ├── cli.py # CLI Client สำหรับสั่งงาน daemon
│ ├── daemon.py # Tkinter overlay + HTTP API + sensitive/rate-limit/highlight
│ ├── mcp_server.py # MCP stdio server สำหรับ Cursor / Antigravity 2.0 (CP2)
│ ├── window_utils.py # pygetwindow + uiautomation wrapper (CP4)
│ ├── ocr_utils.py # Windows OCR (winocr) wrapper (CP5)
│ └── utils.py # Sensitive keywords + Grid overlay drawer
├── mcp_config/
│ ├── cursor.example.json # ตัวอย่าง config สำหรับ .cursor/mcp.json
│ └── antigravity.example.json # ตัวอย่าง config สำหรับ Antigravity 2.0
├── scratch/
│ ├── test_cp2.py # Harness ทดสอบ MCP Server Layer (14/14)
│ ├── test_cp3.py # Harness ทดสอบ Action Primitives (13/13)
│ ├── test_cp4.py # Harness ทดสอบ Window & A11y (12/12)
│ ├── test_cp5.py # Harness ทดสอบ OCR + UX Polish (17/17)
│ └── test_cp7.py # Harness ทดสอบ launch_app (CP7)
├── docs/
│ ├── PUBLISHING.md # Checklist ก่อน push GitHub (maintainer)
│ └── archive/
│ ├── implementation_plan_cp1-cp7.md # ประวัติแผน CP1–CP7 (read-only)
│ └── implementation_plan_cp8-cp12.md # ประวัติแผน CP8–CP12 (read-only)
├── LICENSE # MIT
├── SECURITY.md # Threat model (TH + EN)
├── safety_config.json # Rate limit / blacklist / highlight config (CP5)
├── pyproject.toml # รายละเอียดโปรเจกต์ + Dependencies
├── uv.lock # Lock file ของ uv (อย่าแก้ด้วยมือ)
├── README.md # เอกสารฉบับนี้
├── USAGE_GUIDE.md # คู่มือเลือกใช้ตามงาน (เปิดเว็บ/แอป/prompt ตัวอย่าง)
├── SKILL.md # คู่มือสำหรับ AI Agent (Cursor/Antigravity Skill)
├── RULES.md # กฎเหล็กการทำงานของโปรเจกต์
├── TROUBLESHOOTING.md # คู่มือแก้ปัญหา + behavior reference
└── implementation_plan.md # แผนงานปัจจุบัน + backlog (active)
ระบบต้องการ Python 3.10+ และการจัดการแพ็กเกจด้วย uv
- เปิด PowerShell (รันแบบสิทธิ์ผู้ใช้ปกติ ไม่จำเป็นต้อง Administrator)
- ติดตั้ง dependencies ทั้งหมดด้วย
uv sync(อ่านpyproject.toml+uv.lockอัตโนมัติ):คำสั่งนี้จะติดตั้งuv sync
pyautogui,mss,pillow,opencv-python,pyperclip,requests,playwright,mcp,pygetwindow,uiautomation,winocrฯลฯ ครบในรอบเดียว - (เฉพาะคำสั่ง
web-*) ติดตั้ง Playwright browsers ถ้ายังไม่เคย:uv run playwright install
อยากรู้ว่าสั่งให้ทำอะไรได้บ้าง / เปิดเว็บหรือโปรแกรมใช้อะไร?
อ่าน USAGE_GUIDE.md — ตารางเลือกใช้ตามงาน, ตัวอย่าง prompt, วิธีติดตั้ง Antigravity 2.0
ผู้ใช้ต้องเปิดตัวควบคุมหลัก (Daemon) ก่อนทุกครั้งที่ต้องการอนุญาตให้มีการควบคุมคอมพิวเตอร์:
uv run src/daemon.pyผลลัพธ์: จะมีหน้าต่างเล็ก ๆ สีเข้มแถบแดงลอยเด่นอยู่ด้านบนสุดของจอ (Always on Top) ซึ่งสามารถเอาเมาส์คลิกลากเพื่อย้ายตำแหน่งได้
-
ตรวจสอบสถานะการทำงาน:
uv run src/cli.py status -
จับภาพหน้าจอแบบดั้งเดิม:
uv run src/cli.py screenshot -
จับภาพหน้าจอแบบเปิดตารางพิกัด (Grid Overlay):
uv run src/cli.py screenshot --grid
(รูปจะบันทึกใน
screenshots/screen_xxxx_grid.pngและจะคืนค่าพิกัดให้ AI อ่านผ่านภาพได้ง่าย) -
คลิกเมาส์ (Click):
uv run src/cli.py click --x 500 --y 450 --button left
-
ดับเบิ้ลคลิก (Double Click):
uv run src/cli.py click --x 200 --y 150 --clicks 2
-
พิมพ์ข้อความ (Type):
uv run src/cli.py type --text "Hello World"
-
กดปุ่มลัด (Keyboard Shortcut):
uv run src/cli.py key ctrl alt t -
ลากเมาส์ (Drag):
uv run src/cli.py drag --x1 100 --y1 100 --x2 300 --y2 300
-
เลื่อนหน้าจอ (Scroll):
uv run src/cli.py scroll --direction down --amount 5 # ระบุพิกัดได้ถ้าต้องการให้เลื่อนตรงตำแหน่งใดตำแหน่งหนึ่ง (เมาส์จะย้ายไปก่อนแล้วค่อย scroll) uv run src/cli.py scroll --direction up --amount 3 --x 500 --y 400
-
Action Primitives เพิ่มเติม (CP3):
# คลิก 3 ครั้งติด (เลือกทั้งบรรทัด/ย่อหน้า) uv run src/cli.py triple-click --x 500 --y 300 # กดปุ่มเมาส์ค้าง (drag แบบหลายขั้น) uv run src/cli.py mouse-down --x 100 --y 100 uv run src/cli.py move --x 400 --y 400 uv run src/cli.py mouse-up --x 400 --y 400 # กดปุ่มคีย์บอร์ดค้าง N วินาที (max 30) uv run src/cli.py hold-key --key shift --duration 2.0 # รอเฉยๆ N วินาที (สำหรับ UI animation/loading, max 30) uv run src/cli.py wait --duration 1.5 # อ่านพิกัดเคอร์เซอร์ปัจจุบัน uv run src/cli.py cursor-position # กดคีย์ทีละปุ่ม (sequence) ต่างจาก hotkey ที่กดพร้อมกัน uv run src/cli.py key alt f s --sequence
-
Window & Accessibility (CP4):
# ดู windows ทั้งหมด (title, hwnd, rect, is_active) uv run src/cli.py list-windows # ดู window ที่ focus อยู่ uv run src/cli.py active-window # focus window ตาม hwnd หรือ substring ของ title (case-insensitive) uv run src/cli.py focus-window --title "Visual Studio" # screenshot เฉพาะ bounding rect ของ window (ไม่ใช่ทั้งจอ) uv run src/cli.py window-screenshot --hwnd 12345 # ดึง UI Automation accessibility tree (ไม่ต้องพึ่งพิกัด) uv run src/cli.py inspect-element --title "Notepad" --max-depth 3 # คลิก element จาก A11y tree ด้วย filter ของ name/control_type/automation_id uv run src/cli.py click-element --title "Notepad" --name "Save" --control-type ButtonControl
-
OCR + UX Polish (CP5):
# OCR ทั้งหน้าจอ (Windows built-in OCR, ไม่ต้องลง Tesseract) uv run src/cli.py ocr-screen uv run src/cli.py ocr-screen --lang th-TH # ภาษาไทย (ต้องลง language pack) # หาตัวอักษรบนจอแล้วได้พิกัดกลางกล่อง (สำหรับเอาไป click ต่อ) uv run src/cli.py find-text --query "Submit" uv run src/cli.py find-text --query "(บันทึก|Save)" --regex # ดูประวัติ action 100 รายการล่าสุด (ตอบกลับมาจาก in-memory ring buffer) uv run src/cli.py get-history --n 20 # ดู / reload safety_config.json (rate limit + blacklist + highlight) uv run src/cli.py safety-config show uv run src/cli.py safety-config reload # ข้าม yellow ring overlay (CLI: click/triple-click/drag/click-image/click-element) # MCP no_highlight รองรับ mouse_down/mouse_up ด้วย uv run src/cli.py click --x 800 --y 600 --no-highlight
-
เขียน/อ่าน คลิปบอร์ด (Clipboard):
uv run src/cli.py clipboard write --text "ข้อความทดสอบ" uv run src/cli.py clipboard read
-
คลิกด้วยภาพเทมเพลต (Coordinate-Free Click - Template Matching):
uv run src/cli.py click-image --image "src/play_button_template.png" --confidence 0.8
(ระบุพิกัดโดยการนำภาพเทมเพลตขนาดเล็กไปเทียบหาตำแหน่งบนหน้าจอหลัก แล้วสั่งคลิกจุดศูนย์กลางทันที —
opencv-pythonติดมากับuv syncแล้ว ใช้--confidenceได้เลย; โค้ดยังมี fallback เป็น pixel-perfect ถ้า import OpenCV ล้มเหลว) -
คำสั่งเว็บควบคุมผ่าน Playwright (DOM-based Web Commands - แม่นยำสูง): ใช้สำหรับควบคุมหน้าเว็บด้วย HTML DOM Selectors ไม่ขึ้นกับพิกัดและการสเกลหน้าจอ:
# 1. เปิดเว็บเพจ (ระบุเบราว์เซอร์ผ่าน --channel ได้ เช่น chrome, brave, msedge, firefox) uv run src/cli.py web-open --url "https://music.youtube.com" --channel "brave" # 2. คลิกปุ่มด้วย CSS Selector uv run src/cli.py web-click --selector "ytmusic-play-button-renderer" # 3. พิมพ์ข้อความลงในช่องอินพุต uv run src/cli.py web-type --selector "input#input" --text "ทบทวนอีกครั้ง" # 4. คำสั่งลัด ค้นหาและเริ่มเล่นเพลงบน YouTube Music ทันที uv run src/cli.py web-play-music --query "ทบทวนอีกครั้ง" --channel "chrome" # 5. ปิดเซสชันเบราว์เซอร์ Playwright uv run src/cli.py web-close
-
เปิดโปรแกรม Windows (CP7 — popup ทุกครั้ง):
uv run src/cli.py launch-app --target calc uv run src/cli.py launch-app --target notepad
(แสดง popup Allow/Deny บนจอก่อนรัน — โปรแกรมใน
launch_blacklistเช่น powershell/cmd ถูกบล็อกทันที) -
ปิดการใช้งานระบบควบคุม:
uv run src/cli.py stop
หาก AI ทำงานผิดพลาดหรือเกิดพฤติกรรมไม่พึงประสงค์ คุณสามารถควบคุมกลับคืนได้ทันทีด้วยวิธีใดวิธีหนึ่งดังนี้:
- กดปุ่ม
Escค้างไว้ประมาณ 0.5 วินาที (5 รอบ poll ติดต่อกัน) ระบบจะยกเลิกการทำงานและปิด Daemon ทันที — การกด Esc สั้นๆ ตามปกติ (เช่น ปิด modal, ออกจาก search) ไม่กระทบ - เลื่อนเมาส์กระชากไปที่มุมหน้าจอ (มุมใดมุมหนึ่งจาก 4 มุมจอ) เพื่อเปิดการทำงาน Fail-Safe ของ PyAutoGUI
- คลิกปุ่ม "STOP (Esc)" บนแถบหน้าต่างลอยตัวสีดำบนหน้าจอ
- HTTP API เปิดที่
http://127.0.0.1:8000เท่านั้น (loopback) เพื่อกันการเข้าถึงจากเครื่องอื่นในเครือข่าย - Path ของ logs และ screenshots อยู่ใต้
<project-root>/logs/และ<project-root>/screenshots/เสมอ (คำนวณจากตำแหน่งsrc/daemon.py) ไม่ว่าจะรัน daemon จาก CWD ใดก็ตาม - Browser Channel Switching: หากเปิด session ด้วย
--channel braveแล้วเรียก command ถัดไปด้วย--channel chromeDaemon จะปิด session เดิมและเปิด session ใหม่ตาม channel ที่ระบุโดยอัตโนมัติ - Playwright Thread-safety: ทุกคำสั่งตระกูล
web-*จะถูกประมวลผลใน worker thread เดี่ยว (Single Background Thread) ผ่านplaywright_queueตามที่อธิบายในTROUBLESHOOTING.mdรวมถึงตอน shutdown ก็ปิด browser ผ่านคิวเดียวกัน
ไฟล์ safety_config.json ที่ project root ควบคุมพฤติกรรมความปลอดภัย/UX ของ daemon ค่า default ปลอดภัยและไม่ต้องแก้ก็ใช้งานได้ทันที:
{
"min_action_interval_ms": 50,
"blacklist_window_titles": [],
"launch_blacklist": [
"powershell",
"pwsh",
"cmd",
"wscript",
"cscript",
"mshta",
"regedit",
"certutil",
"bitsadmin"
],
"action_highlight_enabled": true,
"action_highlight_duration_ms": 300,
"action_highlight_radius_px": 40,
"action_history_size": 100
}ค่า default ด้านบนตรงกับ
safety_config.jsonใน repo — แก้ไฟล์แล้วsafety-config reloadได้
| Field | ทำหน้าที่ |
|---|---|
min_action_interval_ms |
ระยะห่างขั้นต่ำ (มิลลิวินาที) ระหว่าง action ที่กระทบหน้าจอ ตั้ง 0 เพื่อปิด rate limit |
blacklist_window_titles |
substring (case-insensitive) ของ window titles ที่ห้าม action โดยไม่ขออนุมัติ — ถ้า active window ตรงจะเด้ง popup sensitive ขอ Allow/Deny |
launch_blacklist |
substring (case-insensitive) ของชื่อ exe ที่ launch_app ห้ามเด็ดขาด (403 ทันที ไม่ popup) — ไม่กระทบ terminal Cursor/Antigravity |
action_highlight_enabled |
เปิด/ปิดวงกลมสีเหลืองที่วาดทับตำแหน่งก่อนคลิก |
action_highlight_duration_ms |
ระยะเวลาที่วงแหวนเหลืองค้างก่อนคลิกจริง (default 300ms) |
action_highlight_radius_px |
รัศมีวงแหวน (default 40) |
action_history_size |
จำนวน action ที่ daemon เก็บใน memory เพื่อ GET /history (เปลี่ยนแล้วต้อง restart daemon) |
หลังแก้ไฟล์ใช้คำสั่ง uv run src/cli.py safety-config reload หรือ POST /safety/reload เพื่อให้ daemon โหลดค่าใหม่โดยไม่ต้อง restart (ยกเว้น action_history_size ที่ต้อง restart)
ตัวอย่าง blacklist ที่ใช้งานจริง:
"blacklist_window_titles": ["Bank", "PayPal", "ตู้เอทีเอ็ม", "1Password", "KeePass"]Computer Control สามารถใช้งานผ่าน Model Context Protocol (MCP) ให้ AI agent เรียก tool โดยตรงแทน CLI ได้
- ติดตั้ง dependencies (รวม
mcpSDK):uv sync
- เปิด daemon ก่อนเสมอ (ต้องมี overlay ยืนยันจากผู้ใช้ — ไม่ auto-spawn):
uv run src/daemon.py - คัดลอก config ตัวอย่างไปยัง Cursor แล้ว แก้
--directoryให้เป็น path ที่ clone จริง (ตัวอย่างใช้C:/path/to/computer-control):- คัดลอก
mcp_config/cursor.example.json→.cursor/mcp.jsonใน workspace นี้ - หรือวางใน
~/.cursor/mcp.jsonสำหรับใช้ทุก workspace
- คัดลอก
- Restart Cursor (หรือ reload MCP servers) แล้วลองเรียก tool จากแชท
Antigravity 2.0 (ใช้ร่วมกับ Cursor ได้ — daemon ตัวเดียว):
- Agent panel → "..." → MCP Servers → Manage → View raw config
- ไฟล์:
C:\Users\<USERNAME>\.gemini\antigravity\mcp_config.json - merge เนื้อหาจาก
mcp_config/antigravity.example.jsonเข้าmcpServers - รายละเอียดเต็ม → USAGE_GUIDE.md §8
| Tool | คำอธิบาย |
|---|---|
screenshot |
จับภาพหน้าจอ (inline PNG) — รองรับ grid, step |
click |
คลิกที่พิกัด (x, y) |
move |
ย้ายเมาส์ |
type_text |
พิมพ์ข้อความ |
press_keys |
กดปุ่ม/shortcut — รองรับ sequence=true (กดทีละปุ่ม) |
drag |
ลากเมาส์ |
scroll |
เลื่อนหน้าจอ (รองรับ x, y) |
clipboard_read / clipboard_write |
อ่าน/เขียนคลิปบอร์ด |
open_url |
เปิด URL ในเบราว์เซอร์ |
click_image |
คลิกจากภาพเทมเพลต |
web_open, web_click, web_type, web_close, web_play_music |
คำสั่ง Playwright เหมือน CLI |
triple_click |
คลิก 3 ครั้งติดที่พิกัดเดียว |
mouse_down / mouse_up |
กด/ปล่อยปุ่มเมาส์ แยกขั้น (สำหรับ drag ซับซ้อน) |
hold_key |
กดปุ่มคีย์บอร์ดค้าง duration วินาที (max 30) |
wait |
รอ duration วินาที (max 30) |
cursor_position |
คืนพิกัดเคอร์เซอร์ {x, y} |
list_windows |
คืน list ของ window: [{title, hwnd, rect, is_active, ...}] |
active_window |
คืน window ที่ focus อยู่ |
focus_window |
activate window ตาม hwnd หรือ title substring |
window_screenshot |
screenshot เฉพาะ bounding rect ของ window |
inspect_element |
คืน UI Automation tree (name, control_type, rect, children ...) |
click_element |
คลิก element แรกที่ตรงกับ filter (name/name_regex/control_type/automation_id/class_name) |
ocr_screen |
OCR ทั้งหน้าจอ (Windows OCR built-in) คืน {text, lines: [{text, bbox}]} |
find_text |
หาข้อความบนจอ คืน bbox + center พิกัด — regex, case_sensitive flag |
get_history |
คืน action history 100 รายการล่าสุด (ตอบกลับจาก ring buffer ใน daemon) |
launch_app |
เปิดโปรแกรม .exe — popup Allow/Deny ทุกครั้ง · target + optional args |
safety_config |
action="show" / action="reload" ดู/reload safety_config.json |
MCP tools click, triple_click, drag, click_image, click_element, mouse_down, mouse_up รับ no_highlight: bool (default false) เพื่อข้ามวงแหวนเหลือง ~0.3 วินาทีก่อนลงมือ — CLI ใช้ --no-highlight บน click, triple-click, drag, click-image, click-element (ยังไม่มีบน mouse-down/mouse-up)
ไม่มี tool stop — ผู้ใช้ต้องกด STOP / Esc / uv run src/cli.py stop เอง
screenshot://latest— ภาพ PNG ล่าสุดdaemon://status— สถานะ daemonlogs://recent— log 100 บรรทัดล่าสุดhistory://recent— action history (in-memory) 100 รายการล่าสุด (CP5)safety://config— ค่าsafety_config.jsonปัจจุบัน (CP5)
"ใช้ computer-control MCP จับ screenshot แบบ grid แล้วบอกพิกัดปุ่ม Start"
"เปิด YouTube Music ด้วย web_play_music query ทบทวนอีกครั้ง channel chrome"
npx -y @modelcontextprotocol/inspector uv --directory C:/path/to/computer-control run python src/mcp_server.py