Skip to main content
Glama

Robot Actions — Remote Device Control

ios_gamepad_state

Present a REAL game controller to an iOS device and set its state. The device registers a virtual DualShock 4 and receives genuine controller HID, so NATIVE apps see a GCExtendedGamepad and a web page sees a W3C standard-mapping pad in navigator.getGamepads(). It shows up in Settings > General > Game Controller. No Safari page is required.

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 — exactly like keydown then keyup. Sending 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 device plays the whole sequence out at intervalMs (default 33 ms ≈ 30 fps). A round trip per frame cannot reach that cadence, so a rapid sequence built out of single calls will always read as held buttons. • Alternate press and release inside frames: [{buttons:[1]}, {}, {buttons:[0,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 0. • READ THIS BEFORE REPORTING A STICK BUG: a stick axis can only express RIGHT and UP on axes[0..1], because the report's joystick fields are unsigned. The left stick's full 360-degree analog push IS delivered, but it arrives on the D-PAD — buttons[12..15], and GCExtendedGamepad.dpad.xAxis/yAxis for native apps, which are bipolar. Reconstruct it as x = right - left, y = down - up. Pushing left and reading axes[0] === 0 is the EXPECTED, structural behaviour, not a fault to debug. • While a sequence is playing, this call owns the pad — a controller streamed from a live viewer is paused and resumes on its own shortly after. • Confirm the pad EXISTS with ios_gamepad_status; confirm VALUES in the app under test.

Input routes to whatever holds focus, so foreground the app under test first — measuring while Settings or another app is in front reads as "nothing works".

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
idNoIGNORED. Accepted so older callers do not break. The controller is a real device on the phone and its identity is fixed when it is registered, so passing an id here does NOT re-attach it as that controller and does NOT change what a tester displays — it is silently discarded. Read the current identity with ios_gamepad_status. Button mapping is always W3C standard order regardless.
axesNoAxis values -1..1: [leftX, leftY, rightX, rightY]. Omitted axes read as 0.
udidYesiOS device UDID
resetNoRegister a FRESH controller before sending this frame, instead of reusing the one already there. Use ONLY when the controller has stopped responding — the usual sign is that calls keep succeeding while the app under test sees nothing, and ios_gamepad_status still reports one as registered. Two costs, so do not pass it routinely: the call takes several seconds while the device adopts the new controller, and every registration leaves a permanent extra entry under Settings > General > Game Controller that the device never expires.
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 axes/buttons when present.
buttonsNoButton values 0..1 in W3C standard order (0-3 face, 4/5 shoulders, 6/7 triggers, 12-15 d-pad, 16 home, 17 touchpad on a DualShock). >= 0.5 counts as pressed. An empty/omitted entry releases everything.
intervalMsNoGap between frames in ms (default 33). Lower = faster mashing; 33 ms matches a 30 fps controller poll.

Schema Changelog

Changes observed during successful MCP inspections.

  1. 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 the full behavioral burden. It thoroughly discloses frame semantics, held-button behavior, sequence ownership pausing live viewers, reset side effects, the ignored `id` field, and the unsigned-axes structural quirk. It even explains expected behavior that might otherwise be misreported as a bug.

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?

Though long, the description is front-loaded with purpose and then structured into labeled usage sections. Every paragraph earns its place by covering a real failure mode or operational detail. The bullet-style 'HOW TO FIRE INPUT PROPERLY' section makes complex temporal semantics easy for an agent to follow.

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?

Given the tool's high complexity, absence of annotations, and no output schema, the description is remarkably complete. It covers prerequisites, focus requirements, frame cadence, release semantics, stick-axis caveats, sequence limits, reset behavior, and verification routing via ios_gamepad_status. No critical operational gap remains.

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?

Schema coverage is 100%, but the description meaningfully extends parameter meaning beyond the schema: it explains W3C button ordering, the >=0.5 press threshold, axes as [leftX, leftY, rightX, rightY] with -1..1 range, the unsigned-axis left/up limitation, and how `frames` requires release frames. This is far above the baseline for high schema coverage.

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 opening sentence states a specific verb and resource: 'Present a REAL game controller to an iOS device and set its state.' It distinguishes what makes this tool unique by explaining the virtual DualShock 4, GCExtendedGamepad, W3C gamepad exposure, and the fact that no Safari page is needed. It also names the verification sibling ios_gamepad_status, making the tool's role clear relative to related tools.

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?

The description gives explicit when-to-use and how-to-use guidance: one call equals one frame, press/release frames must pair, rapid sequences should use `frames` rather than repeated calls, and axes should be swept across frames. It also tells the agent to foreground the app under test and to verify existence with ios_gamepad_status, reducing ambiguity about setup and alternatives.

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