mcpField
P
podium-mcp

podium-mcp

本地服务
github.com开发工具618 周前更新

关于 podium-mcp

podium-mcp 是面向移动端端到端测试与调试的 MCP 服务,为 iOS 模拟器和真机以及 Android 设备提供统一 stdio 入口。它整合原生界面自动化、WebView 与 React Native 检查,以及无需视觉识别的 Canvas/WebGL 操作。

主要功能

  1. 01控制 iOS 与 Android 设备和应用
  2. 02检查原生界面并执行自动化流程
  3. 03验证操作结果并返回证据
  4. 04检查 WebView DOM 与网络流量
  5. 05调试 React Native 与 Metro
  6. 06无视觉识别地操作 Canvas/WebGL

适用场景

  1. 01在移动设备上执行端到端流程
  2. 02复现缺陷并收集日志与崩溃报告
  3. 03检查 WebView 页面和请求
  4. 04自动化 Canvas 或 WebGL 界面

MCP 相关

提供包含 51 个工具的单一 MCP stdio 端点,供 MCP 客户端控制设备、执行测试并检查应用。

配置

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

mcp.json · 通用配置
{
"mcpServers": {
"hoainho-podium": {
"command": "npx",
"args": [
"-y",
"podium-mcp"
]
}
}
}
启动命令npx -y podium-mcp

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
npmpodium-mcp0.4.0

工具

51

收录的工具列表 · 更新于 2 周前

此工具无需参数。

详细介绍

podium-mcp

一根指挥棒。奏响所有乐器。

一个 MCP stdio 端点,提供 51 个工具,用于控制 iOS(模拟器 + 真机)和 Android 设备、自动化原生 UI、执行端到端流程、进行可信断言、调试 React Native、检查 WebView DOM + 网络,以及通过无视觉画布/WebGL 大脑操作 Pixi/Konva/Fabric/Phaser/Three/Babylon(已在 WebKit 中实时验证)——此外,还提供一座用于经过插桩的 Unity/GL 构建的实验性引擎桥接(AltTester)——只需一个连接,无需半打服务。

npm Glama mcp.so CI License: MIT

tools 51 tests 378 tokens ~5x cheaper canvas 6 live engines Node ≥22 TypeScript strict MCP stdio PRs welcome


podium-mcp Agent 会话——一个提示词即可在运行中的 iOS 模拟器上打开 Safari,输入 github.com/hoainho,浏览个人主页并打开一个代码仓库

一个提示词 → podium 实时操控 Safari → 输入 URL → 浏览个人主页 → 打开一个代码仓库。素材采集自运行中的 iPhone 16 Pro 模拟器。


指挥台是指挥家站立的地方——在同一处指挥整个乐团。此 MCP 服务通过一个 stdio 端点整合了八组能力:

  • 设备与应用管理 — 通过统一的平台标记设备模型管理 iOS 模拟器(simctl)、真实 iPhone(devicectl)和 Android(adb)。
  • 原生 UI 检查与手势 — 通过 idb/mobilecli 执行操作,并在必要时回退到 Maestro(不会为每个手势单独启动 JVM)。
  • 端到端流程与批量自动化 — 声明式 Maestro 流程、有序操作批次,以及工程师→QA 流程导出器。
  • 可信断言 — 预言机阶梯(WebView-DOM › 原生 a11y › Maestro),可返回可证伪且有证据支持的判定,并且验证失败时默认拒绝通过。
  • WebView DOM + 网络 — 将 WKWebView DOM 映射到点击坐标、执行 JS、驱动导航,并将页面内 HTTP 流量捕获为 JSON/HAR。
  • React Native 调试 — 通过 CDP 获取 Metro 控制台日志、网络请求和应用内状态,以及主机/模拟器崩溃报告。
  • 真机 — 通过 adb 操作 Android 模拟器/设备(手势 + uiautomator 层级结构);通过 devicectl 管理真实 iOS 设备生命周期,并可选择使用 WebDriverAgent 后端。
  • 画布与游戏引擎自动化,无需视觉 — 画布/WebGL 大脑将 Pixi/Konva/Fabric/Phaser/Three/Babylon UI 作为可寻址对象进行操作(已在 WebKit 中实时验证)。实验性引擎桥接通过 AltTester 插桩构建驱动 Unity/GL(或通过 window.__podiumEngine WebGL 桥接);代码已完成并通过模拟测试,但尚未在实时 Unity 构建中运行。 与其在每个客户端配置中接入多个 MCP 服务,podium-mcp 不如通过一个连接提供所有功能,并配备共享的 execFile 层(不使用 shell)、统一的结构化错误处理、针对 Maestro iOS 驱动不稳定问题的自动重试,以及一个健康检查工具,用于确认主机上有哪些可用功能。

目录

原因

要端到端驱动 React Native 应用,通常意味着要协调多个 MCP 服务—— 一个用于设备和应用控制,一个用于 UI 流程,一个用于 Metro/调试器日志,另一个 用于 WebView 检查——每个服务都有自己的配置项、特性和故障模式。 podium-mcp 将这些整合到一个服务中,并提供:

  • 一个基于 execFile 的命令运行器(不使用 shell——参数会原样传递),
  • 统一的结构化错误处理(工具不会导致服务崩溃),
  • 针对 Maestro 已知的 iOS 驱动不稳定问题自动重试,
  • 工具链(例如 adb)缺失时优雅降级,
  • 有证据支撑的判定,让 Agent 知道一个流程是否确实成功。

基准测试

Podium 基于两项选择构建,让它快速且成本低廉:它以结构化数据驱动 UI, 而非截图;并通过原生 后端路由手势,无需每次操作都启动 JVM。

Token 成本——无视觉模式约便宜 5 倍

基于截图的 Agent 会在每一步都向视觉模型发送图像。 Podium 则返回精简的结构化元素列表。在一个等效的 8 步 移动流程中(1179×2556 截图与约 20 个元素的列表相比):

方式每步8 步流程
截图 / 视觉循环~2,070 个 token16,557 个 token
Podium——无视觉、结构化数据~390 个 token3,117 个 token
节省5.3×−13,440 个 token(−81%)
vision loop  ████████████████████████████████  16,557 tokens
Podium       ██████  3,117 tokens   (5.3× cheaper, −81%)

差距会随着每一步不断扩大——一个 30 步的会话大约消耗 62k 对比 12k 个输入 token。除了每步成本外,完整的 51 个工具的 schema 会随 每个请求一同传输(约 3,612 个 token,约 71 个/工具);Podium 保持工具描述精简, 避免工具区块占据过多上下文窗口。

对于 canvas / WebGL UI,这项优势是结构性的,而不仅仅是成本更低: Canvas Brain 按名称和文本定位对象,而仅依赖截图的 Agent 必须 在每一帧都重新分析像素。

速度——原生优先的手势后端

手势通过 idb / mobilecli 路由,而不是每次操作都启动 Maestro 的 JVM (在运行中的 iPhone 16 Pro 模拟器上测得):

操作Maestro(每次调用都启动 JVM)Podium 原生模式加速比
tap_on~14.7 s~0.6 s~24×
inspect_screen~8.9 s~0.9 s~10×
一个连接,而非六个

全部 51 个工具——设备和应用控制、UI 自动化、声明式 Maestro 流程、有证据支持的断言、WebView DOM + 网络捕获、React Native / Metro 调试,以及无视觉画布/WebGL 自动化(另有用于已插桩 Unity/GL 的实验性引擎桥接)——都通过单个 stdio 端点提供,取代通常由六七个独立 MCP 服务组成的工具栈。

Token 数量是启发式估算值(约 4 个字符/token;Anthropic 的图像公式约为 750 px/token)——运行 npm run token-bench 可复现,也可以换用 Anthropic count_tokens API 获取精确数量。速度数据是在运行中的 iPhone 16 Pro 模拟器上测得的(npm run benchmark)。

要求

  • macOS,并安装 Xcode 命令行工具(xcrun、simctl)
  • Node.js ≥ 22(使用原生 fetch 和 WebSocket;.npmrc 设置了 engine-strict=true)
  • mobilecli——作为 npm 依赖自动捆绑;默认原生手势 + WebView 后端(无需单独安装)
  • (可选) idb(idb + idb_companion)——两者都存在时优先使用的原生手势后端;自动检测
  • (可选) 在 PATH 上(或位于 ~/.maestro/bin)的 Maestro——run_flow 引擎和手势回退路径
  • (可选) 正在运行的 Metro 打包器,供 metro_* 调试工具使用
  • (可选) Android SDK + adb——adb 路径仅用于检测;缺失时会优雅降级

平台范围(v0.3.0): podium 可自动化iOS 模拟器、真实 iPhone(通过 devicectl 管理生命周期 + 可选启用 WebDriverAgent)以及 Android 模拟器/设备(通过 adb 手势 + uiautomator 层级结构)。device_list 会为每个目标标记平台,并按目标选择后端。缺少某个工具链(例如 adb)时,相应路径会返回说明性结果,而不会失败。

安装

Claude Code 插件(推荐)

无需手动配置——只需一次性设置市场,然后安装:

/plugin marketplace add github:hoainho/podium-mcp
/plugin install podium-mcp@podium

该插件会自动启动 MCP 服务(全部 51 个工具),并提供五种技能:

技能调用方式功能
设备信息/podium-mcp:device-info <UDID> [<BUNDLE_ID>]健康检查、屏幕尺寸、方向、应用列表
E2E 流程/podium-mcp:e2e <UDID> <BUNDLE_ID> [path or description]运行或编写 Maestro 流程
Bug 复现/podium-mcp:bug-repro <UDID> <BUNDLE_ID> <description>捕获视频、日志和崩溃证据
RN 调试/podium-mcp:rn-debug [UDID] [logs|apps|crash|all]Metro 日志、已连接应用、崩溃报告
画布智能/podium-mcp:canvas <UDID> <intent>检查 / 解析 / 点击画布-WebGL UI,无需视觉识别
npx(零安装)
{
  "mcpServers": {
    "podium": { "command": "npx", "args": ["-y", "podium-mcp"] }
  }
}
手动安装(从源代码)
git clone [email protected]:hoainho/podium-mcp.git
cd podium-mcp
npm install
npm run build

用法

将构建好的服务注册到任意 MCP 客户端。Claude Code(.mcp.json):

{
  "mcpServers": {
    "podium": {
      "type": "stdio",
      "command": "node",
      "args": ["/absolute/path/to/podium-mcp/dist/index.js"]
    }
  }
}

通过原始 stdio 进行快速手动冒烟测试(列出已注册的 51 个工具):

printf '%s\n' \
  '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"smoke","version":"0"}}}' \
  '{"jsonrpc":"2.0","method":"notifications/initialized"}' \
  '{"jsonrpc":"2.0","id":2,"method":"tools/list"}' | node dist/index.js

请始终先调用 podium_health,确认主机上有哪些工具链可用。

快速入门(使用顺序)

  1. podium_health——确认 xcrun / maestro / 原生后端是否可用。
  2. device_list——选择已启动模拟器的 udid。
  3. 读取状态——app_list、app_state、screen_size、orientation_get。
  4. 操作设备——先调用 app_launch,再使用 tap_on / input_text / swipe / press_key,以及 set_location 和 orientation_set。使用 run_steps 批量执行多个操作。
  5. 编写并验证——使用 inspect_screen 发现元素,使用 run_flow 执行声明式检查,然后用 assert_visible / validate_flow 给出有证据支持的结论。
  6. 检查 WebView——webview_inspect → 点击坐标、webview_eval、webview_navigate、webview_network。
  7. 捕获并调试——screenshot / record_start→record_stop;metro_logs / metro_network / metro_state;crash_list / crash_get。

51 个工具

每个工具都会返回结构化 JSON,且不会抛出异常——失败会作为 MCP 工具错误返回。权威的参数说明请参阅 docs/tool-catalog.md。

**平台支持(v0.3.0):**以下手势、检查和生命周期工具可在 iOS 模拟器、真实 iPhone(devicectl + 通过 PODIUM_WDA_URL 选择启用 WebDriverAgent)和 Android(通过 adb 控制模拟器/设备;通过 uiautomator 获取层级结构)上运行。device_list 会为每台设备标注平台,并针对目标选择后端。

游戏引擎 — 通过 AltTester 使用 Unity / GL,无视觉 · 实验性(4)
工具关键参数底层引擎行为
engine_inspectudid, by?, valueAltTester(TCP)/ WebGL CDP 桥接按名称/路径/组件/文本列出引擎对象及其绝对屏幕坐标——不使用截图
engine_tapudid, by?, valueAltTester / CDP解析对象并点击其屏幕坐标
engine_swipeudid, fromX/Y, toX/Y, durationMs?AltTester / CDP在引擎视图内滑动
engine_calludid, by?, value, component, method, parameters?AltTester / CDP通过反射调用 C# 组件方法(相当于引擎版的 DOM 事件处理程序)

状态:实验性。线协议格式已通过模拟对象进行单元测试;AltTester 路径尚未通过实时 Unity 构建验证(提供经过插桩的构建前,engine-smoke 会跳过),且 Unity-WebGL 需要应用公开 window.__podiumEngine。引擎工具需要经过 AltTester 插桩的构建版本(开发/预发布),或 WebGL 桥接;在未经插桩的构建版本上,工具会安全失败并返回可执行的错误提示——绝不会回退到视觉方案。对于使用 JS 框架的 Canvas/WebGL 应用,下方的 Canvas 分析模块是经过验证的路径。

Canvas 分析模块 — Pixi/Konva/Fabric/Phaser/Three/Babylon,无视觉(3)
工具关键参数底层引擎行为
canvas_inspectudid, by?, value?, webviewId?注入式场景图桥接(CDP eval)列出 Canvas 对象及可直接用于点击的 CSS 像素坐标——不使用截图
canvas_resolveudid, intent, webviewId?桥接 + 语义解析器将模糊意图(“关闭”、“✕”)映射到按相关性排序且有依据的目标;若 confidentEnough 不满足则安全失败
canvas_tapudid, intent, bundleId?, webviewId?解析器 + 原生点击在绝对屏幕坐标处解析并点击有把握的匹配项(否则安全失败)

**已通过实时验证:**六个框架均通过了 DPR 为 1 和 3 的 Playwright-WebKit(≈ WKWebView)测试套件(npm run test:canvas,共 19 项测试)。Canvas 工具需要一个可检查的 WKWebView,其中托管受支持的框架,且能够访问其根对象(通常位于 window 上,或 Pixi 的 __PIXI_APP__)。没有框架/没有可检查的 WebView → 安全失败并返回可执行的错误提示——绝不会回退到视觉方案。

诊断(1)
工具关键参数底层引擎行为
podium_token_reportsteps?, screenshotWidth?, screenshotHeight?, elementsPerStep?, toolCount?token 估算器无视觉输入与截图/视觉循环的输入 token 数、节省比例,以及每个请求的工具定义开销
健康状态与工具链(1)
工具关键参数底层引擎行为
podium_health—which 探测不会失败;报告 toolchain { xcrun, maestro, adb }、原生后端以及 platforms: [ios-sim, ios-real, android]
设备与模拟器(6 项)
工具关键参数后端引擎行为
device_list—simctl list -j + adb devices合并后的 iOS 设备清单;如果没有 adb → android: { available: false }(仅检测)
device_bootudidsimctl boot幂等——如果设备已启动 → alreadyBooted: true;最多等待 30 s
screen_sizeudidsimctl io screenshot + sips{ widthPx, heightPx }(实际像素)
orientation_getudid原生查询 → 截图启发式判断{ orientation, basis }(原生查询时结果精确)
set_locationudid, latitude, longitudesimctl location set将 QA 地理位置转圈问题的修复固化为工具
open_urludid, urlsimctl openurl深层链接 + https://
应用(6 项)
工具关键参数后端引擎行为
app_installudid, path (.app/.zip)simctl install结构化工具错误
app_launchudid, bundleIdsimctl launch显式设置 30 s 超时(冷启动的 RN 应用不再被误报为失败)
app_terminateudid, bundleIdsimctl terminate结构化工具错误
app_uninstalludid, bundleIdsimctl uninstall结构化工具错误
app_listudidsimctl listapps + plutil{ count, apps: [{ bundleId, name, type }] }
app_stateudid, bundleIdsimctl listapps + launchctl{ installed, running }——按 bundle ID 精确匹配
捕获(3 项)
工具关键参数后端引擎行为
screenshotudid, saveTo?simctl io screenshot返回 path + byteSize(不会产生臃肿的 base64 数据)
record_startudid, saveTo? (.mp4)分离运行的 simctl io recordVideo{ ok, path, pid };带时间戳的路径 + 时长看护机制(PODIUM_MAX_RECORDING_MS);每个 udid 仅限一个
record_stopudid向录制器发送 SIGINT + 刷新{ ok, path, sizeBytes }
UI 检查与手势(8 项)
工具关键参数后端引擎行为
inspect_screenudid, compact?原生扁平 AX 列表 → maestro hierarchycompact:true(默认)仅返回有意义的节点
tap_onudid, bundleId, text|id|x+y, double?, long?原生点击 → Maestro 回退通过元素列表解析 text/id;报告 backend
input_textudid, bundleId, text, submit?原生 → Maestro 回退报告 backend
swipeudid, bundleId, direction, start/end?原生 → Maestro 回退根据逻辑屏幕尺寸解析 %/像素覆盖值
press_keyudid, bundleId, key原生 → Maestro 回退返回/电源/Tab 仅适用于 Android
orientation_setudid, bundleId, value原生 → Maestro 回退PORTRAIT / LANDSCAPE_LEFT / LANDSCAPE_RIGHT / UPSIDE_DOWN
tap_with_fallbackudid, x, y, maxRetries?, offsetStep?原生点击 + 前后预言机用于 WebGL/Canvas 覆盖层;不会盲目遍历(需选择启用 offsetStep)
notification_bar_clearudid, bundleId?原生点击 + 预言机关闭 RN 调试通知栏
流程与批量自动化(4 项)
工具关键参数后端引擎行为
run_stepsudid, bundleId, steps[]原生后端(idb/mobilecli)单次调用中按顺序批量执行操作;返回每步结果
run_flowudid + yaml/files/dir(+tags) 中的任意一项maestro test执行前验证是否恰好指定一项;返回每步的通过/失败结果
export_flowsteps[], output path流程生成器将 run_steps 批次导出为可复用的 Maestro 流程(工程师→QA 桥接)
cheat_sheet—内置的 assets/maestro-cheat-sheet.yaml完全离线的 Maestro 语法参考手册
断言与判定——预言机阶梯(5)
工具关键参数底层引擎行为
assert_visibleudid, text|id, …预言机阶梯(WebView-DOM › a11y › Maestro)给出有依据的通过/失败结果;报告用于证明结果的预言机
assert_textudid, text预言机阶梯assert_visible 的按文本简写形式
assert_not_visibleudid, text|id预言机阶梯默认判定为失败——如果无法验证元素不存在,就判定为失败
wait_for_elementudid, text|id, timeoutMs?预言机阶梯(轮询)轮询直至元素可见或超时
validate_flowudid, flow + assertions预言机阶梯 + 工作流运行对刚构建的工作流是否可用给出可信、可证伪的判定
WebView DOM 与网络(4)
工具关键参数底层引擎行为
webview_inspectudid, selector?, webviewId?, max?mobilecli(CDP)将 CSS 选择器解析为 DOM 元素,并提供绝对位置 tapX/tapY
webview_evaludid, expression, webviewId?mobilecli(CDP)在页面上下文中运行 JS;受 PODIUM_DISABLE_WEBVIEW_EVAL=1 控制
webview_navigateudid, action (goto/back/forward/reload), url?mobilecli(CDP)控制 WebView 导航
webview_networkudid, durationMs?, format (json/har)?, saveTo?, redact?, includeResources?CDP + 页面内 fetch/XHR shim + Resource Timing捕获 WebView 内的 HTTP 流量;导出已脱敏的 JSON 或 HAR 1.2
React Native 调试——Metro CDP(4)
工具关键参数底层引擎行为
metro_appsport? (8081)GET http://localhost:<port>/json区分不同错误(超时、未运行或其他错误)
metro_logswsUrl?/port?, durationMs?, maxLogs?WebSocket + CDP Runtime.enable未提供 URL 时自动发现首个应用
metro_networkwsUrl?/port?, durationMs?, maxEntries?CDP Network.enable请求(url/method/status/mimeType/ts)
metro_stateexpression?/wsUrl?/port?, timeoutMs?CDP Runtime.evaluate读取应用内状态(默认读取全局暴露的 Redux store)
崩溃诊断(2)
工具关键参数底层引擎行为
crash_listprocessName?, sinceHours?, udid?主机 + 模拟器 DiagnosticReports按时间从新到旧排列;标记 source: host | simulator
crash_getid, udid?同上防止路径遍历(仅使用 basename);如实截断

预言机阶梯——可信断言

“运行正常”被定义为有依据、可证伪的判定,而非“看起来没问题”。断言和 validate_flow 通过三级阶梯判定可见性,并使用最强的可用信号:

  1. WebView DOM——存在可检查的 WKWebView 时,查询真实 DOM。
  2. 原生辅助功能——原生 AX 元素集(通过 idb/mobilecli)。
  3. Maestro——作为后备方案使用 assertVisible/assertNotVisible。

assert_not_visible 默认判定为失败:如果无法确切验证元素不存在(例如 WebView 无法读取),就报告失败,而不是误报通过。每个判定都会指出得出结果的预言机,以便 Agent 评估其可信度。

原生优先的手势后端

命令式手势(tap_on、input_text、swipe、press_key、orientation_set、run_steps)和 inspect_screen 会通过当前最快的可用后端执行。系统只探测一次并缓存结果(同时设置较短的负缓存 TTL,以便启动后才运行的后端也能被检测到):

  1. idb —— 安装了 idb 和 idb_companion 时使用(原生,速度最快)。
  2. mobilecli —— 随附的 npm 依赖(预编译的 Go 二进制文件)。默认选项,无需安装。
  3. Maestro 回退 —— 没有可用的原生后端时,或需要执行原生后端无法表达的操作时使用(双击/长按、UPSIDE_DOWN)。手势会生成一个最简流程,其中包含 launchApp: { stopApp: false },将应用带到前台,但不会重启应用,因此可以保留状态。

每个结果都会报告所用的 backend。设置 PODIUM_DISABLE_NATIVE=1 可强制使用 Maestro。消除每次手势启动 JVM 的开销后,在 iPhone 16 Pro 模拟器上,tap_on 耗时从约 14.7 秒降至约 0.6 秒,inspect_screen 从约 8.9 秒降至约 0.9 秒。运行 npm run benchmark 可执行完整的通过/失败测试。

Maestro 不稳定时的重试机制: 使用回退后端时,其 iOS 驱动有时会报错:Failed to connect to 127.0.0.1:<port>。流程最多重试 2 次,间隔 2 秒/5 秒退避,并报告 retries 次数;如果仍然失败,则返回原始输出和修复提示。

WebView 和 RN 网络分析

两个独立的网络层,对应两个工具:

  • metro_network 通过 CDP Network 域捕获 RN/Hermes 目标上的请求——对于原生 RN 应用自身发出的 fetch,应使用此工具。
  • webview_network 捕获 WKWebView 内部的流量:它会注入 fetch/XHR 记录器(功能丰富——可捕获开始记录后调用的请求的方法、状态码、标头和正文),并且读取浏览器的 Performance Resource Timing 缓冲区(includeResources 默认开启),获取自导航以来的所有请求,包括开始记录前的请求(URL/时序/大小)。合并结果可生成近乎完整的请求列表,并可导出为经过脱敏的 JSON 或 HAR 1.2。

如果 RN 外壳在 WebView 中承载 UI,那么应用的 API 调用会在 Web 层执行,因此 metro_network 看不到这些请求,应使用 webview_network。WebView 工具要求 WKWebView.isInspectable = true(调试/预发布版本中默认开启,生产环境中关闭);如果找不到可检查的 WebView,工具会返回一条可采取行动的错误信息。

已说明的限制(属于设计如此,并非缺陷)

  • Canvas/WebGL 需要配合使用的 JS 框架 —— 当应用暴露场景图根节点(已通过实时验证)时,canvas 模块可按选择器操作 Pixi/Konva/Fabric/Phaser/Three/Babylon UI。原始/自定义 WebGL canvas、不透明/生产构建,或没有 AltTester/window.__podiumEngine 桥接的 Unity,都无法通过选择器定位——请改用基于截图坐标的 tap_with_fallback,或为构建添加检测机制。
  • WebView 工具仅供开发/QA 使用 —— 生产版 App Store 构建通常会设置 isInspectable = false;工具会返回可采取行动的错误信息,并回退到坐标点击。
  • 无法从应用沙盒读取 WebView 内容进程的内存(平台限制)——请使用间接信号(内存警告、进程终止)。
  • Maestro 的 text: 匹配器使用完整字符串正则表达式(IGNORE_CASE) —— 无法匹配部分字符串;请原样复制层级结构中的 text,或使用 .* 作为锚点。
  • Android 要求 adb 位于 PATH 中 —— adb 可用后,手势、检查和截图功能即可正常运行;如果缺少 adb,所有 Android 路径都会返回结构化的“未找到 adb”结果。
  • 没有原生后端时,orientation_get 使用截图宽高比进行启发式判断 —— iOS 模拟器不提供直接的方向查询。
  • record_start/record_stop 在进程内保存状态 —— 请在同一连接上按 start → … → stop 的顺序执行;每个 udid 同时只能有一项录制(如果录制始终未停止,监控程序会将其结束)。

架构

src/
  index.ts          # MCP server entry — registers every tool group, warms caches
  lib/
    exec.ts         # execFile-based runner (NO shell) + timeout/timedOut flag
    result.ts       # shared ok/error MCP content helpers
    simctl.ts       # xcrun simctl wrappers + device-list TTL cache
    native.ts       # gesture/inspect backend: idb → mobilecli → null (re-probe TTL)
    idb.ts          # idb gesture/inspect adapter
    gesture.ts      # unified native→Maestro executors (shared by screen + steps)
    oracle.ts       # the oracle ladder: WebView-DOM › a11y › Maestro
    maestro.ts      # Maestro engine: flow runner, idb retry, hierarchy
    export-maestro.ts # run_steps → reusable Maestro flow
    har.ts          # HAR 1.2 export for webview_network
    webview.ts      # mobilecli CDP — WebView list/inspect/eval/navigate/network
    metro.ts        # Metro CDP — app discovery, logs, network, state
    crash.ts        # DiagnosticReports crash listing/reading
    recording.ts    # detached screen recording lifecycle + watchdog (platform-aware)
    device-target.ts # DeviceTarget model + PlatformDriver registry (v0.3.0)
    drivers/        # per-platform lifecycle: ios-sim, android, ios-real
    adb.ts          # Android adb driver (list/install/launch/screenshot/wm size)
    adb-backend.ts  # adb gesture/inspect (input + uiautomator → AX elements)
    iosreal.ts      # real iOS via devicectl (list/install/launch) + capture
    wda.ts          # opt-in WebDriverAgent backend (/source + tap/swipe/keys)
    engine.ts       # no-vision engine client (AltTester + WebGL-in-WebView)
    engine-transport.ts # WebSocket transport for the AltTester bridge
    canvas-types.ts # Canvas Brain shared contract (CanvasObject, selectors)
    canvas-adapters.ts  # in-page bridge: detect + walk Pixi/Konva/Fabric/Phaser/Three/Babylon
    canvas-resolver.ts  # semantic "close brain": intent → ranked, evidenced target
    canvas-a11y.ts  # Flutter/ARIA fallback reader → CanvasObject (scaffolding, not wired — #9)
    canvas-vision.ts # opt-in vision fallback scaffolding (not wired — #9)
    token-report.ts # token estimators + no-vision vs vision-loop comparison
  tools/            # one file per group:
                    #   health, device, screen, steps, flow, assert, validate,
                    #   webview, debug, engine, canvas, token
assets/             # bundled offline Maestro cheat sheet + demo.gif
scripts/            # benchmark.ts, compare-mcps.ts, token-bench.mjs
e2e/                # smoke suites (smoke / full-smoke / webview-network-live / android-smoke / engine-smoke)
test/canvas-e2e/    # live Playwright-WebKit canvas bridge suite (6 frameworks)
docs/               # tool catalog, e2e transcript, roadmap, token-economics

开发与测试

npm run build       # tsc
npm run typecheck   # tsc --noEmit
npm test            # vitest run — 359 unit/integration tests (exec/network mocked, no sim needed)
npm run test:canvas # live canvas bridge suite in Playwright WebKit — 19 tests (run `npx playwright install webkit` first)
npm run benchmark   # spawn a fresh server over stdio and sweep the tool suite
node e2e/smoke.e2e.mjs        # real E2E against a booted simulator (macOS + Xcode)
node e2e/full-smoke.e2e.mjs   # drives the iOS-sim tool handlers (happy + structured-error paths)
node e2e/android-smoke.e2e.mjs # Android emulator/device smoke (story A3)
node e2e/engine-smoke.e2e.mjs  # AltTester engine smoke; skips without an instrumented build (story C4)

31 个文件中共有 359 项单元/集成测试,另有 19 项实时画布桥接测试(共 378 项),全部通过——其中包括 v0.3.0 设备目标注册表、Android adb 驱动程序和 uiautomator 解析器、AltTester 引擎客户端和 WebGL 桥接、devicectl/WDA 真实 iOS 解析器,以及 v0.2.0 判定阶梯、录制看门狗、手势一致性、HAR 导出、WebView 和 Metro 流程。

标准:TypeScript 严格模式,不使用 as any / @ts-ignore,不执行 shell 命令(所有命令均通过 lib/exec.ts 执行),工具返回结构化错误,而不是抛出异常。请参阅 CONTRIBUTING.md 中的“添加新工具”检查清单。

CI 上的端到端测试:E2E (simulator) 工作流会在 macOS 运行器上启动真实的 iOS 模拟器,并每晚及按需运行冒烟测试套件(不作为 PR 门禁——模拟器运行速度较慢)。full-smoke.e2e.mjs 会验证目标存在时的正常路径,以及依赖缺失时的真实结构化错误路径(用于 WebView 的调试版 isInspectable 应用;用于 metro_* 的已连接 RN 应用)。

路线图与贡献

podium-mcp 已可用于生产环境中的 iOS/Android UI 自动化和无视觉画布/WebGL(Pixi/Konva/Fabric/Phaser/Three/Babylon——已通过实时验证)。贡献者可以切实推进的前沿领域,位于尚未解决的问题中:

高影响力——help wanted

  • #1 — 使用实时插桩的 Unity 构建验证 AltTester/Unity 引擎路径(这是实现真实 Unity 自动化的最大缺口)。
  • #2 — 为画布核心实现真实设备上的 WKWebView 端到端测试(目前已在 Playwright WebKit 中验证)。
  • #3 — Unity-WebGL 适配器:自动检测并提供可直接接入的 window.__podiumEngine 桥接。

适合入门的问题——good first issue

  • #4 — 添加更多画布适配器(PlayCanvas、Cocos Creator、p5.js)。
  • #5 — 提供 canvas_hittest / canvas_object_rect 工具。
  • #7 — 通过 Anthropic count_tokens API 获取精确的 token 数量。
  • #6 — 处理 Konva Group/Container 目标。

添加工具请遵循 CONTRIBUTING.md 中的一份检查清单:TypeScript 严格模式、不使用 shell、结构化错误且绝不抛出异常、添加 vitest 测试,并在工具目录中添加一行。欢迎提交 PR。

发布

server.json 是 MCP Registry 的官方清单。推送 v* 标签后,会依次运行 Publish to npm 和 Publish to MCP Registry(io.github.hoainho/* 命名空间使用 GitHub OIDC——无需长期有效的令牌)。两个工作流都会先运行 typecheck → build → test 作为门禁;只有匹配的 npm 版本发布后,Registry 发布才会成功,且版本不可变。

提示词指南与参考资料

  • prompts/ — 可直接复制粘贴的提示词,适用于端到端流程、测试用例、功能验证、错误修复和设备控制。每条提示词都会注明其驱动的 podium 工具,并已在真实模拟器上验证。请从 prompts/README.md 开始。
  • docs/tool-catalog.md — 权威的逐工具参考文档。
  • docs/e2e-demo.md — 在已启动的 iPhone 16 Pro 模拟器上运行生产级 RN 应用时的真实交互记录。

设计理念

  • 一个统一入口,一次连接。 单个服务为所有移动端功能提供入口,因此 Agent 只需配置一个端点,即可一次性发现全部 51 个工具。
  • 从设计上保障安全。 所有外部命令都通过 execFile 层执行,并使用明确的参数数组,绝不使用 shell 字符串。
  • 绝不让主控程序崩溃。 工具会返回结构化结果和错误,而不是抛出异常;一次调用失败不会导致服务停止运行。
  • 降级运行,而非直接失败。 如果缺少工具链(例如 Android 的 adb),会返回说明性结果,而不是硬性报错。
  • 以证据为准,不靠猜测。 断言通过 oracle 梯级返回有证据支持的判定;无法验证时则采用失败关闭策略。

贡献

欢迎贡献,请参阅 CONTRIBUTING.md 和 行为准则。报告错误和提出功能请求时,请使用 issue 模板。

安全

请按照 SECURITY.md 中的说明私下报告漏洞,不要公开提交 issue。 SECURITY.md 还说明了 webview_eval / run_flow 的信任边界,以及对话记录中可能包含个人身份信息(PII)的注意事项。

许可证

MIT © 2026 hoainho

评论

支持 Markdown

第一次接触 MCP?

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

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