Bindings
Expose custom host functions to agents as CLI commands inside the VM.
Expose your host JavaScript functions (defined with Zod input schemas) to agents as auto-generated CLI commands installed at /usr/local/bin/agentos-{name} inside the VM, injected into the agent’s system prompt and callable inside scripts for code-mode token savings.
Getting started
Define a bindings group with Zod input schemas and pass it to agentOS(). Each binding becomes a CLI command inside the VM.
import { agentOS, setup } from "@rivet-dev/agentos";
import { z } from "zod";
// Define a group of bindings (host functions). Each tool has a Zod input
// schema and an `execute` handler that runs on the host. The group is exposed to
// the agent as a CLI command at /usr/local/bin/agentos-{name} inside the VM.
const weatherBindings = {
name: "weather",
description: "Weather data bindings",
tools: {
forecast: {
description: "Get the weather forecast for a city",
inputSchema: z.object({
city: z.string().describe("City name"),
days: z.number().optional().describe("Number of days"),
}),
execute: async (input: { city: string; days?: number }) => {
const res = await fetch(
`https://api.weather.example/forecast?city=${input.city}&days=${input.days ?? 3}`,
);
return res.json();
},
examples: [
{ description: "3-day forecast for Paris", input: { city: "Paris", days: 3 } },
],
},
},
};
const vm = agentOS({
toolKits: [weatherBindings],
});
export const registry = setup({ use: { vm } });
registry.start();
import { createClient } from "@rivet-dev/agentos/client";
import type { registry } from "./server";
const client = createClient<typeof registry>({ endpoint: "http://localhost:6420" });
const agent = client.vm.getOrCreate("my-agent");
// The agent invokes the binding itself as a shell command:
// agentos-weather forecast --city Paris --days 3
const sessionId = await agent.createSession("claude", {
env: { ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY! },
});
await agent.sendPrompt(sessionId, "What's the weather in Paris?");
Each binding can set an explicit timeout (in milliseconds) for long-running work. Bindings run without a timeout unless one is set.
Zod to CLI mapping
Zod schema fields are converted to CLI flags automatically. Field names are converted from camelCase to kebab-case.
| Zod type | CLI syntax | Example |
|---|---|---|
z.string() | --name value | --path /tmp/out.png |
z.number() | --name 42 | --limit 5 |
z.boolean() | --flag / --no-flag | --full-page |
z.enum(["a","b"]) | --name a | --format json |
z.array(z.string()) | --name a --name b | --tags foo --tags bar |
Optional fields (via .optional()) become optional flags. Required fields are enforced at validation time. Use .describe() on Zod fields to generate useful --help output.
What the agent sees
When bindings are registered, CLI shims are installed at /usr/local/bin/agentos-{name} inside the VM and the binding list is injected into the agent’s system prompt, so keep binding descriptions concise to save tokens.
The agent interacts with bindings as shell commands:
The listing subcommand is still named list-tools for CLI compatibility.
# List all available bindings groups
agentos list-tools
# List bindings in a specific group
agentos list-tools weather
# Get help for a binding
agentos-weather forecast --help
# Call a binding with flags
agentos-weather forecast --city Paris --days 3
# Call a binding with inline JSON
agentos-weather forecast --json '{"city":"Paris","days":3}'
# Call a binding with JSON from a file
agentos-weather forecast --json-file /tmp/input.json
On success, the binding exits 0 and writes a JSON envelope to stdout:
{"ok":true,"result":{"temperature":22,"condition":"sunny"}}
On failure (validation or execution error), the binding exits non-zero and writes the error message to stderr:
Missing required flag: --city
Bindings vs MCP servers
agentOS supports two ways to give agents access to external functionality: bindings and MCP servers. Both work, but they have different tradeoffs.
| Bindings | MCP Servers | |
|---|---|---|
| How it works | Call JavaScript functions on the host directly | Connect to a standard MCP server |
| Authentication | None required. Direct binding to the agent’s OS. | Requires custom auth configuration per server |
| Code mode | Built-in. Bindings are exposed as CLI commands, so agents can call them inside scripts for up to 80% token reduction. | Requires extra work to make code mode work out of the box |
| Latency | Near-zero. Bound directly to the host process. | Extra network hop to reach the MCP server |
| Setup | Define bindings in your actor code with Zod schemas | Configure any standard MCP server |
Use bindings when you want to expose your own JavaScript functions to agents. Use MCP servers when you want to connect to existing third-party services. See Sessions for MCP server configuration.
Security
Binding calls from the agent securely invoke your execute() functions on the host. Your functions run with full access to the host environment, so you can call databases, APIs, and services directly without proxying credentials into the VM. The agent never sees the credentials, it only sees the binding’s input/output contract.
Bindings run on the host with full access to the host environment, so do not expose bindings that could compromise the host without appropriate safeguards.