frida-ios-mcp
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": true
} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| device_listA | List Frida devices. Default USB-only. Need matching frida-server on phone (17.x with this package). |
| app_listA | Enumerate apps: identifier, name, pid. Default userFacing=true filters noisy Apple services. Use runningOnly for live apps, query for name/id substring. |
| session_openA | Open long-lived Frida session (spawn-only on this stack). ALWAYS uses mode=spawn: kill → spawn suspended → inject agent → resume. mode=attach is ignored/forced to spawn unless FRIDA_MCP_ALLOW_ATTACH=1 (unreliable: touch/net). TikTok: after open, wait 3–5s before screen_snapshot. Never dump_tree/find_view. spawn restarts the process (login UI state may reset). captureNet=true installs NSURLSession + TTNet hooks before resume (launch traffic). withSpringBoard=true attaches SpringBoard in parallel (dual inject; App+SB concurrent RPCs). |
| dual_pingA | [advanced] Parallel health: app ping + SpringBoard ping at the same time (proves dual inject + concurrent locks). |
| sb_ensureA | [advanced] Attach SpringBoard now without listing alerts. Use to warm dual session; then app tools + sb_* can run in parallel. |
| probe_helpA | Recommended probe loop and which tools to prefer/avoid. Call first in a new session. |
| session_statusB | Session health: alive, refsValid/hasSnapshot, lastSnapshotGeneration, openInFlight, appLockBusy/waiters, recovery[]. |
| session_respawnA | Force spawn+inject+resume for current bundle. Kills the app process. Prefer only when session is dead. |
| session_closeA | Close app session. Default also closes SpringBoard and clears Photos side channel (photosAlive). closeSpringBoard=false keeps SB; closePhotos=false keeps Photos. |
| session_force_unlockA | Emergency: reset stuck locks, detach sessions, kill in-flight/last app pid. Use when orphanFridaOpPossible or open hangs. Then ONE session_open. |
| pingB | Agent liveness probe (returns pong). Do not use wrong RPC names as probes. |
| screen_windowA | Key window size: {width,height,x,y,cx,cy,className}. Safe on TikTok. |
| screen_snapshotA | Read screen → generation-scoped refs (g3t8). PRIMARY read tool. Defaults: onScreenOnly=true, limit=40 (token-safe). TikTok: texts only (tree blocked). search= substring by default; a|b auto-enables regex. showDiff=true compares to previous snapshot. Do not parallelize app acts (tap/swipe/type). |
| screen_searchB | Filter last snapshot. query default SUBSTRING; regex:true or a|b for regex. Does not touch device. |
| screen_shotA | Pixel screenshot via lockdown ScreenshotService (pymobiledevice3) — NOT Accessibility, not Frida UI dump. Use when texts are sparse / visual layout unclear. Still prefer screen_snapshot for tap refs. Needs FRIDA_MCP_PYTHON + pymobiledevice3 (+ optional Pillow for JPEG). Returns image + meta. |
| process_listA | [advanced] List device processes (pid, name). query is LITERAL substring only (not regex; SpringBoard ok, a|b is wrong). |
| tapA | Tap by ref (gNtM) or x,y. Default resnapshot=true returns new screen_snapshot in result.snapshot. Set resnapshot=false only when chaining many acts then one snapshot. |
| double_tapC | Double-tap (like) at ref or x,y. gapMs default 140. resnapshot default true. |
| swipeA | Swipe direction or path. Prefer durationMs (e.g. 280). Agent uses seconds; duration>10 is treated as ms (avoids 280→280s lock traps). Clamped ~0.15–2.5s. resnapshot default true (feed browse: set false then one snapshot). |
| set_otpA | Fill TikTok OTP (TMVerificationCodeInputView / TUXPinField). Pass full code string e.g. 123456. |
| tiktok_open_searchB | From For You feed, open TikTok search landing by tapping the top-right magnifier (retries a few points). Not the narrow 搜尋 submit button. Then smart_type on wide [input], then tap 搜尋 to submit. |
| set_text_at_pointB | [debug] setText at point — NOT 拟人. Prefer type_text / smart_type_text. Prefer first-class tools for daily probes. |
| dump_modalD | [debug] dumpModalView. BLOCKED on TikTok. Daily probe: do not use. |
| rpc_callC | [debug] Whitelisted agent RPC. Prefer first-class tools + probe_help. |
| sb_alert_listA | List SpringBoard alerts. Live actionViewCount + actionViewCountRaw (raw may be higher; live can undercount stacks). hasAlert if either count path shows UI. After force: do not trust actionViewCount===1 — use sb_alert_dismiss({all:true}). After dismiss → app screen_snapshot. |
| sb_alert_triggerA | [advanced] Create a test system alert (SBAlertItemTestRecipe). Default force=false: skip if alert already present (no stack). force:true stacks another. Next: sb_alert_list → sb_alert_dismiss({all:true}) or sb_alert_tap. |
| sb_alert_tapA | [advanced] Tap SpringBoard alert button by title. Then call app screen_snapshot. Do not parallel with dismiss. |
| sb_alert_dismissA | Dismiss SB alert. Default policy=deny. all=false: one layer after ~300ms settle (trust cleared; empty → cleared:true rounds:0). Stacked: all=true (loop until clear or maxRounds=5). Returns cleared/remaining/rounds/needsRetry. If needsRetry or cleared=false after settle → re-list or all:true again. Do not parallel tap+dismiss. |
| sb_closeA | Detach SpringBoard Frida session (app session_open stays open). |
| type_textA | 拟人逐字 into ALREADY-FOCUSED field (TypeTextAction). Default perCharDelayMs=90 + jitter. If field not focused → use smart_type_text instead. resnapshot default true. |
| smart_type_textA | PREFERRED typing: tap real input (ref|x,y) → wait typable FR → 拟人逐字. Rejects chrome/chips (好友/有什麼好事). TikTok AWESearchBar may canInsertText=false but still types. Prefer wide search-bar [input]; avoid hot-search chips. retryOnFail default false. resnapshot default true. |
| clear_textA | Clear current firstResponder text field (setText empty). |
| human_pauseA | Random step gap sleep (fleetcontrol human_pause). Not typing delay — use between actions. |
| first_responderA | Current firstResponder info (className/frame/canInsertText). Check focus before type_text. |
| press_homeA | Background current app (suspend) so SpringBoard shows. Session may remain attached to previous app. |
| waitA | Sleep N milliseconds. Prefer wait_until_texts after TikTok session_open instead of blind wait. |
| wait_until_textsA | Poll screen_snapshot until on-screen text matches pattern or preset (or timeout). TikTok: prefer preset "tiktok_feed" (EN/ZH-Hant/ZH-Hans/JA/KO) — do not hardcode one language. Custom pattern still allowed for page-specific probes. |
| net_enableA | [advanced] Start in-process HTTP capture. captureMode: nsurl | ttnet | all (default all). ttnet hooks TikTok TTHttpTaskChromium AFTER request filters (api.tiktokv.com + headers/sign fields). signTrace:true attaches module+offset backtrace on sign_header writes (MetaSec RE). captureResponse wraps TTNet onReadResponseData+setIsCompleted (stable). NSURLSession wrap skipped when TTHttpTaskChromium present. Each call RESETS opts. Typical RE: session_open({captureNet:true, netOptions:{signTrace:true}}) → use app → net_dump / tiktok_sign. |
| net_disableA | [advanced] Stop recording new network entries (buffer retained until net_clear). |
| net_clearB | [advanced] Clear captured network buffer. |
| net_statusB | [advanced] Network capture status: enabled, hooksInstalled, count, options. |
| net_dumpB | [advanced] Quiet HTTP dump. Entries may include stack=nsurl|ttnet, signHeaders, query, backtrace (if signTrace). rawCount=buffer; returned(=count)=entries after filter. Default: redact, DROP data: URLs, FOLD binary, dedupe method+url. RE tip: redact:false dedupe:false query:"tiktokv" or query:"sign_header". Add Phone: query:"phone|bind|mobile|passport|verify". |
| tiktok_inboxA | [advanced] Refresh TikTok Inbox plus Message Requests/notification entries without UI navigation. Returns username, content, conversationId, peerUid, and isMessageRequest. |
| tiktok_replyB | [advanced] Reply through TikTok's real chat composer. With dryRun:false, opens the chat, types into ChatInputTextView, taps 傳送, and succeeds only after the exact text is re-read from live message models. |
| tiktok_imB | [advanced] In-process TikTok IM network runtime. action: status | conversations | inbox | send_text | messages | open_chat | peer_conversation | phone_status. inbox refreshes normal chats and Message Requests/notification pages without UI navigation; returns username + newest content. send_text defaults dryRun:true. With dryRun:false, transport defaults to the real chat composer and succeeds only after the exact text is re-read from live message models. messages: peer nickname/content/time (best-effort). open_chat: open message VC. peer_conversation: build id from peerUid. |
| tiktok_postsC | [advanced] List current user's posts via in-process TTNet (App MetaSec signs). Returns awemeId, desc, createTime, shareUrl, stats. |
| tiktok_signB | [advanced] MetaSec sign observability (NOT offline Argus recompute). action: last | enable_trace. last → recent sign_header / signHeaders entries (x-security-argus, x-Tt-Token, …). enable_trace → net_enable({signTrace:true, captureMode:ttnet}). Prefer session_open captureNet+signTrace. |
| photos_ensureA | [advanced] Spawn+resume Photos.app (com.apple.mobileslideshow), settle ~4s, inject photos agent. Does not close TikTok/app session. May steal foreground briefly. |
| media_uploadC | [advanced] AFC upload PC file to /DCIM/100APPLE/{IMG|VID}_XXXX.ext. Needs Python + pymobiledevice3. stage=upload on failure. |
| photos_importB | [advanced] PhotoKit import already-on-device file (devicePath or remotePath under /DCIM). Host=Photos.app only. Returns localIdentifier. |
| photos_import_fileA | [advanced] One-shot: AFC upload + Photos ensure + PhotoKit import + optional sqlite verify. Preferred for AI. Needs FRIDA_MCP_PYTHON with pymobiledevice3 (no auto pip). Missing deps → stage=afc in ≤5s. Accepts image or small mp4 (mediaType=video). Video: avoid parallel session_open other apps or expect needsRetry + photos_list. |
| photos_listB | [advanced] Pull Photos.sqlite via AFC; list untrashed assets (not Recently Deleted). Optional mediaType=image|video and idPrefix/localIdentifier filter. Default = all untrashed. Needs FRIDA_MCP_PYTHON with pymobiledevice3 (fast-fail stage=afc if missing). |
| photos_clearA | [advanced] PhotoKit trash all untrashed image/video (Recently Deleted), verify count=0, optional DCIM source cleanup. needsRetry if leftover. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 53 tools
Tools are highly specific with detailed descriptions, making each one clearly distinct. Even overlapping areas like typing (type_text vs smart_type_text) are well-differentiated.
Most tools follow a consistent snake_case convention, but there are minor inconsistencies like screen_snapshot vs screen_shot and verb_noun vs noun_verb order. Prefixes for subdomains (tiktok_, sb_, photos_) aid clarity.
With 53 tools, the set is extensive and covers a broad domain, but the count is high compared to typical MCP servers. While many are advanced or debug-specific, it still feels heavy for a single server.
The tool set covers device management, session handling, UI interaction, network capture, and TikTok-specific features, leaving few obvious gaps. Advanced tools add depth for power users.