Skip to main content
For every box, you can configure a built-in agent like Claude Code, Codex or OpenCode. It has access to the filesystem, git, and shell commands and should simulate running an Agent on your own computer. You can choose between:
  • run() when you want to wait for completion and then read the final typed result.
  • stream() when you want real-time output while the agent is running.

Configure an Agent

Get your Claude API key from the Claude Console.
.env
UPSTASH_BOX_API_KEY=box_xxxxxxxxxxxxxxxxxxxxxxxx
ANTHROPIC_API_KEY=sk-ant-xxxxxxxxxxxxxxxx
import { Agent, Box } from "@upstash/box"

const box = await Box.create({
  runtime: "node",
  agent: {
    harness: Agent.ClaudeCode,
    model: "anthropic/claude-sonnet-4-5",
    apiKey: process.env.ANTHROPIC_API_KEY!,
  },
})

Agent Options

You can pass provider-specific agent options with the options field on box.agent.run() and box.agent.stream().
const run = await box.agent.run({
  prompt: "Refactor the auth flow and keep changes minimal",
  options: {
    effort: "medium",
    maxTurns: 12,
  },
})
The exact option shape depends on the configured agent:
  • ClaudeCode: maxTurns, maxBudgetUsd, effort, thinking, disallowedTools, agents, promptSuggestions, fallbackModel, systemPrompt
  • Codex: modelReasoningEffort, modelReasoningSummary, personality, webSearch
  • OpenCode: reasoningEffort, textVerbosity, reasoningSummary, thinking

Quickstart

Codebase refactor

Use Claude Code when you want an agent to work through a larger code change with filesystem, shell, and git access.
const stream = await box.agent.stream({
  prompt: `
Refactor the payment module to:
- move shared validation into src/payment/validation.ts
- keep the public API unchanged
- update tests if needed
- summarize the main risks before finishing
  `,
})

for await (const chunk of stream) {
  if (chunk.type === "text-delta") process.stdout.write(chunk.text)
}

console.log(stream.status)
console.log(stream.result)

API

Prompt (required)

Type: string
Supported on: box.agent.run() and box.agent.stream()
The task instruction sent to the agent.

Options

Type: AgentOptions
Supported on: box.agent.run(), box.agent.stream(), and box.schedule.agent()
Provider-specific agent options forwarded to the underlying runner.
const stream = await box.agent.stream({
  prompt: "Review the latest git diff and summarize risks",
  options: {
    effort: "high",
    maxTurns: 20,
  },
})

Timeout

Type: number
Supported on: box.agent.run(), box.agent.stream(), and box.schedule.agent()
Default: no execution timeout
Execution timeout in milliseconds. When reached, the run is aborted.

onToolUse

Type: { name: string; input: Record<string, unknown> }
Supported on: box.agent.run() and box.agent.stream()
Called whenever the agent invokes a tool (for example file, shell, or git tools).

responseSchema

Type: Zod Schema
Supported on: box.agent.run()
Attach a Zod schema to get typed output.
import { z } from "zod"

const responseSchema = z.object({
  customers: z.array(
    z.object({
      name: z.string(),
      revenue: z.number(),
    }),
  ),
})

const analysis = await box.agent.run({
  prompt: "Analyze /work/report.csv and return top customers by revenue",
  responseSchema,
})

console.log(analysis.result.customers)

maxRetries

Type: number
Supported on: box.agent.run()
Default: 0
Retry count to compensate temporary provider outages or similar transient errors. Retries use exponential backoff (1s, 2s, 4s, …) capped at 30s.

Webhook

Type: WebhookConfig
Supported on: box.agent.run()
Useful for fire-and-forget mode. The SDK returns immediately and sends the completion payload to your webhook URL when the run succeeds or fails.