Browsers, shells and files for AI agents. In one isolated session.
Each Boxline session is a cloud machine your agent can drive: Chrome over CDP with Playwright or Puppeteer, an optional bash shell, and a shared /workspace disk. Start one with an API call, watch it live, and pay by the second.
Free plan with a $5 usage credit every month. Browser sessions from $0.045 per hour.
One machine
Log in, download, analyse, upload. Without shipping files around.
Real agent tasks cross the line between browsing and computing. In Boxline, the browser, the shell and the disk share one sandbox, so each step picks up exactly where the last one left off.
Log in with the browser
Drive Chrome with Playwright, Puppeteer or raw CDP. Save the login in a context so the next session starts signed in.
Download the CSV
Browser downloads land in /workspace/downloads, whichever client clicks. One API call waits for the file to finish.
Analyse it in the shell
Run Python or Node against the file with exec, or open the terminal. Need the site's login in the shell? Export the browser's cookies for curl.
Upload the result
Hand the output back to a website with the browser's upload action, or read it through the files API.
Features
Built for agents that run for real.
The pieces you need once an agent leaves the demo: quick starts, state that survives, a way to look over its shoulder and a bill that matches what ran.
Fast start
Sessions come from a warm pool of ready machines. Our target is under one second from request to running session.
Session move
Move a live session to a fresh machine with one API call. Tabs, logins and files come along, and clients reconnect to the same URL.
Live view
Watch any session's browser in real time, and click in to take over when your agent needs a hand.
Pause and resume
Pause to save browser state and files and stop billing. Connecting again resumes the session.
Contexts
Keep logins between sessions, so your agent does not have to sign in on every run.
Actions API
Send clicks, typing and screenshots in one request. They run next to the browser for low latency.
MCP server
Claude, Cursor and other MCP clients can use sessions as tools with a few lines of config.
Per-second billing
Pay for the seconds a session runs. No per-session fee, and nothing while it is paused for up to 24 hours.
For developers
Bring the tools you already use.
Connect Playwright over CDP, use the TypeScript SDK, add the MCP server to your client, or give Claude’s bash tool a real machine to run on.
- Playwright, Puppeteer or raw Chrome DevTools Protocol
- A shell with Python, Node, ffmpeg and sudo built in
- REST API with a single
x-api-keyheader
import { chromium } from "playwright";
const API = "https://api.staging.boxline.dev/v1";
const headers = {
"x-api-key": process.env.BOXLINE_API_KEY!,
"content-type": "application/json",
};
// 1. Create a session with a browser
const session = await fetch(`${API}/sessions`, {
method: "POST",
headers,
body: JSON.stringify({ browser: true, timeout: 300 }),
}).then((r) => r.json());
// 2. Connect Playwright over CDP
const browser = await chromium.connectOverCDP(session.connectUrl);
const context = browser.contexts()[0];
const page = context.pages()[0] ?? (await context.newPage());
await page.goto("https://example.com");
console.log(await page.title());
// 3. Release it: billing stops at the second you do
await browser.close();
await fetch(`${API}/sessions/${session.id}/release`, { method: "POST", headers });Any CDP client works. More in the browser docs.
import { readFile } from "node:fs/promises";
import { Boxline } from "@boxline/sdk";
import { chromium } from "playwright";
const client = new Boxline(); // reads BOXLINE_API_KEY and BOXLINE_API_URL
const session = await client.sessions.create({
browser: true,
shell: true,
});
try {
// Browser: export a report. Downloads land in /workspace/downloads.
const browser = await chromium.connectOverCDP(session.connectUrl!);
const page = browser.contexts()[0].pages()[0];
await page.goto("https://example.com/reports");
await page.getByRole("link", { name: "Export CSV" }).click();
const csv = await session.files.waitFor("downloads/*.csv");
// Files: put a script next to the download.
await session.files.write("summarise.py", await readFile("summarise.py"));
// Shell: run it with Python, on the same machine.
const result = await session.exec(`python3 summarise.py ${csv.path}`);
console.log(result.stdout);
} finally {
await session.release();
}Browser, disk and shell in one script. See the SDK docs.
{
"mcpServers": {
"boxline": {
"command": "npx",
"args": ["-y", "@boxline/mcp"],
"env": {
"BOXLINE_API_KEY": "your-api-key",
"BOXLINE_API_URL": "https://api.staging.boxline.dev"
}
}
}
}For Claude Desktop, Cursor and other MCP clients. Setup for each is in the MCP docs.
import Anthropic from "@anthropic-ai/sdk";
import { Boxline } from "@boxline/sdk";
const anthropic = new Anthropic();
const client = new Boxline();
const session = await client.sessions.create({
browser: false,
shell: true,
});
const messages: Anthropic.Beta.BetaMessageParam[] = [
{ role: "user", content: "Use Python to list the 10 largest files under /usr/lib." },
];
try {
while (true) {
const res = await anthropic.beta.messages.create({
model: "claude-opus-5",
max_tokens: 16000,
betas: ["server-side-fallback-2026-07-01"],
fallbacks: "default",
tools: [{ type: "bash_20250124", name: "bash" }],
messages,
});
if (res.stop_reason === "refusal") break;
if (res.stop_reason === "pause_turn") {
messages.push({ role: "assistant", content: res.content });
continue;
}
const calls = res.content.filter(
(b): b is Anthropic.Beta.BetaToolUseBlock => b.type === "tool_use",
);
if (calls.length === 0) break;
messages.push({ role: "assistant", content: res.content });
// Each bash call runs in the session's persistent shell
const results: Anthropic.Beta.BetaToolResultBlockParam[] = [];
for (const call of calls) {
const input = call.input as { command?: string; restart?: boolean };
if (input.restart) {
await session.shell.restart();
results.push({ type: "tool_result", tool_use_id: call.id, content: "Shell restarted." });
continue;
}
const run = await session.exec(input.command ?? "", { timeoutMs: 120_000 });
results.push({
type: "tool_result",
tool_use_id: call.id,
content: run.stdout + run.stderr || "(no output)",
is_error: run.exitCode !== 0,
});
}
messages.push({ role: "user", content: results });
}
} finally {
await session.release();
}Claude’s bash tool calls run in the session’s persistent shell. See the shell docs.
Isolation
Every session gets a sandbox of its own.
Agents open untrusted pages and run code they wrote a moment ago. Boxline keeps each session in its own sandbox so that work stays contained.
Today
One gVisor sandbox per session
Each session runs in its own gVisor sandbox. gVisor implements the Linux system-call interface in user space, so processes in a session do not talk to the host kernel directly.
Always
Never shared between customers
A session belongs to one customer. Its browser, shell and disk are never shared with another customer’s sessions.
Roadmap
MicroVMs
MicroVM isolation is on the roadmap. We will announce it in the changelog when it is available.
Pricing
Pay for the seconds your sessions run.
Usage-based pricing with no per-session fee. Plans add included usage, more concurrency and longer sessions.
Browser session, billed per second.
Browser and shell on 1 vCPU and 3 GiB.
Usage credit on the Free plan, with 3 concurrent sessions.
Give your agent a machine of its own.
Start on the Free plan: a $5 usage credit every month and up to 3 concurrent sessions. Usage is billed per second, with no per-session fee.