Troupe Cloud
MCP in the cloud
Troupe Cloud serves the device tools over MCP at https://api.troupe.ali.ve/mcp, so a coding agent can start
a hosted device, install your app and drive it. This page covers connecting a client with OAuth or an API key,
choosing the project, and the two toolsets.
The endpoint
/mcp speaks MCP over Streamable HTTP and keeps no state between requests. It takes a bearer credential only:
an API key, or an access token issued for /mcp. The tools are the ones a local runtime serves (see
MCP), and each needs the same scopes as its procedure.
Write the client's config
troupe mcp install prints the entry for your client; --write merges it into the client's project file.
bunx troupe mcp install --client claude-code --cloud https://api.troupe.ali.ve{
"mcpServers": {
"troupe": {
"type": "http",
"url": "https://api.troupe.ali.ve/mcp"
}
}
}--client | File | With --api-key-env TROUPE_API_KEY the entry adds |
|---|---|---|
claude-code | .mcp.json | "headers": { "Authorization": "Bearer ${TROUPE_API_KEY}" } |
cursor | .cursor/mcp.json | "headers": { "Authorization": "Bearer ${env:TROUPE_API_KEY}" } |
vscode | .vscode/mcp.json | "headers": { "Authorization": "Bearer ${env:TROUPE_API_KEY}" } |
codex | .codex/config.toml | bearer_token_env_var = "TROUPE_API_KEY" |
Unlike the local entry, the cloud entry holds no path of your machine and no secret, so a team can commit it.
--name sets the server's name in the file, and --toolset all asks for every tool. Codex reads a project's
.codex/config.toml only in a project it trusts.
Sign in with OAuth
Without --api-key-env the entry carries no credential and the client signs in for you. Troupe Cloud is its
own OAuth 2.1 authorization server:
- The first request is answered 401 with a pointer to the endpoint's metadata, from which the client finds the authorization server.
- The client identifies itself with a Client ID Metadata Document: its
client_idis anhttpsURL of a document that lists its redirect addresses. Dynamic client registration is not offered. - It uses the authorization code flow with PKCE (
S256), for the resourcehttps://api.troupe.ali.ve/mcp. - Your browser opens Troupe Cloud's consent page. Choose an organization, or one project of it, and allow.
The sign-in then holds devices:read, devices:acquire, devices:drive, apps:install and logs:read, cut
to what your role allows, and runs:read when the client asks for it. It never holds another scope. It lasts
at most 30 days, with access tokens of at most 10 minutes that the client refreshes. Revoke it under
Account, Connected apps: see connected apps.
A client that signs in only through dynamic client registration cannot use OAuth here; troupe mcp install
says so for Cursor. Give such a client an API key.
Send an API key
With --api-key-env the entry sends an API key from an environment variable. The file holds
the variable's name, never the key:
bunx troupe mcp install --client codex --cloud https://api.troupe.ali.ve \
--api-key-env TROUPE_API_KEY[mcp_servers.troupe]
url = "https://api.troupe.ali.ve/mcp"
bearer_token_env_var = "TROUPE_API_KEY"Start the client with the variable set. Give the key the five device scopes above, restrict it to one project, and give each developer or agent a key of its own, so that revoking one stops only that one.
Choose the project
Tools that start or list sessions work in one project. Sign in for one project on the consent page, or use a
key for one project. A sign-in or a key for a whole organization must send a Troupe-Project header with
every request; without one sessions_create answers PROJECT_REQUIRED.
Toolsets
| Toolset | Address | Tools |
|---|---|---|
curated, the default | /mcp | 31 |
all | /mcp?toolset=all | 53 |
The curated set is what an agent needs to drive a device:
| 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 |
| The screen | ui_snapshot, ui_query, ui_waitFor |
| Input | input_tap, input_doubleTap, input_longPress, input_swipe, input_type, input_fill, input_pressKey, input_pressButton, input_scroll, input_setOrientation, input_hideKeyboard |
| Media | media_screenshot, which answers with an image |
| Logs | logs_read, logs_crashes |
all adds every other procedure the cloud serves as a tool, among them input_drag, input_pinch, the
system group, apps_uninstall, apps_setPermissions, files_get and the read-only runs_list, runs_get
and runs_events. Two procedures are never tools: streams.ticket, because its answer is a credential for a
stream an MCP client cannot open, and runs.publish. The procedures for builds, keys and the rest of the cloud
contract are not tools either.
How the tools behave
- A tool's name is its procedure's id with the dot replaced by an underscore, and its input and output are the procedure's: see the runtime reference.
- A session an agent starts has the holder kind
mcp: it ends after 10 minutes without a call and after 60 minutes at the latest, unlesssessions_createasks for other limits. See limits and timeouts. timeoutMsis capped at 50 seconds. A longer wait is a tool that returns at once and one that waits, such assessions_createandsessions_wait.apps_installtakes a build's artifact or a URL with its SHA-256: see installing an app.- An error is a tool result marked as an error, whose text is the error body as JSON: a code, a message and data.
- A tool beyond the credential's scopes is refused with HTTP 403 and an
insufficient_scopechallenge that names the scopes it needs. - Tool calls spend the request budgets like any other call.