app icon
Better E2B Sandbox
0.0.3

Create and manage E2B sandboxes for Dify workflows, with Claude Code and Next.js tooling.

lysonober/better-e2b-sandbox114 installs

Better E2B Sandbox Plugin for Dify

Author: lysonober

Version: 0.0.3

Type: Tool

Better E2B Sandbox creates and manages E2B cloud sandboxes inside Dify workflows. It supports Claude Code integration, Next.js project scaffolding (npm and Bun), stateful interactive shell sessions, common package installation, file operations, template building, and full sandbox lifecycle management with pause, resume, and kill capabilities.

Security Warning: Disable Public Access to Your Workflow

When you create a new workflow in Dify, the Web App and Backend Service API access points are enabled by default. This means anyone with the URL can trigger your workflow, which in turn can create sandboxes, run commands, read files, and consume your E2B and Anthropic API credits.

Before publishing or sharing your workflow, you must:

  1. Go to your workflow settings in Dify.
  2. Disable Web App access if you do not need a public-facing interface.
  3. Disable Backend Service API access if you do not need external API calls.
  4. If you do need these access points enabled, add authentication (API keys, OAuth, or IP whitelisting) to prevent unauthorized access.

Without these precautions, a leaked workflow URL allows anyone to create sandboxes under your E2B account, run arbitrary code via Claude Code, and access any credentials (GitHub tokens, Vercel tokens, Anthropic keys) that you configured in the plugin. E2B bills per second for running sandboxes, so unauthorized usage can result in unexpected charges.

This is not a limitation of this plugin. It is a standard Dify workflow security consideration that applies to any plugin that manages external resources.

Quick Start Workflow

[Image blocked: Quick Start Workflow Flowchart]

How Sandbox Timeout Actually Works (Read This First)

The single most confusing concept in E2B is the sandbox timeout. If you do not understand this, you will waste money or lose work. Here is how it works.

When you create a sandbox, you set a timeout. For example, Create Claude Code Sandbox with gives you a 30-minute sandbox. This means the sandbox will automatically shut down 30 minutes after creation, regardless of what is running inside it.

Here is the critical part: every time you call Sandbox.connect(), the timeout resets. Every tool in this plugin that talks to an existing sandbox (Send Sandbox Input, Install Packages, Read Sandbox File, Write Sandbox File, Start Shell Session, Pause Sandbox, and so on) internally calls Sandbox.connect(). That connect call resets the sandbox timeout to whatever value the tool passes.

Story: The 24-hour sandbox that died in 30 minutes

You create a Claude Code sandbox with (24 hours). The sandbox starts with a 24-hour clock. You store the sandbox_id. Five minutes later, you call Send Sandbox Input with the default (30 minutes). At that moment, the 24-hour clock is thrown away and replaced with a 30-minute clock. The sandbox will now die 30 minutes after that Send Sandbox Input call, not 24 hours after creation.

What you should do: If you need a long-lived sandbox, make sure every subsequent tool call also uses a long timeout. If you created a 24-hour sandbox, set (or use ) on every Send Sandbox Input call too. Or better yet, use Pause Sandbox between interactions, which preserves state indefinitely (up to 30 days) without consuming compute.

Story: Using extend_lifecycle to keep a sandbox alive

You have a sandbox running a background task. The user has not sent a message in 25 minutes, and the 30-minute timeout is about to expire. You call Send Sandbox Input with . This action does not run any command. It just connects with (1 hour), which resets the sandbox clock to 1 hour from now. The background task keeps running.

Story: The heartbeat pattern for long-running tasks

You want Claude Code to monitor an API endpoint every 5 minutes for the next 6 hours. You call Setup Sandbox Heartbeat with , , , and (6 hours). The tool sends a specialized prompt to Claude Code that tells it to create a background script with . Claude Code creates the script and starts it. The sandbox stays alive for 6 hours because of the timeout you set.

But what if your E2B plan only allows 1-hour sandboxes? Then you need a different approach: set the sandbox timeout to 1 hour, and have your Dify workflow call Send Sandbox Input with every 50 minutes. Each call resets the clock. The background task survives because the sandbox never expires.

The Tools (Detailed)

This plugin provides 18 tools. Here is what each one does, when to use it, and how its parameters work.

Create Sandbox

The most basic creation tool. It starts a new sandbox from a template alias (or the default base template if you leave template_alias empty).

Parameters that matter:

  • : The template to use. Leave empty for a bare Linux sandbox. Use if you want Claude Code pre-installed (but Create Claude Code Sandbox is better for that). Use any custom alias you built with Build Template.
  • : Extra environment variables. Format: or .
  • : Labels for filtering in List Sandboxes. Format: .
  • : Comma-separated port numbers. The tool generates external URLs like for each port.
  • : (default) writes env vars permanently into the sandbox. means env vars are only available when explicitly passed with each command.
  • GitHub and Vercel override parameters: If you set , it overrides both the envs_json GITHUB_TOKEN and the provider credential. Same for Vercel parameters.

Story: Creating a sandbox to analyze a private repository

You want Claude Code to review code in a private GitHub repo. You call Create Sandbox with , , , . The sandbox starts with GITHUB_TOKEN and GITHUB_USER injected. You then call Send Sandbox Input with , . The clone succeeds because the token is in the environment.

Create Claude Code Sandbox

Creates a sandbox specifically optimized for Claude Code. This is the tool you should use when your primary goal is to run Claude Code prompts.

What it does that Create Sandbox does not:

  1. Uses the official template alias, which has Claude Code CLI pre-installed.
  2. Automatically injects ANTHROPIC_API_KEY into the sandbox environment.
  3. Writes E2B_SANDBOX_ID into /home/user/.profile and /home/user/.bashrc using the filesystem API (not shell commands, which avoids the /root/.bashrc permission denied error).
  4. Runs automatically to ensure the CLI is up to date. The update tries three commands in order: , , . The first one that succeeds wins.
  5. Writes with your chosen permissions preset.
  6. Optionally injects Claude Code memory files (user memory and project memory).

Permissions presets:

  • (default): Bypasses all permission prompts. Best for non-interactive sandbox environments where Claude Code cannot ask the user for confirmation. This is the recommended default for Dify workflows.
  • : Allows common development operations (read, edit, write, git status, npm, pip, pytest) but asks before git push, WebFetch. Denies reading .env files and using curl/wget.
  • : Non-interactive mode for CI pipelines. Auto-denies anything not explicitly allowed.
  • : Read-only access. Cannot edit, write, or run commands.
  • : Planning only. No tool execution at all.

Story: Setting up a Claude Code sandbox with project context

You are building a Dify bot for a law firm. Each lawyer has domain expertise that should persist across conversations. You call Create Claude Code Sandbox with:

The sandbox starts with Claude Code configured to bypass all permission prompts, the lawyer's expertise written to ~/.claude/CLAUDE.md, and project conventions written to CLAUDE.md in the working directory. Every Claude Code prompt in this sandbox will see both memory files.

Create Next.js Sandbox

Creates a sandbox with a fresh Next.js project scaffolded using the latest . This tool does not rely on any pre-built Next.js template. Instead, it always starts from the base template and runs the scaffolding commands at creation time, guaranteeing you get the latest Next.js and shadcn versions.

What happens step by step:

  1. Creates a base sandbox (no template alias).
  2. Runs in /home/user/nextjs-app.
  3. Runs (non-interactive shadcn initialization).
  4. If , runs (installs all shadcn UI components).
  5. Starts the dev server in background: .
  6. Waits up to 60 seconds for port 3000 to become reachable. If it does not, returns the dev server log from /tmp/nextjs-dev.log so you can diagnose the issue.

Important: This tool requires (it is the default). Without internet, npx cannot download packages.

Story: Creating a Next.js sandbox and then adding Claude Code

You want users to be able to create a Next.js project and then use Claude Code to modify it. Your Dify workflow does:

  1. Create Next.js Sandbox with , , . Store the sandbox_id.
  2. Install Packages with and the sandbox_id from step 1. Now the sandbox has both Next.js and Claude Code.
  3. Send Sandbox Input with , , (fresh session since Claude Code was just installed).

The user sees the dev server URL from step 1, and after step 3, the Next.js project has a dark mode toggle.

Create Next.js (Bun) Sandbox

Same as Create Next.js Sandbox, but uses Bun instead of npm. The tool first installs Bun (), then uses and . The port readiness timeout is 90 seconds (longer than npm because Bun installation adds time). Dev server log goes to /tmp/nextjs-bun-dev.log.

Send Sandbox Input

The primary interaction tool. Once you have a sandbox_id, this is how you talk to it.

Actions:

  • (default): Sends as a prompt to Claude Code CLI. Requires ANTHROPIC_API_KEY (from provider credentials or ). If (default), uses to resume the most recent conversation. If false, starts fresh with .
  • : Runs as a shell command. Each call is a fresh shell, so cd and export do not persist across calls. Use Start Shell Session if you need stateful sessions.
  • : Runs . Use this to keep the sandbox alive without doing anything meaningful.
  • : Does not run any command. Just connects with a 1-hour timeout to reset the sandbox clock.

What happens when Claude Code CLI is missing:
If you select on a sandbox that does not have Claude Code installed (for example, a sandbox created with Create Sandbox or Create Next.js Sandbox), the tool detects "command not found" in the error output and returns a clear message telling you to run Install Packages with the Claude Code Latest preset first. It does not crash.

What happens when Claude Code CLI is outdated:
If Claude Code CLI refuses to run because it needs an update (error message contains "needs an update" and "claude update"), the tool automatically runs the update sequence (same as Create Claude Code Sandbox) and retries the original command. This only triggers when the CLI explicitly refuses, not on every call.

Story: Multi-turn conversation with Claude Code

Turn 1: User says "Create a Python web scraper for Hacker News". Your workflow calls Create Claude Code Sandbox, stores sandbox_id, then calls Send Sandbox Input with , , . Claude Code creates the scraper. Workflow returns the output and pauses the sandbox.

Turn 2: User says "Add error handling and retry logic". Your workflow calls Send Sandbox Input with the same sandbox_id, , , . Claude Code remembers the scraper it created and modifies it. Because resume_session is true, it has full context from turn 1.

Turn 3: User says "Run it and show me the output". Your workflow calls Send Sandbox Input with , . The shell command runs the scraper and returns the JSON output.

Install Packages

Installs tools and packages in an existing sandbox. This is the general-purpose "add stuff to a sandbox" tool.

How to use:

  • Quick single install: Use dropdown. Pick "Claude Code Latest", "OpenClaw", or "Remotion".
  • Multiple presets at once: Use with comma delimiter: .
  • Custom commands: Use with your chosen delimiter.

Preset commands and what they actually run:

  • :
  • :
  • :

Presets execute first, then custom commands, in order. Each command runs sequentially as the user "user" (not root).

Story: Installing multiple tools at once

You created a base sandbox and want to set up a full development environment. You call Install Packages with:

This runs four commands in order: (1) npm install Claude Code, (2) npm install pnpm, (3) pip install requests and beautifulsoup4, (4) apt-get install jq. The output tells you which succeeded and which failed.

Start Shell Session / Send Shell Session Input / Kill Shell Session

These three tools work together to provide stateful interactive shell sessions. They solve the problem that (used by Send Sandbox Input with action=shell_command) starts a fresh shell every time, so cd, exported variables, and shell history do not persist.

Start Shell Session:

  • Creates a PTY (pseudo-terminal) session, like opening a new terminal tab.
  • Returns a (integer) that you use for all subsequent interactions.
  • Optional parameter sets the initial working directory.

Send Shell Session Input:

  • Sends to the PTY and reads back output.
  • By default appends a newline (simulates pressing Enter).
  • (default 2) controls how long to wait for output. For fast commands like , 2 seconds is fine. For slow commands like , increase it.
  • (default 4000) caps the output length to avoid flooding.
  • Output may contain ANSI escape sequences (colors, cursor movement) because it is a real terminal.

Kill Shell Session:

  • Terminates the PTY process by PID.

Story: Using a stateful shell to navigate and build a project

Step 1: Start Shell Session with , . Returns .

Step 2: Send Shell Session Input with , . Output shows the directory listing.

Step 3: Send Shell Session Input with , . Output shows the prompt changed to my-project directory.

Step 4: Send Shell Session Input with , , . The shell remembers you are in my-project because the PTY session is stateful.

Step 5: Send Shell Session Input with , , .

Step 6: Kill Shell Session with .

Notice how steps 3 through 5 all happen in the same shell. If you had used Send Sandbox Input with action=shell_command, each call would start in /home/user and you would have to prepend to every command.

Setup Sandbox Heartbeat

A specialized Claude Code tool for creating periodic background tasks. It prepends a detailed system prompt to your task description that teaches Claude Code how to write a background loop script.

When to use: When you want something to happen repeatedly inside the sandbox over a long period. Examples: health checks, data polling, log rotation, periodic API calls.

Parameters:

  • (required): What should happen. Be specific.
  • : How often. Examples: "5 minutes", "30 seconds", "1 hour".
  • : How long. Examples: "6 hours", "1 day", "until stopped".
  • Default timeout is 3600 seconds (1 hour), longer than other tools.

Story: Monitoring a deployment

You just deployed a web app from a sandbox. You want to monitor it for the next 2 hours. You call Setup Sandbox Heartbeat with:

Claude Code creates a script like:

It runs it with and reports the PID. Two hours later, the sandbox expires. If you need to check the alerts before that, call Read Sandbox File with .

Guard Output

A security tool that blocks or redacts known secret values from output text before it reaches end users.

How it works:

  1. Collects secret values from provider credentials (e2b_api_key, e2b_access_token, anthropic_api_key).
  2. Optionally accepts additional secrets via parameter.
  3. For each secret, generates three matching variants: exact string, base64 encoding, URL encoding (only for secrets 12+ characters to avoid false positives).
  4. Scans the input text for any of these variants.
  5. In mode (default): If any secret is found, replaces the entire output with a warning message.
  6. In mode: Replaces each matched secret with and returns the modified text.

Story: Preventing API key leakage in a chatbot

Your Dify workflow runs Claude Code and returns the output to users. Claude Code might accidentally print environment variables (for example, if the user asks "show me all environment variables" and Claude runs ). Without Guard Output, the ANTHROPIC_API_KEY would be sent to the user.

Your workflow: Send Sandbox Input (claude_code) -> Guard Output (text = output from previous step, mode = redact) -> Reply node. If Claude Code's output contains the API key, it gets replaced with [REDACTED] before reaching the user.

Read Sandbox File

Reads a file or lists a directory from the sandbox filesystem.

For files: Returns the file content directly.

For directories: Lists all entries (files, directories, symlinks) in a tree format, then reads file contents in parallel using up to 50 concurrent threads. You can control how many files to read with (0 = tree only, -1 = read all, positive number = limit). Hidden files (starting with .) are excluded by default unless .

Story: Reviewing what Claude Code created

After running Claude Code to create a project, you call Read Sandbox File with . The tool returns:

To read the src directory, make another call with .

Write Sandbox File

Writes content to a file in the sandbox. Parent directories are created automatically.

Story: Injecting a configuration file before running Claude Code

You want Claude Code to work with a specific .env file. You call Write Sandbox File with , . Then you call Send Sandbox Input with , .

Pause Sandbox

Freezes a sandbox in place. The sandbox stops consuming compute resources, but its entire state (filesystem, memory, running processes) is preserved for up to 30 days.

Technical detail: Pausing takes approximately 4 seconds per 1 GiB of RAM.

When to use: Between user interactions in a multi-turn conversation. Pause after each response, resume (by calling any tool with the sandbox_id) when the user sends the next message.

Story: Cost-efficient multi-turn conversation

Your chatbot creates a sandbox for each user conversation. A user sends a message at 10:00 AM, you create a sandbox and run Claude Code. The response takes 30 seconds. Without pausing, the sandbox runs (and costs money) until the 30-minute timeout. With pausing, you pause immediately after getting the response. The sandbox costs 30 seconds of compute instead of 30 minutes. When the user replies at 10:15 AM, any tool call with that sandbox_id automatically resumes it.

List Sandboxes

Lists all sandboxes (running and paused) in your E2B account with optional filtering.

Filters:

  • : running, paused, or all (default).
  • : Comma-separated IDs to look up specific sandboxes.
  • Metadata filters: , , , (key=value pairs).

Story: Cleaning up forgotten sandboxes

You notice your E2B bill is higher than expected. You call List Sandboxes with and see 15 running sandboxes. Most of them have and values. You identify 10 sandboxes from yesterday's testing that were never killed. You call Kill Sandbox for each one.

Kill Sandbox

Permanently destroys a sandbox. All files, Claude Code conversation history, and running processes are gone. There is no undo.

When to use: When a conversation ends and you are certain you will not need the sandbox again.

Build Template

Creates a reusable E2B template with pre-installed dependencies and repositories. The build runs on E2B's infrastructure, not on your Dify server.

Base strategies:

  • (default): Start from E2B's base Linux image.
  • : Extend an existing template (yours or a public one).
  • : Start from any Docker image.

What you can pre-install:

  • : System packages (comma-separated). Example: .
  • : Python packages (comma-separated). Example: .
  • : Node packages (comma-separated). Example: .
  • : Git URLs to clone (comma-separated). Cloned to /home/user/REPO_NAME.
  • : Advanced shell commands.

Story: Building a template for a specific project

Your team works on a Python ML project. Every sandbox needs numpy, pandas, scikit-learn, and the project repo. You call Build Template with:

The build takes a few minutes. After that, every Create Sandbox with starts with everything pre-installed. No waiting for pip install or git clone.

List Templates

Lists all templates in your E2B account with their aliases, build status, CPU, memory, and visibility settings.

Environment Variable Injection

All creation tools support environment variable injection with a clear three-layer priority system:

  1. Tool override parameter (highest priority): , , etc.
  2. envs_json field: Extra environment variables you pass as a JSON object or key=value pairs.
  3. Provider credential (lowest priority): Values configured in the plugin settings.

For example, if your provider credential has , your envs_json has , and your tool parameter has , the sandbox gets .

The parameter controls when variables are injected:

  • (default): Variables are set at sandbox creation time and persist for the entire sandbox lifetime.
  • : Variables are only available when explicitly passed with each command (as a shell prefix).

Vercel variables deserve special mention: when you set Vercel Team ID (via or provider credential), the plugin injects both and with the same value, because different Vercel tools expect different variable names.

Claude Code Permissions Presets

Create Claude Code Sandbox writes inside the sandbox. This file controls what Claude Code is allowed to do.

PresetdefaultModeBest For
allow_all (default)bypassPermissionsNon-interactive sandboxes, Dify workflows
dev_standardacceptEditsDay-to-day development with safety rails
dev_webfetch_allowlistacceptEditsDevelopment needing external docs/packages
ci_build_testdontAskCI pipelines, automated testing
review_readonlydontAskCode review, no modifications
plan_modeplanPlanning only, no execution

You can append custom rules via , , and parameters. Format: semicolon-separated rules like or JSON array like .

Common Mistakes and How to Avoid Them

Mistake: Using shell_command action for multi-step operations

Each call starts a fresh shell. If you call followed by , the second call runs in /home/user (the default), not in /home/user/project.

Fix: Either combine commands with (e.g., ), or use Start Shell Session for a stateful session.

Mistake: Forgetting that connect resets the timeout

As explained above, every tool call resets the sandbox timeout. If you create a sandbox with a 2-hour timeout but all your Send Sandbox Input calls use the default 30-minute timeout, the sandbox will die 30 minutes after the last interaction, not 2 hours after creation.

Fix: Set consistent timeouts across all tool calls, or use Pause Sandbox between interactions.

Mistake: Using claude_code action on a non-Claude-Code sandbox

If you create a sandbox with Create Sandbox or Create Next.js Sandbox, Claude Code CLI is not installed. Calling Send Sandbox Input with will fail.

Fix: Either use Create Claude Code Sandbox, or call Install Packages with before using the claude_code action.

Mistake: Not using Guard Output before replying to users

Claude Code might accidentally output API keys or tokens. If your workflow sends Claude Code output directly to a Reply node, those secrets reach the end user.

Fix: Always place Guard Output between Send Sandbox Input and the Reply node.

Workflow Design Patterns

Pattern 1: Simple single-turn Claude Code

User Message -> Create Claude Code Sandbox -> Send Sandbox Input (claude_code) -> Guard Output -> Reply -> Kill Sandbox

Pattern 2: Multi-turn conversation with pause/resume

First turn: User Message -> Create Claude Code Sandbox -> Store sandbox_id -> Send Sandbox Input (claude_code) -> Guard Output -> Reply -> Pause Sandbox

Subsequent turns: User Message -> Send Sandbox Input (claude_code, same sandbox_id, resume_session=true) -> Guard Output -> Reply -> Pause Sandbox

Final turn (detected by Dify logic): ... -> Reply -> Kill Sandbox

Pattern 3: Next.js development with Claude Code

Create Next.js Sandbox -> Store sandbox_id -> Install Packages (claude_code_latest) -> Send Sandbox Input (claude_code, "modify the project...") -> Guard Output -> Reply

Pattern 4: Pre-built template for fast startup

One-time setup: Build Template (with git repo, packages) -> Store template alias

Every conversation: Create Sandbox (template_alias=your-template) -> Send Sandbox Input -> ...

Pricing Notes

E2B bills per second for running sandboxes. Paused sandboxes preserve state without running compute costs.

  • CPU: $0.000014/s per vCPU (2 vCPU default = $0.000028/s)
  • Memory: $0.0000045/GiB/s
  • Storage: 10 GiB included (Hobby), 20 GiB included (Pro)

Practical guidance: Use Pause Sandbox between interactions to stop paying for idle compute. A 30-minute running sandbox with 2 vCPU and 512 MiB RAM costs about $0.05 for the compute plus $0.004 for memory. Pausing reduces that to near zero between interactions.

Reference

Contact

Email: [email protected]

CATEGORY
Tool
VERSION
0.0.3
lysonober·02/14/2026 01:20 AM
REQUIREMENTS
Tool invocation
Maximum memory
256MB