---
title: "ComputeSDK"
description: "Deploy the daemon using ComputeSDK's provider-agnostic sandbox API."
---

[ComputeSDK](https://computesdk.com) provides a unified interface for managing sandboxes across multiple providers. Write once, deploy anywhere—switch providers by changing environment variables.

## Prerequisites

- `COMPUTESDK_API_KEY` from [console.computesdk.com](https://console.computesdk.com)
- Provider API key (one of: `E2B_API_KEY`, `DAYTONA_API_KEY`, `VERCEL_TOKEN`, `MODAL_TOKEN_ID` + `MODAL_TOKEN_SECRET`, `BLAXEL_API_KEY`, `CSB_API_KEY`)
- `ANTHROPIC_API_KEY` or `OPENAI_API_KEY` for the coding agents

## TypeScript Example

```typescript
import {
  compute,
  detectProvider,
  getMissingEnvVars,
  getProviderConfigFromEnv,
  isProviderAuthComplete,
  isValidProvider,
  PROVIDER_NAMES,
  type ExplicitComputeConfig,
  type ProviderName,
} from "computesdk";
import { SandboxAgent } from "sandbox-agent";

const PORT = 3000;
const REQUEST_TIMEOUT_MS =
  Number.parseInt(process.env.COMPUTESDK_TIMEOUT_MS || "", 10) || 120_000;

/**
 * Detects and validates the provider to use.
 * Priority: COMPUTESDK_PROVIDER env var > auto-detection from API keys
 */
function resolveProvider(): ProviderName {
  const providerOverride = process.env.COMPUTESDK_PROVIDER;

  if (providerOverride) {
    if (!isValidProvider(providerOverride)) {
      throw new Error(
        `Unsupported provider "${providerOverride}". Supported: ${PROVIDER_NAMES.join(", ")}`
      );
    }
    if (!isProviderAuthComplete(providerOverride)) {
      const missing = getMissingEnvVars(providerOverride);
      throw new Error(
        `Missing credentials for "${providerOverride}". Set: ${missing.join(", ")}`
      );
    }
    return providerOverride as ProviderName;
  }

  const detected = detectProvider();
  if (!detected) {
    throw new Error(
      `No provider credentials found. Set one of: ${PROVIDER_NAMES.map((p) => getMissingEnvVars(p).join(", ")).join(" | ")}`
    );
  }
  return detected as ProviderName;
}

function configureComputeSDK(): void {
  const provider = resolveProvider();

  const config: ExplicitComputeConfig = {
    provider,
    computesdkApiKey: process.env.COMPUTESDK_API_KEY,
    requestTimeoutMs: REQUEST_TIMEOUT_MS,
  };

  // Add provider-specific config from environment
  const providerConfig = getProviderConfigFromEnv(provider);
  if (Object.keys(providerConfig).length > 0) {
    (config as any)[provider] = providerConfig;
  }

  compute.setConfig(config);
}

configureComputeSDK();

// Build environment variables to pass to sandbox
const envs: Record<string, string> = {};
if (process.env.ANTHROPIC_API_KEY) envs.ANTHROPIC_API_KEY = process.env.ANTHROPIC_API_KEY;
if (process.env.OPENAI_API_KEY) envs.OPENAI_API_KEY = process.env.OPENAI_API_KEY;

// Create sandbox
const sandbox = await compute.sandbox.create({
  envs: Object.keys(envs).length > 0 ? envs : undefined,
});

// Helper to run commands with error handling
const run = async (cmd: string, options?: { background?: boolean }) => {
  const result = await sandbox.runCommand(cmd, options);
  if (typeof result?.exitCode === "number" && result.exitCode !== 0) {
    throw new Error(`Command failed: ${cmd} (exit ${result.exitCode})\n${result.stderr || ""}`);
  }
  return result;
};

// Install sandbox-agent
await run("curl -fsSL https://releases.rivet.dev/sandbox-agent/latest/install.sh | sh");

// Install agents conditionally based on available API keys
if (envs.ANTHROPIC_API_KEY) {
  await run("sandbox-agent install-agent claude");
}
if (envs.OPENAI_API_KEY) {
  await run("sandbox-agent install-agent codex");
}

// Start the server in the background
await run(`sandbox-agent server --no-token --host 0.0.0.0 --port ${PORT}`, { background: true });

// Get the public URL for the sandbox
const baseUrl = await sandbox.getUrl({ port: PORT });

// Wait for server to be ready
const deadline = Date.now() + REQUEST_TIMEOUT_MS;
while (Date.now() < deadline) {
  try {
    const response = await fetch(`${baseUrl}/v1/health`);
    if (response.ok) {
      const data = await response.json();
      if (data?.status === "ok") break;
    }
  } catch {
    // Server not ready yet
  }
  await new Promise((r) => setTimeout(r, 500));
}

// Connect to the server
const client = await SandboxAgent.connect({ baseUrl });

// Detect which agent to use based on available API keys
const agent = envs.ANTHROPIC_API_KEY ? "claude" : "codex";

// Create a session and start coding
await client.createSession("my-session", { agent });

await client.postMessage("my-session", {
  message: "Summarize this repository",
});

for await (const event of client.streamEvents("my-session")) {
  console.log(event.type, event.data);
}

// Cleanup
await sandbox.destroy();
```

## Supported Providers

ComputeSDK auto-detects your provider from environment variables:

| Provider | Environment Variables |
|----------|----------------------|
| E2B | `E2B_API_KEY` |
| Daytona | `DAYTONA_API_KEY` |
| Vercel | `VERCEL_TOKEN` or `VERCEL_OIDC_TOKEN` |
| Modal | `MODAL_TOKEN_ID` + `MODAL_TOKEN_SECRET` |
| Blaxel | `BLAXEL_API_KEY` |
| CodeSandbox | `CSB_API_KEY` |

## Notes

- **Provider resolution order**: `COMPUTESDK_PROVIDER` env var takes priority, otherwise auto-detection from API keys.
- **Conditional agent installation**: Only agents with available API keys are installed, reducing setup time.
- **Command error handling**: The example validates exit codes and throws on failures for easier debugging.
- `sandbox.runCommand(..., { background: true })` keeps the server running while your app continues.
- `sandbox.getUrl({ port })` returns a public URL for the sandbox port.
- Always destroy the sandbox when you are done to avoid leaking resources.
- If sandbox creation times out, set `COMPUTESDK_TIMEOUT_MS` to a higher value (default: 120000ms).

## Explicit Provider Selection

To force a specific provider instead of auto-detection, set the `COMPUTESDK_PROVIDER` environment variable:

```bash
export COMPUTESDK_PROVIDER=e2b
```

Or configure programmatically using `getProviderConfigFromEnv()`:

```typescript
import { compute, getProviderConfigFromEnv, type ExplicitComputeConfig } from "computesdk";

const config: ExplicitComputeConfig = {
  provider: "e2b",
  computesdkApiKey: process.env.COMPUTESDK_API_KEY,
  requestTimeoutMs: 120_000,
};

// Automatically populate provider-specific config from environment
const providerConfig = getProviderConfigFromEnv("e2b");
if (Object.keys(providerConfig).length > 0) {
  (config as any).e2b = providerConfig;
}

compute.setConfig(config);
```

## Direct Mode (No ComputeSDK API Key)

To bypass the ComputeSDK gateway and use provider SDKs directly, see the provider-specific examples:

- [E2B](/deploy/e2b)
- [Daytona](/deploy/daytona)
- [Vercel](/deploy/vercel)
