--- title: Build a Coding Agent Using Claude Agent SDK and Daytona description: Step-by-step guide to building an autonomous coding agent using Claude Code and Daytona sandboxes. --- This guide demonstrates how to run an autonomous coding agent based on [Claude Code](https://code.claude.com/docs/en/overview) inside a Daytona sandbox environment. The agent uses the [Claude Agent SDK](https://platform.claude.com/docs/en/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 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/en/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/en/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: RPG game demo generated by coding agent 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 #### 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 Get your API keys: - **Daytona API key:** [Daytona Dashboard](https://app.daytona.io/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 ``` Note: The `SANDBOX_ANTHROPIC_API_KEY` key is passed into the Daytona sandbox environment and is accessible to any code executed inside the sandbox. #### 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/en/secrets) keep the raw value out of the sandbox entirely: the environment variable holds only an opaque placeholder (`dtn_secret_`), 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.io/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/en/secrets#substitution-scope) for the full substitution scope. #### Local Usage Node.js 18 or newer is required to run this example. Please ensure your environment meets this requirement before proceeding. Install dependencies: ```bash npm install ``` Run the agent: ```bash npm run start ``` The agent will start and wait for your prompt. ### 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 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 On initialization, the main program: 1. Creates a new [Daytona sandbox](/docs/en/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/en/process-code-execution#command-execution). 3. Creates a new [code interpreter context](/docs/en/process-code-execution#run-code-stateful). 4. Uploads the coding agent script to the sandbox with [file uploading](/docs/en/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 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 The sandbox agent uses the [Claude Agent SDK](https://platform.claude.com/docs/en/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/en/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/en/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/en/agent-sdk/python). #### 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