website/src/content/docs/agent-os/networking.mdx
vmFetch proxies HTTP requests to services running inside the VMUse vmFetch to send HTTP requests to a service running inside the VM.
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));
```ts @nocheck server.ts
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();
Send requests with custom methods, headers, and body.
<CodeGroup> ```ts @nocheck client.ts 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));
```ts @nocheck server.ts
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();
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.
<CodeGroup stacked> ```ts @nocheck server.ts 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();
```ts @nocheck client.ts
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);
Use expireSignedPreviewUrl to immediately revoke a preview token.
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);
```ts @nocheck server.ts
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();
preview.maxExpiresInSeconds to cap the maximum lifetime.vmFetch for server-to-server access. Use preview URLs for browser or external access.