Burrowbox Blog
← All posts

Meta's Muse gives every user a cloud computer. Here's how to do the same for your customers

· The Burrowbox team · 4 min read

#What Muse does

Meta announced Muse on September 8, 2026. It's a personal agent that sends email, books travel, fills out forms and makes purchases for people. (Meta)

From Meta's own posts, here's how it uses computing:

  • One machine per user. Each user's agent runs on its own virtual machine in Meta's cloud, the "Muse Secure VM". No other user's agent can reach it. (Meta)
  • A real computer. The agent has a file system, a terminal and a full web browser, and its memory carries over between conversations. (How We Designed Muse)
  • Secrets it can't see. Passwords and payment details go into secure storage, so Muse can use them without seeing them. A separate Sentinel agent on the same machine has to approve anything that reaches the internet. (Meta) The agent runs in an isolated container and only gets stand-in tokens. Real credentials are added as a request leaves the machine. (Meta engineering)
  • People approve and audit. Muse checks with the user before sensitive actions, such as sending an email or making a purchase, and keeps a full record of what it has done. (Meta)

#The pattern

Each user gets a persistent computer. The agent works there with a browser and files and uses stored logins without seeing them. The user can watch what it does. If your product runs agents for your customers, this is the setup you want, and you don't have to build the machines yourself.

#Build it with Burrowbox and the Vercel AI SDK

Burrowbox gives each customer a persistent Linux machine with a browser that stays signed in, an encrypted vault and its own MCP endpoint. Burrowbox isn't involved with Muse. Below, a Next.js app gives each user their own machine.

#1. A machine per user (REST)

// lib/burrowbox.ts
export const bb = (path: string, body?: unknown) =>
  fetch(`https://burrowbox.dev${path}`, {
    method: body ? "POST" : "GET",
    headers: { Authorization: `Bearer ${process.env.BURROWBOX_KEY}`, "Content-Type": "application/json" },
    body: body ? JSON.stringify(body) : undefined,
  }).then((r) => r.json());

// Returns the user's machine, running, with its mcpUrl and mcpToken.
export async function machineFor(user: { id: string; machineId?: string }) {
  if (user.machineId) {
    await bb(`/api/machines/${user.machineId}/start`, { ttlMinutes: 30 }); // resumes where it left off
    return bb(`/api/machines/${user.machineId}`);
  }
  const m = await bb("/api/machines", { size: "tiny", browser: "full", ttlMinutes: 30, externalId: user.id });
  await db.users.update(user.id, { machineId: m.id }); // your database
  return m;
}

externalId tags the machine with your user's id. browser: "full" (Chromium) keeps the browser's logins across restarts. When ttlMinutes runs out, the machine turns off and keeps its files, apps and browser cookies, and start brings it back still signed in.

#2. Their logins go into their machine's vault

curl -X PUT https://burrowbox.dev/api/machines/$MACHINE_ID/vault/airline \
  -H "Authorization: Bearer $BURROWBOX_KEY" -H "Content-Type: application/json" \
  -d '{"url": "https://airline.example.com/login", "username": "sam@example.com", "password": "…"}'

The agent calls browser_login, which fills and submits the form without returning the password to the model. See Vault.

#3. Run the agent on the user's machine (AI SDK + MCP)

The AI SDK's MCP client connects to the machine's MCP endpoint with the machine-scoped token, so this agent can't reach any other machine.

// app/api/agent/route.ts
import { generateText, isStepCount } from "ai";
import { createMCPClient } from "@ai-sdk/mcp";
import { machineFor } from "@/lib/burrowbox";

export async function POST(req: Request) {
  const { prompt } = await req.json();
  const user = await currentUser(); // your auth
  const machine = await machineFor(user);

  const mcp = await createMCPClient({
    transport: { type: "http", url: machine.mcpUrl, headers: { Authorization: `Bearer ${machine.mcpToken}` } },
  });
  try {
    const { text } = await generateText({
      model: "anthropic/claude-sonnet-5.5",
      tools: await mcp.tools(), // browser_navigate, browser_login, shell_run, file_write, …
      stopWhen: isStepCount(25),
      prompt,
    });
    return Response.json({ text });
  } finally {
    await mcp.close();
  }
}

#4. Let the user watch

Create a short-lived live-view link on the server and show it in an iframe. With interactive: false, input is blocked on the machine itself.

const view = await bb(`/api/machines/${machine.id}/live-view`, {
  mode: "browser", interactive: false, ttlSeconds: 900, allowedOrigins: ["https://app.example.com"],
});
// <iframe src={view.url} style={{ width: "100%", aspectRatio: "16/10", border: 0 }} />

Burrowbox doesn't filter outbound traffic the way Sentinel does. Your agent decides which steps need the user's confirmation. See Embed the live view.

#What it costs

A tiny machine costs $0.07 an hour while running and $0.001 an hour while stopped. A user who runs their agent 30 minutes a day costs about $1.05 a month in running time plus $0.72 for storage. See Billing.

Create an account to try it.

#Sources