Operating System
Networking & Previews
Proxy HTTP requests into agentOS VMs and create shareable preview URLs.
vmFetchproxies HTTP requests to services running inside the VM- Preview URLs create time-limited, shareable public URLs to VM services
- Token-based access with configurable expiration and revocation
- CORS enabled for browser access to preview URLs
Fetch from a VM service
Use vmFetch to send HTTP requests to a service running inside the VM.
import { createClient } from "rivetkit/client";
import type { registry } from "./server";
const client = createClient<typeof registry>("http://localhost:6420");
const agent = client.vm.getOrCreate(["my-agent"]);
// Start a web server inside the VM
await agent.writeFile(
"/home/user/server.js",
'require("http").createServer((req, res) => res.end("Hello from VM")).listen(3000);',
);
await agent.spawn("node", ["/home/user/server.js"]);
// Fetch from the VM service
const response = await agent.vmFetch(3000, "/");
console.log("Status:", response.status);
console.log("Body:", new TextDecoder().decode(response.body));
import { agentOs } from "rivetkit/agent-os";
import { setup } from "rivetkit";
import common from "@rivet-dev/agent-os-common";
import pi from "@rivet-dev/agent-os-pi";
const vm = agentOs({
options: { software: [common, pi] },
});
export const registry = setup({ use: { vm } });
registry.start();
vmFetch with options
Send requests with custom methods, headers, and body.
import { createClient } from "rivetkit/client";
import type { registry } from "./server";
const client = createClient<typeof registry>("http://localhost:6420");
const agent = client.vm.getOrCreate(["my-agent"]);
const response = await agent.vmFetch(3000, "/api/data", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ key: "value" }),
});
console.log("Status:", response.status, response.statusText);
console.log("Headers:", response.headers);
console.log("Body:", new TextDecoder().decode(response.body));
import { agentOs } from "rivetkit/agent-os";
import { setup } from "rivetkit";
import common from "@rivet-dev/agent-os-common";
import pi from "@rivet-dev/agent-os-pi";
const vm = agentOs({
options: { software: [common, pi] },
});
export const registry = setup({ use: { vm } });
registry.start();
Create a preview URL
Preview URLs are essentially port forwarding for VM services. They create a time-limited, publicly accessible URL that proxies HTTP requests to a specific port inside the VM. Use them to share web app previews with users, embed dev servers in iframes, or give external tools access to services running inside the agent’s VM.
import { agentOs } from "rivetkit/agent-os";
import { setup } from "rivetkit";
import common from "@rivet-dev/agent-os-common";
import pi from "@rivet-dev/agent-os-pi";
const vm = agentOs({
preview: {
defaultExpiresInSeconds: 3600, // 1 hour default
maxExpiresInSeconds: 86400, // 24 hour maximum
},
options: { software: [common, pi] },
});
export const registry = setup({ use: { vm } });
registry.start();
import { createClient } from "rivetkit/client";
import type { registry } from "./server";
const client = createClient<typeof registry>("http://localhost:6420");
const agent = client.vm.getOrCreate(["my-agent"]);
// Start a web app in the VM
await agent.spawn("node", ["/home/user/app.js"]);
// Create a preview URL (default 1 hour expiration)
const preview = await agent.createSignedPreviewUrl(3000);
console.log("Preview path:", preview.path);
console.log("Token:", preview.token);
console.log("Expires at:", new Date(preview.expiresAt));
// Create a preview URL with custom expiration
const shortPreview = await agent.createSignedPreviewUrl(3000, 300); // 5 minutes
console.log("Short-lived preview:", shortPreview.path);
Revoke a preview URL
Use expireSignedPreviewUrl to immediately revoke a preview token.
import { createClient } from "rivetkit/client";
import type { registry } from "./server";
const client = createClient<typeof registry>("http://localhost:6420");
const agent = client.vm.getOrCreate(["my-agent"]);
const preview = await agent.createSignedPreviewUrl(3000);
// Revoke the token immediately
await agent.expireSignedPreviewUrl(preview.token);
import { agentOs } from "rivetkit/agent-os";
import { setup } from "rivetkit";
import common from "@rivet-dev/agent-os-common";
import pi from "@rivet-dev/agent-os-pi";
const vm = agentOs({
options: { software: [common, pi] },
});
export const registry = setup({ use: { vm } });
registry.start();
Recommendations
- Preview tokens are stored in SQLite and survive sleep/wake cycles. Expired tokens are cleaned up automatically.
- Default preview expiration is 1 hour. Configure
preview.maxExpiresInSecondsto cap the maximum lifetime. - CORS is enabled on preview URLs, allowing browser access from any origin.
- Use
vmFetchfor server-to-server access. Use preview URLs for browser or external access. - See Security for more on preview URL token security.