claudestream
claudestream is a Python library and CLI that runs Claude Code as a subprocess and decodes its stream-json output into typed events, with async and sync sessions, sandbox policies, and Python-defined tools. It is for Python programs that drive Claude Code directly, instead of shelling out to it and parsing text. Every protocol line arrives as a typed event object, so a session reads as an ordinary loop over Python values, and the same session runs either async or sync.
Install
uv pip install claudestream
Quick start
One-shot ask
from claudestream import SessionConfig, SyncSession
config = SessionConfig(model="sonnet", profile="default")
with SyncSession(config) as session:
result = session.ask("What is 2 + 2?")
print(result.text)
Streaming events
from claudestream import SessionConfig, SyncSession, AssistantText, ToolUse, Result
config = SessionConfig(model="sonnet", profile="default")
with SyncSession(config) as session:
for event in session.send("List the files in the current directory"):
if isinstance(event, AssistantText):
print(event.text, end="")
elif isinstance(event, ToolUse):
print(f"\n[tool: {event.name}]")
elif isinstance(event, Result):
print(f"\n(cost: ${event.total_cost_usd:.4f})")
Async session
import asyncio
from claudestream import SessionConfig, AsyncSession, AssistantText
async def main():
config = SessionConfig(model="sonnet", profile="default")
async with AsyncSession(config) as session:
async for event in session.send("Hello!"):
if isinstance(event, AssistantText):
print(event.text, end="")
asyncio.run(main())
Multi-turn conversation
from claudestream import SessionConfig, SyncSession, AssistantText
config = SessionConfig(model="sonnet", profile="default")
with SyncSession(config) as session:
for event in session.send("Remember that my name is Alice."):
if isinstance(event, AssistantText):
print(event.text, end="")
print()
for event in session.send("What is my name?"):
if isinstance(event, AssistantText):
print(event.text, end="")
Custom tools
Define tools with the @tool decorator. claudestream auto-generates JSON Schema from type hints and serves them via MCP.
from claudestream import tool, collect_tools, SessionConfig, SyncSession, AssistantText
@tool("my_server")
def lookup_weather(city: str, units: str = "celsius") -> str:
"""Look up current weather for a city.
Args:
city: City name to look up.
units: Temperature units, celsius or fahrenheit.
"""
return f"22 degrees {units} in {city}"
config = SessionConfig(
model="sonnet",
profile="default",
tools=[lookup_weather._tool],
)
with SyncSession(config) as session:
for event in session.send("What's the weather in Paris?"):
if isinstance(event, AssistantText):
print(event.text, end="")
Agents
Agents are JSON-defined configurations with prompt templates, tool schemas, sandbox policies, and budget limits.
from claudestream import (
load_agent, invoke_agent_sync, SessionConfig, AssistantText,
)
agent = load_agent("code_reviewer") # loads .claudestream/agents/code_reviewer.agent.json
config = SessionConfig(model="sonnet", profile="default")
with invoke_agent_sync(agent, config, variables={"file": "main.py"}) as session:
for event in session.send("Review this file"):
if isinstance(event, AssistantText):
print(event.text, end="")
Sandbox policies
Restrict which tools Claude can use and which paths it can write to.
from claudestream import create_sandbox, SessionConfig, SyncSession
sandbox = create_sandbox(
tools=["Read", "Bash"],
write_paths=["/home/user/project"],
)
config = SessionConfig(model="sonnet", profile="default", sandbox=sandbox)
with SyncSession(config) as session:
result = session.ask("Read the README and summarize it")
print(result.text)
CLI
| Command | Description |
|---|---|
send |
Send a prompt to Claude and display the complete response with events |
stream |
Stream a prompt with real-time incremental token-by-token output to stdout |
events |
Debug mode: display all raw JSON protocol events from the subprocess |
repl |
Start an interactive multi-turn read-eval-print loop session with Claude |
ask |
Send a prompt to Claude and print only the final response text |
doctor |
Check claudestream environment health: binary, version, and profile |
config |
Show resolved configuration including binary path and version |
| agent | Manage and run agents defined in .agent.json files. Agent definitions declare a model, prompt template, allowed tools with input schemas, sandbox permissions, and budget limits (cost, turns, tokens). Use subcommands to validate configurations, run agents against prompts, and inspect metadata. |
agent run |
Load an agent definition and run it with the given prompt. Accepts a path to a .agent.json file or a bare agent name (resolved from .claudestream/agents/). The definition specifies the model, a prompt template with {variable} placeholders, tool schemas, sandbox policy, and budget constraints. Use --var key=value to substitute template variables. Use --model to override the model declared in the definition. |
agent list |
List available agents from .claudestream/agents/. Scans the agents directory in the working directory (or the directory specified by --cwd) and prints a table with each agent's name, schema version, and description. Use this to discover which agents are configured before running one with 'agent run'. |
agent info |
Display agent definition details for a given agent name or path. Loads the .agent.json file, parses it, and prints every configured field: name, version, description, model, budget limits, sandbox policy, tool schemas, MCP server config, and stream options. Use this to inspect an agent's full configuration before invoking it. |
agent validate |
Validate an agent definition by loading and checking its .agent.json file for structural and semantic correctness. Verifies that budget values are non-negative, the prompt template is non-empty, tool schemas are well-formed, and required fields are present. Reports specific errors on failure or prints a success confirmation. |
Configuration
| Field | Type | Default | Description |
|---|---|---|---|
model |
str |
Claude model identifier (e.g. "claude-sonnet-4-20250514") | |
profile |
str |
Claude Code profile name (e.g. "work", "personal") | |
cwd |
`str | None` | None |
binary |
`str | None` | None |
sandbox |
`Sandbox | None` | None |
permission_mode |
`str | None` | None |
supported_dialog_kinds |
`list[str] | None` | None |
intercept_permissions |
bool |
False |
Route permission prompts (and interactive tools like AskUserQuestion) to the consumer as PermissionRequest events. When True, forces --permission-prompt-tool stdio and always sends the initialize handshake so the CLI delivers can_use_tool control_requests. |
system_prompt |
`str | None` | None |
tools |
`list[Tool] | None` | None |
extra_args |
`list[str] | None` | None |
env |
`dict[str, str] | None` | None |
resume_session_id |
`str | None` | None |
session_resolution |
`SessionResolution | None` | None |
debug |
`DebugOptions | None` | None |
mcp |
`McpOptions | None` | None |
plugins |
`PluginOptions | None` | None |
stream |
`StreamOptions | None` | None |
process_limits |
`ProcessLimits | None` | None |
budget |
`Budget | None` | None |
poll_timeout |
float |
1.0 |
Seconds between event queue polls in SyncSession |
join_timeout |
float |
5.0 |
Seconds to wait for the background thread on SyncSession close |
effort |
`str | None` | None |
json_schema |
`dict | None` | None |
fallback_model |
`str | None` | None |
betas |
`list[str] | None` | None |
add_dirs |
`list[str] | None` | None |
builtin_tools |
`list[str] | None` | None |
brief |
bool |
False |
Produce shorter, more concise model responses |
settings |
`str | None` | None |
setting_sources |
`str | None` | None |
file_specs |
`list[str] | None` | None |
cost_log_path |
`str | None` | None |
agent_name |
`str | None` | None |
agents_json |
`str | None` | None |
hooks |
`dict | None` | None |
no_persistence |
bool |
False |
Disable session persistence so nothing is saved to disk |
from_pr |
`str | None` | None |
tool_context |
Any |
None |
Object injected into tool handlers via the inject mechanism |
Sandbox fields
| Field | Type | Default | Description |
|---|---|---|---|
tools |
`list[str] | None` | None |
bare |
bool |
False |
Suppress CLAUDE.md loading (passes --bare) |
write_paths |
`list[str] | None` | None |
log_violations |
bool |
False |
Log denied tool calls at WARNING level |
skip_permissions |
bool |
False |
Bypass all permission prompts (passes --dangerously-skip-permissions) |
Dependencies
| Package | Version Constraint |
|---|---|
strictcli |
>=0.41.0 |
msgspec |
* |
selfdoc |
* |
claudewheel |
* |
strictspec |
>=0.2.1 |
Modules
- claudestream (
claudestream/__init__.py): A Python library and CLI for streaming Claude Code's JSON protocol, providing typed events, async/sync sessions, and tool registration. - claudestream._agent (
claudestream/_agent.py): Agent definition loader and budget enforcement for Claude Code sessions, with sync and async context managers for invoking agents. - claudestream._agent_schema (
claudestream/_agent_schema.py) - claudestream._async_session (
claudestream/_async_session.py): Async session manager for the Claude Code stream-json protocol, handling process lifecycle, event parsing, and permission callbacks. - claudestream._cli (
claudestream/_cli.py): Command-line interface entry point for claudestream, providing send, listen, and agent commands for interacting with Claude Code. - claudestream._color (
claudestream/_color.py): ANSI color output support with automatic TTY detection, NO_COLOR environment variable compliance, and a reusable Colorizer class. - claudestream._options (
claudestream/_options.py): Option structs for configuring claudestream sessions, covering session resolution, debug, MCP, plugins, stream output, process limits, budget, tool schema, and the unified SessionConfig. - claudestream._process (
claudestream/_process.py): Subprocess management for launching and monitoring the Claude Code CLI process, including graceful shutdown and atexit cleanup. - claudestream._protocol (
claudestream/_protocol.py): NDJSON protocol layer that reads raw Claude Code stream-json output lines and decodes them into typed Event objects for consumption. - claudestream._sync_session (
claudestream/_sync_session.py): Synchronous session wrapper that bridges the async Claude Code stream-json protocol to a blocking iterator-based interface. - claudestream._tools (
claudestream/_tools.py): Tool registration API providing the Tool struct and a decorator for defining user tools that are served via MCP to Claude Code. - claudestream.events (
claudestream/events.py): Typed event dataclasses for every Claude Code stream output event, including assistant messages, tool use, permissions, and results. - claudestream.messages (
claudestream/messages.py): Typed message structs for all Claude Code stream input messages, including user prompts, tool results, and permission responses. - claudestream.policy (
claudestream/policy.py): Sandbox and permission policy types for Claude Code sessions, defining allow, deny, and approval rules for tool execution requests.
Project layout
claudestream/
├── __init__.py
├── _agent.py
├── _agent_schema.py
├── _async_session.py
├── _cli.py
├── _color.py
├── _options.py
├── _process.py
├── _protocol.py
├── _sync_session.py
├── _tools.py
├── events.py
├── messages.py
└── policy.py
License
MIT
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 claudestream-0.15.2.tar.gz.
File metadata
- Download URL: claudestream-0.15.2.tar.gz
- Upload date:
- Size: 317.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ec7d641520abbd869be0d34d3c261b0c12450816549bc2f16960329181d8b2a2
|
|
| MD5 |
6eb04f4cb9a6f4b1ef3efe237f3536c0
|
|
| BLAKE2b-256 |
6fe91ad50c216f7906c832f666316e74c30805d3bb05580822a9573c20c36019
|
Provenance
The following attestation bundles were made for claudestream-0.15.2.tar.gz:
Publisher:
publish.yml on smm-h/claudestream
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
claudestream-0.15.2.tar.gz -
Subject digest:
ec7d641520abbd869be0d34d3c261b0c12450816549bc2f16960329181d8b2a2 - Sigstore transparency entry: 2833427070
- Sigstore integration time:
-
Permalink:
smm-h/claudestream@9624ff0776a4c040721eae3796b6c55e22a87d18 -
Branch / Tag:
refs/tags/v0.15.2 - Owner: https://github.com/smm-h
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@9624ff0776a4c040721eae3796b6c55e22a87d18 -
Trigger Event:
release
-
Statement type:
File details
Details for the file claudestream-0.15.2-py3-none-any.whl.
File metadata
- Download URL: claudestream-0.15.2-py3-none-any.whl
- Upload date:
- Size: 64.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
78b063aebd53da6cb5d2c02a8fdd976b53e160264476c561808b0003dbe50c5f
|
|
| MD5 |
dc8a9cf7e22271bce0dbca707dc5efe7
|
|
| BLAKE2b-256 |
cecabfecaf31494f7b771321ef25b19ae7596b16fd42990c7b60fddb69436127
|
Provenance
The following attestation bundles were made for claudestream-0.15.2-py3-none-any.whl:
Publisher:
publish.yml on smm-h/claudestream
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
claudestream-0.15.2-py3-none-any.whl -
Subject digest:
78b063aebd53da6cb5d2c02a8fdd976b53e160264476c561808b0003dbe50c5f - Sigstore transparency entry: 2833427082
- Sigstore integration time:
-
Permalink:
smm-h/claudestream@9624ff0776a4c040721eae3796b6c55e22a87d18 -
Branch / Tag:
refs/tags/v0.15.2 - Owner: https://github.com/smm-h
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@9624ff0776a4c040721eae3796b6c55e22a87d18 -
Trigger Event:
release
-
Statement type: