# coil > Agent threads with their own Linux computer. Each thread has an agent, a shell, a browser, and a disk you can pause and fork. ## How an agent uses coil Connect an MCP client to `https://coil.coey.dev/mcp`. Every request must be signed in. On an instance behind Cloudflare Access, send an Access token in the `cf-access-token` header. On an instance with Sign in with Cloudflare, send the session cookie from `https://coil.coey.dev/oauth/login`; without it the answer is 401. 1. Call `coil_describe` to get the TypeScript declaration of the `coil` object. 2. Call `coil_run` with the body of an async function. Each `await coil.(input)` is one call, at most 40 per run. The script has no network access of its own. 3. Or call any capability below directly as its own MCP tool, or with REST. Example `coil_run` script: ```js const t = await coil.thread_create({ title: "demo" }); await coil.thread_exec({ name: t.name, command: "echo '' > index.html && (busybox httpd -p 3000 &)" }); await coil.browser_open({ name: t.name, url: "localhost:3000" }); const page = await coil.browser_snapshot({ name: t.name }); await coil.browser_click({ name: t.name, ref: "e1" }); await coil.thread_pause({ name: t.name }); return { thread: t.name, page }; ``` The same list drives the MCP tools, `coil_run`, the REST endpoint, and these docs. ## Threads ### thread_list List your threads, newest activity first. - No input. - Returns: Array of { name, title, phase, busy, repo, updatedAt } ### thread_create Create a thread: its own agent and its own Linux computer. repo is an optional git URL. - `name`: Optional thread name; one is made up if empty - `repo`: Optional git URL to clone into /workspace - `title`: Optional title shown in the sidebar - `size`: Container size One of lite, standard-1, standard-2, standard-3, standard-4. - Returns: The thread view: { name, title, phase, messages, surfaces, ... } ### thread_send Send a message to the thread agent and wait for the turn to finish. Reuse requestId to retry safely. - `name` (required): Thread name, for example "fix-login-3a9c2e" - `text` (required): The message - `requestId`: Optional idempotency key - Returns: { status, answer } ### thread_status Phase, transcript, compaction pairs, turns, and recent commands of a thread. - `name` (required): Thread name, for example "fix-login-3a9c2e" - Returns: The thread view ### thread_fork Start a new thread from this thread's disk and a summary of its conversation. - `name` (required): Thread name, for example "fix-login-3a9c2e" - `forkName`: Optional name for the fork - Returns: The new thread view ### thread_message Send a message from one thread to another. The receiver starts a turn now, or queues it until its current turn ends. Returns at once. - `from` (required): The sending thread - `to` (required): The receiving thread - `text` (required): The message - Returns: { queued } ### thread_wait Wait until a thread finishes its turn, up to seconds, and return its last answer. - `name` (required): Thread name, for example "fix-login-3a9c2e" - `seconds`: At most 600; default 120 - Returns: { done, answer } ### thread_context_budget Set a smaller context window for a thread, in tokens, or 0 for the model limit. The thread compacts at 75% of it and continues from its HANDOFF: note. - `name` (required): Thread name, for example "fix-login-3a9c2e" - `tokens` (required): Context size in tokens; 0 clears it - Returns: The usage, with contextWindow ### model_list List the models you can pick: the gateway models plus every Workers AI text model with tool use on your account, newest first. Refreshed from Cloudflare every hour. - No input. - Returns: Model ids with label, context window, price per million tokens, and vision support ### thread_model Choose the model for a thread, for example gateway/claude-opus-5-5 or a Workers AI model id. With Sign in with Cloudflare it runs on your own account. - `name` (required): Thread name, for example "fix-login-3a9c2e" - `model` (required): A model id from the model list - Returns: The usage, with the context window of the new model ### thread_stop Stop the agent turn now. A running tool call ends at once and the thread stays awake. - `name` (required): Thread name, for example "fix-login-3a9c2e" - Returns: null ## Shell ### thread_exec Run a shell command in the thread computer, in /workspace. - `name` (required): Thread name, for example "fix-login-3a9c2e" - `command` (required): Run with bash -lc - Returns: { exitCode, stdout, stderr, seq } ## Files ### thread_read_file Read a file from the thread computer. - `name` (required): Thread name, for example "fix-login-3a9c2e" - `path` (required): Relative to /workspace - Returns: The file contents as text ### thread_write_file Write a text file into /workspace on the thread computer, for example to upload a local pi extension folder file by file. - `name` (required): Thread name, for example "fix-login-3a9c2e" - `path` (required): Relative to /workspace; must stay inside it - `content` (required): The full text of the file - Returns: { path, bytes } ## Browser ### browser_open Load a URL in the thread's browser. localhost is the thread computer. - `name` (required): Thread name, for example "fix-login-3a9c2e" - `url` (required): For example localhost:3000 - Returns: Page title and URL ### browser_snapshot List clickable elements as refs (e1, e2, ...) plus the page text. - `name` (required): Thread name, for example "fix-login-3a9c2e" - Returns: Text with one line per element: ref, role, label ### browser_click Click an element by its ref from browser_snapshot. - `name` (required): Thread name, for example "fix-login-3a9c2e" - `ref` (required): For example e3 - Returns: What was clicked and the page now open ### browser_type Type text, optionally into an element ref first. - `name` (required): Thread name, for example "fix-login-3a9c2e" - `text` (required): Text to type - `ref`: Optional element to click first - Returns: How many characters were typed ### browser_eval Run a JavaScript expression in the page and return the result. - `name` (required): Thread name, for example "fix-login-3a9c2e" - `expression` (required): For example document.title - Returns: The result as text ## Computer ### thread_compact Summarise the conversation and save the disk, as one recorded pair. - `name` (required): Thread name, for example "fix-login-3a9c2e" - Returns: The saved pair: { at, reason, snapshot, summaryEntry } ### thread_pause Save the disk and turn the computer off. The next call resumes it. - `name` (required): Thread name, for example "fix-login-3a9c2e" - Returns: The saved pair, or null if it was already off ### thread_resize Change the container size. A running computer is paused and restarted at the new size. - `name` (required): Thread name, for example "fix-login-3a9c2e" - `size` (required): Container size One of lite, standard-1, standard-2, standard-3, standard-4. - Returns: { size, restarted } ## Pi extensions ### thread_extensions Load stock pi extensions into the thread. Each source is an https git URL (optionally #ref) or a ./path inside /workspace, for example an uploaded folder. Their tools run inside the thread computer and the agent can call them from its next turn. An empty list removes them. - `name` (required): Thread name, for example "fix-login-3a9c2e" - `sources` (required): For example ["https://github.com/owner/repo", "./uploads/my-extension"] - Returns: { tools: [{ name, description, extension }], errors, unsupported } ## Warm bases ### base_prepare Clone a repo, run a setup command once, and snapshot it. New threads on that repo start warm. - `repo` (required): Git URL - `setup`: Optional setup command, for example npm ci - Returns: The base record ## REST `POST https://coil.coey.dev/api/capabilities/` with the input as a JSON body runs one capability and returns its result as JSON.