Overview
The SDK provides SandboxManager (accessed via rt.sandbox) for creating and managing sandboxes, and Sandbox instances with real-time status/metrics subscriptions via Convex.
The SDK is not yet published to npm. Install from GitHub: npm install github:runtools-ai/runtools-sdk
Creating Sandboxes
import { RunTools } from '@runtools/sdk';
const rt = new RunTools({ apiKey: process.env.RUNTOOLS_API_KEY });
// Create with default template (base-ubuntu)
const sandbox = await rt.sandbox.create();
// Create with options
const sandbox = await rt.sandbox.create({
template: 'desktop-ubuntu',
name: 'my-dev-env',
sshKeys: ['ssh-ed25519 AAAA... user@laptop'],
idleTimeoutSeconds: 1800,
vcpus: 4,
memoryMb: 4096,
tags: { project: 'my-app' },
env: { NODE_ENV: 'development' },
});
SandboxCreateOptions
| Field | Type | Default | Description |
|---|
template | string | 'base-ubuntu' | Template: base-ubuntu or desktop-ubuntu |
name | string | - | Friendly name |
sshKeys | string[] | - | SSH public keys to inject |
password | string | - | Root password (alternative to SSH keys) |
idleTimeoutSeconds | number | 600 | Auto-pause after inactivity (0 = disabled) |
vcpus | number | 2 | vCPU count |
memoryMb | number | 1024 | Memory in MB |
tags | Record | - | Key-value tags |
env | Record | - | Environment variables |
waitForReady | boolean | false | Wait for SSH/VNC readiness before returning |
Listing Sandboxes
// List all sandboxes
const sandboxes = await rt.sandbox.list();
// Filter by status
const running = await rt.sandbox.list({ status: 'running' });
// Each item: { id, name?, status, template?, tags?, createdAt }
Destroying Sandboxes
// Destroy by ID (manager method)
await rt.sandbox.destroy('sandbox-abc123');
Sandbox Instance Methods
After creating a sandbox, you get a Sandbox instance:
const sandbox = await rt.sandbox.create({ template: 'base-ubuntu' });
Wait for Ready
// Wait until SSH (and VNC for desktop) is ready
await sandbox.waitForReady(); // Default 60s timeout
await sandbox.waitForReady(120000); // Custom timeout (ms)
Execute Commands
const result = await sandbox.exec('ls -la');
console.log(result.stdout); // Directory listing
console.log(result.stderr); // Error output
console.log(result.exitCode); // 0 = success
// With options
const result = await sandbox.exec('npm install', {
timeout: 120000, // 2 minutes
cwd: '/workspace',
env: { CI: 'true' },
});
Pause and Resume
await sandbox.pause(); // Snapshot VM state to disk
await sandbox.resume(); // Restore from snapshot (~500ms)
Destroy
await sandbox.destroy(); // Closes subscriptions + deletes sandbox
Close Subscriptions
await sandbox.close(); // Closes Convex subscriptions only (sandbox keeps running)
Real-Time Events (Convex)
The SDK uses Convex WebSocket subscriptions for real-time status and metrics. Events auto-start when you register the first listener.
// Status changes (running, paused, stopped, etc.)
sandbox.on('status', (state: SandboxState) => {
console.log('Status:', state.status);
console.log('SSH Ready:', state.sshReady);
console.log('VNC Ready:', state.vncReady);
console.log('Template:', state.template);
});
// Live metrics (~1 update/second)
sandbox.on('metrics', (m: SandboxMetrics) => {
console.log('CPU:', m.cpuPercent, '%');
console.log('Memory:', m.memUsedPercent, '%');
console.log('Net RX:', m.netRxBytesPerSec, 'bytes/s');
console.log('Disk Read:', m.diskReadBytesPerSec, 'bytes/s');
});
// Fires once when SSH becomes ready
sandbox.on('ready', () => {
console.log('Sandbox is ready!');
});
// Error events
sandbox.on('error', (err) => {
console.error('Error:', err);
});
// Subscription closed
sandbox.on('close', () => {
console.log('Subscriptions closed');
});
Current State Accessors
sandbox.id; // Sandbox ID
sandbox.status; // Current status string
sandbox.sshReady; // boolean
sandbox.vncReady; // boolean
sandbox.state; // Full SandboxState object (or null)
sandbox.metrics; // Full SandboxMetrics object (or null)
Types
import type {
Sandbox,
SandboxManager,
SandboxState,
SandboxMetrics,
SandboxCreateOptions,
SandboxEventType,
SandboxEvents,
} from '@runtools/sdk';
SandboxState
| Field | Type | Description |
|---|
sandboxId | string | Sandbox ID |
status | string | creating, running, paused, stopped |
template | string | Template name |
sshReady | boolean | SSH is accessible |
vncReady | boolean | VNC is accessible (desktop only) |
ip | string | VM internal IP |
publicIp | string | FC Agent public IP |
sshPort | number | SSH forwarded port |
vncPort | number | VNC forwarded port |
vncUrl | string | Full VNC URL |
SandboxMetrics
| Field | Type | Description |
|---|
cpuPercent | number | CPU usage % |
memTotalBytes | number | Total memory |
memUsedBytes | number | Used memory |
memUsedPercent | number | Memory usage % |
netRxBytesPerSec | number | Network receive rate |
netTxBytesPerSec | number | Network transmit rate |
diskReadBytesPerSec | number | Disk read rate |
diskWriteBytesPerSec | number | Disk write rate |
What’s NOT Available in the SDK
The following are not in the SDK (use REST API or CLI instead):
sandbox.files.* — Use sandbox.exec('cat file.txt') instead
sandbox.getUrl() — URL pattern is https://{port}-{sandboxId}.sandboxes.runtools.ai
sandbox.getSSH() — SSH via ssh {sandboxId}@ssh.runtools.ai
sandbox.snapshot() / sandbox.rollback() — Use CLI: runtools sandbox snapshot/rollback
sandbox.branch() — Not implemented
sandbox.execStream() — Not implemented
rt.agents.* — Not implemented in SDK
rt.tools.* — Not implemented in SDK