Commit graph

112 commits

Author SHA1 Message Date
Ashwin Bhat
d7c3368533
docs: mark package as deprecated in favor of claude-agent-sdk
🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-29 13:13:40 -07:00
github-actions[bot]
e8832f115a
chore: bump version to 0.0.23 (#172)
This PR updates the version to 0.0.23 after publishing to PyPI.

## Changes
- Updated version in `pyproject.toml`
- Updated version in `src/claude_code_sdk/__init__.py`

## Release Information
- Published to PyPI: https://pypi.org/project/claude-code-sdk/0.0.23/
- Install with: `pip install claude-code-sdk==0.0.23`

🤖 Generated by GitHub Actions

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-09-17 19:46:18 -07:00
Dickson Tsai
f550c21a7e
Add support for streaming partial messages via include_partial_messages option (#168)
Some checks are pending
Lint / lint (push) Waiting to run
Test / test (3.10) (push) Waiting to run
Test / test (3.11) (push) Waiting to run
Test / test-e2e (3.13) (push) Blocked by required conditions
Test / test-examples (3.11) (push) Blocked by required conditions
Test / test-examples (3.12) (push) Blocked by required conditions
Test / test-examples (3.13) (push) Blocked by required conditions
Test / test (3.12) (push) Waiting to run
Test / test (3.13) (push) Waiting to run
Test / test-e2e (3.10) (push) Blocked by required conditions
Test / test-e2e (3.11) (push) Blocked by required conditions
Test / test-e2e (3.12) (push) Blocked by required conditions
Test / test-examples (3.10) (push) Blocked by required conditions
## Summary
- Adds support for streaming partial messages through the
`include_partial_messages` option
- Introduces `StreamEvent` message type to handle Anthropic API stream
events
- Enables real-time streaming of Claude's responses for building
interactive UIs

## Changes
- Added `StreamEvent` dataclass with proper structure matching
TypeScript SDK (uuid, session_id, event, parent_tool_use_id)
- Added `include_partial_messages` boolean option to `ClaudeCodeOptions`
- Updated message parser to handle `stream_event` message type
- Updated subprocess CLI transport to pass `--include-partial-messages`
flag when enabled
- Added example demonstrating partial message streaming usage

## Test plan
- [x] Verified CLI flag is passed correctly when
`include_partial_messages=True`
- [x] Confirmed `StreamEvent` structure matches TypeScript SDK
implementation
- [x] Added test for user parameter in transport
- [x] Example runs successfully with streaming events

🤖 Generated with [Claude Code](https://claude.ai/code)

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-09-17 16:32:21 -07:00
Dan Siwiec
607921dcb0
feat: expose parent_tool_use_id to support subagent tracking #138 (#166) 2025-09-17 14:47:09 -07:00
Dan Siwiec
fd98d12f94
feat: allow claude code process to run as a custom user (#133) (#134)
Some checks are pending
Lint / lint (push) Waiting to run
Test / test-e2e (3.12) (push) Blocked by required conditions
Test / test-e2e (3.13) (push) Blocked by required conditions
Test / test (3.10) (push) Waiting to run
Test / test (3.11) (push) Waiting to run
Test / test (3.12) (push) Waiting to run
Test / test (3.13) (push) Waiting to run
Test / test-e2e (3.10) (push) Blocked by required conditions
Test / test-e2e (3.11) (push) Blocked by required conditions
Test / test-examples (3.10) (push) Blocked by required conditions
Test / test-examples (3.11) (push) Blocked by required conditions
Test / test-examples (3.12) (push) Blocked by required conditions
Test / test-examples (3.13) (push) Blocked by required conditions
2025-09-16 16:40:19 -07:00
github-actions[bot]
3010aaf092
chore: bump version to 0.0.22 (#163)
Some checks failed
Lint / lint (push) Has been cancelled
Test / test (3.10) (push) Has been cancelled
Test / test (3.11) (push) Has been cancelled
Test / test (3.12) (push) Has been cancelled
Test / test (3.13) (push) Has been cancelled
Test / test-e2e (3.10) (push) Has been cancelled
Test / test-e2e (3.11) (push) Has been cancelled
Test / test-e2e (3.12) (push) Has been cancelled
Test / test-examples (3.12) (push) Has been cancelled
Test / test-examples (3.13) (push) Has been cancelled
Test / test-e2e (3.13) (push) Has been cancelled
Test / test-examples (3.10) (push) Has been cancelled
Test / test-examples (3.11) (push) Has been cancelled
This PR updates the version to 0.0.22 after publishing to PyPI.

## Changes
- Updated version in `pyproject.toml`
- Updated version in `src/claude_code_sdk/__init__.py`

## Release Information
- Published to PyPI: https://pypi.org/project/claude-code-sdk/0.0.22/
- Install with: `pip install claude-code-sdk==0.0.22`

🤖 Generated by GitHub Actions

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-09-12 08:27:47 -07:00
Dickson Tsai
db6f167280
Update changelog, readme, and examples for custom tools and hooks (#162) 2025-09-12 08:14:34 -07:00
Michael Gendy
0aab45be7d
Remove max thinking tokens (#144)
Some checks are pending
Lint / lint (push) Waiting to run
Test / test-e2e (3.12) (push) Blocked by required conditions
Test / test (3.10) (push) Waiting to run
Test / test (3.11) (push) Waiting to run
Test / test (3.12) (push) Waiting to run
Test / test (3.13) (push) Waiting to run
Test / test-e2e (3.10) (push) Blocked by required conditions
Test / test-e2e (3.11) (push) Blocked by required conditions
Test / test-e2e (3.13) (push) Blocked by required conditions
Test / test-examples (3.10) (push) Blocked by required conditions
Test / test-examples (3.11) (push) Blocked by required conditions
Test / test-examples (3.12) (push) Blocked by required conditions
Test / test-examples (3.13) (push) Blocked by required conditions
It's not used anywhere and it can be set through the env parameter

`ClaudeCodeOptions(env={"MAX_THINKING_TOKENS" : 8000})`
2025-09-12 02:22:01 -07:00
Dickson Tsai
4ea71cfb97
Hooks: Clean up types and implement example (#153)
Some checks failed
Test / test (3.13) (push) Has been cancelled
Test / test (3.12) (push) Has been cancelled
Lint / lint (push) Has been cancelled
Test / test (3.10) (push) Has been cancelled
Test / test (3.11) (push) Has been cancelled
Test / test-e2e (3.10) (push) Has been cancelled
Test / test-e2e (3.11) (push) Has been cancelled
Test / test-e2e (3.12) (push) Has been cancelled
Test / test-e2e (3.13) (push) Has been cancelled
Test / test-examples (3.10) (push) Has been cancelled
Test / test-examples (3.11) (push) Has been cancelled
Test / test-examples (3.12) (push) Has been cancelled
Test / test-examples (3.13) (push) Has been cancelled
2025-09-08 13:45:21 -07:00
Ashwin Bhat
839300404f
Add custom tool callbacks and e2e tests (#157)
## Summary
This PR adds support for custom tool callbacks and comprehensive e2e
testing for MCP calculator functionality.

## Key Features Added
- **Custom tool permission callbacks** - Allow dynamic tool permission
control via `can_use_tool` callback
- **E2E test suite** - Real Claude API tests validating MCP tool
execution end-to-end
- **Fixed MCP calculator example** - Now properly uses `allowed_tools`
for permission management

## Changes
### Custom Callbacks
- Added `ToolPermissionContext` and `PermissionResult` types for tool
permission handling
- Implemented `can_use_tool` callback support in SDK client
- Added comprehensive tests in `tests/test_tool_callbacks.py`

### E2E Testing Infrastructure  
- Created `e2e-tests/` directory with pytest-based test suite
- `test_mcp_calculator.py` - Tests all calculator operations with real
API calls
- `conftest.py` - Pytest config with mandatory API key validation
- GitHub Actions workflow for automated e2e testing on main branch
- Comprehensive documentation in `e2e-tests/README.md`

### Bug Fixes
- Fixed MCP calculator example to use `allowed_tools` instead of
incorrect `permission_mode`
- Resolved tool permission issues preventing MCP tools from executing

## Testing
E2E tests require `ANTHROPIC_API_KEY` environment variable and will fail
without it.

Run locally:
```bash
export ANTHROPIC_API_KEY=your-key
python -m pytest e2e-tests/ -v -m e2e
```

Run unit tests including callback tests:
```bash
python -m pytest tests/test_tool_callbacks.py -v
```

🤖 Generated with [Claude Code](https://claude.ai/code)

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Kashyap Murali <kashyap@anthropic.com>
2025-09-08 08:51:40 -07:00
Ashwin Bhat
d3190f12d3
Add PostToolUse hook for automatic ruff formatting (#158)
Configure automatic formatting via ruff check --fix and ruff format
after Edit/Write/MultiEdit operations

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-authored-by: Claude <noreply@anthropic.com>
2025-09-08 07:06:46 -07:00
Ashwin Bhat
9377faa943
Standardize GitHub workflow triggers (#155)
Some checks failed
Lint / lint (push) Waiting to run
Test / test (3.10) (push) Waiting to run
Test / test (3.11) (push) Waiting to run
Test / test (3.12) (push) Waiting to run
Test / test (3.13) (push) Waiting to run
Claude Code E2E Test / integration-test (3.10) (push) Has been cancelled
Claude Code E2E Test / integration-test (3.11) (push) Has been cancelled
Claude Code E2E Test / integration-test (3.12) (push) Has been cancelled
Claude Code E2E Test / integration-test (3.13) (push) Has been cancelled
## Summary
- Standardized the trigger configuration across test, lint, and e2e
workflows
- All workflows now use consistent format with pull_request listed
before push
- E2E workflow now also runs on pushes to main branch

## Test plan
- [ ] Verify workflows trigger correctly on pull requests
- [ ] Verify workflows trigger correctly on pushes to main branch
- [ ] Check that e2e tests run successfully on main branch

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-authored-by: Claude <noreply@anthropic.com>
2025-09-07 18:31:38 -07:00
Ashwin Bhat
73f861235e
Add CI workflow for Claude Code SDK e2e testing (#154)
Some checks are pending
Lint / lint (push) Waiting to run
Test / test (3.10) (push) Waiting to run
Test / test (3.11) (push) Waiting to run
Test / test (3.12) (push) Waiting to run
Test / test (3.13) (push) Waiting to run
## Summary
- Added GitHub Actions workflow to test SDK integration with Claude Code
CLI
- Tests run on PR open/synchronize events across Python 3.10-3.13

## Test plan
- [x] Workflow triggers on PR events
- [x] Installs Claude Code CLI via official script
- [x] Runs quickstart example
- [x] Runs streaming_mode example

🤖 Generated with [Claude Code](https://claude.ai/code)

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-09-06 22:41:53 -07:00
github-actions[bot]
ff4fe897a5
chore: bump version to 0.0.21 (#152)
Some checks failed
Lint / lint (push) Has been cancelled
Test / test (3.10) (push) Has been cancelled
Test / test (3.11) (push) Has been cancelled
Test / test (3.12) (push) Has been cancelled
Test / test (3.13) (push) Has been cancelled
This PR updates the version to 0.0.21 after publishing to PyPI.

## Changes
- Updated version in `pyproject.toml`
- Updated version in `src/claude_code_sdk/__init__.py`

## Release Information
- Published to PyPI: https://pypi.org/project/claude-code-sdk/0.0.21/
- Install with: `pip install claude-code-sdk==0.0.21`

🤖 Generated by GitHub Actions

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-09-05 13:40:30 -07:00
Ashwin Bhat
e4feaf2e57
Remove unstable public APIs from SDK (#151)
Some checks are pending
Lint / lint (push) Waiting to run
Test / test (3.10) (push) Waiting to run
Test / test (3.11) (push) Waiting to run
Test / test (3.12) (push) Waiting to run
Test / test (3.13) (push) Waiting to run
Hide hooks, tool permission callbacks, and SDK MCP server APIs from
public interface while keeping implementation code intact. These
features are not yet stable and should not be documented or exposed to
users.

Changes:
- Remove hook-related exports (HookCallback, HookContext, HookMatcher)
from __all__
- Remove tool permission exports (CanUseTool, ToolPermissionContext)
from __all__
- Remove SDK MCP exports (tool, create_sdk_mcp_server, SdkMcpTool) from
__all__
- Delete examples using unstable APIs (tool_permission_callback.py,
mcp_calculator.py)
- Remove SDK MCP server documentation from README

🤖 Generated with [Claude Code](https://claude.ai/code)

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-09-05 11:48:12 -07:00
Ashwin Bhat
99d13717d5
feat: Enable real-time debug output via debug-to-stderr flag (#150)
- Add conditional stderr routing in subprocess transport
- When debug-to-stderr flag is set, Claude CLI debug output goes
directly to Python's stderr
- Keeps stdout clean for JSON message parsing while providing debug
visibility
- Simplifies implementation by removing temp file and background task
complexity
- Update examples to demonstrate debug-to-stderr usage

🤖 Generated with [Claude Code](https://claude.ai/code)

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-09-05 10:24:24 -07:00
Dickson Tsai
2c8c7fd373
Address anyio.BrokenResourceError issue from #139 (#149)
Some checks are pending
Lint / lint (push) Waiting to run
Test / test (3.10) (push) Waiting to run
Test / test (3.11) (push) Waiting to run
Test / test (3.12) (push) Waiting to run
Test / test (3.13) (push) Waiting to run
## Summary

This PR addresses the `anyio.BrokenResourceError` issue from #139 and
aligns the Python SDK's error handling with the TypeScript SDK
implementation.

## Changes

### Fix stream closure issue in Query
- Removed the `async with` context manager from
`Query.receive_messages()` that was closing the stream after first use
- The stream now remains open for the entire session, allowing multiple
queries in streaming mode
- This fixes the `BrokenResourceError` that occurred during multi-turn
conversations

### Align subprocess transport with TypeScript SDK
Following the TypeScript `ProcessTransport` implementation pattern:

- **Added `_exit_error` tracking**: Captures and preserves process-level
errors for better error propagation
- **Enhanced `write()` method checks**: 
  - Validates transport readiness before writing
  - Checks if process is still alive (exit code)
  - Checks for stored exit errors before attempting writes
  - Marks transport as not ready on write failures
- **Improved error handling in `connect()`**: Stores errors as
`_exit_error` for later reference
- **Simplified `is_ready()` method**: Now just returns the `_ready`
flag, matching TypeScript's simpler approach

### Other improvements
- Added asyncio pytest plugin configuration (`-p asyncio` in
pyproject.toml)
- Added clarifying comment about TextReceiveStream line handling

## Testing

The multi-turn conversation example now works correctly:
```bash
python examples/streaming_mode.py multi_turn_conversation
```

## Related Issues

Fixes #139
2025-09-05 13:11:27 +09:00
Ashwin Bhat
681f46c873
fix: Convert camelCase to snake_case for Python naming conventions (#146)
Some checks are pending
Lint / lint (push) Waiting to run
Test / test (3.10) (push) Waiting to run
Test / test (3.11) (push) Waiting to run
Test / test (3.12) (push) Waiting to run
Test / test (3.13) (push) Waiting to run
- Renamed PermissionRuleValue fields: toolName → tool_name, ruleContent
→ rule_content
- Renamed PermissionResultAllow fields: updatedInput → updated_input,
updatedPermissions → updated_permissions
- Removed unused PermissionResult import from query.py
- Fixed trailing whitespace issues in types.py
- Updated all usages in examples and tests to use snake_case

These changes ensure compliance with Python's PEP 8 naming conventions
and fix linting errors.

🤖 Generated with [Claude Code](https://claude.ai/code)

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-09-04 19:26:00 -07:00
kashyap murali
68f0d7aa7d
feat: Add tool permission and hook callbacks support (#143)
Some checks failed
Lint / lint (push) Has been cancelled
Test / test (3.10) (push) Has been cancelled
Test / test (3.11) (push) Has been cancelled
Test / test (3.12) (push) Has been cancelled
Test / test (3.13) (push) Has been cancelled
## Summary

Adds comprehensive support for tool permission callbacks and hook
callbacks to the Python SDK, enabling fine-grained control over tool
execution and custom event handling.

## Key Changes

- **Tool Permission Callbacks**: Control which tools Claude can use and
modify their inputs
  -  type with async support
  -  with suggestions from CLI
  -  for structured responses
  
- **Hook Callbacks**: React to events in the Claude workflow
  -  type for event handlers
  -  for conditional hook execution
  - Support for tool_use_start, tool_use_end events
  
- **Integration**: Full plumbing through ClaudeCodeOptions → Client →
Query
- **Examples**: Comprehensive example showing permission control
patterns
- **Tests**: Coverage for all callback scenarios

## Implementation Details

- Callbacks are registered during initialization phase
- Control protocol handles can_use_tool and hook_callback requests
- Backwards compatible with dict returns for tool permissions
- Proper error handling and type safety throughout

Builds on top of #139's control protocol implementation.

---------

Co-authored-by: Dickson Tsai <dickson@anthropic.com>
2025-09-03 10:16:11 -07:00
kashyap murali
9ef57859af
feat: Add in-process SDK MCP server support (#142)
## Summary

Adds in-process SDK MCP server support to the Python SDK, building on
the control protocol from #139.

**Note: Targets `dickson/control` branch (PR #139), not `main`.**

## Key Changes

- Added `@tool` decorator and `create_sdk_mcp_server()` API for defining
in-process MCP servers
- SDK MCP servers run directly in the Python process (no subprocess
overhead)
- Moved SDK MCP handling from Transport to Query class for proper
architectural layering
- Added `McpSdkServerConfig` type and integrated with control protocol

## Example

```python
from claude_code_sdk import tool, create_sdk_mcp_server

@tool("greet", "Greet a user", {"name": str})
async def greet_user(args):
    return {"content": [{"type": "text", "text": f"Hello, {args['name']}!"}]}

server = create_sdk_mcp_server(name="my-tools", tools=[greet_user])

options = ClaudeCodeOptions(mcp_servers={"tools": server})
```

## Testing

- Added integration tests in `test_sdk_mcp_integration.py`
- Added example calculator server in `examples/mcp_calculator.py`

---------

Co-authored-by: Dickson Tsai <dickson@anthropic.com>
Co-authored-by: Ashwin Bhat <ashwin@anthropic.com>
Co-authored-by: Claude <noreply@anthropic.com>
2025-09-03 08:29:32 -07:00
Dickson Tsai
22fa9f473e
Implement control protocol support for Python SDK (#139)
Some checks failed
Lint / lint (push) Has been cancelled
Test / test (3.10) (push) Has been cancelled
Test / test (3.11) (push) Has been cancelled
Test / test (3.12) (push) Has been cancelled
Test / test (3.13) (push) Has been cancelled
## Summary

This PR implements control protocol support in the Python SDK, aligning
it with the TypeScript implementation pattern. The refactor introduces a
Query + Transport separation to enable bidirectional communication
between the SDK and CLI.

## Motivation

The previous Python SDK implementation used a high-level abstraction in
the Transport ABC (`send_request`/`receive_messages`) that couldn't
handle bidirectional communication. This prevented support for:
- Control messages from CLI to SDK that need responses
- Hooks implementation  
- Dynamic permission mode changes
- SDK MCP servers

## Changes

### Core Architecture Refactor

1. **New Query Class** (`src/claude_code_sdk/_internal/query.py`)
   - Manages control protocol on top of Transport
   - Handles control request/response routing
   - Manages initialization handshake with timeout
   - Supports hook callbacks and tool permission callbacks
   - Implements message streaming

2. **Refactored Transport ABC**
(`src/claude_code_sdk/_internal/transport/__init__.py`)
- Changed from high-level (`send_request`/`receive_messages`) to
low-level (`write`/`read_messages`) interface
   - Now handles raw I/O instead of protocol logic
   - Aligns with TypeScript ProcessTransport pattern

3. **Updated SubprocessCLITransport**
(`src/claude_code_sdk/_internal/transport/subprocess_cli.py`)
   - Simplified to focus on raw message streaming
   - Removed protocol logic (moved to Query)
   - Improved cleanup and error handling

4. **Enhanced ClaudeSDKClient** (`src/claude_code_sdk/client.py`)
   - Now uses Query for control protocol
   - Supports initialization messages
   - Better error handling for control protocol failures

### Control Protocol Features

- **Initialization handshake**: SDK sends initialize request, CLI
responds with supported commands
- **Control message types**: 
  - `initialize`: Establish bidirectional connection
  - `interrupt`: Cancel ongoing operations  
  - `set_permission_mode`: Change permission mode dynamically
- **Timeout handling**: 60-second timeout for initialization to handle
CLI versions without control support

### Examples

Updated `examples/streaming_mode.py` to demonstrate control protocol
initialization and error handling.

## Testing

- Tested with current CLI (no control protocol support yet) - gracefully
falls back
- Verified backward compatibility with existing `query()` function
- Tested initialization timeout handling
- Verified proper cleanup on errors

## Design Alignment

This implementation closely follows the TypeScript reference:
- `src/core/Query.ts` → `src/claude_code_sdk/_internal/query.py`
- `src/transport/ProcessTransport.ts` →
`src/claude_code_sdk/_internal/transport/subprocess_cli.py`
- `src/entrypoints/sdk.ts` → `src/claude_code_sdk/client.py`

## Next Steps

Once the CLI implements the control protocol handler, this will enable:
- Hooks support
- Dynamic permission mode changes
- SDK MCP servers
- Improved error recovery

🤖 Generated with [Claude Code](https://claude.ai/code)

---------

Co-authored-by: Ashwin Bhat <ashwin@anthropic.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Kashyap Murali <kashyap@anthropic.com>
2025-09-01 23:04:22 -07:00
Anudeep Yegireddi
9a64bc3a64
fix: propagate user cwd to subprocess environment (#136)
Some checks failed
Lint / lint (push) Has been cancelled
Test / test (3.10) (push) Has been cancelled
Test / test (3.11) (push) Has been cancelled
Test / test (3.12) (push) Has been cancelled
Test / test (3.13) (push) Has been cancelled
The subprocess transport was ignoring user-specified cwd from
ClaudeCodeOptions, causing the working directory preference to be
overridden by os.environ. This fix ensures the CWD environment variable
is properly passed to child processes.

- Add PWD env var when self._cwd is set in SubprocessCLITransport
- Fixes issue where custom working directory was not respected
- Maintains backward compatibility

Tests: All existing tests pass
2025-08-29 22:36:52 -07:00
8519mark
ea7e86714f
add end of command options to sanitize user prompt (#130)
The PR should address the issue where user prompt maybe treated as a
option with leading `-`
Assuming `claude` does follow POSIX standard, the `--` option should
solve the issue.

fixes #129
2025-08-29 18:09:01 -07:00
Abhijeeth Padarthi
a801a33086
simplify example with interrupt (#127)
This PR simplifies the example with interrupt. 
There is a flag interrupt_sent that isn't required since the execution
loop will terminate after interrupt with the following message:
`{"content": [{"type": "text", "text": "[Request interrupted by
user]"}]}`
2025-08-29 18:08:13 -07:00
Suzanne Wang
f794e17e78
Add support for custom env vars (#131)
Some checks failed
Lint / lint (push) Has been cancelled
Test / test (3.10) (push) Has been cancelled
Test / test (3.11) (push) Has been cancelled
Test / test (3.12) (push) Has been cancelled
Test / test (3.13) (push) Has been cancelled
## Key changes
- Adds env field to `ClaudeCodeOptions`, allowing custom env vars to cli
- Updates tests and examples

## Motivation
Bringing Python SDK to feature parity with TS SDK, which supports custom
env vars

## Notes
- Environment variables are merged in order: system env → user env → SDK
required vars
- This implementation seems slightly more robust than the TypeScript
version, which can exclude OS envs vars if a user passes a minimal env
object
- Some linting changes seem to have been picked up
2025-08-25 14:02:03 -07:00
Michael Gendy
30df222bfc
Move thinking block parsing from user to assistant messages (#119)
Some checks failed
Lint / lint (push) Has been cancelled
Test / test (3.10) (push) Has been cancelled
Test / test (3.11) (push) Has been cancelled
Test / test (3.12) (push) Has been cancelled
Test / test (3.13) (push) Has been cancelled
Related to https://github.com/anthropics/claude-code-sdk-python/pull/28
cc @dicksontsai
2025-08-19 13:36:12 -07:00
Rushil Patel
bc01cd7e9a
feat: enable custom transports (#91)
## Summary

This PR exposes the `Transport` interface in the public API, enabling
users to pass custom transport implementations to the `query()`
function. Previously, transport selection was internal and users had no
way to provide custom implementations.

**Primary Benefits:**
- 🔌 **Remote claude code** - Connect to Claude Code CLIs running
remotely
- The concrete use case here is to be able to implement a custom
transport that can communicate to claude code instances running in
remote sandboxes. Currently the the sdk only works with Claude Codes
running in a local subprocess limiting the scenarios in which this SDK
can be used.

## Changes

### Public API Changes
- **Exposed the previously internal `Transport` abstract base class** in
`claude_code_sdk.__init__.py`
- **Added `transport` parameter** to `query()` function signature
- **Updated docstring** with transport parameter documentation

### Internal Changes
- **Modified `InternalClient.process_query()`** to accept optional
transport parameter
- **Added transport selection logic** - use provided transport or
default to `SubprocessCLITransport`
- **Updated `__all__` exports** to include `Transport`

### Testing
- **Updated existing tests** to work with new transport parameter
- **Maintained backward compatibility** - all existing code continues to
work unchanged

## Testing

### Existing Tests
-  All existing unit tests pass with new transport parameter
-  Integration tests updated to mock new transport interface
-  Subprocess buffering tests continue to work with exposed transport

### New Functionality Testing
-  Verified custom transport can be passed to `query()`
-  Confirmed default behavior unchanged when no transport provided  
-  Validated transport lifecycle ( connect → receive → disconnect)
-  Tested transport interface compliance with abstract base class

## Example Usage

### Basic Custom Transport
```python
from claude_code_sdk import query, ClaudeCodeOptions, Transport

class MyCustomTransport(Transport):
    # Implement abstract methods: connect, disconnect, 
    # send_request, receive_messages, is_connected
    pass

transport = MyCustomTransport()
async for message in query(
    prompt="Hello",
    transport=transport
):
    print(message)
```

## Related
- #85 

🤖 Generated with [Claude Code](https://claude.ai/code)

---------

Signed-off-by: Rushil Patel <rpatel@codegen.com>
2025-08-19 13:28:42 -07:00
github-actions[bot]
91315e3824
chore: bump version to 0.0.20 (#121)
Some checks failed
Lint / lint (push) Has been cancelled
Test / test (3.10) (push) Has been cancelled
Test / test (3.11) (push) Has been cancelled
Test / test (3.12) (push) Has been cancelled
Test / test (3.13) (push) Has been cancelled
This PR updates the version to 0.0.20 after publishing to PyPI.

## Changes
- Updated version in `pyproject.toml`
- Updated version in `src/claude_code_sdk/__init__.py`

## Release Information
- Published to PyPI: https://pypi.org/project/claude-code-sdk/0.0.20/
- Install with: `pip install claude-code-sdk==0.0.20`

🤖 Generated by GitHub Actions

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-08-14 08:45:28 -07:00
Michael Gendy
b6a5b98604
Add support for plan permission mode (#116)
Some checks failed
Lint / lint (push) Has been cancelled
Test / test (3.10) (push) Has been cancelled
Test / test (3.11) (push) Has been cancelled
Test / test (3.12) (push) Has been cancelled
Test / test (3.13) (push) Has been cancelled
2025-08-07 13:06:05 -07:00
yokomotod
f1e6dda230
fix: add support for thinking content blocks (#28)
Some checks are pending
Lint / lint (push) Waiting to run
Test / test (3.10) (push) Waiting to run
Test / test (3.11) (push) Waiting to run
Test / test (3.12) (push) Waiting to run
Test / test (3.13) (push) Waiting to run
## Summary

Fixes an issue where `thinking` content blocks in Claude Code responses
were not being parsed, resulting in empty `AssistantMessage` content
arrays.

## Changes
- Added `ThinkingBlock` dataclass to handle thinking content with
`thinking` and `signature` fields
- Updated client parsing logic in `_internal/client.py` to recognize and
create `ThinkingBlock` instances
- Added comprehensive test coverage for thinking block functionality

## Before

```python
# Claude Code response with thinking block resulted in:
AssistantMessage(content=[])  # Empty content!
```

## After

```python
# Now correctly parses to:
AssistantMessage(content=[
    ThinkingBlock(thinking="...", signature="...")
])
```

Fixes #27

---------

Co-authored-by: Dickson Tsai <dickson@anthropic.com>
2025-08-06 19:00:02 -07:00
Sam Fu
6bbe00cc15
fix pytest allowed tool (#117) 2025-08-06 16:03:30 -07:00
Sam Fu
58b5a41a15
allow claude gh action to lint, typecheck, and run tests (#115)
Co-authored-by: Ashwin Bhat <ashwin@anthropic.com>
2025-08-06 15:29:34 -07:00
Sam Fu
f233df1852
teach ClaudeCodeOptions.mcp_servers to accept a filepath (#114)
Some checks are pending
Lint / lint (push) Waiting to run
Test / test (3.10) (push) Waiting to run
Test / test (3.11) (push) Waiting to run
Test / test (3.12) (push) Waiting to run
Test / test (3.13) (push) Waiting to run
`claude`'s `--mcp-config` takes either a JSON file or string, so support
this in `ClaudeCodeOptions`
```
  --mcp-config <file or string>    Load MCP servers from a JSON file or string
```

---------

Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
Co-authored-by: Sam Fu <shunfu@users.noreply.github.com>
2025-08-06 14:13:59 -07:00
Dickson Tsai
9fc830028e
Add extra_args field to ClaudeCodeOptions for forward compatibility (#111)
Some checks failed
Lint / lint (push) Has been cancelled
Test / test (3.10) (push) Has been cancelled
Test / test (3.11) (push) Has been cancelled
Test / test (3.12) (push) Has been cancelled
Test / test (3.13) (push) Has been cancelled
## Summary
- Adds `extra_args` field to `ClaudeCodeOptions` to support passing
arbitrary CLI flags
- Enables forward compatibility with future CLI flags without requiring
SDK updates
- Supports both valued flags (`--flag value`) and boolean flags
(`--flag`)

## Changes
- Add `extra_args: dict[str, str | None]` field to `ClaudeCodeOptions`
- Implement logic in `SubprocessCLITransport` to handle extra args:
- `None` values create boolean flags (e.g., `{"verbose": None}` →
`--verbose`)
- String values create flags with arguments (e.g., `{"output": "json"}`
→ `--output json`)
- Add comprehensive tests for the new functionality

## Test plan
- [x] Added unit tests for settings file path handling
- [x] Added unit tests for settings JSON object handling  
- [x] Added unit tests for extra_args with both valued and boolean flags
- [x] All tests pass (`python -m pytest tests/`)
- [x] Type checking passes (`python -m mypy src/`)

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-authored-by: Claude <noreply@anthropic.com>
2025-08-04 22:47:24 -07:00
Sam Fu
8f4b7777b9
remove mcp_tools field from ClaudeCodeOptions (#110)
Some checks are pending
Lint / lint (push) Waiting to run
Test / test (3.10) (push) Waiting to run
Test / test (3.11) (push) Waiting to run
Test / test (3.12) (push) Waiting to run
Test / test (3.13) (push) Waiting to run
the `mcp_tools` field in `ClaudeCodeOptions` seems to have been there
since the initial commit but I couldn't find any references in the repo,
so I believe it may be vestigial and unused
2025-08-04 11:14:01 -07:00
github-actions[bot]
6255850eb2
chore: bump version to 0.0.19 (#105)
Some checks failed
Lint / lint (push) Has been cancelled
Test / test (3.10) (push) Has been cancelled
Test / test (3.11) (push) Has been cancelled
Test / test (3.12) (push) Has been cancelled
Test / test (3.13) (push) Has been cancelled
This PR updates the version to 0.0.19 after publishing to PyPI.

## Changes
- Updated version in `pyproject.toml`
- Updated version in `src/claude_code_sdk/__init__.py`

## Release Information
- Published to PyPI: https://pypi.org/project/claude-code-sdk/0.0.19/
- Install with: `pip install claude-code-sdk==0.0.19`

🤖 Generated by GitHub Actions

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-07-31 22:37:33 -07:00
Dickson Tsai
0cb5efa923
Support --add-dir flag (#104) 2025-07-31 20:52:30 -07:00
Dickson Tsai
fbda510ee4
Fix subprocess deadlock with MCP servers via stderr redirection (#103)
Some checks are pending
Lint / lint (push) Waiting to run
Test / test (3.10) (push) Waiting to run
Test / test (3.11) (push) Waiting to run
Test / test (3.12) (push) Waiting to run
Test / test (3.13) (push) Waiting to run
## Summary

Fixes a critical deadlock issue that occurs when MCP servers produce
verbose stderr output. The SDK would hang indefinitely when the stderr
pipe buffer filled up.

## The Problem

The deadlock occurred due to sequential reading of subprocess streams:
1. SDK reads stdout completely before reading stderr
2. When stderr pipe buffer fills (64KB on Linux, 16KB on macOS),
subprocess blocks on write
3. Subprocess can't continue to stdout, parent waits for stdout →
**DEADLOCK** 🔒

## The Solution  

Redirect stderr to a temporary file instead of a pipe:
- **No pipe buffer** = no possibility of deadlock
- Temp file can grow as needed (no 64KB limit)
- Still capture stderr for error reporting (last 100 lines)
- Works consistently across all async backends

## Implementation Details

- `stderr=tempfile.NamedTemporaryFile()` instead of `stderr=PIPE`
- Use `deque(maxlen=100)` to keep only recent stderr lines in memory
- Temp file is automatically cleaned up on disconnect
- Add `[stderr truncated, showing last 100 lines]` message when buffer
is full

## Testing

- Verified no deadlock with 150+ lines of stderr output
- Confirmed stderr is still captured for error reporting
- All existing tests pass
- Works with asyncio, trio, and other anyio backends

## Impact

- Fixes consistent hangs in production with MCP servers
- No functional regression - stderr handling is preserved
- Simpler than concurrent reading alternatives
- More robust than pipe-based solutions

Fixes the issue reported in Slack where SDK would hang indefinitely when
receiving messages from MCP servers with verbose logging.

🤖 Generated with [Claude Code](https://claude.ai/code)

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-07-31 11:42:20 -07:00
github-actions[bot]
0de87a2a96
chore: bump version to 0.0.18 (#102)
Some checks are pending
Lint / lint (push) Waiting to run
Test / test (3.10) (push) Waiting to run
Test / test (3.11) (push) Waiting to run
Test / test (3.12) (push) Waiting to run
Test / test (3.13) (push) Waiting to run
This PR updates the version to 0.0.18 after publishing to PyPI.

## Changes
- Updated version in `pyproject.toml`
- Updated version in `src/claude_code_sdk/__init__.py`

## Release Information
- Published to PyPI: https://pypi.org/project/claude-code-sdk/0.0.18/
- Install with: `pip install claude-code-sdk==0.0.18`

🤖 Generated by GitHub Actions

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-07-31 11:02:29 -07:00
Dickson Tsai
fa3962de3f
Improve UserMessage types to include ToolResultBlock (#101)
Fixes https://github.com/anthropics/claude-code-sdk-python/issues/90
2025-07-31 07:51:39 -07:00
Dickson Tsai
df94948edc
Add settings option to ClaudeCodeOptions (#100)
Some checks are pending
Lint / lint (push) Waiting to run
Test / test (3.10) (push) Waiting to run
Test / test (3.11) (push) Waiting to run
Test / test (3.12) (push) Waiting to run
Test / test (3.13) (push) Waiting to run
## Summary
- Add `settings` field to `ClaudeCodeOptions` to expose the `--settings`
CLI flag
- Allow SDK users to specify custom settings configuration path

## Changes
- Added `settings: str | None = None` field to `ClaudeCodeOptions`
dataclass
- Added CLI argument conversion logic in `SubprocessCLITransport` to
pass `--settings` flag to Claude Code CLI

## Test plan
- [x] All existing tests pass
- [x] Linting passes (`python -m ruff check`)
- [x] Type checking passes (`python -m mypy src/`)

🤖 Generated with [Claude Code](https://claude.ai/code)

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-07-30 23:59:21 -07:00
github-actions[bot]
472aa23aae
chore: bump version to 0.0.17 (#88)
Some checks failed
Lint / lint (push) Has been cancelled
Test / test (3.10) (push) Has been cancelled
Test / test (3.11) (push) Has been cancelled
Test / test (3.12) (push) Has been cancelled
Test / test (3.13) (push) Has been cancelled
This PR updates the version to 0.0.17 after publishing to PyPI.

## Changes
- Updated version in `pyproject.toml`
- Updated version in `src/claude_code_sdk/__init__.py`

## Release Information
- Published to PyPI: https://pypi.org/project/claude-code-sdk/0.0.17/
- Install with: `pip install claude-code-sdk==0.0.17`

🤖 Generated by GitHub Actions

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-07-23 22:52:20 -07:00
Dickson Tsai
5f8351fce9
Make streaming implementation trio-compatible (#84)
Some checks are pending
Lint / lint (push) Waiting to run
Test / test (3.10) (push) Waiting to run
Test / test (3.11) (push) Waiting to run
Test / test (3.12) (push) Waiting to run
Test / test (3.13) (push) Waiting to run
## Summary
- Replace asyncio.create_task() with anyio task group for trio
compatibility
- Update client.py docstring example to use anyio.sleep
- Add trio example demonstrating multi-turn conversation

## Details
The SDK already uses anyio for most async operations, but one line was
using asyncio.create_task() which broke trio compatibility. This PR
fixes that by using anyio's task group API with proper lifecycle
management.

### Changes:
1. **subprocess_cli.py**: Replace asyncio.create_task() with anyio task
group, ensuring proper cleanup on disconnect
2. **client.py**: Update docstring example to use anyio.sleep instead of
asyncio.sleep
3. **streaming_mode_trio.py**: Add new example showing how to use the
SDK with trio

## Test plan
- [x] All existing tests pass
- [x] Manually tested with trio runtime (created test script that
successfully runs multi-turn conversation)
- [x] Linting and type checking pass

🤖 Generated with [Claude Code](https://claude.ai/code)
2025-07-22 23:31:42 -07:00
Dickson Tsai
b25cdf81c9
Add changelog and changelog format check (#77)
Some checks failed
Lint / lint (push) Has been cancelled
Test / test (3.10) (push) Has been cancelled
Test / test (3.11) (push) Has been cancelled
Test / test (3.12) (push) Has been cancelled
Test / test (3.13) (push) Has been cancelled
2025-07-21 10:53:01 -07:00
github-actions[bot]
1d8ba02062
chore: bump version to 0.0.16 (#83)
This PR updates the version to 0.0.16 after publishing to PyPI.

## Changes
- Updated version in `pyproject.toml`
- Updated version in `src/claude_code_sdk/__init__.py`

## Release Information
- Published to PyPI: https://pypi.org/project/claude-code-sdk/0.0.16/
- Install with: `pip install claude-code-sdk==0.0.16`

🤖 Generated by GitHub Actions

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-07-21 09:55:50 -07:00
Dickson Tsai
21428b4f4d
Fix "Publish to PyPI" workflow: Add commit signing and improve diff (#82)
* Adds commit signing
* Converts sed pattern matching to a script to ensure we don't update
version values unrelated to PyPI
* Remove the `Publish to Test PyPI first'` step since it no longer works
2025-07-21 09:53:24 -07:00
Dickson Tsai
c4384ead71
Merge pull request #75 from anthropics/dickson/streaming
Some checks failed
Lint / lint (push) Has been cancelled
Test / test (3.10) (push) Has been cancelled
Test / test (3.11) (push) Has been cancelled
Test / test (3.12) (push) Has been cancelled
Test / test (3.13) (push) Has been cancelled
Implement streaming
2025-07-19 22:38:15 -07:00
Dickson Tsai
e852710d8c
Remove hardcoded timeout for control messages to match Typescript SDK 2025-07-19 20:43:07 -07:00
Dickson Tsai
5325dea9fd
Lint 2025-07-19 20:19:40 -07:00
Dickson Tsai
3e7da418ce
Fix json error handling 2025-07-19 20:16:45 -07:00