Skip to main content
Glama

Robot Actions — Remote Device Control

device_gamepad_state

Present a connected game controller to an Android device and set its state. The device sees a REAL controller — a kernel-level input device that native games and apps receive exactly as they would a pad plugged into the phone.

HOW TO FIRE INPUT PROPERLY: • One call = ONE frame = one instant in time. A button stays pressed until you send a frame WITHOUT it, so every press needs a matching release frame — keydown then keyup. Press after press just holds them all down. • For anything that should look played rather than stepped — mashing, combos, a stick sweep — pass frames instead of calling repeatedly. The sequence plays out device-side at intervalMs (default 33 ms ≈ 30 fps). A round trip per frame cannot reach that cadence, so a rapid sequence built from single calls always reads as held buttons. • Alternate press and release inside frames: [{buttons:[1]}, {}, {buttons:[1,1]}, {}] is tap A, release, tap A+B, release. • Axes are [leftX, leftY, rightX, rightY], -1..1. Sweep them across frames to roll a stick; omitted axes read as centred. • Confirm with device_gamepad_status.

Buttons and axes use W3C standard order, identical to the iOS gamepad tools — the mapping onto whatever the chosen controller reports is done for you. Pick profile to match the hardware you want the device to believe is attached; it changes both the reported identity and the button layout, so a game showing on-screen prompts shows the right ones. This is the tool to reach for. device_uhid_gamepad_state is the raw twin — it takes the fixed-format report directly (one profile, rotated bit order) instead of translating from W3C arrays; use it only to send an exact report byte-for-byte.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
axesNoAxis values -1..1: [leftX, leftY, rightX, rightY]. Omitted axes read as centred.
udidYesDevice serial number (UDID)
framesNoPlay a SEQUENCE of frames at intervalMs instead of setting one state. This is how you produce real gameplay input: include the release frames (an entry with no buttons releases everything). Capped at 300 frames. Overrides buttons/axes when present.
buttonsNoButton values 0..1 in W3C standard order (0-3 face, 4/5 shoulders, 6/7 analog triggers, 8 select, 9 start, 10/11 stick clicks, 12-15 d-pad, 16 home, 17 touchpad). >= 0.12 counts as pressed. Omitted releases everything.
profileNoWhich controller the device should believe is attached (default dualshock4). Changing it between calls unplugs and re-attaches the pad.
intervalMsNoGap between frames in ms (default 33). Lower = faster mashing; 33 ms matches a 30 fps controller poll.
browserTouchpadNoAlso expose the touchpad click (index 17) to a web page open on the device. Off by default. The pad is a REAL input device here, and Chromium's Android mapper fills indices 0-16 only, so index 17 reaches the kernel and native apps but can never reach a browser gamepad tester on its own — not even from a physically-plugged DualShock. This overlays it onto the page. Indices 0-16 still come from the real pad; only 17 is synthesized. Needs an inspectable page open; ignored if there is none. After a navigation the page only exposes a pad once it sees activity, and the touchpad alone cannot provide it — lead with a stick sweep, e.g. frames [{axes:[1,0,0,0]},{axes:[0,0,0,0]},{buttons:[...17]}], which wakes it without adding a button to a tester's history.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changed
    • changedInput schema / properties / browserTouchpad / description
      Previous value: -"Also expose the touchpad click (index 17) to a web page open on the device. Off by default. The pad is a REAL input device here, and Chromium's Android mapper fills indices 0-16 only, so index 17 reaches the kernel and native apps but can never reach a browser gamepad tester on its own — not even from a physically-plugged DualShock. This overlays it onto the page. Indices 0-16 still come from the real pad; only 17 is synthesized. Needs an inspectable page open; ignored if there is none. After a navigation the page only exposes a pad once it sees activity, and the touchpad alone cannot provide it — lead with a stick sweep, e.g. frames [{axes:[1,0,0,0]},{axes:[0,0,0,0]},{buttons:[...17]}], which wakes it without adding a button to a tester's history."New value: +"Also expose the touchpad click (index 17) to a web page open on the device. Off by default. The pad is a REAL input device here, and Chromium's Android mapper fills indices 0-16 only, so index 17 reaches the kernel and native apps but can never reach a browser gamepad tester on its own — not even from a physically-plugged DualShock. This overlays it onto the page. Indices 0-16 still come from the real pad; only 17 is synthesized. Needs an inspectable page open; ignored if there is none. After a navigation the page only exposes a pad once it sees activity, and the touchpad alone cannot provide it — lead with a stick sweep, e.g. frames [{axes:[1,0,0,0]},{axes:[0,0,0,0]},{buttons:[...17]}], which wakes it without adding a button to a tester's history."
  2. Changed1 schema field changed
    • changedInput schema / properties / browserTouchpad / description
      Previous value: -"Also expose the touchpad click (index 17) to a web page open on the device. Off by default. The pad is a REAL input device here, and Chromium's Android mapper fills indices 0-16 only, so index 17 reaches the kernel and native apps but can never reach a browser gamepad tester on its own — not even from a physically-plugged DualShock. This overlays it onto the page. Indices 0-16 still come from the real pad; only 17 is synthesized. Needs an inspectable page open; ignored if there is none. After a navigation the page only exposes a pad once it sees activity, and the touchpad alone cannot provide it — lead with a stick sweep, e.g. frames [{axes:[1,0,0,0]},{axes:[0,0,0,0]},{buttons:[...17]}], which wakes it without adding a button to a tester's history."New value: +"Also expose the touchpad click (index 17) to a web page open on the device. Off by default. The pad is a REAL input device here, and Chromium's Android mapper fills indices 0-16 only, so index 17 reaches the kernel and native apps but can never reach a browser gamepad tester on its own — not even from a physically-plugged DualShock. This overlays it onto the page. Indices 0-16 still come from the real pad; only 17 is synthesized. Needs an inspectable page open; ignored if there is none. After a navigation the page only exposes a pad once it sees activity, and the touchpad alone cannot provide it — lead with a stick sweep, e.g. frames [{axes:[1,0,0,0]},{axes:[0,0,0,0]},{buttons:[...17]}], which wakes it without adding a button to a tester's history."
  3. Added

TDQS

A5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries full burden and delivers: kernel-level emulation, frame semantics, default intervalMs, profile-switch behavior (unplugs/re-attaches), and detailed browserTouchpad caveats. Nothing is hidden or omitted.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Structured with a short summary, bulleted rules, and an alternatives paragraph. Though lengthy, every sentence earns its place and is front-loaded with the most critical usage constraint (one frame = one instant). No wasted words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Complete for a complex input tool: covers state model, frame sequencing, button/axis formats, defaults, profile selection, sibling routing, confirmation step, and an edge-case workaround (browser touchpad wake-up). Nothing an agent needs to call correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Although schema coverage is 100%, the description adds substantial value beyond it: W3C button order, press threshold (0.12), axe order and centering, frame override behavior, intervalMs cadence rationale, and touchpad synthesis details. Richly enhances schema-only understanding.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb+resource: 'Present a connected game controller to an Android device and set its state.' It explicitly names the sibling tool (device_uhid_gamepad_state) and clarifies which one to reach for, making differentiation immediate.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Includes a dedicated 'HOW TO FIRE INPUT PROPERLY' section with explicit when-to-use frames vs. single calls, release-frame requirements, and a direct comparison to the raw twin tool with the condition 'use it only to send an exact report byte-for-byte.' No inference needed.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources