# Build a Coding Agent Using Claude Agent SDK and Daytona (/docs/guides/claude/claude-agent-sdk-interactive-terminal-sandbox)

This guide demonstrates how to run an autonomous coding agent based on [Claude Code](https://code.claude.com/docs/overview) inside a Daytona sandbox environment. The agent uses the [Claude Agent SDK](https://platform.claude.com/docs/agent-sdk/overview) to follow user prompts.

The agent can develop full-stack web apps, write code in any language, install dependencies, and run scripts. It can also start and manage dev servers, and generate preview links for live apps.

---

### 1. Workflow Overview [#1-workflow-overview]

When you launch the main module, a Daytona sandbox is created and a Python agent is initialized inside it. The agent is based on the [Claude Agent SDK](https://platform.claude.com/docs/agent-sdk/overview).

You interact with the main program via a command line chat interface. The program sends your prompts to the agent inside the sandbox, which executes them and returns the results:

```
$ npm run start                                   174s
Creating sandbox...
Installing Agent SDK...
Initializing Agent SDK...
Press Ctrl+C at any time to exit.
User: Build a Zelda-like game where I can move around the screen and talk to famous programmers
Thinking...
I'll build a Zelda-like game for you! This will be a fun project with player movement and NPC interactions with famous programmers.
🔨 Write
🔨 Write
Now let me start a simple HTTP server to host the game:
🔨 Bash
Perfect! I've created a Zelda-like game called "Programmer's Quest" for you! 🎮

## Game Features:

✨ Zelda-style gameplay:
- Top-down 2D view with classic retro aesthetics
- Player character with sword and shield
- Grid-based movement system
- Environmental obstacles (trees and rocks)

👥 Famous Programmers as NPCs:
1. Linus Torvalds - Creator of Linux
2. Grace Hopper - COBOL pioneer and Admiral
3. Alan Turing - Father of computer science
4. Ada Lovelace - First computer programmer
5. Dennis Ritchie - Creator of C and UNIX

🎮 Controls:
- Arrow Keys or WASD - Move your character
- SPACE - Talk to NPCs when you're near them

🌟 Gameplay:
- Explore the grassy map and find all 5 legendary programmers
- Each NPC has multiple quotes that cycle when you talk to them
- NPCs glow when you're near them
- Dialog boxes appear with their famous quotes
- Track your progress in the HUD

## Play Now:
🎯 [Click here to play the game!](https://80-8e2c4d23-212a-4f1e-bb6c-abfa71aeed3a.proxy.daytona.works)

The game features smooth movement, collision detection with trees and rocks, and an immersive dialog system. Try to find and talk to all 5 famous programmers to learn their wisdom! Each has 3 different quotes that cycle as you keep talking to them.

Enjoy your adventure! 🗡️✨
User:
```

The agent can also host web apps and provide you with a preview link using the [Daytona Preview Links](https://www.daytona.io/docs/preview/) feature. When your task involves running or previewing a web application, the agent automatically reasons about this need, hosts the app, and generates a preview link for you to inspect the live result:

<Image
  src="/docs/images/claude-agent-sdk-interactive-terminal-sandbox-result.gif"
  alt="RPG game demo generated by coding agent"
  width={600}
/>

You can continue interacting with your agent until you are finished. When you exit the program, the sandbox will be deleted automatically.

### 2. Project Setup [#2-project-setup]

#### Clone the Repository [#clone-the-repository]

First, clone the daytona [repository](https://github.com/daytona/guides.git) and navigate to the example directory:

```bash
git clone https://github.com/daytona/guides.git
cd guides/typescript/anthropic/single-claude-agent-sdk
```

#### Configure Environment [#configure-environment]

Get your API keys:

- **Daytona API key:** [Daytona Dashboard](https://app.daytona.com/dashboard/keys)
- **Anthropic API key:** [Anthropic Console](https://console.anthropic.com/)

Copy `.env.example` to `.env` and add your keys:

```bash
DAYTONA_API_KEY=your_daytona_key
SANDBOX_ANTHROPIC_API_KEY=your_anthropic_key
```

<Callout type="caution" title="API Key Security">
Note: The `SANDBOX_ANTHROPIC_API_KEY` key is passed into the Daytona sandbox environment and is accessible to any code executed inside the sandbox.
</Callout>

#### Alternative: Inject the Key as a Daytona Secret [#alternative-inject-the-key-as-a-daytona-secret]

The default setup passes the Anthropic key into the sandbox as a plain environment variable, so anything running inside the sandbox - including the agent itself - can read the raw key with `env`. [Daytona Secrets](/docs/secrets) keep the raw value out of the sandbox entirely: the environment variable holds only an opaque placeholder (`dtn_secret_<id>`), and Daytona's outbound proxy substitutes the real value into HTTPS request headers at egress - and only for requests to the hosts the Secret allows. An agent that dumps the environment or exfiltrates it never sees a usable key.

The Secret-based flow needs `@daytona/sdk` 0.192.0 or newer and a one-time Secret setup:

1. Create the Secret once for your organization - in the [Daytona Dashboard](https://app.daytona.com/dashboard/secrets) or with a one-off script (save as `create-secret.ts` next to this guide's `.env` and run `npx tsx create-secret.ts`):

   ```typescript
   import { Daytona } from '@daytona/sdk'
   import * as dotenv from 'dotenv'

   dotenv.config()

   async function main() {
     const value = process.env.SANDBOX_ANTHROPIC_API_KEY
     if (!value) throw new Error('SANDBOX_ANTHROPIC_API_KEY is not set')

     const daytona = new Daytona()
     await daytona.secret.create({
       name: 'anthropic-api-key',
       value,
       hosts: ['api.anthropic.com'], // the only host the real key may be sent to
     })
   }

   main()
   ```

2. In `src/index.ts`, swap the `ANTHROPIC_API_KEY` env var for a `secrets:` mapping (environment variable name to Secret name):

   ```diff
    sandbox = await daytona.create({
      // Claude Code is memory intensive, so we use a medium snapshot
      snapshot: 'daytona-medium', // This snapshot has 4GiB RAM and 2 vCPUs
   -  envVars: {
   -    ANTHROPIC_API_KEY: process.env.SANDBOX_ANTHROPIC_API_KEY,
   -  },
   +  secrets: {
   +    ANTHROPIC_API_KEY: 'anthropic-api-key',
   +  },
    })
   ```

Inside the sandbox, `env` now shows `ANTHROPIC_API_KEY=dtn_secret_...`, yet the Claude Agent SDK still authenticates: it sends the key as the `x-api-key` HTTPS request header to `api.anthropic.com`, where the proxy swaps in the real value. Substitution happens only in HTTPS request headers toward allowed hosts - requests to any other host carry the harmless placeholder. See the [Secrets documentation](/docs/secrets#substitution-scope) for the full substitution scope.

#### Local Usage [#local-usage]

<Callout type="note" title="Node.js Version">
Node.js 18 or newer is required to run this example. Please ensure your environment meets this requirement before proceeding.
</Callout>

Install dependencies:

```bash
npm install
```

Run the agent:

```bash
npm run start
```

The agent will start and wait for your prompt.

### 3. Example Usage [#3-example-usage]

Example chat session:

```
$ npm run start
Creating sandbox...
Installing Agent SDK...
Initializing Agent SDK...
Press Ctrl+C at any time to exit.
User: Create a fun pet store landing page in Svelte
Thinking...
I'll create a fun pet store landing page in Svelte for you! Let me set up the project and build an engaging landing page with animations and a colorful design.
🔨 Bash
🔨 Bash
Now let me create a fun and engaging pet store landing page with animations, colorful sections, and interactive elements:
🔨 Read
> 🔨 Write
Now let me create the component files:
🔨 Write
🔨 Write
🔨 Write
🔨 Write
🔨 Write
Now let's update the main CSS file and start the development server:
🔨 Read
🔨 Write
Now let's start the development server:
🔨 Bash
🔨 TaskOutput
Perfect! 🎉 I've created a fun and colorful pet store landing page in Svelte! Here's what I built:

## Features:

✨ Hero Section

- Beautiful gradient background with animated floating cards
- Eye-catching navigation bar
- Call-to-action buttons with hover effects
- Bouncing emoji animations

🎯 Features Section

- 4 key benefits (Free Delivery, Premium Quality, Special Offers, Award Winning)
- Interactive cards with hover animations
- Icons that rotate and scale on hover

🛍️ Products Section

- 6 featured products with colorful backgrounds
- Star ratings
- Add to cart functionality
- Smooth hover animations

📧 Newsletter Section

- Vibrant gradient background with floating pet emojis
- Email subscription form
- Success message animation
- Special 20% off offer

👣 Footer

- Comprehensive navigation links
- Social media icons
- Dark gradient design

## Live Preview:

Your pet store is now running at: https://80-b3739199-d90e-4bde-ab18-450d74c950e8.proxy.daytona.works

The page includes:

- Smooth scroll behavior
- Responsive design for mobile devices
- Fun animations throughout
- Interactive elements with hover effects
- Colorful gradients and modern styling
- Emoji-based icons for a playful feel

Click the link to see your fun pet store landing page in action! 🐾
User:

```

### 4. Understanding the Agent's Architecture [#4-understanding-the-agents-architecture]

This example consists of two main components:

- **Main Program:** The main program is a Node.js script (`index.ts`) that runs on your local machine. It uses the Daytona SDK to create and manage a Daytona sandbox. The main program provides a command line interface for interacting with the agent inside the sandbox.
- **Sandbox Agent:** The sandbox agent is a Python script (`coding_agent.py`) that runs inside the Daytona sandbox. It uses the Claude Agent SDK to create a customized coding agent similar to Claude Code.

#### Initialization [#initialization]

On initialization, the main program:

1. Creates a new [Daytona sandbox](/docs/sandboxes) with your Anthropic API key included in the environment variables.
2. Installs the Claude Agent SDK by running `pip install` in the sandbox with [process execution](/docs/process-code-execution#command-execution).
3. Creates a new [code interpreter context](/docs/process-code-execution#run-code-stateful).
4. Uploads the coding agent script to the sandbox with [file uploading](/docs/file-system-operations#upload-a-single-file).
5. Initializes the Claude Agent SDK by running `import coding_agent` in the code interpreter context.
6. Waits for user input and sends prompts to the agent in the code interpreter context as shown below.

#### Main Program Code [#main-program-code]

Once the agent is running, the program creates a readline interface to read user input and sends it to the agent.
Each user request is passed to the agent by running a Python command in the code interpreter context:

```typescript
const result = await sandbox.codeInterpreter.runCode(
  `coding_agent.run_query_sync(os.environ.get('PROMPT', ''))`,
  {
    context: ctx,
    envs: { PROMPT: prompt },
    onStdout,
    onStderr,
  }
)
```

The `onStdout` and `onStderr` callbacks are used to pass the agent's output back to the main program. After the agent finishes responding to the prompt, the main program waits for the next user input.

#### Sandbox Agent Code [#sandbox-agent-code]

The sandbox agent uses the [Claude Agent SDK](https://platform.claude.com/docs/agent-sdk/overview) to create a customized coding agent based on Claude Code.
The agent is initialized with a system prompt that includes the workspace directory and an example of the [preview URL format](/docs/preview):

```python
system_prompt = """
You are running in a Daytona sandbox.
Use the /home/daytona directory instead of /workspace for file operations.
Your public preview URL for port 80 is: {}.
""".format(preview_url)
```

It also specifies the [tools and permission mode](https://platform.claude.com/docs/agent-sdk/quickstart#key-concepts) of the agent:

```python
client = ClaudeSDKClient(
  options=ClaudeAgentOptions(
    allowed_tools=["Read", "Edit", "Glob", "Grep", "Bash"],
    permission_mode="acceptEdits",
    system_prompt=system_prompt
  )
)
```

The code to run queries and receive responses follows the examples in Anthropic's [Claude Agent Python SDK documentation](https://platform.claude.com/docs/agent-sdk/python).

#### Clean up [#clean-up]

When you exit the main program, the Daytona sandbox and all files are automatically deleted.

**Key advantages:**

- Secure, isolated execution in Daytona sandboxes
- Communicate with the agent directly in your terminal
- Automatic dev server detection and live preview links
- Multi-language and full-stack support
- Simple setup and automatic cleanup
