mcpField
T
Touchpoint

Touchpoint

本地服务
github.com/Touchpoint-Labs生产力4720 周前更新

关于 Touchpoint

Touchpoint 是跨平台 Python 库,also 提供 MCP 服务,通过操作系统无障碍 API 读取桌面应用的 UI 元素。它面向需要控制原生应用、Electron 应用和浏览器的 Agent,无需视觉模型即可获取名称、角色、状态和位置等结构化数据。

主要功能

  1. 01读取系统无障碍树中的结构化元素信息
  2. 02支持 Linux、macOS 和 Windows
  3. 03通过 CDP 支持 Chromium 与 Electron 应用
  4. 04提供视觉模式和无视觉模式两种 MCP 工作方式
  5. 05可按名称查找元素并执行点击、输入等操作

适用场景

  1. 01让 Agent 在 Slack、VS Code 等桌面应用中执行操作
  2. 02在无视觉能力的本地模型上控制桌面应用
  3. 03在浏览器中收集数据后填写原生应用表格

MCP 相关

Touchpoint 内置 MCP 服务,向 Claude、Cursor 等 MCP 客户端暴露截图、快照、查找、点击、输入和窗口管理等工具。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

暂未收录安装方式

我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。

代码仓库

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

Touchpoint

让 AI Agent 能够观察并操作任何桌面。

PyPI Python MIT License Alpha
Linux macOS Windows

pip install touchpoint-py

Touchpoint 演示 — AI Agent 使用 Touchpoint 创建格式化的 Excel 表格

AI Agent 在 Chrome 中调研数据,然后创建格式化的 Excel 表格——约 12 分钟内完成整个任务


Touchpoint 是一个跨平台 Python 库,通过原生辅助功能 API 读取桌面 UI 并与之交互。只需一次导入、一个 API,即可在 Linux、macOS 和 Windows 上使用,并通过 CDP(Chrome DevTools Protocol)内置支持 Chromium 和 Electron 应用。

Touchpoint 不会截取像素或运行视觉模型,而是读取真实的辅助功能树——屏幕上每个元素的结构化名称、角色、状态和位置。运行快速、可靠,无需视觉模型。它附带 MCP 服务,让 Claude、Cursor 等 LLM Agent 或任何本地模型开箱即用地控制任意桌面应用。

import touchpoint as tp

elements = tp.find("Send", role=tp.Role.BUTTON, app="Slack")
tp.click(elements[0])
为什么选择 Touchpoint?
截图 / 视觉浏览器自动化Touchpoint
原生桌面应用⚠️ 不准确或缓慢❌✅
浏览器⚠️ 不准确或缓慢✅✅ 通过 CDP
Electron 应用(Slack、VS Code 等)⚠️ 不准确或缓慢⚠️ 仅限 Web 内容✅ 原生 + Web
结构化元素数据❌ 需要 OCR / 视觉模型✅ 仅限 Web✅ 名称、角色、状态、位置
兼容本地 / 非视觉模型❌✅ 仅限 Web✅ 所有应用
兼容 Linux、macOS、Windows✅✅✅

目录


安装

需要 Python 3.10+。

pip install touchpoint-py

所有功能均已包含:平台原生后端、浏览器和 Electron 应用的 CDP 支持、MCP 服务以及截图功能。平台专属依赖项会通过 pip 环境标记自动安装。

平台要求
平台后端要求
LinuxAT-SPI2安装 xdotool(输入操作和 minimize_window 所必需)和 wmctrl(所有窗口管理操作所必需,用于 AT-SPI → X11 ID 映射)。大多数桌面环境都包含 python3-gi 和 gir1.2-atspi-2.0;如果缺少,请安装。
WindowsUI Automation无 — 使用内置的 COM API
macOSAccessibility (AX)授予权限:系统设置 → 隐私与安全性 → 辅助功能

快速开始

import touchpoint as tp

# Discover
apps = tp.apps()                            # ["Firefox", "Slack", "Terminal", ...]
windows = tp.windows()                      # Window objects with title, position, size
all_els = tp.elements(app="Firefox", named_only=True)  # only elements with text labels

# Find
results = tp.find("Search", role=tp.Role.TEXT_FIELD, app="Firefox")

# Act
tp.set_value(results[0], "touchpoint python", replace=True)
tp.press_key("enter")
tp.hotkey("ctrl", "s")                      # keyboard shortcuts

# Wait for UI changes
tp.wait_for("results", app="Firefox", timeout=10)

# Screenshot
img = tp.screenshot()                       # full desktop → PIL.Image
img = tp.screenshot(app="Firefox")           # cropped to app window
元素 ID

每个元素都有唯一 ID,例如 atspi:1234:1:2.0 或 cdp:9222:TID:4。操作函数接受 Element 对象或纯 ID 字符串,方便在多个步骤之间存储引用:

results = tp.find("Send", max_results=1)
element_id = results[0].id                  # "atspi:1234:1:5.2"

# later...
tp.click(element_id)                        # works with just the string
输出格式

控制结果的返回方式:

tp.elements(app="Slack", format="flat")     # one compact line per element (best for LLMs)
tp.elements(app="Slack", format="tree")     # indented parent/child hierarchy
tp.elements(app="Slack", format="json")     # full JSON with all fields

MCP 服务

Touchpoint 提供了一个 MCP(Model Context Protocol) 服务,可供任何兼容 MCP 的客户端使用。借助它,Claude、Cursor、本地模型等大模型 Agent,或任何支持 MCP 的工具都能控制你的桌面。

两种模式 — 视觉与无视觉

设置 TOUCHPOINT_MODE=no-vision(默认值:vision)即可切换模式:

  • 视觉模式 — Agent 使用 screenshot() 查看屏幕,并通过元素 ID 或坐标进行交互。最适合视觉能力强的前沿模型。
  • 无视觉模式 — Agent 使用 snapshot() 获取活动窗口的精简结构化文本树,然后直接通过元素 ID 执行操作。适用于任何模型,包括不具备视觉能力的本地模型。大多数操作工具都会附加自动验证标记((new window: ...)、(focus moved)、(no change detected)),以便 Agent 无需截图即可检测状态变化。
工具
类别视觉模式无视觉模式
定位screenshot、snapshot、apps、windowssnapshot、diff_snapshot、apps、windows
查找find、get_elementfind
读取read_textread_text
操作click(元素或坐标)、set_value、set_numeric_value、select_text、focus、actionclick(仅元素)、set_value、set_numeric_value、select_text、focus、action
键盘type_text、press_keytype_text、press_key
鼠标mouse_move、scrollscroll
窗口activate_window、minimize_window、fullscreen_window、close_window、move_window、resize_windowactivate_window、minimize_window、fullscreen_window、close_window
等待wait_for、wait_for_app、wait_for_windowwait_for、wait_for_app、wait_for_window
健康状况diagnosticsdiagnostics

MCP 服务内置了指导 Agent 在各种模式下正确执行工作流的说明,包括 定位 → 操作 → 验证 循环、何时使用 read_text 而非 find,以及如何从错误中恢复。

         ┌──────────┐
    ┌───▶│  ORIENT  │  screenshot · apps · windows
    │    └────┬─────┘
    │         ▼
    │    ┌──────────┐
    │    │  LOCATE  │  find · snapshot · get_element
    │    └────┬─────┘
    │         ▼
    │    ┌──────────┐
    │    │   ACT    │  click · set_value · type_text · press_key
    │    └────┬─────┘
    │         ▼
    │    ┌──────────┐
    │    │  VERIFY  │───▶ Done ✅
    │    └────┬─────┘
    │         │ not yet
    └─────────┘
客户端设置
Claude Desktop

配置文件位置:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json
{
  "mcpServers": {
    "touchpoint": {
      "command": "touchpoint-mcp"
    }
  }
}

如果使用 virtualenv,请使用完整路径:"/path/to/venv/bin/touchpoint-mcp"

VS Code / GitHub Copilot

将以下内容添加到工作区中的 .vscode/mcp.json:

{
  "servers": {
    "touchpoint": {
      "command": "touchpoint-mcp"
    }
  }
}
Cursor

创建或编辑 ~/.cursor/mcp.json:

{
  "mcpServers": {
    "touchpoint": {
      "command": "touchpoint-mcp"
    }
  }
}
Windsurf

编辑 ~/.codeium/windsurf/mcp_config.json:

{
  "mcpServers": {
    "touchpoint": {
      "command": "touchpoint-mcp"
    }
  }
}
Claude Code (CLI)
claude mcp add touchpoint -- touchpoint-mcp
OpenClaw

将以下内容添加到 ~/.openclaw/openclaw.json 中的 mcpServers:

{
  "mcpServers": {
    "touchpoint": {
      "command": "touchpoint-mcp"
    }
  }
}
### 环境变量
所有设置均为可选 — 点击查看可用设置
变量示例说明
TOUCHPOINT_CDP_DISCOVERtrue自动从运行中的进程发现 CDP 端口
TOUCHPOINT_CDP_PORTS{"Chrome": 9222}显式指定应用与端口的映射(JSON)
TOUCHPOINT_CDP_APPGoogle Chrome单个应用名称(与 _PORT 配合使用)
TOUCHPOINT_CDP_PORT9222单个端口(与 _APP 配合使用)
TOUCHPOINT_CDP_REFRESH_INTERVAL5.0CDP 端口扫描的间隔秒数
TOUCHPOINT_SCALE_FACTOR1.25覆盖显示缩放比例
TOUCHPOINT_FUZZY_THRESHOLD0.6find() 的最低匹配分数(0.0–1.0)
TOUCHPOINT_FALLBACK_INPUTtrue原生操作失败时使用坐标回退
TOUCHPOINT_MAX_ELEMENTS5000每次查询的最大元素数
TOUCHPOINT_MAX_DEPTH20默认树深度限制
TOUCHPOINT_AX_MESSAGING_TIMEOUT1.0等待 macOS AX 应用回复的最长秒数

浏览器与 Electron 应用(CDP)

对于 Electron 和 Chromium 应用(Slack、Discord、VS Code 等),原生辅助功能 API 返回的数据有限。Touchpoint 的 CDP 后端通过 Chrome DevTools Protocol 连接,以获取完整的网页内容。

默认启用自动发现 — Touchpoint 会自动查找通过调试端口启动的运行中浏览器和 Electron 应用。除了使用标志启动应用外,无需手动配置。

设置
  1. 使用调试端口启动应用:
# Linux
google-chrome --remote-debugging-port=9222 --user-data-dir=/tmp/tp-chrome

# macOS
open -na "Google Chrome" --args --remote-debugging-port=9222 --user-data-dir=/tmp/tp-chrome

# Windows
start chrome --remote-debugging-port=9222 --user-data-dir=%TEMP%\tp-chrome
  1. 配置 Touchpoint:
import touchpoint as tp

tp.configure(cdp_discover=True)             # auto-discover from running processes
# or
tp.configure(cdp_ports={"Google Chrome": 9222})  # explicit mapping
  1. 使用 source 参数控制获取的内容:
tp.elements(app="Google Chrome", source="full")     # native chrome + web content (default)
tp.elements(app="Google Chrome", source="cdp_ax")   # web content only (CDP accessibility tree)
tp.elements(app="Google Chrome", source="native")   # native UI only (toolbar, tabs, menus)
tp.elements(app="Google Chrome", source="dom")      # DOM walker (catches what AX misses)

CDP 结果会与原生后端结果合并 — 在一次 elements() 调用中,你可以同时获得 AT-SPI2/UIA/AX 提供的工具栏和窗口控件,以及 CDP 提供的完整网页内容。

source="ax" 仍作为兼容性别名接受,对应 source="cdp_ax"。新代码中请优先使用 cdp_ax,以免与原生 macOS AX 后端混淆。


API 参考

发现
函数说明
tp.apps()列出辅助功能树中的应用名称
tp.windows()所有窗口及其 id、标题、应用、位置、大小和活动状态
tp.elements(app, role, states, ...)UI 元素,支持筛选、树模式和格式化
tp.element_at(x, y)屏幕坐标处最深层的元素
tp.get_element(id)按 ID 获取单个元素的最新快照
搜索与等待
函数说明
tp.find(query, app, role, ...)按名称搜索 — 4 阶段匹配:完全匹配 → 包含匹配 → 单词匹配 → 模糊匹配
tp.wait_for(query, ...)轮询直到元素出现(或设置 gone=True 时消失)
tp.wait_for_app(app, ...)轮询直到应用出现或消失
tp.wait_for_window(title, ...)轮询直到窗口出现或消失
操作
函数描述
tp.click(element)通过无障碍操作点击,坐标方式作为回退
tp.double_click(element)双击
tp.right_click(element)右键单击/打开上下文菜单
tp.set_value(element, text)设置文本内容(先清空请使用 replace=True)
tp.set_numeric_value(element, n)设置滑块或微调框的值
tp.select_text(element, text)在 Linux、Windows、macOS 和 web/CDP 中选择文本内容的子字符串
tp.select_text_range(element, start, end)已知偏移量时选择字符范围
tp.focus(element)将键盘焦点移至此处
tp.action(element, name)按名称执行原始无障碍操作
tp.activate_window(window)将窗口置于前台(从最小化状态还原)
tp.minimize_window(window)最小化窗口。使用 activate_window 还原。
tp.fullscreen_window(window, fullscreen=True)进入或退出窗口的全屏模式
tp.close_window(window)正常关闭窗口
tp.move_window(window, x, y)将窗口移至新的屏幕位置
tp.resize_window(window, width, height)将窗口调整为 width × height 像素
输入
函数描述
tp.type_text(text)在当前聚焦的元素中输入文本
tp.press_key(key)按下并释放按键("enter"、"tab"、"escape")
tp.hotkey(*keys)按键组合(tp.hotkey("ctrl", "s"))
tp.click_at(x, y)在屏幕坐标处单击
tp.double_click_at(x, y)在坐标处双击
tp.right_click_at(x, y)在坐标处右键单击
tp.mouse_move(x, y)移动光标
tp.scroll(direction, amount)在当前光标位置滚动
屏幕截图与配置
函数描述
tp.screenshot(app, element, ...)截取整个桌面,或裁剪为应用/窗口/元素/显示器范围
tp.monitor_count()已连接的显示器数量
tp.configure(...)设置运行时选项(参见配置)
tp.diagnostics()报告后端、输入、CDP、超时和依赖项的健康状况

所有操作函数都接受 Element 对象或字符串 ID。elements()、find() 和 get_element() 支持 format="flat"、format="json" 或 format="tree"(仅适用于元素),以返回预先格式化的字符串而非对象。窗口管理已通过 Linux AT-SPI2、Windows UIA 和 macOS AX 后端实现。


架构

┌───────────────────────────────────────────────────────┐
│               import touchpoint as tp                 │
│  tp.find() · tp.click() · tp.screenshot() · ...       │
│                    (Public API)                       │
├─────────────────────────┬─────────────────────────────┤
│     Backend (ABC)       │    InputProvider (ABC)      │
├─────────────────────────┼─────────────────────────────┤
│  AT-SPI2     (Linux)    │  Xdotool       (X11)        │
│  UIA         (Windows)  │  SendInput     (Win32)      │
│  AX          (macOS)    │  CGEvent       (macOS)      │
│  CDP         (browsers) │                             │
├─────────────────────────┴─────────────────────────────┤
│  Utilities: formatter · matcher · screenshot · scale  │
└───────────────────────────────────────────────────────┘

双层设计:

  • Backend 读取无障碍树并执行结构化操作(单击、set_value、focus)。感知元素,可靠性高。
  • InputProvider 模拟原始键盘和鼠标输入。基于坐标,无法感知元素。当无法使用原生无障碍操作时,会自动回退使用。

CDP 与平台后端并行运行。两者的结果会合并:来自 AT-SPI2/UIA/AX 的原生窗口界面(工具栏、标签页、菜单),加上来自 CDP 的完整网页内容,统一到一个 API 中。

如需了解详细的内部实现,请参阅 ARCHITECTURE.md。


配置

tp.configure(
    fuzzy_threshold=0.6,          # minimum match score for find() (0.0–1.0)
    fallback_input=True,          # use InputProvider when native actions fail
    type_chunk_size=40,           # split long text into chunks for typing (0 = disable)
    max_elements=5000,            # max elements per query
    max_depth=20,                 # default tree depth limit
    scale_factor=None,            # display scale override (None = auto-detect)
    cdp_ports={"Chrome": 9222},   # explicit CDP port mapping
    cdp_discover=True,            # auto-discover CDP ports from running processes
    cdp_refresh_interval=5.0,     # seconds between CDP target scans
    ax_messaging_timeout=1.0,     # max seconds to wait for a macOS AX app reply
)

tp.diagnostics() 返回便于转换为 JSON 的健康状况报告。报告包含 当前使用的后端、输入提供程序、CDP 目标、可选的平台工具、已配置的 超时时间,以及最近因 AX 消息超时而跳过的 macOS 应用。


开发

git clone https://github.com/Touchpoint-Labs/touchpoint.git
cd touchpoint
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
pytest

状态

Alpha — 已在所有三个平台上实现完整功能并通过测试。根据用户反馈,API 在 1.0 版本发布前可能会有变更。

平台后端输入CDP测试
Linux (X11)✅ AT-SPI2✅ xdotool✅✅
Windows✅ UIA✅ SendInput✅✅
macOS✅ AX✅ CGEvent✅✅
已知限制
  • Wayland 输入 — Linux InputProvider 使用 xdotool,需要 X11。在纯 Wayland(没有 XWayland)环境下,无法模拟键盘和鼠标。辅助功能树和原生操作仍可正常使用。

  • 同步 CDP — CDP 调用会阻塞,直到收到 WebSocket 响应。为避免死锁,JavaScript 对话框(alert、confirm、prompt)会自动关闭。计划重写为异步实现。

  • 没有浏览器导航 API — Touchpoint 不提供内置的 URL 导航功能。Agent 可以直接与 UI 元素交互来导航:找到地址栏,输入 URL,然后按 Enter。

  • CDP 窗口是页面目标,而不是操作系统窗口 — 但窗口管理仍可正常工作:tp.activate_window() 通过 CDP 将目标置于前台,而针对已显示的 cdp: 窗口执行 minimize/fullscreen/close/move/resize 时,会将操作路由到对应的原生操作系统窗口(通过所属 PID 确定),并由平台后端处理。只有在无法找到该目标对应的原生操作系统窗口时(例如该窗口已关闭),才会引发 ActionFailedError。

  • 后端角色/状态一致性仍不均衡 — macOS AX 和 Windows UIA 在 0.3.0 中都有显著改进,但 Windows 仍更多依赖启发式方法,且未映射的长尾角色也比其他后端更多。


路线图

高优先级
  • 异步 CDP 架构 — 非阻塞 WebSocket、完善的对话框排队机制、并发查询多个标签页
中优先级
  • 后端角色/状态一致性 — 弥合剩余的角色映射差异,尤其是 Windows 上 UIA 的长尾角色
  • Wayland 输入后端 — 在 X11 不可用时使用 libei / xdg-desktop-portal RemoteDesktop
低优先级
  • 工具提示和通知的可见性
  • 元素缓存

许可证

MIT

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。