# Yutori AI Agent Quickstart You are helping a user set up Yutori from scratch. Yutori provides APIs and agent tools for: | Capability | Use it for | | --- | --- | | Scout | Continuous web monitoring on a schedule | | Research | One-time deep web research | | Browsing | One-time browser automation | | Navigator | A computer-use model API for custom browser agents | Prioritize the CLI/MCP setup first. Do not ask the user to paste API keys into chat. ## Setup Drive setup yourself. The user's only action is clicking **Allow** in a browser tab that opens during auth. 1. Install the CLI, MCP server, and skills in one shot (you run this): ```bash curl -fsSL https://yutori.com/install.sh | YUTORI_INSTALL_CLIENT= bash ``` Substitute `` with your agent's slug — common values: `claude-code`, `codex`, `cursor`, `vscode`, `claude-desktop`, `gemini-cli`, `zed`, `opencode` (run `npx add-mcp list-agents` for the full list). If `YUTORI_INSTALL_CLIENT` is unset the installer registers MCP for the default set (`claude-code`, `codex`, `cursor`, `gemini-cli`). In non-TTY mode the installer does the CLI install via `uv tool install yutori`, registers the Yutori MCP server for the chosen client(s), and installs the seven workflow skills (`yutori-scout`, `yutori-research`, `yutori-browse`, `yutori-computer-use`, `yutori-competitor-watch`, `yutori-api-monitor`, `yutori-login`) at user scope for the chosen client(s). Auth and verification are skipped — they need a browser and an API key (step 2 below). If `~/.local/bin` isn't on your PATH yet, invoke `yutori` via `$(uv tool dir --bin)/yutori` or run `export PATH="$(uv tool dir --bin):$PATH"` for the rest of this session. 2. Authenticate (you run this; **user clicks Allow**): ```bash yutori auth login ``` **Always run this yourself first**, even on a headless host. The command calls `webbrowser.open(auth_url)`, binds `127.0.0.1` for the OAuth callback, and saves the API key to `~/.yutori/config.json`. The Bash call blocks for up to 5 minutes waiting for the user — if it times out, rerun. Two cases: - **Desktop / browser available**: the sign-in tab opens automatically. Tell the user: *"I'm opening a Yutori sign-in tab — click Allow when it loads."* - **Headless host / no browser**: the command prints `Could not launch a browser` followed by an `auth_url`. **Relay that URL to the user** — they paste it into a browser on their own machine, click Allow, and the OAuth callback still completes through your Bash process. Don't skip running `yutori auth login` just because the host might be headless; try it and react to what it prints. 3. Ask the user to restart this coding agent so the MCP tools and skills load. ### Fallback: if step 1 didn't configure MCP or skills The installer's status table will say `MCP server: SKIP` or `MCP skills: SKIP` if Node.js/npx wasn't on PATH. Run only the failed step(s): ```bash # MCP server npx add-mcp -y -g -n yutori -a "uvx yutori-mcp" # Workflow skills npx -y skills add yutori-ai/yutori-mcp -g -y -a ``` If `npx` isn't available, native CLIs work for some clients: - Claude Code: `claude mcp add --scope user yutori -- uvx yutori-mcp` - Codex: `codex mcp add yutori -- uvx yutori-mcp` **Fallback path:** if your Bash tool can't bind `127.0.0.1` for the auth callback (remote dev environment, sandboxed agent) or the user is on a different machine, ask the user to run `curl -fsSL https://yutori.com/install.sh | bash` in their own terminal — the interactive installer walks through CLI, auth, MCP, skills, and a verification task end-to-end. ## Verify **You run these yourself** once the user confirms `yutori auth login` completed: ```bash yutori auth status # confirms an API key is configured yutori usage # validates the key and shows daily quota / active scouts ``` If both succeed, proceed to **Demonstrate** below. If MCP tools have already loaded in your session (i.e. the coding agent was restarted), `list_api_usage` is an equivalent MCP check. ## Demonstrate After auth and verify succeed, run the three demos yourself via the `yutori` CLI in your Bash tool — **no coding-agent restart needed**. (After restart, the MCP tools `run_research_task`, `run_browsing_task`, `create_scout` and the `/yutori-*` skills also become available; use either path.) The task APIs are async: `run` starts the task and returns a `task_id`; you then poll `get TASK_ID` until `status` is `succeeded` or `failed`. Examples below mirror the canonical queries at so demo and docs stay aligned. ### Research (3–10 min) ```bash yutori research run "What are the latest developments in quantum computing from the past week? Include company announcements, research papers, and product releases." # returns task_id; poll until done yutori research get ``` Show the user the returned summary once `status: succeeded`. ### Browsing (30–120 sec) ```bash yutori browse run "Give me a list of all employees (names and titles) of Yutori." "https://yutori.com" yutori browse get ``` Confirm with the user before running additional browsing tasks — each one spends credits. ### Scout — draft only, **do not auto-create** Scouts are *recurring* and spend credits on every scheduled run. Show the user the query you would use and ask for explicit confirmation before running: ```bash yutori scouts create -q "Tell me about the latest news, product updates, press releases, social media announcements, investments into, or other relevant information about Yutori" ``` If they decline, skip the Scout demo and end with a recap of Research + Browsing. ## Navigator API Navigator is Yutori's visual-control model family. Navigator n1.5 (model id `n1.5-latest`) controls browsers. Navigator n2 (model id `n2`) controls a complete desktop through a CUA harness. Both use the **OpenAI Chat Completions-compatible endpoint**: you send a screenshot plus a task instruction, and the model returns actions as tool calls. You execute those actions, append the results, capture a fresh screenshot, and call again - an **agent loop** - until the model returns a text response with no tool calls. There is no `yutori` CLI command for Navigator loops; call them from Python via `client.chat.completions.create(...)`, which is a drop-in OpenAI-compatible client. For n2, use Yutori MCP to drive a local Mac. To build your own n2 agent, use `examples/navigator_n2/` for local Docker or `examples/navigator_n2_daytona.py` for a separate third-party Daytona integration. ### Minimal single call ```python from yutori import YutoriClient from yutori.navigator import playwright_screenshot_to_data_url from playwright.sync_api import sync_playwright with YutoriClient() as client, sync_playwright() as p: browser = p.chromium.launch() page = browser.new_page() page.goto("https://www.yutori.com") image_url = playwright_screenshot_to_data_url(page) response = client.chat.completions.create( messages=[ { "role": "user", "content": [ {"type": "text", "text": "List the team member names."}, {"type": "image_url", "image_url": {"url": image_url}}, ], } ], ) message = response.choices[0].message print(message.content) # model's reasoning / final answer for tc in message.tool_calls or []: print(tc.function.name, tc.function.arguments) ``` ### Building an agent loop In practice you run a loop: execute the returned tool calls on your Playwright `page`, append the results as `tool` messages, capture a fresh screenshot, and call `create()` again until the model returns no tool calls. The `yutori.navigator` subpackage provides helpers for this — screenshot capture, coordinate denormalization (model uses a 1000×1000 space), message trimming, and key mapping. For a complete working agent loop with retries, structured output, and expanded tools, see [`examples/navigator_n1_5.py`](https://github.com/yutori-ai/yutori-sdk-python/blob/main/examples/navigator_n1_5.py). ### Navigator n1.5 parameters Pass these as keyword args to `client.chat.completions.create(...)`: | Parameter | Purpose | |-----------|---------| | `model` | `"n1.5-latest"` (default) or a dated version like `"n1.5-20260428"`. | | `tool_set` | Built-in tool set: `"browser_tools_core-20260403"` (default — 18 coordinate-based tools) or `"browser_tools_expanded-20260403"` (adds `extract_elements`, `find`, `set_element_value`, `execute_js`). | | `disable_tools` | Remove specific tools by name, e.g. `["hold_key", "drag"]`. | | `json_schema` | JSON Schema dict for structured output. Model returns conforming JSON; accessible as `response.parsed_json`. | | `temperature` | Sampling temperature (default 0.3). | The core action space covers clicks, scroll, type, key press, drag, mouse move/down/up, navigation (`goto_url`, `go_back`, `go_forward`, `refresh`), `wait`, and `hold_key`. Coordinates are in a normalized 1000×1000 space — use `denormalize_coordinates(coords, width, height)` to map to viewport pixels. For the full action reference, see . For the SDK and CLI reference, see the link at the bottom of this file. ### Navigator n2 (computer use) Navigator n2 operates a full desktop. `N2ComputerAgent` defaults to `model="n2"` and to the pinned current tool set, `TOOL_SET_COMPUTER_USE_LATEST` (`"computer_use_tools-20260830"`); raw `client.chat.completions.create` calls should pass both explicitly. The set exposes `computer_batch`, `edit`, `read`, `write`, and `bash`. A batch holds up to 20 actions drawn from 15 GUI action types, runs sequentially against one observed frame, stops at its first error, and receives one screenshot result. n2 is non-streaming and rejects caller-provided `json_schema`, `response_format`, and non-auto `tool_choice`. It accepts `disable_tools` — only `bash`, `read`, `write`, and `edit` may be disabled (`computer_batch` is the GUI surface and cannot be; unknown names are rejected rather than ignored) — and `tools`: custom definitions in the standard OpenAI shape, appended after the set's, refused if their name shadows a tool the set already serves (disable the served tool first; `computer_batch` cannot be redefined). `N2ComputerAgent` implements only the set's tools, so custom tools need your own loop over `chat.completions.create`. Implement every tool of the set your harness serves (the model runs shell work through `bash` rather than a GUI terminal, and expects `read` on an image file to return the image). n2 trains with the full set and performs best with it — a reduced dated set should keep at least `computer_batch` and `bash`. A caller system message is appended under a `# User Instructions` header after the server's own prompt. Send the full conversation; the server keeps images only in the two newest image-bearing messages. Only `computer_batch` results carry a screenshot — after `bash`/file calls (and at run start) the model requests a fresh frame itself with a `screenshot` batch member. Long runs compact automatically by default (`compactor="auto"` -> `N2InlineCompactor`), reproducing the trained long-horizon regime (64K context, same compaction prompt, 53,760-token trigger); pass `compactor=None` to instead run past the trained context and stop at the 128k serving limit with `stopped_by="context_limit"`. - **Local Docker:** [`examples/navigator_n2/`](https://github.com/yutori-ai/yutori-sdk-python/tree/main/examples/navigator_n2) implements the full current tool set in a disposable local container. - **Third-party Daytona desktop:** [`examples/navigator_n2_daytona.py`](https://github.com/yutori-ai/yutori-sdk-python/blob/main/examples/navigator_n2_daytona.py) is a compact hosted example. The SDK runs the loop; a Yutori-maintained `DaytonaComputer` adapter and lifecycle wiring execute actions on Daytona. The script declares Python 3.10+, the Yutori SDK, and the tested Daytona version as inline dependencies, so run it with `uv run examples/navigator_n2_daytona.py ""` plus a `DAYTONA_API_KEY`. The adapter serves the full current tool set (file tools via the SDK's `ShellFileToolsMixin`); [`examples/navigator_n2/cua_adapter.py`](https://github.com/yutori-ai/yutori-sdk-python/blob/main/examples/navigator_n2/cua_adapter.py) is the full-surface reference for tool implementations and result formats. Walkthrough: . - **Local Mac:** install Yutori MCP and run ```bash uvx yutori-mcp computer-use setup uvx yutori-mcp computer-use run "In Calculator, compute 17 * 23 and report the result." --app Calculator ``` `uvx yutori-mcp` then exposes the `run_computer_use_task` MCP tool on macOS. It controls the visible foreground desktop and sends what is on screen to Yutori, so run it while the user is not touching the Mac. `N2ComputerAgent` drives any adapter that implements the async handler surface — the GUI primitives plus `run_bash_command` and the file tools — exported for type-checking as the `yutori.navigator.N2Computer` protocol. Ownership: the loop implements `computer_batch` itself (coordinate mapping, sequencing, one post-batch screenshot) and calls only GUI primitives on the adapter; the `bash` and file-tool output contracts belong to the adapter — `ShellFileToolsMixin` provides the file tools over any sandbox shell with python3, and `format_shell_output` renders `bash` results. Exact handler signatures, error conventions, and output formats: the "Navigator n2 loop" section of the SDK reference (api.md, linked below), with `examples/navigator_n2/cua_adapter.py` as the full-surface reference implementation. `yutori.navigator.macos.MacOSComputer` is the native Mac adapter Yutori MCP uses (`pip install 'yutori[macos]'`); it encodes full-screen observations as compressed WebP and enforces the 10 MB request budget. Model reference: . For SDK/API integration details, use: - Python SDK and CLI reference: https://github.com/yutori-ai/yutori-sdk-python/blob/main/api.md - MCP server and skill setup: https://github.com/yutori-ai/yutori-mcp - API docs index for agents: https://docs.yutori.com/llms.txt