The package is named for the cloud app it speaks to — cloud apps/sandbox is
hanzo-sandbox here — so there is one name per concept across the two languages.
Built against the routes rather than guessed:
GET|POST /v1/sandboxes list, create
GET|DELETE /v1/sandboxes/:id get, delete
POST /v1/sandboxes/:id/exec argv | command, stdin, dir, timeoutSec
GET|POST /v1/sandboxes/:id/fs read, write
The API key carries the org, and the client sends nothing else. cloud resolves
it through principal.OrgOf(user, org), which returns nothing without a validated
principal — "no validated principal, so the org claim is untrusted" — and the
gateway strips a client-supplied X-Org-Id before a handler sees it. A first cut
took `org` as a required argument and sent the header on every call; that would
have been ignored at best.
Two things the tests found, both real:
* with no key configured the client still sent `Authorization: Bearer `, an
empty credential that reads as a present one and hides "no key" behind
whatever the server says about a bad one. It sends no header now.
* cloud spells the size field `class`, which python cannot, so Sandbox maps it
to `cls` at the boundary instead of leaving callers to index a dict.
This is the REMOTE half. hanzo_sandbox.sandbox stays the local one — unshare,
namespaces, a boundary on this machine. Same word, unrelated concerns, separate
modules.
Served by a real HTTP server in the tests, since what breaks in a client of this
shape is the request: path, method, credential.
Co-authored-by: Hanzo Dev <[email protected]>
Hanzo Python SDK
The flagship Python SDK for the Open AI Cloud — models, agents, tools, memory, and MCP in one install.
This is the most complete Hanzo SDK — a uv workspace of 60+ composable packages
covering the full AI surface: the typed cloud client, an agent framework, the
Model Context Protocol server and tools, persistent memory + RAG, distributed
compute, and a batteries-included CLI. If you build AI in Python, start here.
Install
pip install hanzoai # the typed cloud API client
pip install hanzo # orchestration helpers, agents, MCP
pip install "hanzo[all]" # everything, including optional extras
The hanzo command is not a Python package — it is a native binary:
curl -fsSL https://hanzo.sh | sh
hanzo auth login
Quickstart
from hanzoai.cloud import ApiClient, Configuration, ChatApi
config = Configuration(host="https://api.hanzo.ai", access_token="sk-...")
with ApiClient(config) as client:
print(ChatApi(client).post_v1_chat_completions())
hanzoai.cloud is the client, and it is the only one. Method and class names are
the document's operation ids, so they move when the document does — that is what
makes the client checkable against a release instead of against memory.
Every route is https://api.hanzo.ai/v1/<service>/*. Models come from the Zen
family (our own models) plus any provider you connect — one typed client, no proxy
in the middle.
Examples — the six canonical flows
examples/ carries one directory per flow. These are the same six in every
Hanzo SDK, so a reader who knows one language's set can navigate another's.
| flow | what it does | routes |
|---|---|---|
hello |
identity — prove the key works | GET /v1/bot/auth/me |
chat |
one completion | POST /v1/chat/completions |
money |
balance + usage | GET /v1/billing/balance, GET /v1/billing/usage |
store |
KV round-trip | POST /v1/kv, GET/DELETE /v1/kv/{name} |
agent |
create + run + read | POST /v1/agents, POST /v1/agents/{ref}/run, GET /v1/agents/{ref}/runs |
tools |
tool catalog | GET /v1/tools |
Each reads HANZO_API_KEY from the environment and talks to
https://api.hanzo.ai unless HANZO_BASE_URL says otherwise:
export HANZO_API_KEY=sk-...
uv run python -m examples.hello
They import from hanzoai.cloud — the client generated from
https://api.hanzo.ai/v1/openapi.json, which is where new work goes.
examples/client.py is the single place a base URL or an env var is resolved.
CI imports all six on every push, which is what keeps them from rotting into
pseudocode.
Packages
The workspace splits cleanly by concern. The headline packages:
| Package | Purpose |
|---|---|
hanzoai |
Typed cloud API client (generated from the Hanzo OpenAPI surface). |
hanzo |
Orchestration helpers and the older Python CLI (console script hanzo-py). |
hanzo-mcp |
Model Context Protocol server — discovers tools via entry points. |
hanzo-agents / hanzo-agent |
Agent framework — build and orchestrate agents and swarms. |
hanzo-network |
Distributed AI compute and node orchestration. |
hanzo-memory |
Persistent memory + RAG (SQLite, optional vector backends). |
hanzo-tools-* |
60+ single-concern tool packages (shell, browser, fs, code, vector, iam, …), each exposing a TOOLS list. |
python-sdk/
└── pkg/
├── hanzoai/ # typed cloud client (OpenAPI-generated)
├── hanzo/ # orchestration helpers + legacy Python CLI
├── hanzo-mcp/ # MCP server (entry-point tool discovery)
├── hanzo-agents/ # agent framework
├── hanzo-network/ # distributed compute
├── hanzo-memory/ # memory + RAG
└── hanzo-tools-*/ # composable tool packages
CLI
The Hanzo CLI is a native binary, not a Python package:
curl -fsSL https://hanzo.sh | sh
hanzo auth login
hanzo models list
hanzo "fix the failing test"
It carries one command group per Hanzo Cloud product, generated from the same
contract this SDK is generated from. hanzo --help prints the tree.
pip install hanzo still ships the older Python CLI as hanzo-py. It is
named that way on purpose: two programs called hanzo on one PATH is how
hanzo login came to mean different things to different people.
Model Context Protocol (hanzo-mcp)
hanzo-mcp hosts the MCP server and discovers tools through
[project.entry-points."hanzo.tools"], so any installed hanzo-tools-* package
lights up automatically.
from hanzo_mcp import create_mcp_server
server = create_mcp_server()
server.register_tool(my_tool)
server.start()
Agents (hanzo-agents)
from hanzo_agents import Agent, Swarm
agent = Agent(
name="researcher",
model="zen5-coder",
instructions="You are a research assistant.",
)
swarm = Swarm([agent])
result = await swarm.run("Research quantum computing.")
Network (hanzo-network)
from hanzo_network import LocalComputeNode, DistributedNetwork
node = LocalComputeNode(node_id="node-001")
network = DistributedNetwork()
network.register_node(node)
Memory (hanzo-memory)
Persistent memory and RAG backed by SQLite, with optional vector search
(sqlite-vec, lancedb, kuzu). Global state lives in ~/.hanzo/; per-project
state in .hanzo/.
from hanzo_memory import MemoryService
memory = MemoryService()
await memory.store("key", "value")
result = await memory.retrieve("key")
Development
This is a uv workspace.
git clone https://github.com/hanzoai/python-sdk.git
cd python-sdk
uv sync --all-packages # install the whole workspace
uv run pytest tests/ -v # run tests
make lint # ruff lint
make format # ruff format
make type-check # mypy / pyright
Per-package work:
uv run pytest pkg/hanzo-mcp -v
cd pkg/hanzo && uv build
Configuration
HANZO_API_KEY=your-api-key
HANZO_BASE_URL=https://api.hanzo.ai
HANZO_LOG_LEVEL=INFO
Or ~/.hanzo/config.yaml:
api:
key: your-api-key
base_url: https://api.hanzo.ai
logging:
level: INFO
Security
- Transport is TLS 1.3+. Secrets belong in a KMS, never in source or plaintext.
- SOC 2 audit in progress; HIPAA BAA available.
Report vulnerabilities to [email protected]. See SECURITY.md.
Contributing
Contributions welcome — see CONTRIBUTING.md. Use type hints,
add tests for new behavior, and run make lint before opening a PR.
License
Apache License 2.0 — see LICENSE.
Support
- Docs: docs.hanzo.ai
- Issues: github.com/hanzoai/python-sdk/issues
- Email: [email protected]
Hanzo — the Open AI Cloud
Open source · every language · on-chain settlement. hanzo.ai · docs.hanzo.ai
SDKs in every language — Python (flagship) · TypeScript · Go · Rust · C++ · Swift · Kotlin · umbrella