# Vercel AI SDK (/docs/integrations/ai-sdk)



`@crownest/ai-sdk` exposes CrowNest Sandboxes as a compact starter set for
Vercel AI SDK agents. It wraps the TypeScript SDK with four model-callable
tools: `runCode`, `runCommand`, `readFile`, and `writeFile`.

Use it when an AI SDK agent should execute code, run shell commands, or
inspect Workspace files without hand-writing CrowNest client calls in the
agent loop.

MCP is the complete model-callable parity surface for CrowNest. Use
`@crownest/mcp` when an agent needs Workspace Runs, Previews, Artifacts,
Projects, API Key metadata, byte transfer helpers, event replay, or Evidence
Bundles as model-callable tools. Use `@crownest/ai-sdk` when the app wants the
smallest CrowNest tool set inside a Vercel AI SDK loop.

<Callout type="info" title="AI SDK v6 tool API">
  This package targets `ai@6.x`, where custom tools use `tool({ inputSchema,
    execute })`.
</Callout>

## Install [#install]

```bash title="Terminal"
pnpm add @crownest/ai-sdk ai @ai-sdk/openai
export CROWNEST_API_KEY="cn_live_..."
export OPENAI_API_KEY="sk-..."
```

`@crownest/ai-sdk` reads `CROWNEST_API_KEY` through the TypeScript SDK. Pass
`apiKey`, `baseUrl`, `template`, `ttlMs`, or `sandboxId` to `crownestTools()`
when you need explicit configuration.

## generateText [#generatetext]

```ts title="main.ts"
import { openai } from "@ai-sdk/openai";
import { crownestTools, killSession } from "@crownest/ai-sdk";
import { generateText, stepCountIs } from "ai";

const tools = crownestTools({
  template: "python-node",
  ttlMs: 15 * 60_000,
});

try {
  const result = await generateText({
    model: openai(process.env.OPENAI_MODEL ?? "gpt-4o-mini"),
    system:
      "Use CrowNest tools for code execution and Workspace file operations. Keep generated files under /workspace.",
    prompt:
      "Create a small CSV, write it to /workspace/revenue.csv, run Python to summarize total revenue, and report the result.",
    tools,
    stopWhen: stepCountIs(5),
  });

  console.log(result.text);
} finally {
  await killSession(tools);
}
```

## streamText [#streamtext]

```ts title="stream.ts"
import { openai } from "@ai-sdk/openai";
import { crownestTools, killSession } from "@crownest/ai-sdk";
import { stepCountIs, streamText } from "ai";

const tools = crownestTools();

try {
  const result = streamText({
    model: openai(process.env.OPENAI_MODEL ?? "gpt-4o-mini"),
    prompt: "Run Python in CrowNest to print the first five Fibonacci numbers.",
    tools,
    stopWhen: stepCountIs(5),
  });

  for await (const text of result.textStream) {
    process.stdout.write(text);
  }
} finally {
  await killSession(tools);
}
```

## Session lifecycle [#session-lifecycle]

When `sandboxId` is omitted, `crownestTools()` lazily creates one Sandbox on
the first tool call and reuses it for the tool set. That lets a model write a
file, run code against it, and read the result in one run.

```ts
const tools = crownestTools({ template: "python-node", ttlMs: 15 * 60_000 });
```

Pass a pinned Sandbox id when another part of your application owns the
Sandbox lifecycle:

```ts
const tools = crownestTools({ sandboxId: "sbx_existing" });
```

Always call `killSession(tools)` for tool sets that create their own
Sandbox. TTL expiry is the backstop if the host process exits before cleanup.

Tool calls are serialized within one tool set so a model-emitted `writeFile`
can complete before a sibling `runCode` or `readFile` observes the Workspace.

## Tool behavior [#tool-behavior]

| Tool         | Behavior                                                                                                                                    |
| ------------ | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `runCode`    | Runs Python, JavaScript, or TypeScript code and returns stdout, stderr, inline outputs, artifact ids, rejected outputs, and traceback text. |
| `runCommand` | Runs a shell command in a Sandbox, defaulting to `/workspace`, and returns command id, status, exit code, stdout, and stderr.               |
| `readFile`   | Reads a UTF-8 Workspace file and caps returned content at 64 KB by default.                                                                 |
| `writeFile`  | Writes a UTF-8 Workspace file and creates parent directories by default.                                                                    |

These tools are intentionally not a one-to-one wrapper over every CrowNest
resource. For full primitive coverage, connect the MCP server or call the
TypeScript/Python SDKs directly from application code.

## Next steps [#next-steps]

* [MCP](/docs/integrations/mcp) exposes a larger tool surface to MCP hosts.
* [TypeScript SDK Code](/docs/sdk/code) documents the Code Run result shape.
* [Agent patterns](/docs/guides/agent-patterns) has multi-step recipes across
  SDK, CLI, and MCP surfaces.
