Skip to main content

HarnessBox

PyPI CI License: MIT Python 3.12+

Run AI coding agents in secure sandbox environments with workspace orchestration, auto-pause, and multi-session support.

import os
from harnessbox import HarnessBox

async with HarnessBox(
    provider="e2b",
    harness="claude-code",
    secrets={
        "provider_api_key": os.getenv("E2B_API_KEY"),
        "harness_secrets": {"ANTHROPIC_API_KEY": os.getenv("ANTHROPIC_API_KEY")},
    },
) as hb:
    async for event in hb.send_message("Fix the failing test"):
        print(event.delta or "", end="")

HarnessBox is the sole public API — provision sandboxes, manage workspaces, run agent sessions. Zero runtime dependencies.

Install

pip install harnessbox

# With E2B provider
pip install "harnessbox[e2b]"

Quickstart

import os
from harnessbox import HarnessBox, GitWorkspace

hb = HarnessBox(
    provider="e2b",
    harness="claude-code",
    secrets={
        "provider_api_key": os.getenv("E2B_API_KEY"),
        "harness_secrets": {"ANTHROPIC_API_KEY": os.getenv("ANTHROPIC_API_KEY")},
    },
    workspace=GitWorkspace(
        remote="https://github.com/user/repo.git",
        branch="main",
        commit_on_exit=True,
    ),
)

sandbox_id = await hb.create()
async for event in hb.send_message("Fix the tests"):
    print(event.delta or "", end="")
await hb.kill()

How It Works

HarnessBox is a Python library. You import it, provision a sandbox, and stream agent output. That's the whole product.

from harnessbox import HarnessBox

hb = HarnessBox(provider="e2b", harness="claude-code", secrets={...})
await hb.create()

async for event in hb.send_message("Fix the failing test"):
    print(event.delta or "", end="")

await hb.kill()

Everything else is a deployment choice:

┌────────────────────────────────────────────────────────────┐
│              HarnessBox (Python SDK)                         │
│                                                             │
│  • Create workspaces and sessions                          │
│  • Stream agent output as async events                     │
│  • Auto-pause idle sandboxes, resume on next message       │
│  • Persist state across restarts (SQLite)                  │
│  • Security policies, credential guards                    │
└─────────────────────┬───────────────────┬──────────────────┘
                      │                   │
        "I'm a script │                   │ "I need a web UI
        or service"   │                   │  or team access"
                      ▼                   ▼
           ┌─────────────────┐  ┌────────────────────────────┐
           │  Use the SDK    │  │  Run `harnessbox serve`    │
           │  directly       │  │  (same SDK + HTTP/SSE)     │
           │                 │  │                            │
           │  No server.     │  │  Adds: multi-client,      │
           │  No infra.      │  │  web dashboard, shared    │
           │  Just Python.   │  │  state across consumers.  │
           └─────────────────┘  └────────────────────────────┘

Think of it like SQLite vs Postgres. SQLite is embedded — no server, works great for one process. Postgres adds a server for shared access. Same SQL, same data model, different deployment. HarnessBox works the same way.

When you don't need the server:

  • Scripts and CI pipelines
  • Single-developer tools
  • Programmatic agents (backend services)
  • Anything where one Python process is enough

When you add the server:

  • You're building a web UI for your team
  • Multiple clients (web + CLI + SDK) need to see the same workspaces
  • You want an always-on orchestrator that survives process restarts
  • You're running our hosted platform (base_url="https://api.harnessbox.dev")

Server

The server is the SDK running as a long-lived process that accepts HTTP connections. Same features, accessible over the network.

# Self-hosted
pip install "harnessbox[server]"
harnessbox serve --port 8080

# Or with Docker
docker run -p 8080:8080 harnessbox/server

Point the SDK at your server (planned for v0.4.0):

# SDK becomes a thin client — all orchestration happens server-side
hb = HarnessBox(base_url="http://localhost:8080", secrets={...})
# Same API, same streaming, same everything

Server endpoints:

  • POST /v1/workspaces — create workspace
  • GET /v1/workspaces — list workspaces
  • DELETE /v1/workspaces/{id} — destroy workspace
  • POST /v1/workspaces/{id}/prompt — send prompt (SSE stream)
  • GET /v1/workspaces/{id}/events — subscribe to live events (SSE)

Security

HarnessBox generates agent-specific deny rules and PreToolUse hook guards that protect credentials inside sandboxes:

Threat Defense
printenv / env / os.environ Bash deny rules + hook guard
Read .env, .aws/credentials Read deny rules
WebFetch exfiltration Tool deny rules
Agent spawning sub-agents Agent deny rules
/proc/self/environ Bash deny rules + hook guard
IMDS credential theft (169.254.169.254) Hook guard regex
Git credential helper leak git config credential.* deny
from harnessbox import SecurityPolicy

policy = SecurityPolicy(
    denied_tools=["WebFetch", "WebSearch", "Agent"],
    denied_bash_patterns=["rm -rf /"],
    deny_network=True,
    include_credential_guards=True,  # on by default
)

Built-in Harness Types

Harness Config Dir System Prompt CLI
claude-code .claude CLAUDE.md claude --dangerously-skip-permissions ...
codex .codex AGENTS.md codex --model o4-mini -q {prompt}
opencode .opencode AGENTS.md opencode -p {prompt}

Key Features

Feature Description
Auto-pause/resume Idle workspaces pause → $0/hr. Resume transparently on next message.
Multi-session Multiple concurrent agent sessions per workspace.
Branch-based pooling Same (remote, branch) reuses existing workspace.
Security policies Credential guards, tool deny lists, network blocking.
Git workflows Clone, commit, push on exit. Branch creation from base.
Zero dependencies Stdlib only at runtime. Provider SDKs are optional extras.
Any provider E2B, Docker, Daytona, EC2. Protocol-based extensibility.

API Reference

HarnessBox

from harnessbox import HarnessBox, HarnessBoxSecrets

hb = HarnessBox(
    provider="e2b",                    # Provider name or instance
    harness="claude-code",             # Agent harness type
    api_key="hb_live_...",             # Platform key (None = self-hosted)
    secrets=HarnessBoxSecrets(         # Or pass as dict
        provider_api_key="e2b_...",
        harness_secrets={"ANTHROPIC_API_KEY": "sk-ant-..."},
    ),
    model="claude-sonnet-4-6-20250514",
    system_prompt=Path("CLAUDE.md"),    # Path to load from file, or str for inline content
    workspace=GitWorkspace(...),
    security_policy=SecurityPolicy(...),
    setup_script="npm install",
    timeout=300,
)

# Lifecycle
sandbox_id = await hb.create()
async for event in hb.send_message("Fix tests"):
    print(event.delta)
response = await hb.send_message("Fix tests", stream=False)
result = await hb.run_command("pytest")
await hb.write_file("/workspace/f.py", "content")
content = await hb.read_file("/workspace/f.py")
await hb.kill()

# Context manager (auto create + kill)
async with HarnessBox(provider="e2b") as hb:
    async for event in hb.send_message("Hello"):
        print(event.delta)

GitWorkspace

GitWorkspace(
    remote: str,                          # HTTPS git remote URL
    *,
    branch: str = "main",
    base_branch: str | None = None,       # Branch to fork from
    commit_on_exit: bool = False,
    commit_message: str | None = None,
    clone_depth: int | None = None,
    auth_token: str | None = None,        # Never stored as env var
)

SecurityPolicy

SecurityPolicy(
    denied_tools: list[str] = [],
    denied_bash_patterns: list[str] = [],
    deny_network: bool = False,
    include_credential_guards: bool = True,
)

Project Structure

harnessbox/
  __init__.py                   # public API
  harnessbox.py                 # HarnessBox — sole public entry point
  workspace_manager.py          # internal workspace orchestration
  agent_manager.py              # internal agent lifecycle
  sandbox.py                    # internal sandbox orchestration
  workspace.py                  # Workspace protocol, GitWorkspace
  providers.py                  # SandboxProvider protocol
  lifecycle.py                  # WorkspaceState machine
  storage.py                    # StorageBackend protocol
  streaming.py                  # UniversalEvent, StreamParser
  events.py                     # EventBuffer (SSE replay)
  server.py                     # HTTP/SSE transport
  config/
    harness.py                  # HarnessTypeConfig registry
    manifest.py                 # SandboxManifest builder
  security/
    policy.py                   # SecurityPolicy, deny rules
    hooks.py                    # PreToolUse hook guard
    events.py                   # SandboxEvent, EventHandler
  _providers/
    e2b.py                      # E2B provider
  _storage/
    sqlite.py                   # SQLite backend
    memory.py                   # In-memory backend
tests/                          # 651 tests

License

MIT

Release files for harnessbox 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for harnessbox 0.3.0
File Size Uploaded
harnessbox-0.3.0.tar.gz 187.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for harnessbox 0.3.0
File Interpreter ABI Platform
harnessbox-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size:288.7 kB

Release files / harnessbox-0.3.0.tar.gz

Download URL harnessbox-0.3.0.tar.gz
Size 187.5 kB
Tags Source
SHA-256 checksum
How to use checksums
b50bd8f677c30bad41b13a887f7c4e34776de109f869956d6e8c957af0319dfe
BLAKE2b-256 checksum
How to use checksums
4075dccad525e60686c1f6eae2b084138b31f3dbda647e1bb28c6c0daf37c9f5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 19, 2026.

Transparency log

Release files / harnessbox-0.3.0-py3-none-any.whl

Download URL harnessbox-0.3.0-py3-none-any.whl
Size 101.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
7e6d4e2f8adf624f8c849467ba0203e6d0c952331a325304cdb7d42d6a91f560
BLAKE2b-256 checksum
How to use checksums
c052483a3fef5af4e37f6d06f394054f0ba7355b1298e0ae3f9b92fb1ed187c2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 19, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.3.0 This release

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page