Skip to main content
Glama

interact

Plays keyboard, mouse, touch, wheel, scroll, resize and clock steps on an open Three.js page, then returns state changes, console output, motion, sound, and optional screenshots for testing interactions.

Instructions

Plays the open page: keyboard, mouse, touch, wheel, scroll, resize and clock steps sent frame by frame (steps lists the kinds), and returns what changed in the state (its new values; the whole state when nothing changed), the console log/warn/info lines and errors the steps raised, a Motion line when the subject (window.__game.subject, or where the state puts its player) turned, or stopped while a key was still held, a Sound line with how many sounds the steps started on a page that makes sound, and with look: true look's picture and list after the steps, in the same reply. Every mouse and touch step says which named object in the scene is under it, and its distance. Use it to play an interaction the request names and read the state it leaves, to set a moment up ({ state }) and step to it ({ until }), or to keep a play as a check (save).

Input Schema

NameRequiredDescriptionDefault
gameNoThe name the game was opened under with the `open` tool, to act on ("main" by default; a subagent uses its own).
lookNoAlso return `look`'s picture after the steps.
saveNoSave this call (its steps and `expect`, which it needs) as a check of this name in game-tests.json when every Expect entry holds. A call with `save` plays its steps from a fresh reload, as `test` and the after-edit hook will rerun them: leading state steps become its setup.
hoverNoAfter the steps, move the mouse to each named object's centre on screen and return what changed there after `frames`, one diff per name.
stepsNoSteps, in order. { key, frames? } presses the key, holds it `frames` frames (default 1) and releases it; { key, down: true } holds it across steps until { key, down: false }; { mouse: click|dblclick|down|up|move, x, y }; { mouse: move, relative: [dx, dy] } (mouse look under pointer lock); { wheel: deltaY, x?, y? }; { resize: [w, h] }; { scroll: px | { progress: 0..1 } | { to: "#section" } } (scrolls the window; the reply says where, and the progress of Lenis, ScrollTrigger or drei ScrollControls when found); { touch: start|move|end|tap, x, y }; { wait: frames, draw? }; { action, ...args } for window.__game.act; { state: {...} } (sets observe()'s keys through window.__game.setState, then draws a frame: set the scene up first, as { state: { player: { x: 2, z: 0 } } }); { until: {...}, max? } (steps one frame at a time until the state holds, at most `max` frames, 600 by default, and says the frame or what it saw; its values as `expect`'s); { clock: { timescale?, paused? } } (sets the clock's time scale, or resumes (paused: false) or pauses real-time play; the clock reads 60 s at frame 0 on purpose, past any boot, so a page's own time starts there). A step's frames run without drawing except its last (an until draws none); draw: true on a step draws every frame, for a picture that builds up over frames (trails, progressive rendering). Each other step advances `frames` (default 1); `frames: 0` sends it on the same frame as the next step (two keys down at once, for a diagonal).
traceNoUp to 6 dotted paths into observe() read every frame of the steps (after leading state steps): one line per path with its first and last value, its peak or low and their frames, and the first frame it changed, as `player.y: 0 → peak 2.04 at frame 22 → 0 at frame 44; first changed at frame 2`. Tune by numbers: jump height and airtime, stopping distance, frames from key to motion. Read for the first 600 frames of the steps; a longer run keeps those.
expectNoChecked against the state after the steps, in this reply: { score: 1, "player.x": [2.9, 3.1] } gives `Expect: score 1 ✓ · player.x 2.97 ✗ expected 2.9 to 3.1`. A value is a number, string or boolean (equal), [min, max] (a range; two numbers are always a range), a list of other values (one of them, as ["banana", "star"]) or null (exists), keyed by dotted paths into observe() ("coins.0.x" for lists).
framesNoFrames to wait at each hovered object (default 1).
recordNotrue: play the steps (after leading { state } steps) in real time, each frame 1/60 s, and record them: a GIF in the run folder (480 px, each frame shown for its real time, HTML over the canvas included) and four moments of it in the reply, with the game's real frame intervals at a 60 Hz pace (median, p95, max; a slower frame reads as its own time, not a 60 Hz screen's 33 ms) on the GPU named; with look: true, look's picture too. 15 s at most; the clock is paused again after. Evidence of real-time play for an agent or a judge.

Schema Changelog

Changes observed during successful MCP inspections.

  1. First observedv0.2.1

TDQS

A3.6/5.0
Behavior4/5

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

With no annotations, the description carries the full burden and does so richly: it discloses frame defaults, that a step's frames run without drawing except its last, that `until` draws none, that `save` replays from a fresh reload, the 60 s clock offset at frame 0, trace's 600-frame read window, and record's 15 s cap and post-recording clock pause. It omits failure semantics — whether a failing step or a broken `expect` aborts the run or how errors in steps are reported.

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

Conciseness2/5

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

The opening sentence is a ~150-word run-on with deeply nested parentheses, hard to parse before the agent reaches the actual usage clause at the end. Substantial content duplicates the per-parameter schema descriptions (the full step-type enumeration, frames defaults), so it is over-long rather than front-loaded and economical.

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

Completeness4/5

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

For a 9-parameter, nested, annotation-free tool with no output schema, the description explains the reply shape in detail: state diff, console log/warn/info and errors, Motion and Sound lines, and `look` output on request. That covers what an agent needs to interpret results; only error/abort behavior is left unexplained.

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

Parameters3/5

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

Schema description coverage is 100%, and each parameter already carries a long schema-side description, so the baseline is 3. The top-level text adds some framing (`steps` lists the kinds, `until` takes expect-style values, `save` requires `expect`), but most of its content restates what the schema already documents.

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

Purpose4/5

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

The description names a specific verb+resource: it plays the open page with keyboard/mouse/touch/wheel/scroll/resize/clock steps and returns the changed state, console lines, and motion/sound/look results. It references related tools (`open`, `look`, `test`, `observe()`) but never draws a clean line against siblings like `feel` or `eval`, so the boundary with those is left implicit.

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

Usage Guidelines4/5

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

It gives concrete when-to-use cases: play an interaction the request names, set a moment up with `{ state }`, step to it with `{ until }`, or persist a play as a check via `save`, plus `record` as real-time evidence. It does not state when NOT to use it (e.g., a bare picture should go to `look`, a state read without input to `observe`), so routing to alternatives is only implied.

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