Google ADK plugin backed by E2B sandboxes.
Project description
e2b-adk
A Google ADK plugin backed by E2B sandboxes. Attach it to an ADK agent and the agent can generate and run code, execute shell commands, read and write files, and start long-running processes — all inside an isolated E2B sandbox, with no infrastructure of your own.
Under the hood every tool call runs in the E2B Code Interpreter, so the model's code executes in a real Python kernel instead of being trusted blind.
Install
pip install e2b-adk
Or with uv:
uv pip install e2b-adk
Credentials
You need an E2B API key for the sandbox and a model key for the agent's LLM (Gemini is ADK's default):
export E2B_API_KEY="..."
export GOOGLE_API_KEY="..."
Get an E2B key at e2b.dev/dashboard.
Quickstart
Create the plugin, hand its tools to an Agent, and register the plugin on the
App. The plugin owns the sandbox lifecycle — you never create or tear one down
yourself.
import asyncio
from google.adk.agents import Agent
from google.adk.apps import App
from google.adk.runners import InMemoryRunner
from e2b_adk import E2BPlugin
async def main() -> None:
plugin = E2BPlugin()
agent = Agent(
model="gemini-2.5-flash",
name="coder",
instruction="Write and run Python to answer the user. Verify with run_code.",
tools=plugin.get_tools(),
)
app = App(name="demo", root_agent=agent, plugins=[plugin])
async with InMemoryRunner(app=app) as runner:
# run_debug prints the conversation as it runs.
await runner.run_debug("Compute the 20th Fibonacci number.")
asyncio.run(main())
Tools
plugin.get_tools() returns six tools. Each returns a JSON-serializable dict
with a success flag — tools report failures in the result rather than raising,
so a bad call never aborts the agent run. success means the tool ran: code
that raised or a command that exited non-zero still returns success: True with
the failure captured in error / exit_code. Only a call that could not run at
all (sandbox unavailable, timeout) returns success: False.
| Tool | Does | Key result fields |
|---|---|---|
run_code |
Run code in a stateful kernel (variables persist across calls) | stdout, stderr, text, error |
run_command |
Run a shell command (each call is independent) | stdout, stderr, exit_code |
write_file |
Write a file in the sandbox | path |
read_file |
Read a file back | path, content |
list_files |
List a directory | entries ([{name, type}]) |
start_background_command |
Start a long-running process; optional preview URL for a port | pid, preview_url (+ readiness when port is set) |
Configuration
E2BPlugin takes keyword-only options, all optional. Anything you don't set
falls back to the E2B SDK's own default — the plugin overrides none of them.
E2BPlugin(
# Common options
api_key=None, # defaults to the E2B_API_KEY env var
template=None, # E2B sandbox template
metadata=None, # dict[str, str] attached to the sandbox
envs=None, # dict[str, str] environment variables
timeout=None, # sandbox timeout in seconds (re-applied on every tool call)
plugin_name="e2b_plugin",
# Passed straight through to AsyncSandbox.create() — see the E2B SDK docs
secure=None,
allow_internet_access=None,
mcp=None,
network=None,
lifecycle=None, # e.g. pause/auto-resume; defaults to E2B's behavior
volume_mounts=None,
# **opts: any other AsyncSandbox.create() / connection param (proxy, request_timeout, …)
)
Examples
examples/data_analysis.py— a data-analysis agent that saves a dataset and computes real answers with pandas instead of guessing.examples/code_generator.py— a code generator that executes every snippet before returning it.
Run one with the credentials above:
uv run --extra examples python examples/data_analysis.py
v1 notes
- Sequential tool calls. One sandbox is shared per plugin; calls are meant to run one at a time, not concurrently. Concurrent calls are safe for the sandbox lifecycle (creation is locked) but share one filesystem and kernel.
- Text-only output. Tools return text —
stdout/stderr/file contents. Rich results (charts, dataframes, images) are not surfaced yet. - Lazy, shared sandbox lifecycle. The sandbox is created on the first tool call and reused for the agent's lifetime, then killed when the runner exits.
- Keep-alive while active, expiry when idle. While a sandbox SDK operation
is active, a best-effort heartbeat refreshes its
timeout(E2B's default is 300s), including when a foreground call runs longer than that timeout. A final refresh starts the full idle window when the operation ends. An idle gap longer thantimeoutstill expires the sandbox under E2B's default lifecycle (on_timeout: kill), and later tool calls return failure results — pass e.g.lifecycle={"on_timeout": {"action": "pause"}, "auto_resume": True}to pause and auto-resume across idle gaps instead. - Bounded output. Output larger than 10 KB per field is truncated with a
…[truncated N bytes]marker so a single call can't flood the model's context.
License
MIT — see LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file e2b_adk-0.1.0.tar.gz.
File metadata
- Download URL: e2b_adk-0.1.0.tar.gz
- Upload date:
- Size: 32.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
52fb93fded0c8ae463b7c03a03cf871f8f090004ea57ed775ba1e54c8f8ef6bf
|
|
| MD5 |
c3b425ab2439c740edfbc612da93c1ce
|
|
| BLAKE2b-256 |
d7ae7846be2e83dc7c652ef12d76b2661cd01044ee91a01b73f3e42dc29de577
|
Provenance
The following attestation bundles were made for e2b_adk-0.1.0.tar.gz:
Publisher:
release.yml on e2b-dev/e2b-adk-plugin
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
e2b_adk-0.1.0.tar.gz -
Subject digest:
52fb93fded0c8ae463b7c03a03cf871f8f090004ea57ed775ba1e54c8f8ef6bf - Sigstore transparency entry: 2186091497
- Sigstore integration time:
-
Permalink:
e2b-dev/e2b-adk-plugin@3d4a0b2a55c1f84cb9c93b6878c930e450abc980 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/e2b-dev
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@3d4a0b2a55c1f84cb9c93b6878c930e450abc980 -
Trigger Event:
release
-
Statement type:
File details
Details for the file e2b_adk-0.1.0-py3-none-any.whl.
File metadata
- Download URL: e2b_adk-0.1.0-py3-none-any.whl
- Upload date:
- Size: 24.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
75ab2c97567c114665061d14e3a290fc760c84c90ca0b54817072a357b807af3
|
|
| MD5 |
281b20e49f5bef968170db72b8fb7fb9
|
|
| BLAKE2b-256 |
f6e314e48e8997d3ad135df58f1736fe834b9f6aacd051d48440dbf210caf9d5
|
Provenance
The following attestation bundles were made for e2b_adk-0.1.0-py3-none-any.whl:
Publisher:
release.yml on e2b-dev/e2b-adk-plugin
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
e2b_adk-0.1.0-py3-none-any.whl -
Subject digest:
75ab2c97567c114665061d14e3a290fc760c84c90ca0b54817072a357b807af3 - Sigstore transparency entry: 2186091536
- Sigstore integration time:
-
Permalink:
e2b-dev/e2b-adk-plugin@3d4a0b2a55c1f84cb9c93b6878c930e450abc980 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/e2b-dev
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@3d4a0b2a55c1f84cb9c93b6878c930e450abc980 -
Trigger Event:
release
-
Statement type: