Metadata-Version: 2.5
Name: claudestream
Version: 0.15.2
Summary: 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
Project-URL: Homepage, https://smmh.dev/claudestream/
Project-URL: Documentation, https://smmh.dev/claudestream/
Project-URL: Repository, https://github.com/smm-h/claudestream
Project-URL: Issues, https://github.com/smm-h/claudestream/issues
Project-URL: Changelog, https://github.com/smm-h/claudestream/blob/main/CHANGELOG.md
Author-email: SMM-H <lisa.codi@veliu.com>
License-Expression: MIT
License-File: LICENSE
Keywords: agent,claude,claude-code,cli,ndjson,rlsbl,stream-json,streaming
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Requires-Python: >=3.11
Requires-Dist: claudewheel
Requires-Dist: msgspec
Requires-Dist: selfdoc
Requires-Dist: strictcli>=0.41.0
Requires-Dist: strictspec>=0.2.1
Description-Content-Type: text/markdown

<!-- Auto-generated by selfdoc from docs/_README.md — do not edit -->

# 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

```python
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

```python
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

```python
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

```python
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.

```python
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.

```python
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.

```python
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` | Working directory for the Claude Code process; None uses current dir |
| `binary` | `str | None` | `None` | Path to the Claude CLI binary; None uses PATH lookup |
| `sandbox` | `Sandbox | None` | `None` | Tool/filesystem sandbox policy; None means no restrictions |
| `permission_mode` | `str | None` | `None` | Initial permission mode (e.g. "default", "plan", "acceptEdits"); passed unvalidated to --permission-mode |
| `supported_dialog_kinds` | `list[str] | None` | `None` | Dialog kinds the consumer can render; when set, the initialize handshake is always sent and declares supportedDialogKinds |
| `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` | Custom system prompt to prepend to the session |
| `tools` | `list[Tool] | None` | `None` | User-defined tools served via MCP to Claude Code |
| `extra_args` | `list[str] | None` | `None` | Additional raw CLI arguments passed to the process |
| `env` | `dict[str, str] | None` | `None` | Extra environment variables for the subprocess |
| `resume_session_id` | `str | None` | `None` | Session ID to resume; None starts a new session |
| `session_resolution` | `SessionResolution | None` | `None` | Session lookup/resume/fork strategy |
| `debug` | `DebugOptions | None` | `None` | Debug output configuration |
| `mcp` | `McpOptions | None` | `None` | External MCP server configuration |
| `plugins` | `PluginOptions | None` | `None` | Plugin loading paths and URLs |
| `stream` | `StreamOptions | None` | `None` | Controls which events appear in the output stream |
| `process_limits` | `ProcessLimits | None` | `None` | Subprocess buffer/timeout tuning |
| `budget` | `Budget | None` | `None` | Cost, turn, and token limits for the session |
| `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` | Model reasoning effort level (e.g. "low", "medium", "high") |
| `json_schema` | `dict | None` | `None` | JSON Schema to constrain model output format |
| `fallback_model` | `str | None` | `None` | Model to fall back to if the primary model is unavailable |
| `betas` | `list[str] | None` | `None` | Beta feature flags to enable in the session |
| `add_dirs` | `list[str] | None` | `None` | Additional directories to include in the session context |
| `builtin_tools` | `list[str] | None` | `None` | Built-in tool names to enable (e.g. "computer") |
| `brief` | `bool` | `False` | Produce shorter, more concise model responses |
| `settings` | `str | None` | `None` | Path to a custom settings file |
| `setting_sources` | `str | None` | `None` | Comma-separated setting source override |
| `file_specs` | `list[str] | None` | `None` | Files to attach to the session context |
| `cost_log_path` | `str | None` | `None` | Path to JSONL file for per-turn cost logging; None disables logging |
| `agent_name` | `str | None` | `None` | Built-in agent name to activate in Claude Code |
| `agents_json` | `str | None` | `None` | Path to a custom agents JSON configuration file |
| `hooks` | `dict | None` | `None` | Hook definitions for lifecycle events (e.g. pre-tool-use) |
| `no_persistence` | `bool` | `False` | Disable session persistence so nothing is saved to disk |
| `from_pr` | `str | None` | `None` | GitHub PR identifier to load as session context |
| `tool_context` | `Any` | `None` | Object injected into tool handlers via the inject mechanism |

## Sandbox fields

| Field | Type | Default | Description |
| --- | --- | --- | --- |
| `tools` | `list[str] | None` | `None` | Tool allow-list; None means all tools allowed |
| `bare` | `bool` | `False` | Suppress CLAUDE.md loading (passes --bare) |
| `write_paths` | `list[str] | None` | `None` | Allowed paths for Write/Edit/MultiEdit; None means unrestricted |
| `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
