Skip to content

Running Claude Code with Daytona

View as Markdown

Claude Code allows you to automate and orchestrate tasks using natural language and code. With Daytona, you can easily run Claude Code inside isolated sandboxes, making it simple to experiment and execute tasks securely.

Running Claude Code in a Daytona Sandbox

You can run Claude Code and execute tasks with it directly inside a Daytona sandbox. The following examples show how to set up a sandbox, install Claude Code, run tasks programmatically, and stream logs in real time.

Note: While both sync and async modes support streaming PTY output, AsyncDaytona is recommended as it provides automatic background callbacks via on_data. The synchronous API requires blocking iteration or manual threading to handle output.

import os
import asyncio
from daytona import AsyncDaytona
async def run_claude_code():
async with AsyncDaytona() as daytona:
sandbox = await daytona.create()
# Define the Claude Code command to be executed
claude_command = "claude --dangerously-skip-permissions -p 'write a dad joke about penguins' --output-format stream-json --verbose"
# Install Claude Code in the sandbox
await sandbox.process.exec("npm install -g @anthropic-ai/claude-code")
pty_handle = await sandbox.process.create_pty_session(
id="claude", on_data=lambda data: print(data.decode(), end="")
)
await pty_handle.wait_for_connection()
# Run the Claude Code command inside the sandbox
await pty_handle.send_input(
f"ANTHROPIC_API_KEY={os.environ['ANTHROPIC_API_KEY']} {claude_command}\n"
)
# Use this to close the terminal session if no more commands will be executed
# await pty_handle.send_input("exit\n")
await pty_handle.wait()
# If you are done and have closed the PTY terminal, it is recommended to clean up resources by deleting the sandbox
# await sandbox.delete()
if __name__ == "__main__":
asyncio.run(run_claude_code())