UIA-X——扩展的用户界面自动化
一 MCP服务器 使AI代理能够完全控制桌面应用程序 通过UI自动化。指向任何MCP客户端(Claude Desktop、VS Code Copilot、, opencode、自定义代理),它可以查看、单击、键入和导航 任何窗口应用程序——就像人类操作员一样。
今天: Windows(通过pywinauto的UIA/MSAA)、Linux(通过pyatspi的AT-SPI2), 以及macOS(通过PyObjC的AXAPI)。 桥接抽象已经到位——所有三个平台共享一个相同的 MCP刀具表面。
______________________________________________________________________
快速启动(HTTP+neneneba API密钥)
建议部署:使用生成的API密钥通过HTTP进行服务。
Windows(PowerShell)
# 1. Clone and install
git clone https://github.com/doucej/uia-x.git
cd uia-x
python -m venv .venv
.venv\Scripts\activate
pip install -e .
# 2. Start the server (prints the active API key to stdout at startup)
$env:MCP_TRANSPORT="streamable-http"
python -m uiax.serverLinux
注: pyatspi必须对您使用的Python解释器可见。如果 您正在virtualenv中运行,可以使用以下命令创建它 --system-site-packages 或者直接使用Python系统。# 1. Install system dependencies (AT-SPI2 + venv support for system Python)
sudo apt install python3-pyatspi gir1.2-atspi-2.0 at-spi2-core python3-venv
# 2. Clone and install (system Python, so pyatspi is visible)
git clone https://github.com/doucej/uia-x.git
cd uia-x
python3 -m venv --system-site-packages .venv
source .venv/bin/activate
pip install -e .
# 3. Start the server
export MCP_TRANSPORT=streamable-http
python -m uiax.servermacOS
# 1. Clone and install
git clone https://github.com/doucej/uia-x.git
cd uia-x
python3 -m venv .venv
source .venv/bin/activate
pip install -e .
# 2. Grant Accessibility access to Terminal (System Settings → Privacy & Security
# → Accessibility) so AXAPI can inspect other apps.
# 3. Start the server
export MCP_TRANSPORT=streamable-http
python -m uiax.server开 第一 启动(生成新密钥并将哈希保存到磁盘):
[uiax] *** NEW API KEY GENERATED ***
[uiax] Key:
[uiax] Stored hash in: ~/.uiax/api_key
[uiax] Save this key – it will not be shown again.
[uiax] To rotate the key run: uiax-server --reset-key
[uiax] starting server (backend=real, auth=apikey, transport=streamable-http, http://0.0.0.0:8000)密钥文件位于每个平台的主目录下:
| 平台 | 路径 |
|---|---|
| 窗户 | C:\Users\\.uiax\api_key |
| Linux | /home//.uiax/api_key |
| macOS | /Users//.uiax/api_key |
开 随后的 启动(从磁盘加载哈希值——明文不可恢复):
[uiax] API key loaded from disk (~/.uiax/api_key).
[uiax] The hash is stored; use your saved key to authenticate.
[uiax] To display the key again set UIAX_API_KEY= or delete the file to regenerate.
[uiax] To rotate the key run: uiax-server --reset-key
[uiax] starting server (backend=real, auth=apikey, transport=streamable-http, http://0.0.0.0:8000)要随时旋转关键点,请执行以下操作:
uiax-server --reset-key # generates and saves a new key, then exits要锁定每次启动时打印的固定键,请设置 UIAX_API_KEY:
# Linux / macOS
export UIAX_API_KEY="my-fixed-key"
python -m uiax.server
# Windows (PowerShell)
$env:UIAX_API_KEY="my-fixed-key"
python -m uiax.server
# [uiax] API key sourced from environment variable UIAX_API_KEY.
# [uiax] Key: my-fixed-key3.将您的MCP客户端指向 http://localhost:8000/mcp 并通过API 密钥作为Bearer令牌头或作为 api_key 每个工具调用上的参数。
______________________________________________________________________
环境变量
| 变量 | 默认值 | 描述 |
|---|---|---|
MCP_TRANSPORT | stdio | 运输: stdio, sse, streamable-http |
MCP_HOST | 0.0.0.0 | 绑定地址(HTTP模式) |
MCP_PORT | 8000 | 侦听端口(HTTP模式) |
UIAX_AUTH | apikey | 身份验证模式: apikey 或 none.遗留别名: UIA_X_AUTH |
UIAX_API_KEY | *(自动)* | 固定特定的API密钥(跳过磁盘上生成)。旧别名: UIA_X_API_KEY |
UIAX_BACKEND | real | 后端: real (自动检测), linux (AT-SPI2), macos (AXAPI),或 mock (测试)。旧别名: UIA_BACKEND |
______________________________________________________________________
对客户进行身份验证
重点: 已强制执行身份验证 服务器端Theheaders客户端配置中的块只是简单地告诉客户端要使用哪些凭据 present——服务器决定是否接受它们。省略的客户 或者伪造的报头被401拒绝。如果服务器以启动UIAX_AUTH=none,无论客户端是什么,都不会检查凭据 发送。
UIA-X支持 两种方式 要出示API密钥,请使用 您的客户支持:
| 方法 | 何时使用 |
|---|---|
承载头 – Authorization: Bearer | HTTP传输(SSE/可流式传输HTTP)。在任何工具运行之前,在ASGI层处理。VS Code、opencode、Open WebUI、curl和大多数HTTP客户端都会自动发送此消息。 |
刀具参数 – api_key 每次调用时,stdio传输或客户端都无法设置标头。LLM将密钥作为工具参数的一部分传递。 |
如果Bearer标头存在且有效,则工具级别 api_key 参数 被忽略(您可以省略它)。
______________________________________________________________________
客户端配置示例
克劳德桌面(claude_desktop_config.json)
Stdio——服务器作为本地子进程运行。不需要钥匙。
窗户:
{
"mcpServers": {
"uiax": {
"command": "C:/path/to/uia-x/.venv/Scripts/python.exe",
"args": ["-m", "uiax.server"],
"cwd": "C:/path/to/uia-x",
"env": { "UIAX_AUTH": "none" }
}
}
}Linux/macOS:
{
"mcpServers": {
"uiax": {
"command": "/path/to/uia-x/.venv/bin/python",
"args": ["-m", "uiax.server"],
"cwd": "/path/to/uia-x",
"env": { "UIAX_AUTH": "none" }
}
}
}VS代码--stdio(本地)
Stdio-不需要API密钥。
// .vscode/mcp.json
{
"servers": {
"uiax": {
"type": "stdio",
// Windows: "${workspaceFolder}/.venv/Scripts/python.exe"
// Linux / macOS: "${workspaceFolder}/.venv/bin/python"
"command": "${workspaceFolder}/.venv/Scripts/python.exe",
"args": ["-m", "uiax.server"],
"env": { "UIAX_AUTH": "none", "UIAX_BACKEND": "real" }
}
}
}VS代码--HTTP(远程/共享服务器)
在目标计算机上启动服务器,然后配置VS Code进行连接 持有Bearer代币。这 ${input:...} 变量导致VS代码 提示 你曾经 找到钥匙并安全地存放。
// .vscode/mcp.json
{
"inputs": [
{
"type": "promptString",
"id": "uiax-api-key",
"description": "UIA-X API key (from server first-run output)",
"password": true
}
],
"servers": {
"uiax": {
"type": "http",
"url": "http://:8000/mcp",
"headers": {
"Authorization": "Bearer ${input:uiax-api-key}"
}
}
}
}开放代码(~/.config/opencode/opencode.json)
opencode使用 "type": "remote" 对于HTTP MCP服务器。
启用身份验证 -将API密钥传递给首次运行时打印的服务器:
{
"mcp": {
"uiax": {
"type": "remote",
"url": "http://:8000/mcp",
"headers": {
"Authorization": "Bearer "
}
}
}
}无身份验证(本地开发) --使用以下命令启动服务器 UIAX_AUTH=none 和 省略 headers 块:
{
"mcp": {
"uiax": {
"type": "remote",
"url": "http://localhost:8000/mcp"
}
}
}注: opencode以纯文本形式存储密钥(否${input:...}提示 如VS代码)。仅供本地使用,与UIAX_AUTH=none是 最简单的路径。对于远程/共享服务器,将配置文件视为 敏感。
打开WebUI/通用HTTP客户端
任何可以向HTTP请求添加自定义标头的客户端都以相同的方式工作: 集 Authorization: Bearer 每一个请求 /mcp 终点。
# curl example
curl -H "Authorization: Bearer " \
http://:8000/mcp如果服务器端禁用身份验证(UIAX_AUTH=none),只需点击URL 直接——不需要标题。
______________________________________________________________________
建筑
┌─────────────────────────────────────┐
│ MCP Client (LLM Agent) │
│ Claude Desktop / VS Code / Custom │
└──────────────┬──────────────────────┘
│ MCP stdio / HTTP
│ (Bearer auth or api_key param)
▼
┌─────────────────────────────────────┐
│ UIA-X server.py │
│ ┌─────────┐ ┌─────────────────┐ │
│ │ Auth │ │ Process Manager │ │
│ │ Layer │ │ (enumerate/ │ │
│ │ Bearer / │ │ attach windows)│ │
│ │ api_key │ │ │ │
│ └─────────┘ └─────────────────┘ │
│ ┌──────────────────────────────┐ │
│ │ Platform Bridge │ │
│ │ ┌────────┬────────┬──────┐ │ │
│ │ │Windows │ Linux │macOS │ │ │
│ │ │UIA/MSAA│AT-SPI2 │AXAPI │ │ │
│ │ │ │pyatspi │PyObjC│ │ │
│ │ └────────┴────────┴──────┘ │ │
│ └──────────────────────────────┘ │
│ ┌──────────────────────────────┐ │
│ │ Input Injection │ │
│ │ SendKeys · Mouse Click │ │
│ └──────────────────────────────┘ │
└─────────────────────────────────────┘
│
▼ pywinauto / ctypes / comtypes
┌─────────────────────────────────────┐
│ Windows Desktop (dedicated VM session) │
│ Target application (any app) │
└─────────────────────────────────────┘关键组件
| 模块 | 责任 |
|---|---|
server/server.py | FastMCP应用程序、所有工具注册、身份验证门控 |
server/uia_bridge.py | 抽象桥接接口、错误分类、平台检测 |
server/win_bridge.py | 通过pywinauto(Windows)实时UIA+MSAA后端 |
server/mock_bridge.py | 用于测试的模拟后端(任何平台) |
server/process_manager.py | 枚举进程/窗口,连接/分离 |
server/auth.py | API密钥生成、验证、可插拔身份验证 |
mock_uia/tree.py | 模拟元素树(通用、Quicken、MSAA) |
uiax/backends/linux/bridge.py | LinuxBridge–AT-SPI2 UIABridge实现 |
uiax/backends/linux/atspi_backend.py | 节点模型、树遍历、元素搜索 |
uiax/backends/linux/util.py | AT-SPI2实用功能,按键合成 |
uiax/backends/macos/bridge.py | MacOSBridge–AXAPI UIABridge实现 |
uiax/backends/macos/axapi_backend.py | 节点模型、树遍历、元素搜索 |
uiax/backends/macos/util.py | AXAPI实用程序函数,Quartz按键合成 |
______________________________________________________________________
项目布局
uia-x/
├── server/
│ ├── server.py ← FastMCP app, tool registrations
│ ├── uia_bridge.py ← Abstract bridge + error types + platform detection
│ ├── win_bridge.py ← Live UIA + MSAA backend (pywinauto, Windows)
│ ├── mock_bridge.py ← Mock backend for tests
│ ├── process_manager.py ← Process/window enumeration & attachment
│ └── auth.py ← API key authentication layer
├── uiax/
│ └── backends/
│ ├── linux/
│ │ ├── __init__.py ← Public API exports
│ │ ├── atspi_backend.py ← Node model, tree traversal, search
│ │ ├── bridge.py ← LinuxBridge (UIABridge impl) + LinuxProcessManager
│ │ └── util.py ← AT-SPI2 helpers, keystroke synthesis
│ └── macos/
│ ├── __init__.py ← Public API exports
│ ├── axapi_backend.py ← Node model, tree traversal, search
│ ├── bridge.py ← MacOSBridge (UIABridge impl) + MacOSProcessManager
│ └── util.py ← AXAPI helpers, Quartz keystroke synthesis
├── mock_uia/
│ └── tree.py ← MockElement, MockTree, fixture factories
├── tests/
│ ├── test_tools.py ← Core UIA tool tests
│ ├── test_process.py ← Process enumeration & attachment tests
│ ├── test_auth.py ← Authentication layer tests
│ ├── test_input.py ← Keystroke & mouse input tests
│ ├── test_msaa.py ← MSAA / LegacyIAccessible tests
│ ├── test_linux_backend.py ← Linux backend unit tests (mock AT-SPI)
│ ├── test_linux_integration.py ← Linux integration tests (live AT-SPI)
│ ├── test_macos_backend.py ← macOS backend unit tests (mock AXAPI)
│ ├── test_macos_integration.py ← macOS integration tests (live AXAPI + Calculator.app)
│ └── run_headless.sh ← Headless test harness (Xvfb + D-Bus)
├── schemas/ ← JSON Schema for every tool
├── examples/
│ └── quicken/ ← Quicken-specific skill (from V1)
│ ├── AGENT_SKILL_GUIDE.md
│ ├── quicken_attach.py
│ └── example_calls.json
├── pyproject.toml
├── requirements.txt
├── LICENSE ← MIT
├── MIGRATION.md ← V1 → V2 migration guide
└── README.md ← This file______________________________________________________________________
需求
- Python 3.11+
- 视窗 –pywinauto,comtypes(用于Windows UIA后端)
- Linux –python3 pyatspi,at-spi2-core,gir1.2-atspi-2.0(用于Linux at-spi2后端)
- macOS –适用于macOS AXAPI后端的PyObjC(PyObjC框架应用程序服务、PyObjC-框架Quartz、PyObjC-框架Cocoa)
- A. 桌面会话 (物理、RDP、VNC或虚拟X11/Wayland)-可访问性API需要活动桌面
抽象的桥 server/uia_bridge.py 制作平台后端 可互换——MCP工具界面在Windows、Linux和macOS上保持不变。macOS访问权限(TCC)
macOS需要显式 一次性的 无障碍权限授予之前 任何进程都可以读取UI元素或与UI元素交互。这是由 透明度、同意和控制(TCC)框架,同样适用于 每个macOS辅助工具(Hammerspoon、BetterTouchTool、键盘 大师等)。
快速设置(交互式桌面):
- 打开 系统设置→ 隐私和安全→ 无障碍.
- 点击 + 并添加Python解释器(例如。
/usr/bin/python3,
你的康达 python.app,或 打开终端 / iTerm2).
- 切换条目 上。就是这样——补助金在重新启动后仍然有效。
获得许可的内容:
TCC授予信托 *调用可访问性API的二进制文件*,不是为了 个人脚本。所以你授权 python3 (或 Terminal.app 它封装了你的shell),你从该二进制文件运行的每个Python脚本都是 盖满。您永远不需要签名或将个人列入白名单 .py 文件夹。
未签名的Python解释器:
Conda和Homebrew安装未签名的Python二进制文件。TCC识别 通过代码签名处理,因此未签名的二进制文件的行为可能不一致 --许可可能看起来被授予但实际上没有生效, 尤其是在SSH会话等边缘情况下。如果你点击这个:
- 更喜欢Python系统 (
/usr/bin/python3)或正确签名
Python发行版,如果可能的话。
- 康达 船舶a
python.app捆绑($CONDA_PREFIX/python.app)那个
具有捆绑标识符(com.continuum.python).添加 *那* 到 可访问性而非裸露 bin/python3.
- 作为最后的手段,对二进制文件进行ad-hoc签名:
codesign -s - -f /path/to/python3 (这为 TCC,但不能替代生产中的真实代码签名)。
SSH/远程会话:
SSH连接在不同的macOS安全审核会话中运行 登录GUI。即使Python在TCC中是可信的,SSH也会生成进程 不会继承这种信任。解决方法:
| 方法 | 如何 |
|---|---|
open 命令 | open /path/to/python.app --args script.py --在GUI会话中启动 |
| 启动代理 | 创建一个 ~/Library/LaunchAgents/*.plist 运行服务器的程序——在用户的GUI上下文中自动运行 |
| 屏幕共享/VNC | 通过VNC连接并从GUI会话中的终端窗口运行 |
launchctl asuser | sudo launchctl asuser $(id -u) /path/to/python3 script.py --在GUI用户的审核会话下运行 |
企业(MDM)部署:
对于无需手动用户交互的车队部署,请按 隐私偏好政策控制(PPPC)配置文件 该预授权 kTCCServiceAccessibility 到您的签名Python二进制文件。 这要求二进制文件经过正确的代码签名(而不是ad-hoc)。
______________________________________________________________________
安装
pip install -e ".[dev]"或者只是运行时依赖关系:
pip install -r requirements.txt______________________________________________________________________
安全模型
UIA-X对每个请求进行身份验证,除非明确禁用。
⚠️ 桌面访问警告
UIA-X为连接的代理提供 完全控制每个可见的应用程序 在它运行的桌面会话上。它可以点击、打字、阅读屏幕 内容,并调用UI操作——就像坐在键盘前的人一样 可以。这是该工具的重点,但它意味着:
- 敏感数据被泄露。 代理可以看到的任何窗口(电子邮件、银行、,
密码管理器、文件浏览器)是公平的游戏 uia_inspect.
- 破坏性行动是可能的。 代理可以点击“删除”,
“发送”、“格式化”或关闭未保存的文档。
- 凭据可能可见。 自动填充密码,会话令牌
浏览器开发工具、终端窗口中的环境变量——全部可读 通过可访问性树。
最佳实践: 切勿在您用于的同一桌面会话上运行UIA-X 日常工作。请参阅 隔离策略 下面为 每个平台上的推荐设置。
启动键行为
每次服务器启动时,都会解析活动的API密钥并打印状态 到 标准输出 在HTTP服务器开始接受连接之前:
- 首次运行 -生成一个新的加密随机密钥
SHA-256哈希被写入 ~/.uiax/api_key,以及 明文密钥 是 印刷的。复制并保存它——该文件仅存储哈希值,因此 在后续运行中无法恢复明文。
- 后续运行 –从磁盘加载哈希值并进行确认
通知已打印。明文密钥不再显示。
UIAX_API_KEY有人看过 –该密钥按原样使用并打印在
每一家初创公司(非常适合脚本化或容器化部署)。
只有SHA-256哈希被写入磁盘——服务器从不存储 磁盘上的原始密钥。
通过HTTP标头进行身份验证(建议用于HTTP传输)
将密钥作为 持有者代币 在每个HTTP请求上:
Authorization: Bearer 服务器在ASGI中间件中验证标头 *之前* 任何工具 执行。当标题有效时,工具级别 api_key 参数 不需要。
通过工具参数(stdio或回退)进行身份验证
每个工具也接受 api_key 作为参数:
{
"tool": "uia_inspect",
"input": {
"target": {},
"api_key": "your-key-here"
}
}禁用身份验证(本地开发)
UIAX_AUTH=none python -m uiax.server通过环境覆盖密钥
UIAX_API_KEY=my-fixed-key python -m uiax.server
# Legacy alias also accepted:
UIA_X_API_KEY=my-fixed-key python -m uiax.server未来的身份验证方法
身份验证层是可插拔的——可以交换mTLS、OAuth设备代码或任何自定义 提供者通过实现 AuthProvider 协议中 server/auth.py.
______________________________________________________________________
运行服务器
针对实时桌面(stdio,默认):
# Linux / macOS
python -m uiax.server
# Windows (PowerShell)
python -m uiax.serverHTTP模式(建议用于远程/多客户端):
# Linux / macOS
export MCP_TRANSPORT=streamable-http
python -m uiax.server
# → Listening on http://0.0.0.0:8000/mcp# Windows (PowerShell)
$env:MCP_TRANSPORT="streamable-http"
python -m uiax.server
# → Listening on http://0.0.0.0:8000/mcp模拟后端(无需桌面——用于测试):
UIAX_BACKEND=mock python -m uiax.server______________________________________________________________________
隔离策略
因为UIA-X具有完全的桌面访问权限(请参见 桌面访问警告),你应该跑 它在一个 隔离会话 仅包含代理程序的应用程序 需要。以下是针对特定平台的建议。
Windows——专用虚拟机(推荐)
关于多会话RDP的注意事项: 标准Windows 10/11 专业版 不 支持并发远程桌面会话--连接第二个RDP客户端 断开第一个。多会话是Windows Server的一项功能 Pro上没有。不要依赖“并发RDP”解决方法 标准Windows Pro安装。
安全性和稳定性建议: 如果UIA-X在内部运行 *你自己的 活动桌面会话* LLM代理和您共享相同的UI。 这会导致焦点冲突、意外的窗口关闭和不可预测 自动化行为,因为双方都在争夺键盘和鼠标的焦点。 这是一个安全和稳定性问题,而不是许可问题。
最干净的解决方案是在一个 专用Windows虚拟机 那 仅包含目标应用程序。
- 创建Windows虚拟机 (Hyper-V、VirtualBox、VMware、Azure、AWS或任何
管理程序)。最低限度的Windows 10/11安装就足够了; 仅当目标应用程序需要硬件时才需要GPU直通 致使。
- 创建受限本地用户 在VM中(可选但推荐):
net user uiax-agent P@ssw0rd123 /add
# Do NOT add to Administrators — limit what the agent can reach- 以该用户身份登录 在VM控制台中创建活动桌面
会议。UI自动化需要一个活动的、已登录的会话。
- 仅安装目标应用程序 在VM中。代理人只看到
虚拟机桌面上有什么——你的电子邮件、浏览器和密码管理器 留在您的主机上。
- 启动UIA-X 在VM会话中:
$env:MCP_TRANSPORT = "streamable-http"
$env:UIAX_AUTH = "apikey" # or "none" for local-only
python -m uiax.server- 连接您的MCP客户端 从您的主机到
http://:8000/mcp.
云虚拟机: Azure/AWS实例同样运行良好。代理连接 通过网络;通过管理程序控制台或 连接到单个活动会话的可选VNC查看器。
Linux——Docker+虚拟显示
在带有虚拟X11或Wayland显示的Docker容器中运行UIA-X。 代理只看到容器内的东西。
# Dockerfile.uiax-sandbox
FROM ubuntu:24.04
RUN apt-get update && apt-get install -y \
xvfb x11vnc python3 python3-pip \
python3-pyatspi gir1.2-atspi-2.0 at-spi2-core \
dbus-x11 xdotool \
# install target app dependencies here
&& rm -rf /var/lib/apt/lists/*
COPY . /opt/uia-x
WORKDIR /opt/uia-x
RUN pip install -r requirements.txt
# Start a virtual framebuffer + AT-SPI2 + the MCP server
CMD Xvfb :99 -screen 0 1920x1080x24 & \
export DISPLAY=:99 && \
export MCP_TRANSPORT=streamable-http && \
dbus-run-session -- python -m uiax.serverdocker build -t uiax-sandbox -f Dockerfile.uiax-sandbox .
docker run -d -p 8000:8000 --name uiax uiax-sandbox
# Optional: attach a VNC viewer to watch the agent work
# (add x11vnc to the CMD and expose port 5900)如果你需要实时观察代理人,添加 x11vnc 到 容器和暴露端口5900,以便您可以连接VNC查看器。
如果你不需要看,无头 Xvfb 方法更轻 更安全——无法将屏幕内容泄露到外部 集装箱。
macOS-次要用户会话
macOS不支持具有本机GUI访问权限的Docker容器(Darwin 容器是实验性的和有限的)。相反:
- 创建专用macOS用户帐户 以最小的权限。
- 快速用户切换 到那个帐户(
System Settings → Users & Groups → Login Options → Show fast user switching menu). - 在新用户的会话中授予Python访问权限
(参见 macOS访问权限 上文)。
- 在该会话中仅打开目标应用程序。
- 在那里运行UIA-X。您的主要会话保持不变。
或者,使用 macOS虚拟机 (通过Apple Silicon支持 虚拟化框架或通过UTM/Parallels)并在VM内运行UIA-X。
注: 每个macOS用户帐户都有自己的TCC数据库。你必须批准 在UIA-X将运行的每个用户会话中分别设置可访问性权限。
摘要
| 平台 | 建议隔离 | 可观察性 | 状态 |
|---|---|---|---|
| Windows | 专用Windows VM(受限用户) | VM控制台/可选VNC查看器 | 现已上市 |
| Linux | Docker+Xvfb | VNC放入容器(可选) | 现已上市 |
| macOS | 辅助用户/macOS虚拟机 | 快速用户切换/VNC | 现已上市 |
______________________________________________________________________
外露工具
登记了11种工具。全部返回 {"ok": true, ...} 关于成功或 {"ok": false, "error": "...", "code": "..."} 失败。
process_list
枚举正在运行的进程及其顶级窗口。
| 参数 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
api_key | string | 是\* | - | API密钥 |
visible_only | boolean | 否 | true | 仅返回可见窗口 |
select_window
作为自动化目标附加到特定窗口。至少一次搜索 标准是必需的。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
api_key | string | 是\* | API键 |
pid | integer | 否 | 进程ID |
process_name | string | 否 | 可执行文件名(例如。 "notepad.exe") |
window_title | string | 否 | 标题上的子字符串匹配 |
class_name | string | 否 | Win32窗口类 |
hwnd | integer | 否 | 窗口句柄 |
uia_inspect
检查UIA元素树。
| 参数 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
api_key | string | 是\* | - | API密钥 |
target | 对象 | 否 | {} | 元素选择器 |
uia_invoke
调用(单击/激活)元素。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
api_key | string | 是\* | API键 |
target | object | 是 | 元素选择器 |
uia_set_value
设置元素的值(文本字段、日期选择器、组合框)。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
api_key | string | 是\* | API键 |
target | object | 是 | 元素选择器 |
value | string | 是 | 新值 |
uia_send_keys
将按键发送到目标窗口(具有可选元素焦点)。
| 参数 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
api_key | string | 是\* | - | API密钥 |
keys | string | 是 | -- | 按键顺序 |
target | 对象 | 否 | {} | 首先要关注的元素 |
uia_legacy_invoke
通过MSAA调用 DoDefaultAction。对于不可见的所有者绘制控件 标准UIA。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
api_key | string | 是\* | API键 |
target | object | Yes | 选择器(支持MSAA附加功能) |
uia_mouse_click
单击屏幕绝对坐标。
| 参数 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
api_key | string | 是\* | - | API密钥 |
x | integer | 是 | -- | 屏幕X |
y | integer | 是 | -- | 屏幕Y |
double | boolean | 否 | false | 双击 |
button | string | 否 | "left" | "left", "right", "middle" |
send_keys
低级按键注入(无UIA目标焦点)。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
api_key | string | 是\* | API键 |
keys | string | 是 | 按键顺序 |
mouse_click
低级鼠标点击(无UIA目标上下文)。
| 参数 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
api_key | string | 是\* | - | API密钥 |
x | integer | 是 | -- | 屏幕X |
y | integer | 是 | -- | 屏幕Y |
double | boolean | 否 | false | 双击 |
button | string | 否 | "left" | 鼠标按钮 |
uia_get_text
返回单个元素的人类可读文本,而不转储完整文本 树。更喜欢UIA/AXAPI/AT-SPI *价值* 财产;回落到 可访问的 *名字*,然后是平台特定的文本内容。返回两个文本 和一个 source 字段,以便调用者知道它来自哪个属性。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
api_key | string | 是\* | API键 |
target | object | 否 | 元素选择器(默认:根窗口) |
响应字段:
| 字段 | 类型 | 描述 |
|---|---|---|
text | string | 检索到的文本(如果元素没有可读文本,则可能为空) |
source | string | 源属性: "value", "name", "text", "description", "msaa_value", "msaa_name",或 "none" |
Windows计算器示例 --结果显示通过以下方式显示其值 无障碍 *名字* (不是通过ValuePattern,此处没有 元素):
// call
{ "tool": "uia_get_text",
"input": { "target": { "by": "automation_id", "value": "CalculatorResults" } } }
// response
{ "ok": true, "text": "Display is 56", "source": "name" }这 "Display is " 前缀是UWP计算器可访问名称的一部分。 技能指南应该记录这种模式,以便模型知道如何剥离它。
\*除非满足以下条件,否则必须 UIAX_AUTH=none.______________________________________________________________________
使用进程选择器
Agent → process_list()
← [Notepad (pid=5678), Quicken (pid=1234), Calculator (pid=9012), ...]
Agent → select_window(process_name="notepad.exe")
← { window: { hwnd: 0xBB01, title: "Untitled - Notepad", ... } }
Agent → uia_inspect(target={})
← { element: { name: "Untitled - Notepad", children: [...] } }要在运行时切换目标,只需调用 select_window 再次不同 标准。
______________________________________________________________________
目标选择器
所有UIA工具都接受 target 对象:
| 密钥 | 类型 | 描述 |
|---|---|---|
by | string | 策略(见表) |
value | string | 策略的值 |
index | integer | 多个匹配项的从零开始的索引(默认值 0) |
depth | integer | 用于检查的子级深度(默认值 3) |
选择策略
by value | 匹配 |
|---|---|
name | UIA Name 财产 |
automation_id | UIA AutomationId |
control_type | UIA ControlType (例如。 "Button") |
class_name | Win32类名 |
path | /-从根目录中分离名称路径 |
hwnd | Windows HWND(int或十六进制字符串) |
legacy_name MSAA 的 accName | |
legacy_role | MSAA角色常量(int或字符串) |
child_id MSAA 的 CHILDID 整数 |
______________________________________________________________________
编写应用程序特定技能
- 使用
process_list+select_window附加到您的应用程序。 - 使用
uia_inspect随着depth=1映射顶级窗口树。 - 深入子元素以发现自动化ID、名称和类名。
- 编写技能指南(参见
examples/quicken/AGENT_SKILL_GUIDE.md)记录:
- 窗口层次结构 - 表单的选项卡顺序 - 已知类名和自动化ID - 常见工作流程(CRUD、导航、键盘快捷键)
- 创建一个助手脚本,如下所示
examples/quicken/quicken_attach.py为了快速
附件。
______________________________________________________________________
错误代码
| 代码 | 含义 |
|---|---|
TARGET_NOT_ATTACHED | 未选择窗口--调用 select_window 首先 |
PROCESS_NOT_FOUND | 没有符合条件的流程/窗口 |
ELEMENT_NOT_FOUND | 没有与目标选择器匹配的元素 |
PATTERN_NOT_SUPPORTED | 元素不支持所需的模式 |
INVALID_SELECTOR | 未知 by 战略 |
AUTH_ERROR | API密钥无效或丢失 |
PYWINAUTO_UNAVAILABLE | pywinauto未安装或未安装在Windows上 |
UNEXPECTED_ERROR | 未处理的异常 |
______________________________________________________________________
运行测试
pytest tests/ -v所有核心测试都使用 模拟后端 --不需要Windows或目标应用程序。
tests/test_tools.py – Core UIA tools (inspect/invoke/set_value)
tests/test_process.py – Process enumeration & window attachment
tests/test_auth.py – API key authentication
tests/test_input.py – Keystroke & mouse input
tests/test_msaa.py – MSAA / LegacyIAccessible fallback
tests/test_linux_backend.py – Linux AT-SPI2 backend unit tests
tests/test_linux_integration.py – Linux integration tests (requires AT-SPI2)
tests/test_macos_backend.py – macOS AXAPI backend unit tests
tests/test_macos_integration.py – macOS integration tests (requires AXAPI + Calculator.app)运行macOS集成测试
macOS集成测试需要实时GUI会话、可访问性权限, 计算器.app:
# Grant accessibility permission to Python first (manual, one-time):
# System Settings → Privacy & Security → Accessibility → add Python / Terminal
# (see "macOS accessibility permissions" section above for details)
# Run from the GUI session (preferred — TCC trust is automatic):
UIAX_RUN_MACOS_INTEGRATION=1 pytest tests/test_macos_integration.py -v
# Over SSH — launch via `open` so the process runs in the GUI Aqua session:
# (direct SSH execution won't have TCC trust even if Python is whitelisted)
ssh user@mac-host "open /path/to/python.app --args -m pytest \
/path/to/uia-x/tests/test_macos_integration.py -v"
# Or use the live demo script for a quick smoke test:
open /path/to/python.app --args /path/to/uia-x/tests/live_macos_demo.py
cat /tmp/uiax_live_demo.txt # output is tee'd to this file先决条件(macOS):
pip install pyobjc-framework-ApplicationServices pyobjc-framework-Quartz pyobjc-framework-Cocoa运行Linux集成测试
Linux集成测试需要实时AT-SPI2会话和测试应用程序。 使用无头线束:
# Run with Xvfb + D-Bus session (no real display needed)
./tests/run_headless.sh pytest tests/test_linux_integration.py -v
# Or manually enable integration tests
UIA_RUN_INTEGRATION=1 pytest tests/test_linux_integration.py -v先决条件(Debian/Ubuntu):
sudo apt install -y \
python3-pyatspi gir1.2-atspi-2.0 at-spi2-core \
xvfb dbus xterm xdotool______________________________________________________________________
贡献
欢迎投稿!看 贡献.md 用于设置 说明、桥接接口和PR指南。
______________________________________________________________________
许可证
麻省理工学院——见 许可证.
