Skip to content
verify mcp Beta VerifyMCP is currently in beta. If you notice any issues, get in touch and we’ll put it right.

io.github.hoainho/podium-mcp

NPM · PODIUM-MCP · SCANNED SEP 20

Mobile E2E MCP (51 tools): iOS + Android, native UI + canvas/WebGL, no-vision, RN debug

Available components

0 this week 81 Trust /100
Trust breakdown (7 categories)

How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. How we score → Why this is hard to score →

Supply Chain Security98
  • No malware found by supply-chain analysis.Pass
  • No known CVEs affecting this package version or its production dependencies.Pass
  • No install/post-install scripts declared.Pass
  • 31 of 97 dependencies flagged as unhealthy. View diagnostics → Partial
Provenance & Transparency48
  • Source repository is publicly reachable at the declared URL. View diagnostics → Pass
  • Provenance check failed: no build-provenance attestation is published. See how to fix → View diagnostics → Fail
  • Clear OSI-approved license (MIT).Pass
  • Actively maintained (last published 68 days ago).Pass
  • Publishes a security disclosure policy (SECURITY.md).Pass
Schema Quality & AI Usability73
  • AI-judged instruction clarity (excellent).Pass
  • Context-footprint check failed: tool/resource definitions use about 7562 tokens (~148/item across 51 items; 51 tools + 0 resources), over budget; trim descriptions and params. See how to fix → Fail
  • Usage-examples check failed: none of the tools include examples. See how to fix → Fail
Stability & Change Management90
  • Stability observed for 27 of 30 days with no destabilising changes; credit accrues until the full window elapses.Partial
Tool Coverage99
  • 100% of tools have a non-trivial description (not blank, and not just the tool's name).Pass
  • 96% of tool parameters carry a description.Partial
Tool Safety75
  • No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.Pass
  • 0 of 6 tool(s) whose name or description implies an irreversible operation declare an MCP destructiveHint annotation; "app_terminate" implies "terminate" and declares no destructiveHint at all, which the MCP spec reads as destructive by default. See how to fix → Fail
  • An AI judge read all 51 captured unit(s) of tool text and found none that tries to manipulate the model reading it.Pass
Capabilities100
  • Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.Pass
Install

How do I install the io.github.hoainho/podium-mcp server?

io.github.hoainho/podium-mcp runs locally as an npm package, launched with npx -y podium-mcp. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.

npm · podium-mcp

# add to Claude Code
claude mcp add hoainho-podium-mcp -- npx -y podium-mcp
// .cursor/mcp.json
{
  "mcpServers": {
    "hoainho-podium-mcp": {
      "command": "npx",
      "args": [
        "-y",
        "podium-mcp"
      ]
    }
  }
}
// .vscode/mcp.json
{
  "servers": {
    "hoainho-podium-mcp": {
      "command": "npx",
      "args": [
        "-y",
        "podium-mcp"
      ]
    }
  }
}
# add to Codex CLI
codex mcp add hoainho-podium-mcp -- npx -y podium-mcp
// opencode.json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "hoainho-podium-mcp": {
      "type": "local",
      "command": [
        "npx",
        "-y",
        "podium-mcp"
      ],
      "enabled": true
    }
  }
}
# add to OpenClaw
openclaw mcp add hoainho-podium-mcp --command npx --arg -y --arg podium-mcp
# ~/.hermes/config.yaml
mcp_servers:
  hoainho-podium-mcp:
    command: "npx"
    args: ["-y", "podium-mcp"]
// ~/.netclaw/config/netclaw.json
{
  "McpServers": {
    "hoainho-podium-mcp": {
      "Transport": "stdio",
      "Command": "npx",
      "Arguments": [
        "-y",
        "podium-mcp"
      ]
    }
  }
}
# add to Vellum
assistant mcp add hoainho-podium-mcp -t stdio -c npx -a -y podium-mcp
// mcp.json
{
  "mcpServers": {
    "hoainho-podium-mcp": {
      "command": "npx",
      "args": [
        "-y",
        "podium-mcp"
      ]
    }
  }
}
Changelog

Every change we have recorded for this component, newest first. Security-relevant changes are always shown. ▲ marks a change for the better, ▼ a change for the worse; unmarked changes are neutral.

  • 19 Sept 26 +1

    No change was recorded against any check on this day. Stability & Change Management went from 83 to 87. That category is still filling its 30-day observation window: 25 days of observed history at the previous scan, 26 at this one. The score rises as the window fills, whether or not the server changes.

  • 17 Sept 26 −3
    • Stability: pass → 0.80 functional
  • 16 Sept 26 +1
    • Stability: 0.97 → pass security
  • 14 Sept 26 +1

    No change was recorded against any check on this day. Stability & Change Management went from 90 to 93. That category is still filling its 30-day observation window: 27 days of observed history at the previous scan, 28 at this one. The score rises as the window fills, whether or not the server changes.

  • 12 Sept 26 +1

    No change was recorded against any check on this day. Stability & Change Management went from 83 to 87. That category is still filling its 30-day observation window: 25 days of observed history at the previous scan, 26 at this one. The score rises as the window fills, whether or not the server changes.

  • 10 Sept 26 −3
    • Stability: pass → 0.80 functional
  • 9 Sept 26 +1
    • Stability: 0.97 → pass security
  • 7 Sept 26 +1

    No change was recorded against any check on this day. Stability & Change Management went from 90 to 93. That category is still filling its 30-day observation window: 27 days of observed history at the previous scan, 28 at this one. The score rises as the window fills, whether or not the server changes.

Diagnostics

Diagnostic detail from the automated scan of this channel: what the scanner observed at each step, so you can see exactly where a check passed or failed. It is informational only and never changes the trust score.

Captured 20 Sept 2026 · Analysed npm/podium-mcp@0.4.0

Provenance No attestation

The registry publishes no build provenance for this version, so there is nothing to verify.

Result No attestation
Ecosystem npm

Background: How many MCP packages publish verified provenance →

Dependencies 97 packages
Packages resolved 97
Stale 31
Tree resolution Complete

Background: SBOMs and build attestations, explained →

MCP tools · 51 exposed · ~7,562 tokens

The tools this component advertises to a client, with an estimated token cost for each. Expand a tool to see its parameters and schema. The per-tool counts are indicative and are not scored directly; the schema's total context footprint is one signal in Schema Quality & AI Usability. A tool's description is untrusted text the model reads on every call, which is what makes this list a security surface and not just an inventory: how tool poisoning works →

Tool Tokens
app_install ~63

Installs an app on an iOS simulator. Accepts a path to a .app directory or a .zip archive.

NameTypeReqDescription
pathstringyesPath to the .app directory or .zip file to install
udidstringyesSimulator UDID

No output schema declared.

No examples provided.

app_launch ~51

Launches an app on an iOS simulator by bundle ID.

NameTypeReqDescription
bundleIdstringyesApp bundle identifier (e.g. com.example.MyApp)
udidstringyesSimulator UDID

No output schema declared.

No examples provided.

app_list ~51

Returns the list of installed apps on a booted iOS simulator. Includes bundle ID, display name, and application type (User/System).

NameTypeReqDescription
udidstringyesSimulator UDID (from device_list)

No output schema declared.

No examples provided.

app_state ~91

Checks whether an app is installed and/or running on an iOS simulator. installed: exact bundle-id match against the parsed simctl listapps output; running: matches the launchctl UIKitApplication:<bundleId> label on a token boundary (no prefix false positives).

NameTypeReqDescription
bundleIdstringyesApp bundle identifier (e.g. com.example.MyApp)
udidstringyesSimulator UDID

No output schema declared.

No examples provided.

app_terminate ~45

Terminates a running app on an iOS simulator by bundle ID.

NameTypeReqDescription
bundleIdstringyesApp bundle identifier
udidstringyesSimulator UDID

No output schema declared.

No examples provided.

app_uninstall ~55

Uninstalls an app from an iOS simulator by bundle ID.

NameTypeReqDescription
bundleIdstringyesApp bundle identifier to uninstall (e.g. com.example.MyApp)
udidstringyesSimulator UDID

No output schema declared.

No examples provided.

assert_not_visible ~185

Asserts an element/text is ABSENT. FAILS CLOSED: if absence cannot be verified (e.g. a WebView whose DOM is unreadable — native a11y is blind to web content), returns an 'unverifiable' error rather than a false pass. Passes only when a capable oracle confirms absence.

NameTypeReqDescription
bundleIdstringApp bundle id for the Maestro fallback (native surface)
containsbooleanSubstring match for text (default false = exact full-string on native a11y). WebView innerText is always substring.
selectorstringCSS selector — WebView surfaces only
textstringVisible text to match (native a11y / WebView innerText)
timeoutMsintegerConfirmation budget (default 1500)
udidstringyesSimulator UDID

No output schema declared.

No examples provided.

assert_text ~113

Asserts the given text is visible on screen (by-text shorthand for assert_visible). Same oracle ladder + unverifiable handling.

NameTypeReqDescription
bundleIdstringApp bundle id for the Maestro fallback (native surface)
containsbooleanSubstring match for text (default false = exact full-string on native a11y). WebView innerText is always substring.
textstringyesVisible text to assert
timeoutMsinteger
udidstringyesSimulator UDID

No output schema declared.

No examples provided.

assert_visible ~197

Asserts an element/text is visible, via the oracle ladder (WebView-DOM > native a11y > Maestro). Passes only when a capable oracle confirms presence; if the surface is a WebView whose DOM can't be read (isInspectable=false), returns an 'unverifiable' error instead of a false pass. Provide text (any surface) or selector (WebView).

NameTypeReqDescription
bundleIdstringApp bundle id for the Maestro fallback (native surface)
containsbooleanSubstring match for text (default false = exact full-string on native a11y). WebView innerText is always substring.
selectorstringCSS selector — WebView surfaces only
textstringVisible text to match (native a11y / WebView innerText)
timeoutMsintegerPoll budget (default 3000)
udidstringyesSimulator UDID

No output schema declared.

No examples provided.

canvas_inspect ~199

Lists canvas/WebGL objects (Pixi/Konva/Fabric/Phaser/Three/Babylon) as DOM-like elements with tap-ready coordinates — NO screenshot/vision. Optionally filter by selector (name/id/text/type/role). Requires an inspectable WKWebView (isInspectable=true; debug/staging) hosting a canvas/WebGL framework (Pixi/Konva/Fabric/Phaser/Three/Babylon) with its root reachable (commonly on window, or Pixi's __PIXI_APP__). NO screenshots/vision — fails closed otherwise.

NameTypeReqDescription
bystringSelector kind to filter by (omit to list all)
udidstringyesSimulator / device UDID (from device_list)
valuestringSelector value (required when 'by' is given)
webviewIdstringTarget WebView id. Omit to auto-select the first visible one.

No output schema declared.

No examples provided.

canvas_resolve ~198

Resolves a fuzzy intent (e.g. "close", "settings", "✕") to a ranked, EVIDENCED canvas target without tapping — the 'close brain'. Returns the best match, all candidates with reasons, and a fail-closed confidentEnough flag (false when two targets tie). NO vision. Requires an inspectable WKWebView (isInspectable=true; debug/staging) hosting a canvas/WebGL framework (Pixi/Konva/Fabric/Phaser/Three/Babylon) with its root reachable (commonly on window, or Pixi's __PIXI_APP__). NO screenshots/vision — fails closed otherwise.

NameTypeReqDescription
intentstringyesWhat you want to act on, e.g. "close", "play", "settings"
udidstringyesSimulator / device UDID
webviewIdstringTarget WebView id. Omit to auto-select.

No output schema declared.

No examples provided.

canvas_tap ~213

Resolves an intent to a single canvas target and TAPS it at absolute screen coordinates — the native-like 'close this' for canvas UIs. Fail-closed: if no confident, unambiguous match exists it does NOT tap and returns the candidates so you can disambiguate. NO vision. Requires an inspectable WKWebView (isInspectable=true; debug/staging) hosting a canvas/WebGL framework (Pixi/Konva/Fabric/Phaser/Three/Babylon) with its root reachable (commonly on window, or Pixi's __PIXI_APP__). NO screenshots/vision — fails closed otherwise.

NameTypeReqDescription
bundleIdstringApp bundle id (only used for the Maestro tap fallback)
intentstringyesWhat to tap, e.g. "close", "play", or an exact object name
udidstringyesSimulator / device UDID
webviewIdstringTarget WebView id. Omit to auto-select.

No output schema declared.

No examples provided.

cheat_sheet ~43

Returns the bundled Maestro flow script cheat sheet (offline copy). Consult this before authoring unfamiliar Maestro commands, required args, nested properties, conditionals, or multi-screen flows.

Input schema present but exposes no named parameters.

No output schema declared.

No examples provided.

crash_get ~105

Reads a crash report by its id (filename from crash_list). For .ips files returns a parsed JSON header and the report body (first ~8000 chars, truncated flag set if longer). Pass the same udid used for crash_list to also resolve sim-container reports. Path-traversal-safe.

NameTypeReqDescription
idstringyesCrash report filename (id from crash_list)
udidstringSimulator UDID — also looks in that sim's container DiagnosticReports

No output schema declared.

No examples provided.

crash_list ~112

Lists crash reports (.ips/.crash) from ~/Library/Logs/DiagnosticReports — plus the simulator's own container DiagnosticReports when udid is given — sorted newest first. Filter by processName (case-insensitive substring) and/or sinceHours.

NameTypeReqDescription
processNamestringCase-insensitive substring to filter by process name
sinceHoursnumberOnly include crashes from the last N hours
udidstringSimulator UDID — also scans that sim's container DiagnosticReports

No output schema declared.

No examples provided.

device_boot ~66

Boots an iOS simulator by UDID. Waits up to 30 seconds for the boot command to complete. Idempotent: booting an already-booted device returns ok with alreadyBooted:true.

NameTypeReqDescription
udidstringyesSimulator UDID (from device_list)

No output schema declared.

No examples provided.

device_list ~77

Returns a merged inventory of available iOS simulators (udid, name, state, runtime) plus any adb-detected Android devices. If adb is absent, the android section reports availability: false instead of failing. NOTE: Android entries are detection-only — podium's automation tools (tap/inspect/etc.) currently target iOS simulators.

Input schema present but exposes no named parameters.

No output schema declared.

No examples provided.

engine_call ~142

Invokes a C# component method on a game-engine object by reflection — the engine analog of firing a DOM event handler. Requires an AltTester-instrumented build (dev/staging) with the in-app server running — production App Store builds are not instrumented. Uses no screenshots/vision.

NameTypeReqDescription
bystring
componentstringyesComponent (script) name, e.g. ScoreController
methodstringyesMethod name to invoke
parametersarrayMethod parameters (default none)
udidstringyesDevice UDID / Android serial
valuestringyesSelector value identifying the object

No output schema declared.

No examples provided.

engine_inspect ~119

Lists game-engine (Unity/GL) objects matching a selector, each with absolute screen coordinates for tapping — DOM-like addressing with NO vision. Requires an AltTester-instrumented build (dev/staging) with the in-app server running — production App Store builds are not instrumented. Uses no screenshots/vision.

NameTypeReqDescription
bystringSelector kind (default: name)
udidstringyesDevice UDID / Android serial
valuestringyesSelector value (object name, hierarchy path, component, or text)

No output schema declared.

No examples provided.

engine_swipe ~118

Swipes between two screen coordinates inside a game-engine view. Requires an AltTester-instrumented build (dev/staging) with the in-app server running — production App Store builds are not instrumented. Uses no screenshots/vision.

NameTypeReqDescription
durationMsintegerSwipe duration in ms (default 300)
fromXnumberyes
fromYnumberyes
toXnumberyes
toYnumberyes
udidstringyesDevice UDID / Android serial

No output schema declared.

No examples provided.

engine_tap ~98

Taps a game-engine object resolved by selector (engine-reported screen coords, no vision). Requires an AltTester-instrumented build (dev/staging) with the in-app server running — production App Store builds are not instrumented. Uses no screenshots/vision.

NameTypeReqDescription
bystring
udidstringyesDevice UDID / Android serial
valuestringyesSelector value identifying the object to tap

No output schema declared.

No examples provided.

export_flow ~141

Exports a run_steps action sequence to a reusable Maestro flow (the engineer→QA bridge). Selector-based steps (tapText by id/text, key, swipe-by-direction, waitFor, assertVisible, screenshot) transpile cleanly. The lossy steps — coordinate tap/swipe, focused-field type, regex tapText — are emitted as commented '# TODO[unstable]' lines plus a warnings[] list, never as silently divergent YAML. Fix the TODOs to make the flow durable regression.

NameTypeReqDescription
bundleIdstringyesApp bundle id for the flow's appId header
stepsarrayyesThe run_steps action array to transpile

No output schema declared.

No examples provided.

input_text ~177

Types text into the currently-focused element via an ephemeral Maestro flow. Set submit:true to press Enter after typing. Note: Android does not support Unicode via inputText. WebView caveat: inputText injects at the native buffer level — React onChange/onChangeText never fires. For WebView forms use mobile-mcp mobile_type_keys (real keystroke simulation) instead.

NameTypeReqDescription
bundleIdstringyesApp bundle identifier
noLaunchbooleanSkip the implicit launchApp attach step (default false). Set true when an open modal or navigation state must not be disturbed.
submitbooleanPress Enter after typing (default false)
textstringyesText to type
timeoutMsintegerFlow timeout in ms
udidstringyesSimulator / device UDID

No output schema declared.

No examples provided.

inspect_screen ~205

Returns the current view hierarchy for a booted iOS simulator (podium's target platform). Uses idb's flat accessibility tree when idb is installed (fast), else maestro hierarchy. Defaults to compact:true — a flattened list of only the nodes that carry text / accessibility labels / resource-ids (dramatically smaller than the raw tree). Pass compact:false for the full nested hierarchy. LIMITATION: WebView (WKWebView/WebView) content is opaque — the hierarchy shows a single WebView node with no children. Web-rendered buttons, inputs, and labels are invisible to this tool. For WebView apps, identify elements visually via screenshot then calculate logical-point coordinates (screenshot pixels ÷ device scale factor, typically ÷3 on 3× Retina).

NameTypeReqDescription
compactbooleanReturn a flattened list of meaningful nodes only (default true). false = full nested tree.
udidstringyesSimulator / device UDID (from device_list)

No output schema declared.

No examples provided.

metro_apps ~66

Lists React Native apps currently connected to a Metro bundler inspector. Returns CDP-style targets (id, title, webSocketDebuggerUrl). Returns a structured error if Metro is not running on the given port.

NameTypeReqDescription
portintegerMetro dev server port (default 8081)

No output schema declared.

No examples provided.

metro_logs ~189

Reads console logs from a React Native app via the Metro CDP debugger. If webSocketDebuggerUrl is omitted, auto-discovers via metro_apps and uses the first connected app. Reports which app was chosen. Pass saveTo to also write the console timeline to a file for evidence (e.g. attach to a bug).

NameTypeReqDescription
durationMsintegerHow long to collect logs in milliseconds (default 3000)
maxLogsintegerMaximum number of log entries to return (default 100, keeps most recent)
portintegerMetro port for auto-discovery (default 8081)
saveTostringOptional file path; writes the console timeline (one line per entry: [level ts] text) for evidence.
webSocketDebuggerUrlstringCDP WebSocket URL from metro_apps. Omit to auto-discover.

No output schema declared.

No examples provided.

metro_network ~306

Captures network requests from a React Native app via the Metro CDP debugger (Network domain). If webSocketDebuggerUrl is omitted, auto-discovers via metro_apps and uses the first connected app. Pairs requestWillBeSent with responseReceived by requestId (method, url, status, headers, timing). format:'har' emits a valid HAR 1.2 log (HAR-lite — no response bodies yet) you can open in Chrome DevTools → Import HAR; pass saveTo to write the .har file. Sensitive headers (authorization/cookie/…) are REDACTED by default — set redact:false to keep them (don't commit unredacted HAR: it leaks tokens).

NameTypeReqDescription
durationMsintegerHow long to capture network activity in milliseconds (default 3000)
formatstringOutput format: 'json' (default, structured entries) or 'har' (HAR 1.2 log).
maxEntriesintegerMaximum request entries to return (default 100, keeps most recent)
portintegerMetro port for auto-discovery (default 8081)
redactbooleanMask sensitive headers (authorization/cookie/set-cookie/…). Default true.
saveTostringOptional file path to write the output (a .har file when format:'har').
webSocketDebuggerUrlstringCDP WebSocket URL from metro_apps. Omit to auto-discover.

No output schema declared.

No examples provided.

metro_state ~186

Reads app state from a React Native app by evaluating a JS expression in its runtime via the Metro CDP debugger (Runtime.evaluate, returnByValue). Default expression reads a globally-exposed Redux store; override `expression` to read any in-app value. The app must expose the value on a global the runtime can reach. Auto-discovers the ws via metro_apps when omitted.

NameTypeReqDescription
expressionstringJS expression to evaluate (default: a globally-exposed Redux store's getState()). e.g. "store.getState().user" or "globalThis.__APP_STATE__".
portintegerMetro port for auto-discovery (default 8081)
timeoutMsintegerEvaluation timeout in ms (default 5000)
webSocketDebuggerUrlstringCDP WebSocket URL from metro_apps. Omit to auto-discover.

No output schema declared.

No examples provided.

notification_bar_clear ~153

Attempts to dismiss the React Native debug notification bar that sometimes appears at the bottom of the screen and intercepts taps. Taps the debug icons area at (50, 850) via the native backend (idb, else Maestro) and takes a before/after screenshot. NOTE: the (50,850) tap point is a device-specific heuristic, and 'cleared' is decided by a screenshot byte-size delta — a best-effort signal, not a guarantee (see tap_with_fallback caveat).

NameTypeReqDescription
bundleIdstringApp bundle id for the Maestro fallback (ignored when idb is present). Auto-detected if omitted.
udidstringyesSimulator / device UDID

No output schema declared.

No examples provided.

open_url ~48

Opens a URL on an iOS simulator (deep-links, https:// etc.).

NameTypeReqDescription
udidstringyesSimulator UDID
urlstringyesURL to open on the simulator

No output schema declared.

No examples provided.

orientation_get ~55

Returns the current orientation of a booted iOS simulator. Queries the native backend (mobilecli) when available for an exact answer; otherwise derives it from the screenshot aspect ratio.

NameTypeReqDescription
udidstringyesSimulator UDID

No output schema declared.

No examples provided.

orientation_set ~155

Sets the screen orientation on an iOS simulator via an ephemeral Maestro flow. bundleId is required (Maestro needs it for the appId flow header). Valid values: PORTRAIT, LANDSCAPE_LEFT, LANDSCAPE_RIGHT, UPSIDE_DOWN

NameTypeReqDescription
bundleIdstringyesApp bundle identifier
noLaunchbooleanSkip the implicit launchApp attach step (default false). Set true when an open modal or navigation state must not be disturbed.
timeoutMsintegerFlow timeout in ms
udidstringyesSimulator / device UDID
valuestringyesTarget orientation: PORTRAIT | LANDSCAPE_LEFT | LANDSCAPE_RIGHT | UPSIDE_DOWN

No output schema declared.

No examples provided.

podium_health ~80

Returns health status of the podium-mcp server and toolchain availability. Scope: iOS (simulator + real device), Android (emulator + real via adb), game-engine (Unity/GL via AltTester), and no-vision canvas/WebGL automation. macOS + Xcode required; adb for Android, an instrumented build for engine tools.

Input schema present but exposes no named parameters.

No output schema declared.

No examples provided.

podium_token_report ~162

Quantifies Podium's token savings: for an N-step flow, computes input tokens for Podium's no-vision structured flow vs a screenshot/vision loop, the savings ratio, and the fixed per-request tool-definition overhead. Heuristic estimates (~4 chars/token text, ~750 px/token image) — deterministic, no network.

NameTypeReqDescription
elementsPerStepintegerStructured elements returned per step (default 20)
screenshotHeightintegerVision-loop screenshot height px (default 2556)
screenshotWidthintegerVision-loop screenshot width px (default 1179)
stepsintegerFlow length (default 8)
toolCountintegerRegistered tool count for the overhead estimate (default 51)

No output schema declared.

No examples provided.

press_key ~157

Presses a hardware or system key via an ephemeral Maestro flow on the iOS simulator. Note: back/power/tab are Android key events and have no effect on iOS — they remain in the enum for a future Android backend. Valid keys: enter, home, lock, backspace, volume up, volume down, back, power, tab

NameTypeReqDescription
bundleIdstringyesApp bundle identifier
keystringyesKey to press
noLaunchbooleanSkip the implicit launchApp attach step (default false). Set true when an open modal or navigation state must not be disturbed.
timeoutMsintegerFlow timeout in ms
udidstringyesSimulator / device UDID

No output schema declared.

No examples provided.

record_start ~73

Starts a screen recording on a booted iOS simulator. The recording runs in a detached background process. Call record_stop to finalize and retrieve the file.

NameTypeReqDescription
saveTostringDestination file path (must end .mp4). Defaults to a tmp file.
udidstringyesSimulator UDID

No output schema declared.

No examples provided.

record_stop ~54

Stops the active screen recording for an iOS simulator. Sends SIGINT to flush the video file, waits for the file size to stabilize, and returns the path and size.

NameTypeReqDescription
udidstringyesSimulator UDID

No output schema declared.

No examples provided.

run_flow ~262

Execute one or more Maestro flows on a device. Provide exactly one of: yaml (inline YAML string), files (array of flow file paths), or dir (directory path). includeTags and excludeTags are only applicable when using dir. When to use: run_flow gives the full Maestro vocabulary (assertions, conditionals, loops, retries); for a simple sequence of taps/types prefer run_steps, and for one gesture use the individual tools. TRUST BOUNDARY: Maestro flows can run arbitrary JS (evalScript) and local files (runScript/files/dir), so treat run_flow input as locally-executable code.

NameTypeReqDescription
dirstringDirectory containing .yaml flow files
envobjectEnvironment variables passed to the flow
excludeTagsarrayExclude flows tagged with these tags (dir mode only)
filesarrayArray of .yaml flow file paths
includeTagsarrayOnly run flows tagged with these tags (dir mode only)
timeoutMsintegerFlow timeout in milliseconds (default 120 000)
udidstringyesSimulator / device UDID (from device_list)
yamlstringInline Maestro YAML flow string (preferred for exploration)

No output schema declared.

No examples provided.

run_steps ~346

Execute an ordered batch of UI actions in ONE call via the native backend (idb/mobilecli, sub-second; Maestro fallback per step). Eliminates per-gesture MCP round-trips for fast continuous flows (login, navigation, form fill). Step actions: tap {x,y} · tapText {text|id} · type {text,submit} · key · swipe · waitFor {text,timeoutMs} · assertVisible {text} · waitMs · screenshot. Prefer `waitFor` over `waitMs` to act the instant the UI is ready instead of sleeping. WebView note: web-rendered text is invisible to tapText — use tap {x,y} for it; `type` uses real keystrokes so React onChange fires. Stops at the first failed step unless stopOnError:false. bundleId is only needed for the Maestro fallback (auto-detected otherwise). When to use: pick run_steps for >2 known sequential gestures (login, navigation, form fill); use run_flow for Maestro assertions/conditionals/loops/retries; use the individual gesture tools (tap_on, swipe, …) for a single exploratory action.

NameTypeReqDescription
bundleIdstringApp bundle id for Maestro fallbacks (auto-detected from the foreground app if omitted).
stepDelayMsintegerOptional fixed delay inserted after every step (default 0).
stepsarrayyesOrdered list of actions to perform.
stopOnErrorbooleanStop at the first failed step (default true). false = run all and report each.
udidstringyesSimulator / device UDID (from device_list)

No output schema declared.

No examples provided.

screen_size ~45

Returns the pixel dimensions of a booted iOS simulator screen by taking a temp screenshot and reading its pixel dimensions with sips.

NameTypeReqDescription
udidstringyesSimulator UDID

No output schema declared.

No examples provided.

screenshot ~84

Takes a screenshot of an iOS simulator. Returns the saved file path and byte size. Does NOT return base64 to keep payload small. saveTo defaults to a .png file in os.tmpdir().

NameTypeReqDescription
saveTostringDestination file path (must end .png or .jpg). Defaults to a tmp file.
udidstringyesSimulator UDID

No output schema declared.

No examples provided.

set_location ~78

Sets the simulated GPS location on a running iOS simulator. Codifies the QA geo-spinner fix: use this to unblock location-gated features during QA testing without moving the physical device.

NameTypeReqDescription
latitudenumberyesLatitude in decimal degrees
longitudenumberyesLongitude in decimal degrees
udidstringyesSimulator UDID

No output schema declared.

No examples provided.

swipe ~183

Swipes in a direction or between two coordinates via an ephemeral Maestro flow. direction is always required; startX/startY/endX/endY are optional overrides expressed as percentage strings (e.g. '10%,50%') or pixel values.

NameTypeReqDescription
bundleIdstringyesApp bundle identifier
directionstringyesSwipe direction
endXstringEnd X
endYstringEnd Y
noLaunchbooleanSkip the implicit launchApp attach step (default false). Set true when an open modal or navigation state must not be disturbed.
startXstringStart X (e.g. '10%' or '120')
startYstringStart Y
timeoutMsintegerFlow timeout in ms
udidstringyesSimulator / device UDID

No output schema declared.

No examples provided.

tap_on ~341

Tap, double-tap, or long-press an element on screen via an ephemeral Maestro flow. Target by text (regex), accessibility id, or absolute x/y coordinates. bundleId is REQUIRED — Maestro needs it for the appId flow header. WebView caution: text/id selectors only resolve native accessibility nodes. Web-rendered elements inside WKWebView are invisible — tap_on will report COMPLETED but nothing is tapped. Use x+y coordinates instead for WebView content.

NameTypeReqDescription
bundleIdstringyesApp bundle identifier (e.g. com.example.MyApp). Required by Maestro.
doublebooleanUse doubleTapOn instead of tapOn
idstringAccessibility ID of the element
indexintegerZero-based index when multiple elements match
longbooleanUse longPressOn instead of tapOn
longDurationMsintegerHold duration for long press in ms (max 10 000)
noLaunchbooleanSkip the implicit launchApp attach step (default false). Set true when an open modal or navigation state must not be disturbed.
textstringElement text or regex. Matches the FULL label/value case-insensitively (anchored ^…$); an invalid regex falls back to a substring match.
timeoutMsintegerFlow timeout in ms (default 30 000)
udidstringyesSimulator / device UDID
xnumberX coordinate in logical points (numeric only; percent strings are not supported)
ynumberY coordinate — required when x is provided

No output schema declared.

No examples provided.

tap_with_fallback ~319

Sends a raw coordinate tap via the native backend (idb if installed, else a Maestro tapOn-point fallback). Useful for WKWebView game overlays where visual position differs from the DOM hit-test position. The Maestro fallback needs an app context: pass bundleId, or the foreground app is auto-detected. VERIFICATION: 'ok' is decided primarily by a change in the native accessibility element set before/after the tap (stable under animation/video). When no native backend is present it falls back to a screenshot byte-size delta (weak — animation can flip it). The result's `oracle` field reports which was used ('a11y-change' | 'screenshot-bytesize' | 'unverified'). For WebView-rendered targets the a11y tree won't change → oracle:'unverified'; confirm via webview_inspect. offsetStep defaults to 0 (tap the exact point); set it >0 only to deliberately probe nearby y-offsets on retry.

NameTypeReqDescription
bundleIdstringApp bundle id for the Maestro fallback (ignored when idb is present). Auto-detected if omitted.
maxRetriesintegerMaximum tap attempts (default 3)
offsetStepnumberOpt-in Y offset step in px applied per retry (default 0 = always tap the exact point; no blind walk).
udidstringyesSimulator / device UDID
xnumberyesX coordinate in logical points
ynumberyesY coordinate in logical points

No output schema declared.

No examples provided.

validate_flow ~247

Returns a trustworthy, evidenced verdict on whether a just-implemented flow works. Runs your visibility assertions through the oracle ladder (WebView-DOM > native a11y > Maestro; fail-closed on unverifiable) AND auto-checks app health: no recent crash, no error-level Metro logs, no failed (≥400) network requests. ok=true only when ALL assertions pass AND all applicable auto-checks are clean — never a bare 'looks ok'. State the expected outcome as assertions; this tool makes the AI's 'it works' auditable.

NameTypeReqDescription
assertionsarrayExpected-outcome assertions (≥1 recommended)
bundleIdstringApp bundle id (Maestro fallback)
checkCrashesbooleanAuto-check recent crashes (default true)
checkLogsbooleanAuto-check error-level console logs (default true)
checkNetworkbooleanAuto-check failed network requests (default true)
metroPortintegerMetro port for log/network checks (default 8081)
sinceSecondsintegerCrash-recency window in seconds (default 120)
udidstringyesSimulator UDID

No output schema declared.

No examples provided.

wait_for_element ~154

Polls until an element/text is visible (via the oracle ladder), or fails on timeout. Use to act the instant the UI is ready instead of a blind sleep.

NameTypeReqDescription
bundleIdstringApp bundle id for the Maestro fallback (native surface)
containsbooleanSubstring match for text (default false = exact full-string on native a11y). WebView innerText is always substring.
selectorstringCSS selector — WebView surfaces only
textstringVisible text to match (native a11y / WebView innerText)
timeoutMsintegerWait budget (default 10000)
udidstringyesSimulator UDID

No output schema declared.

No examples provided.

webview_eval ~158

Evaluates a JavaScript expression in a WebView's page context and returns the result. Use it to read web-app state (location.href, store values, feature flags, on-screen balances) or to assert conditions against the live DOM. Requires the app's WKWebView to be inspectable (isInspectable=true) — on by default in debug/staging builds, frequently disabled in production App Store builds.

NameTypeReqDescription
expressionstringyesJavaScript expression to evaluate, e.g. "location.href" or "document.querySelectorAll('button').length"
udidstringyesSimulator / device UDID
webviewIdstringTarget WebView id. Omit to auto-select the first visible WebView.

No output schema declared.

No examples provided.

webview_inspect ~220

Lists embedded WebViews (WKWebView) on a booted simulator and, for the selected one, resolves a CSS selector to DOM elements WITH absolute on-screen tap coordinates. This is the answer to the 'WebView content is opaque' limitation of the coordinate tools: instead of eyeballing a screenshot, get tapX/tapY for a real DOM element and feed it straight into tap_on. Defaults to interactive elements when no selector is given. Requires the app's WKWebView to be inspectable (isInspectable=true) — on by default in debug/staging builds, frequently disabled in production App Store builds.

NameTypeReqDescription
maxintegerMaximum elements to return (default 100)
selectorstringCSS selector (default: 'button, a, input, textarea, [role=button]')
udidstringyesSimulator / device UDID (from device_list)
webviewIdstringTarget WebView id (from a prior call). Omit to auto-select the first visible WebView.

No output schema declared.

No examples provided.

webview_navigate ~130

Drives a WebView's navigation: goto a URL, or back / forward / reload. Requires the app's WKWebView to be inspectable (isInspectable=true) — on by default in debug/staging builds, frequently disabled in production App Store builds.

NameTypeReqDescription
actionstringyesNavigation action. 'goto' requires url.
udidstringyesSimulator / device UDID
urlstringDestination URL (required when action is 'goto')
webviewIdstringTarget WebView id. Omit to auto-select the first visible WebView.

No output schema declared.

No examples provided.

Common questions

What is the io.github.hoainho/podium-mcp server?

io.github.hoainho/podium-mcp is listed in the public MCP registry as io.github.hoainho/podium-mcp. Mobile E2E MCP (51 tools): iOS + Android, native UI + canvas/WebGL, no-vision, RN debug. This page covers its npm package (podium-mcp).

Is the io.github.hoainho/podium-mcp server safe to use?

io.github.hoainho/podium-mcp scores 81 out of 100 on VerifyMCP. We found no known CVEs affecting it as of 20 September 2026. It declares no install or post-install scripts. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

What tools does the io.github.hoainho/podium-mcp server expose?

io.github.hoainho/podium-mcp exposes 51 tools: podium_health, device_list, device_boot, app_install, app_launch, and 46 more. Their descriptions and schemas cost roughly 7,562 tokens of context every time the server is loaded.

Is the io.github.hoainho/podium-mcp server still maintained?

io.github.hoainho/podium-mcp is still listed as active in the MCP registry. We last reached this channel on 20 September 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.

What licence is the io.github.hoainho/podium-mcp server under?

io.github.hoainho/podium-mcp declares the MIT licence, which is OSI-approved. That covers the source only, and says nothing about the cost of any service it calls.