Skip to main content
Glama

Screen for AI

Server Details

Show interactive pages on a spare Android phone or tablet and read back saved answers.

Ownership verified

The last two health checks of this connector failed. If this server requires authentication, missing or expired test credentials may be the cause. A test profile lets Glama authenticate for health checks and discover tools; it is separate from your personal connections.

If you are the author, claim ownership, then add or update a test profile under Admin → Test Profile.

Status
Unhealthy
Uptime
12.5% over the last 24 hours
OAuth
Works in Glama
Last Tested
Transport
Streamable HTTP · MCP 2025-11-25
URL
ChatGPT
–
Claude
–

TDQS

A3.7/5.0

Scored across 16 tools

Disambiguation4/5

Each tool targets a distinct resource+action: device (list/status/rename/reset/revoke), display (render/broadcast/get_current/show_default/show_template), page (list/show/delete), operation, and view (state/events). The only plausible confusion is between display_show_default, device_reset, and page_delete (all of which can move a screen to its Start page), and between display_get_current and view_get_state, but the descriptions draw the lines clearly (reset deletes content, show_default does not; get_current is metadata only, get_state is saved answers).

Naming Consistency4/5

All 16 names follow a consistent resource_action pattern (device_get_status, display_render_html, page_delete, view_get_events, operation_get), with plural nouns reserved for list operations (devices_list, pages_list). Minor deviation: a few names carry a third segment (device_get_status, display_show_default, display_show_template), so the pattern is predictable but not perfectly uniform.

Tool Count4/5

Sixteen tools is slightly above the ideal band but each maps to a real, non-duplicated operation across five sub-domains (devices, displays, pages, operations, views). Nothing feels vestigial; the surface is broad because the domain genuinely has device lifecycle, page lifecycle, and state/event reads.

Completeness4/5

Full lifecycle is covered: device list/status/rename/reset/revoke, display render/broadcast/default/template, page list/show/delete, operation polling, and state/event reads. Minor gaps exist — there is no tool to add/pair a new screen or to directly clear a page's saved answers or acknowledge/consume events (event reads are explicitly non-consuming) — but these are workable around physical pairing and page re-renders.

Available Tools

16 tools
device_get_statusGet screen statusB
Read-onlyIdempotent
Inspect

Returns safe connection, capability, and display diagnostics for one authorized screen, with its route and support: the tools, security modes, runtime APIs and limits that work on it. android_api, app_version and webview_version are what the screen itself reported (null: not reported, for example by an older app); an old android_api or webview_version means an old browser engine. Its screen_settings say which of the owner's screen options are on and where the owner finds each one in the app (state null: not reported, not off). No tool changes them; the owner changes them on the screen at the where path. The app's Settings pages: Settings › Recovery: Return to Start, Safe mode, Show the last page again, Clear remote content; Settings › Connected agents: Allow connections on this Wi-Fi, This screen on Wi-Fi, Show when an assistant reads answers; Settings › Account: Connect an account, Connection check, Disconnect account; Settings › Display: App brightness, Night hours, Subtle pixel shift, Immersive mode; Settings › Display › Night hours: Use night hours, Starts, Ends, Night brightness, Let the display turn off in these hours; Settings › Wake & lock screen: Keep screen awake, Show over the lock screen, Wake the screen for new pages, Remote wake alerts; Settings › Wake & lock screen › Wake the screen for new pages: Use wake for new pages, Notifications blocked, Reopen by itself; Settings › Home mode: Use Home mode; Settings › About this screen: Screen name, Export support bundle, Beta feedback, Open-source licenses. Settings opens from the screen menu: the round menu button in the bottom-right corner of the screen, then Settings. The same menu has Start, which returns to the built-in Start page, and recent pages. While the phone is locked and the screen shows over the lock screen, Settings first asks the owner to unlock. On screens whose screen_settings.settings_layout is 1 (older app versions) Settings opens from a Settings button at the top right instead. On the gateway route, display follows what the screen last reported (a page, or its Start page) and names no page. When route_diagnostics.current is false, the report came from a previous connection and the current display is unconfirmed. Without a report of a page or the Start page, display is a placeholder.

Inputs: device (required). Returns: object

device_renameRename a screenA
DestructiveIdempotent
Inspect

Changes the account-visible name of one authorized screen. Stable device IDs stay the same, and duplicate names remain ambiguous selectors. A phone-owned screen on a current app also shows the new name on its clock and in its Settings once it is connected.

Inputs: name (required), device (required). Returns: object

device_resetReset remote screen contentA
Destructive
Inspect

Deletes remote view content/state from the device and returns it to its Start page. This is not a factory reset; pairing and account authorization stay.

Inputs: device (required), client_request_id. Returns: object

device_revokeRevoke a screenA
Destructive
Inspect

Revokes one screen's account authorization and closes its live relay session. The physical device returns to its local unpaired/default flow on authorization failure.

Inputs: device (required). Returns: object

devices_listList your screensB
Read-onlyIdempotent
Inspect

Lists the caller's authorized screens with concise online/current-view status, each screen's route and its support (working tools, security modes, runtime APIs and limits), and the android_api and webview_version each screen reported (null: not reported). A screen's category (phone, tablet or tv) is the device running the app, not its panel technology or the display the person has in mind; a display missing from the caller's list of screens is not one of the caller's screens, so no page reaches it.

Inputs: include_offline. Returns: object

display_broadcast_htmlRender HTML on multiple screensAInspect

Installs the same self-contained HTML on an explicit list of at least two distinct authorized screens (the device IDs or names of the caller's screens), as one independent display operation per screen. There is no all-screens target. With page_id each screen keeps it as the same page, updated by a later broadcast with that page_id.

Inputs: html (required), devices (required), title, page_id, +7 more. Returns: object

display_get_currentGet the current displayB
Read-onlyIdempotent
Inspect

Returns current and last-known-good view metadata without the rendered HTML.

Inputs: device (required). Returns: object

display_render_htmlRender HTML on a screenAInspect

Installs self-contained HTML on one authorized screen and returns its display operation. Inputs: device; html; optional title and source_label; optional page_id; security_mode (one of the screen's support.security_modes); runtime (required_api "0" gives the page window.AISurface, "none" a plain page); ttl_seconds (display lifetime, null: none); client_request_id (repeating a request with the same id returns the same operation). The screen's support field lists its security modes, runtime APIs and size limits. page_id (optional, a name of the caller's choosing such as "weather") becomes the page's view_id and each render a new revision of it: sending the same page_id again shows the new revision in that page's place instead of adding another page to its page history (an earlier revision that holds no saved answers is replaced); without page_id every render is a new page. Each revision has its own saved state, which starts empty: answers saved in an earlier revision reach a new one only through initial_state. The screen's account agents, and Wi-Fi clients joined to its account, update each other's pages with the same page_id; another sender's page with that page_id stays as it is. A runtime API 0 page must call AISurface.ready() and then AISurface.signalReady({ health: "ok" }) within a few seconds of loading (6 s in the current app): a page that does not signal ready is not shown and its render fails with DEVICE_REPORTED_FAILURE. On slow phone-owned screens signalReady's answer arrives only once the page is shown (10-15 s on an Android 5 tablet over the internet); older app versions end the wait after 5 s with RUNTIME_NOT_READY although the page is then shown. A page whose controls wait for that answer stays unusable meanwhile, or for good after the timeout. Until the page is shown, emit() fails with VIEW_NOT_ACTIVE (on older app versions state calls too), and a later call succeeds. AISurface calls return Promises: setState(key, value) saves one value (key: a lowercase letter, then lowercase letters, digits, _ . -, at most 64 characters, like "answer"; value: any JSON), replaceState({ key: value, ... }) replaces all saved values, getState(key?) reads one or all, removeState(key), emit(type, data) records an event, getContext() returns the page context, on(event, listener) subscribes to host events. setState resolves once the value is saved on the screen. A coded refusal (INVALID_STATE_KEY, STATE_STORAGE_FULL, VIEW_NOT_ACTIVE) means this write was not saved. A mutation timeout (RUNTIME_NOT_READY with retryable: false) has an uncertain outcome: the write may have committed before its reply was lost. An authorized getState readback can confirm the current value; a failed readback leaves it uncertain, and a newer edit can supersede the timed-out value. Repeating an event-producing action can duplicate its effect. A page that shows "Saved" before the Promise resolves can show it for an answer that was lost. getState("choice") resolves to the saved value itself, such as "Plate" (not { choice: "Plate" }), or null for a key with no saved value; getState() resolves to one object of every saved key and value. After a reload the page shows what its own script rebuilds at load: text derived from an answer, such as the price of the chosen item, appears again when the script computes it from the value getState returns. Page state (AISurface.setState) is kept on the screen with the page and is the saved state the agent reads; a phone restart can drop events nobody has read yet, so state is the durable record of an answer. ttl_seconds sets the page's display lifetime on the screen (null: no lifetime), after which the screen returns to its Start page. A lifetime does not keep the display lit: the phone turns its display off after its own screen timeout unless the owner's Keep screen awake setting is on (screen_settings.keep_screen_awake in the screen's status). Emoji come from the screen's own system font, which holds only the emoji that existed when its Android version shipped; an emoji the font lacks shows as an empty box. Words and basic symbols (✓ ★ → • ⚠ ♥ ☀) display on every screen. Measured fonts: Android 5 (android_api 21 and 22) shows only the original 2010 emoji, for example ☕ 🍕 🍝 🍲 ✅ 😀, and boxes for every emoji added since 2014, such as 🌶 🌮 🥑 🥢 🥡; Android 8.0 (android_api 26) shows emoji up to 2017 and boxes for those added since 2018, such as 🧁 🥳 🧋; Android 16 (android_api 36) showed every emoji tested, up to 2020. android_api is in each screen's listing and status; null means not reported, so the screen may be old. A page shorter than its screen sits at the top of the page area, so its controls reach the lower part of the screen only when the page fills the area's height, for example a full-height container (min-height: 100vh) with the controls last, above the menu button's covered height. A person's tap opens only http and https links. Other link schemes, such as sms:, tel: and mailto:, stay blocked, so a page cannot start a message, call or email; a page can show the recipient and text for the person to send themselves. Status: queued, received and persisted precede applied; only applied means the screen shows the page, and the returned operation_id identifies the operation in later status reads. A page's scripts run again each time the screen loads it again (an app restart, recovery after a crash, showing it again from the page history), so a value a script saves at load replaces an answer saved after it. initial_state (1-64 saved-state keys with JSON values, at most 768 bytes) is written into the new page's saved state once, when the screen first admits that page and before its scripts run; later loads leave it as it is, and getState and the page's saved-state read return it until the page saves another value. A revised page carries an earlier answer this way and shows it from getState; without initial_state it starts with no saved answers. For example, after the saved state of page_id "bookclub-vote" reads values {"book": "Emma"}, the revision sent with page_id "bookclub-vote" and initial_state {"book": "Emma"} reads "Emma" from getState("book") at load and can show it selected; the person's next saved choice then replaces it, and later loads keep that choice. Screens whose support.render_fields lists initial_state accept it; others answer DEVICE_CAPABILITY_UNSUPPORTED, and the page can be sent without it. Answers saved on a screen stay with that page on the screen and reach the agent only as that page's saved state; no screen tool writes them into another system, such as a school platform, a calendar or a shop. The result's page_warnings (absent when there are none) name problems found in the page before delivery: an inline script with a syntax error, or one the screen's browser cannot parse (judged from its reported webview_version; Android 5's WebView 37 reads only ES5, without arrow functions, let/const, classes or async), a runtime API 0 page with no AISurface.signalReady call, speechSynthesis, SpeechRecognition, getUserMedia or a file input (no screen spoke from a page in tests, and pages get no camera, microphone, photo or file), AISurface.on with a name that is no host event, and AISurface or --ais-overlay-* in a page without runtime API 0. The page is delivered either way. Where the screen's support.limits.operations_retained is set, the service keeps only that many recent operations for the screen. A repeated request with the same client_request_id returns the original operation while it is kept; after it has been removed, the same request is a new operation and shows the page again.

Inputs: html (required), device (required), title, page_id, +7 more. Returns: object

display_show_defaultShow the built-in Start pageAInspect

Returns an authorized screen to its safe built-in Start page (a clock with the screen's name and status) without deleting its last known good view. The result is an operation: queued until the screen takes it, applied once the screen confirms that it shows its Start page. On a phone-owned screen it takes about as long as a page. Afterwards no page is current: a saved-state read without view_id returns VIEW_NOT_FOUND, and one with a page's view_id still returns that page's saved state.

Inputs: device (required), client_request_id. Returns: object

display_show_templateShow a built-in screen templateAInspect

Shows a reviewed, self-contained template on one authorized screen; onboarding.v0 is the first-connection test. The onboarding.v0 template shows one button; the person's tap records the onboarding_completed event for the returned view_id in that page's event history, on screens whose support serves event reads. The applied status means the page is on the screen, not that anyone tapped it. Where the screen's support lists event reads as unsupported (they return DEVICE_CAPABILITY_UNSUPPORTED), the template also saves onboarding_complete in page state, and that view_id's saved state (key "onboarding_complete"), a signed read from the screen, holds onboarding_complete: true once the tap is saved (no value before). Page state belongs to one page: a new client_request_id gives a fresh page with no saved value, while a reused one addresses the same page, whose saved value can come from an earlier tap. Where the screen's support.limits.operations_retained is set, the service keeps only that many recent operations for the screen. A repeated request with the same client_request_id returns the original operation while it is kept; after it has been removed, the same request is a new operation and shows the page again.

Inputs: device (required), template (required), client_request_id. Returns: object

operation_getGet operation statusA
Read-onlyIdempotent
Inspect

Returns the current stage, terminal result, and redacted error of an authorized operation. A slow phone can take a minute or more to apply a page. With wait_seconds (1-10), operation_get answers once the operation is final (applied, failed, expired or superseded) or when that time is up, whichever comes first, with the stage at that moment; without it, at once. A slow phone can need several such calls. Screens on the hosted relay route answer at once either way.

Inputs: operation_id (required), wait_seconds. Returns: object

page_deleteDelete a kept pageA
DestructiveIdempotent
Inspect

Deletes a page the screen keeps, by view_id (every kept revision unless revision is given), with its saved answers (state) and read receipts; its stored events are removed and event history reports a gap. If it is on screen, the screen shows its Start page. The deletion cannot be undone. A page still being installed is not deleted (DEVICE_BUSY). The person can also delete pages on the screen in Settings › Page history.

Inputs: device (required), view_id (required), revision. Returns: object

page_showShow a kept page againA
Idempotent
Inspect

Shows a page the screen keeps again, with its saved answers, by view_id (its newest kept revision unless revision is given). The screen switches to it at once and loads it as its own Show again does; a page that fails to load falls back to the last safe page or the Start page. A page that did not finish showing before, whose display lifetime (ttl_seconds) is over, or a screen whose owner turned remote pages off cannot show it (PAGE_NOT_SHOWABLE). Nothing is deleted. The result is not an operation: it confirms that the screen selected the page, not that the page finished loading.

Inputs: device (required), view_id (required), revision. Returns: object

pages_listList a screen's kept pagesA
Read-onlyIdempotent
Inspect

Lists the pages a phone-owned screen keeps (its page history) that this connection's sender sent (the internet account, or one Wi-Fi app), newest first: view_id, revision, title, source_label, when it was first shown, size, whether it holds answers (saved state or events) and unread answers, whether it is on screen (current) and whether it can be shown again (showable); and pages_used of at most pages_limit, which also counts pages_from_others (pages other Wi-Fi apps or accounts sent, listed only in the screen's Settings › Page history). A screen that keeps pages_limit pages refuses new pages (SCREEN_PAGES_FULL) until kept pages are deleted, unless auto_delete is true (the owner turned on automatic deletion): then each new page deletes the oldest unused one. A long list can arrive in parts: next_offset (null when complete) is the offset that continues it. Works where the screen's support lists it (phone-owned screens with a current app).

Inputs: device (required), offset. Returns: object

view_get_eventsGet view eventsA
Read-onlyIdempotent
Inspect

Reads ordered, non-consuming page interactions after a numeric cursor. Results are bounded and retain view/revision attribution. A null view_id means the current remote view. Event support varies by route. With include_screen_history_gaps=true, the gateway returns available events and any verified gaps together. The gaps cover the screen and may include events from other pages, even when view_id is set. When has_more is true, next_cursor is the after value for the next result with the same device, view_id and filters. With recovery_contract ais.recovery.v0 the result includes explicit recovery_lost gaps after storage recovery.

Inputs: device (required), after, limit, types, +3 more. Returns: object

view_get_stateGet view stateA
Read-onlyIdempotent
Inspect

Reads a bounded state snapshot attributed to a known view revision. A null view_id means the current page; after the screen has moved on (VIEW_NOT_CURRENT or VIEW_NOT_FOUND), the rendered view_id still addresses that page. Retired hosted state returns an explicit error, and a fresh revision restores hosted synchronization. A page that has saved nothing yet returns empty values with state_revision 0. A new revision of the page (the same page_id) starts with no saved answers unless it is sent with these values as initial_state. A phone-owned screen answers only for pages this connection's sender sent; another sender's page returns VIEW_NOT_FOUND. A person can take minutes to answer. Each read is answered by the phone itself and shares its connection with page delivery; reads about ten seconds apart leave room for delivery on slow phones.

Inputs: device (required), keys, view_id. Returns: object

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      B
      quality
      B
      maintenance
      Lets Claude see an Android phone's screen through ADB screenshots and control it by typing over ADB and by speaking button commands aloud through the PC speakers for Google Voice Access to tap, plus gestures, app launching, and optional voice input.
      26
      MIT
    • A
      license
      Not graded
      quality
      A
      maintenance
      Lets AI agents see and use a real Android phone over Wi-Fi: read the screen, find elements by text or ID, tap, type, swipe, take screenshots and read notifications, without ADB or root.
      519
      MIT
    • A
      license
      B
      quality
      C
      maintenance
      Enables any MCP assistant to see and operate an Android phone or emulator over plain adb, reading the accessibility tree to tap elements by name and also supporting screenshots, typing, swiping, app launching and installation, and logcat — with nothing installed on the device and no root required.
      13
      MIT
    • A
      license
      C
      quality
      C
      maintenance
      Enables agents and users to drive Android phones, emulators, and BlueStacks by reading the screen, tapping and typing, verifying screens against saved anchors and checkpoints, and running multi-step routines that resume after failure. Also bridges to Tasker so catalogued tasks can be fired safely while avoiding flagged hazards.
      20
      MIT
    Try in Browser

    Glama MCP Gateway

    Add one secure layer between your agents and this server.

    Resources