Integrate
MCP
Troupe serves its device operations as Model Context Protocol tools, so a coding agent can boot a simulator, install your app, read the screen and tap. This page covers connecting an agent to your local runtime, the two toolsets, and how an agent works with a device.
For the hosted service, see MCP in the cloud.
Connect a coding agent
In a project that has @alivelabs/troupe installed, write the client's project config:
bunx troupe mcp install --client claude-code --write--client | File it writes |
|---|---|
claude-code | .mcp.json |
cursor | .cursor/mcp.json |
vscode | .vscode/mcp.json |
codex | .codex/config.toml |
Without --write the command prints the entry and changes nothing. The entry starts troupe mcp, a bridge
between the client's stdio and the local runtime daemon, which it starts when none runs:
{
"mcpServers": {
"troupe": {
"type": "stdio",
"command": "/path/to/bun",
"args": ["/path/to/project/node_modules/@alivelabs/troupe/bin/troupe.ts", "mcp"]
}
}
}VS Code's file uses the key servers instead of mcpServers. Codex's file is TOML:
[mcp_servers.troupe]
command = "/path/to/bun"
args = ["/path/to/project/node_modules/@alivelabs/troupe/bin/troupe.ts", "mcp"]Four things to know about the entry:
- It holds no credential. The bridge reads the daemon's current token from
runtime.jsoneach time it starts. - It is your machine's own. The paths are absolute, because a client launched from the Dock does not
have your shell's
PATH. Do not commit it: each developer runs the command in their own checkout. For Claude Code,claude mcp add-json troupe '<entry>'keeps it in your local scope instead of.mcp.json. - It runs the project's Troupe. The entry names the
troupein the project'snode_modules, so the agent uses the version the project pins. --writemerges. It adds the entry beside the servers already in the file. The same entry again changes nothing. A different entry of the same name, or a file it cannot merge safely, stops the command with exit code 2.
Codex reads a project's .codex/config.toml only in a project it trusts, and says nothing otherwise. Claude
Code and Cursor ask before they start a project's server.
The connection has been tried with Claude Code, Cursor's CLI, Codex, VS Code and the MCP Inspector.
The endpoint
The daemon serves MCP over Streamable HTTP at /mcp on its loopback port. It is stateless: every request
stands alone. troupe mcp forwards each JSON-RPC message to that endpoint as the runtime's owner and writes
the answers to stdout. Nothing else is written to stdout.
Toolsets
A client gets one of two sets of tools.
| Toolset | Tools | How to choose it |
|---|---|---|
curated | 31, for working with a device | The default |
all | 61: every procedure that can be a tool | troupe mcp --toolset all, or --toolset all on troupe mcp install |
The curated set:
| Group | Tools |
|---|---|
| Sessions | sessions_create, sessions_get, sessions_list, sessions_wait, sessions_heartbeat, sessions_release |
| Catalog | catalog_deviceTypes, catalog_osVersions |
| Apps | apps_install, apps_launch, apps_terminate, apps_list, apps_clearData, apps_openUrl |
| Screen | ui_snapshot, ui_query, ui_waitFor, media_screenshot |
| Input | input_tap, input_doubleTap, input_longPress, input_swipe, input_type, input_fill, input_pressKey, input_pressButton, input_scroll, input_setOrientation, input_hideKeyboard |
| Logs | logs_read, logs_crashes |
all adds the runtime's status and environment checks, uninstalling apps and setting permissions, drag,
pinch and raw gestures, device settings such as location and appearance, and reads of the event streams.
Three procedures are never tools, because they mint or return credentials: pairings.create,
pairings.redeem and streams.ticket.
On the HTTP endpoint the choice is the toolset query parameter: /mcp?toolset=all.
How tools behave
- Names and inputs. A tool's name is its procedure's id with
_for the dot:input.tapisinput_tap. Its input is the procedure's input, so the reference describes every tool. - Results. A tool returns structured content and the same as JSON text.
ui_snapshotreturns its text as an aria snapshot.media_screenshotreturns an image. - Errors. A failure is a tool result with
isError: true. Its text is the error as JSON, with the samecode,message,dataandretryableas on every other surface. - Timeouts.
timeoutMsis capped at 50 seconds. A longer wait is a repeated call:sessions_waitanswersdone: false, and the agent calls it again. - Sessions. A session created through MCP is held as
mcp. It ends after 10 minutes without a call that names it, and after 60 minutes at the latest.sessions_heartbeatkeeps it alive. - Annotations. Each tool says whether it is read-only, idempotent or destructive.
How an agent works with a device
A typical task runs like this.
catalog_deviceTypesandcatalog_osVersionssay what can be started.sessions_createstarts a device, with the app to install:JSON { "spec": { "platform": "ios-simulator", "deviceType": "iPhone 18 Pro" }, "install": [{ "path": "/Users/me/shop/build/Shop.app" }] }sessions_waitanswers when the session isready.apps_launchstarts the app by itsbundleId.ui_snapshotreads the screen. Each element has aref:Output - application "Shop" [ref=e1]: - toolbar "Cart" [ref=e2]: - button "Back" [ref=e3] - heading "Cart" [level=1] [ref=e4] - textbox "Email" [testId="email"] [ref=e5]: "a@b.co" - switch "Remember me" [checked] [ref=e6]The agent acts on a
ref, or on a locator:JSON { "sessionId": "ses_…", "target": { "ref": "e5" }, "value": "ada@example.com" }That is an
input_fill. The runtime waits until the element can take the action, 5 seconds by default.media_screenshotshows the result.logs_readandlogs_crashesexplain a failure.sessions_releasegives the device back.
A ref is valid until the next ui_snapshot of that session. A ref the runtime can no longer find fails
with LOCATOR_REF_STALE: take a new snapshot. A target may also be a locator, which survives snapshots:
{
"target": {
"locator": {
"v": 1,
"steps": [{ "by": "role", "role": "button", "name": { "text": "Sign in" } }]
}
}
}You can watch an agent work: its session appears in Troupe Studio with the live screen.
Next
- MCP in the cloud: the same tools on hosted devices
- Sessions: what a session is and when it ends
- The
troupeCLI: every option oftroupe mcpandtroupe mcp install