Back to App Store

Otto

Telepat · io.pilot.otto
Drive real Chrome tabs from an agent — extract, automate, screenshot, no headless farm.
Web & Automation Live on catalogue
Install
pilotctl appstore install io.pilot.otto
v0.20.0
Version
15
Methods
9.2 MB
Size
guarded
Sandbox
macOS · Linux
Platforms

About Otto

Otto is secure remote browser automation. A controller CLI sends commands over an authenticated WebSocket to a relay daemon, which routes them to a Chrome extension running on live tabs. Code drives the browser deterministically; the agent decides what to do, not how to click.

What an agent gets: - Content extractionotto.extract / otto.extract.format turn a URL into clean markdown, distilled/clean/raw HTML, or text through a real tab. - Site commandsotto.test runs registered actions on real sessions (Reddit/LinkedIn getPosts, Hacker News getFrontPage, Google getSearchResults, …); otto.commands lists what a node exposes. - Page & tab controlotto.screenshot (viewport or full page) and otto.cmd for low-level primitives (tab open/navigate/query, DOM extract). - Status & diagnosticsotto.status (relay + connected nodes), otto.client.status, otto.authcode, otto.extension.info, otto.logs/otto.logs.status, otto.agent.status — all JSON. - Full CLI surfaceotto.exec runs any verbatim otto argv.

Good to know: - Returns JSON wherever the CLI offers it; discover the live surface at runtime with otto.help — every method, its parameters, and its latency class (fast / med / slow). - Real browser tabs, not a headless farm — no Docker, Puppeteer farm, or cloud-browser rental. - Prerequisite stack on the host: a running relay (otto start), Chrome with the Otto extension loaded and paired as a node, and a logged-in controller. Until that is up, page commands return a structured error ({stdout,stderr,exit}); otto.status is the right preflight. - Runs on macOS and Linux (arm64 + amd64); the otto CLI is staged as a self-contained binary and sha-pinned on install. Free and open source (MIT) — no payment, no per-call limit.

Methods · 15

otto.exec
Run any otto subcommand. Payload is {"args":[...]} — the verbatim otto argv. Use this for the full CLI surface beyond the curated methods (config, client register/login/remove, pair, listener unsubscribe, extension update, agent install, site-filtered `commands list --site`, filtered `logs list`, etc.). Add "--json" where the command supports it. Example args: ["commands","list","--site","reddit.com","--json"]. Note: interactive/streaming subcommands (setup, settings, logs follow, listener subscribe-network, test with stream/wait flags, mcp serve, start --attached) are not suitable over one-shot IPC.
otto.status
Relay daemon status as JSON: running pid, port, uptime, log path, and the list of currently connected browser node IDs. The right preflight before any page command — an empty node list means no Chrome extension node is paired/online.
otto.commands
List the automation commands the connected node(s) expose, as JSON. Use to learn which site commands are available before calling otto.test. For a single site, use otto.exec with ["commands","list","--site","<domain>","--json"].
otto.extract
Extract the readable content of a web page through a live paired browser tab, as JSON markdown. Opens a temporary tab on the node, extracts, and closes it. Requires a running relay and a paired Chrome node.
otto.extract.format
Extract page content in a chosen format: markdown, distilled_html, clean_html, raw_html, or text. Returns JSON. Like otto.extract but lets you pick the output representation.
otto.screenshot
Capture a screenshot of a page through a live browser tab; returns JSON (base64 PNG in the envelope, no local Preview window). Requires a running relay and a paired Chrome node.
otto.test
Run a registered site command on a browser node (opens a tab, runs the command, returns JSON). Provide site (e.g. reddit.com), command id (e.g. getPosts), and a JSON payload string (use {} for none, e.g. {"limit":10}). One-shot; requires relay + paired node.
otto.cmd
Send a single raw action to the target browser node and return the full JSON envelope. Provide the action name and a JSON payload string (use {} for none). Use for low-level primitives (e.g. primitive.tab.open) not covered by a curated method.
otto.logs
Read recent relay logs as JSON. For filtered queries (level/source/since/request-id) use otto.exec with ["logs","list",...,"--json"].
otto.logs.status
Relay log storage status as JSON (retention, counts, sizes). Check whether logging is healthy and how much history is available.
otto.client.status
Local controller client identity state and where its secret resolves from (env vs keychain), as JSON. Verify the controller is registered and logged in before running page commands.
otto.authcode
List pending pairing codes from the relay as JSON. See codes awaiting approval when bringing a new Chrome extension node online (approve with `otto pair <code>` via otto.exec).
otto.extension.info
Installed Chrome extension artifact metadata (version, unpacked path, checksum) and configured relay URLs, as JSON. Confirm which extension build the host has staged for the Load-unpacked handoff.
otto.agent.status
Which agent frameworks (claude, codex, cursor, vscode, …) currently have the Otto MCP server registered, as JSON.
otto.help
Discovery: every method with params, kind, and latency class.

What’s New

v0.20.0 Latest
  • Released v0.20.0

Platform Compatibility

macOS Apple Silicon
4.6 MBSupported
macOS Intel
5.1 MBSupported
Linux arm64
5.3 MBSupported
Linux amd64
4.9 MBSupported
You might also like

More in Web & Automation