{"name":"io.github.lvlrSajjad/simframe","slug":"lvlrsajjad-simframe","title":"simframe","description":"Always-warm iOS Simulator and Android emulator frames: agents read the screen in ~20ms","url":"https://mcp.market/server/lvlrsajjad-simframe","rating":null,"grade":"A","score":92,"certified":false,"status":"active","category":"other","tags":[],"presence":{"score":33,"stars":0,"forks":1,"downloads_week":1219,"last_push_at":"2026-09-18T20:04:37.000Z","license":"MIT"},"uptime":null,"claimed":false,"transport":"npm","callable_via_gateway":false,"default_price_micros":0,"repository":"https://github.com/lvlrSajjad/simframe","website":"https://lvlrsajjad.github.io/simframe/","version":"0.18.0","remotes":[],"packages":[{"registryType":"npm","registryBaseUrl":"https://registry.npmjs.org","identifier":"simframe","version":"0.18.0","transport":{"type":"stdio"}}],"tools":[{"name":"sim_assert","description":"Check one thing about the screen and fail loudly if it is not so. Cheaper inside a sim_do flow, where a failed assert stops the remaining steps.","write_action":false,"price_micros":0,"input_schema":null},{"name":"sim_capture","description":"Inspect or control the background capture loops: action \"status\" (what is running and how fresh), \"start\", \"stop\". Capture starts automatically on first use, so you rarely need this.","write_action":false,"price_micros":0,"input_schema":null},{"name":"sim_devices","description":"List the devices simframe can drive — iOS simulators and Android emulators.","write_action":false,"price_micros":0,"input_schema":null},{"name":"sim_do","description":"THE MAIN TOOL, and the cheapest path. Plan the WHOLE flow and run it in one call — tap, type, scroll, wait, assert — asserting after each step that matters. Every step settles and is checked against what that action did here before, so a wrong turn halts the flow instead of tapping on. Single-action tools are for recovery.","write_action":false,"price_micros":0,"input_schema":null},{"name":"sim_find","description":"Resolve one intent to one control: \"tap Save\", \"the Assets tab\", \"back\". Understands verbs, typos, and where on screen you meant. When two things answer equally well it says so and lists them rather than guessing. Use it when you doubt a selector will resolve; otherwise just tap. Prefer a label or a #ref over coordinates.","write_action":false,"price_micros":0,"input_schema":null},{"name":"sim_flow_run","description":"Replay a saved flow by name, verifying each step. Omit `name` to list the saved flows. Save one with sim_do's `saveAs`.","write_action":true,"price_micros":0,"input_schema":null},{"name":"sim_goto","description":"Walk to a screen simframe already knows, over edges it has already verified, with no model call per step. Names come from sim_recall or a previous map. Refuses rather than guesses when the route is unknown or the name is ambiguous — a refusal is cheap and a wrong walk is not.","write_action":false,"price_micros":0,"input_schema":null},{"name":"sim_launch","description":"Launch or relaunch an app, optionally with launch arguments and environment variables — the way to put an app into a test mode without touching its UI.","write_action":false,"price_micros":0,"input_schema":null},{"name":"sim_look","description":"A screenshot: ~1600 tokens, the most expensive call here. Only for what text cannot answer — layout, colour, spacing, a control the map omits. NOT for what a field contains, whether a button is enabled, or whether an action worked: sim_ui reports the first two and the flow's own verdict already answered the third.","write_action":false,"price_micros":0,"input_schema":null},{"name":"sim_open_url","description":"Open a URL or deep link on the device — the fastest way to reach a screen when the app has a link for it.","write_action":false,"price_micros":0,"input_schema":null},{"name":"sim_permission","description":"Grant, revoke or reset a privacy permission for an app. Do this instead of tapping the system alert: the alert is not part of the app under test, and its buttons move between OS versions. Not every service exists on every platform — the device's own backend refuses one it does not have. Services: ….","write_action":false,"price_micros":0,"input_schema":null},{"name":"sim_recall","description":"What happened recently, as text: the screens visited, the actions taken, and what each one did. Use it to re-orient after a failure instead of taking a screenshot, and to learn the screen names sim_goto accepts.","write_action":false,"price_micros":0,"input_schema":null},{"name":"sim_scroll_to","description":"Scroll until something is in view. A control that scrolled off the bottom of a list is not missing, and this is the difference.","write_action":false,"price_micros":0,"input_schema":null},{"name":"sim_state","description":"Cheapest possible check: a stable screen hash, whether anything changed SINCE YOUR LAST LOOK in this session, how long the screen has been still, and an ASCII map of which regions moved. A fraction of the cost of even the text screen map. Use it to poll (\"has it finished loading?\"). To find out WHAT is on screen, use sim_ui.","write_action":false,"price_micros":0,"input_schema":null},{"name":"sim_storage","description":"What the app saved, as text: its UserDefaults and (for React Native) its AsyncStorage, read straight out of","write_action":false,"price_micros":0,"input_schema":null},{"name":"sim_strip","description":"Return the last few buffered frames tiled into ONE image, oldest first — an image, so not cheap. Lets you understand a transition, animation or flicker in a single call instead of a burst of screenshots. Looks backwards in time; it does not wait.","write_action":false,"price_micros":0,"input_schema":null},{"name":"sim_tap","description":"Tap one thing. For more than one step, use sim_do — it batches the verification and costs one round trip. Returns the screen map afterwards.","write_action":false,"price_micros":0,"input_schema":null},{"name":"sim_type_into","description":"Focus a field and type into it. Prefer a sim_do step when this is part of a sequence.","write_action":false,"price_micros":0,"input_schema":null},{"name":"sim_ui","description":"READ THE SCREEN as text: every element numbered, with region, type, label, state, contents and tap point, plus which screen this is and what simframe knows about it. A tenth the cost of a screenshot and more useful, because it says what is tappable and where. Act on what it shows by NAME — whatever it calls \"General\", you can tap as \"General\"; the #3 numbers are exact but only until the screen mov","write_action":false,"price_micros":0,"input_schema":null},{"name":"sim_wait","description":"Wait for the screen to change, settle, or both. sim_do already settles after every step, so you rarely need this inside a flow — reach for it when something moves without you acting, like a push or a background load. Pass `since` from a hash captured before the thing you are waiting on.","write_action":false,"price_micros":0,"input_schema":null},{"name":"sim_wait_for","description":"Block until something appears on screen, then return the screen map. Use this instead of pausing and re-reading.","write_action":false,"price_micros":0,"input_schema":null}],"scan":{"score":92,"grade":"A","scanned_at":"2026-09-19T21:08:23.921Z","report":{"scannerVersion":"0.1.8","scannedAt":"2026-09-19T21:08:23.918Z","components":{"code":{"score":25,"max":25,"notes":["41 source files scanned"]},"reliability":{"score":-1,"max":20,"notes":["no gateway calls yet and no remote to probe"]},"poisoning":{"score":-1,"max":15,"notes":["tools not inspected (local package is not executed); not counted"]},"auth":{"score":12,"max":15,"notes":["local package, no credentials required"]},"maintenance":{"score":15,"max":15,"notes":["last push 1 days ago"]},"identity":{"score":8,"max":10,"notes":["registry namespace matches repository owner","GitHub account older than a year"]}},"findings":[],"inputs":{"packages":[{"registryType":"npm","identifier":"simframe","version":"0.18.0","found":true,"license":"MIT","hasInstallScripts":false,"dependencyCount":1,"publishedAt":"2026-09-17T13:35:25.021Z","repositoryUrl":"git+https://github.com/lvlrSajjad/simframe.git","weeklyDownloads":1219}],"repo":{"found":true,"owner":"lvlrSajjad","repo":"simframe","archived":false,"pushedAt":"2026-09-18T20:04:37Z","stars":0,"forks":1,"openIssues":1,"ownerType":"User","ownerAvatarUrl":"https://avatars.githubusercontent.com/u/42815758?v=4","ownerCreatedAt":"2018-08-29T18:12:21Z","license":"MIT"},"icon":{"url":"https://avatars.githubusercontent.com/u/42815758?v=4&s=128","source":"registry"},"presence":{"stars":0,"forks":1,"downloadsWeek":1219,"license":"MIT","lastPushAt":"2026-09-18T20:04:37.000Z","score":33}}}},"grade_history":[{"kind":"restore","fromGrade":"B","toGrade":"A","reason":"score 92","createdAt":"2026-09-19T21:08:24.646Z"},{"kind":"restore","fromGrade":"C","toGrade":"B","reason":"score 74: Shell command built from a string (injection risk)","createdAt":"2026-09-19T00:27:06.021Z"}],"reviews":[]}