Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
72280d8
Add Claude issue triage workflow
ltawfik Jul 3, 2025
6b3ed6e
Explicit error if the cwd does not exist
RomainGehrig Jun 26, 2025
17b4669
fix: expose transport interface
rushilpatel0 Jul 16, 2025
1676273
feat: enable custom transports to be provided
rushilpatel0 Jul 26, 2025
e12fc7c
remove from package exports SubprocessCLITransport
rushilpatel0 Jul 26, 2025
c0841d8
Initial implementation of bidi streaming
dicksontsai Jul 17, 2025
055d60f
Finalize streaming impl
dicksontsai Jul 18, 2025
5f90eb8
Implement proper client and bidi streaming
dicksontsai Jul 19, 2025
7a24087
Working examples
dicksontsai Jul 19, 2025
28a115f
Fix examples
dicksontsai Jul 19, 2025
f8cab19
Add tests
dicksontsai Jul 19, 2025
e7b9e8c
Close stdin for query()
dicksontsai Jul 19, 2025
4175e4a
Fix test
dicksontsai Jul 19, 2025
0d23841
Ruff
dicksontsai Jul 19, 2025
8ea3a12
Fix test
dicksontsai Jul 19, 2025
5ffc20f
Fix lint
dicksontsai Jul 19, 2025
8796e2d
Fix types
dicksontsai Jul 20, 2025
3408cb6
PR feedback
dicksontsai Jul 20, 2025
bd62813
CLAUDE.md
dicksontsai Jul 20, 2025
ccdb272
Improve examples
dicksontsai Jul 20, 2025
bce29e4
Fix lint and test
dicksontsai Jul 20, 2025
b68d154
Fix json error handling
dicksontsai Jul 20, 2025
3a22f48
Lint
dicksontsai Jul 20, 2025
2eec6a0
Remove hardcoded timeout for control messages to match Typescript SDK
dicksontsai Jul 20, 2025
a520063
Fix "Publish to PyPI" workflow: Add commit signing and improve diff (…
dicksontsai Jul 21, 2025
b8fbe03
chore: bump version to 0.0.16 (#83)
github-actions[bot] Jul 21, 2025
d89a06c
Add changelog and changelog format check (#77)
dicksontsai Jul 21, 2025
e649a98
Make streaming implementation trio-compatible (#84)
dicksontsai Jul 23, 2025
97ee71e
chore: bump version to 0.0.17 (#88)
github-actions[bot] Jul 24, 2025
a517fab
fix tests and add transport param to query
rushilpatel0 Jul 26, 2025
611d332
Add settings option to ClaudeCodeOptions (#100)
dicksontsai Jul 31, 2025
a56711f
Improve UserMessage types to include `ToolResultBlock` (#101)
dicksontsai Jul 31, 2025
85038c7
chore: bump version to 0.0.18 (#102)
github-actions[bot] Jul 31, 2025
01e51c1
Fix subprocess deadlock with MCP servers via stderr redirection (#103)
dicksontsai Jul 31, 2025
6fb59c9
chore: address pr comments
rushilpatel0 Jul 31, 2025
b6ddaea
chore: add missing eof newlines
rushilpatel0 Jul 31, 2025
590ea7a
Support --add-dir flag (#104)
dicksontsai Aug 1, 2025
9a4f082
chore: bump version to 0.0.19 (#105)
github-actions[bot] Aug 1, 2025
8236c50
remove mcp_tools field from ClaudeCodeOptions (#110)
shunfu Aug 4, 2025
2ed25bf
Add extra_args field to ClaudeCodeOptions for forward compatibility (…
dicksontsai Aug 5, 2025
6e10b6d
teach ClaudeCodeOptions.mcp_servers to accept a filepath (#114)
shunfu Aug 6, 2025
ab185e0
allow claude gh action to lint, typecheck, and run tests (#115)
shunfu Aug 6, 2025
4e8c11a
fix pytest allowed tool (#117)
shunfu Aug 6, 2025
fc96e51
fix: add support for thinking content blocks (#28)
yokomotod Aug 7, 2025
6f4ca74
Add support for plan permission mode (#116)
Mng-dev-ai Aug 7, 2025
2ed4d03
chore: bump version to 0.0.20 (#121)
github-actions[bot] Aug 14, 2025
c0d4e1d
fix: post rebase cleanup
rushilpatel0 Aug 17, 2025
3f02be5
Merge branch 'main' into feat/enable-custom-transports
rushilpatel0 Aug 17, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/claude_code_sdk/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
CLINotFoundError,
ProcessError,
)
from ._internal.transport import Transport
from .client import ClaudeSDKClient
from .query import query
from .types import (
Expand All @@ -30,6 +31,8 @@
__all__ = [
# Main exports
"query",
# Transport
"Transport",
"ClaudeSDKClient",
# Types
"PermissionMode",
Expand Down
27 changes: 19 additions & 8 deletions src/claude_code_sdk/_internal/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,12 @@
from collections.abc import AsyncIterable, AsyncIterator
from typing import Any

from ..types import ClaudeCodeOptions, Message
from ..types import (
ClaudeCodeOptions,
Message,
)
from .message_parser import parse_message
from .transport import Transport
from .transport.subprocess_cli import SubprocessCLITransport


Expand All @@ -15,19 +19,26 @@ def __init__(self) -> None:
"""Initialize the internal client."""

async def process_query(
self, prompt: str | AsyncIterable[dict[str, Any]], options: ClaudeCodeOptions
self,
prompt: str | AsyncIterable[dict[str, Any]],
options: ClaudeCodeOptions,
transport: Transport | None = None,
) -> AsyncIterator[Message]:
"""Process a query through transport."""

transport = SubprocessCLITransport(
prompt=prompt, options=options, close_stdin_after_prompt=True
)
# Use provided transport or choose one based on configuration
if transport is not None:
chosen_transport = transport
else:
chosen_transport = SubprocessCLITransport(
prompt=prompt, options=options, close_stdin_after_prompt=True
)

try:
await transport.connect()
await chosen_transport.connect()

async for data in transport.receive_messages():
async for data in chosen_transport.receive_messages():
yield parse_message(data)

finally:
await transport.disconnect()
await chosen_transport.disconnect()
8 changes: 7 additions & 1 deletion src/claude_code_sdk/_internal/transport/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,13 @@


class Transport(ABC):
"""Abstract transport for Claude communication."""
"""Abstract transport for Claude communication.

WARNING: This internal API is exposed for custom transport implementations
(e.g., remote Claude Code connections). The Claude Code team may change or
or remove this abstract class in any future release. Custom implementations
must be updated to match interface changes.
"""

@abstractmethod
async def connect(self) -> None:
Expand Down
2 changes: 1 addition & 1 deletion src/claude_code_sdk/_internal/transport/subprocess_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def __init__(
self._is_streaming = not isinstance(prompt, str)
self._options = options
self._cli_path = str(cli_path) if cli_path else self._find_cli()
self._cwd = str(options.cwd) if options.cwd else None
self._cwd: str | None = None
self._process: Process | None = None
self._stdout_stream: TextReceiveStream | None = None
self._stderr_stream: TextReceiveStream | None = None
Expand Down
26 changes: 25 additions & 1 deletion src/claude_code_sdk/query.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@
from typing import Any

from ._internal.client import InternalClient
from ._internal.transport import Transport
from .types import ClaudeCodeOptions, Message


async def query(
*,
prompt: str | AsyncIterable[dict[str, Any]],
options: ClaudeCodeOptions | None = None,
transport: Transport | None = None,
) -> AsyncIterator[Message]:
"""
Query Claude Code for one-shot or unidirectional streaming interactions.
Expand Down Expand Up @@ -56,6 +58,9 @@ async def query(
- 'acceptEdits': Auto-accept file edits
- 'bypassPermissions': Allow all tools (use with caution)
Set options.cwd for working directory.
transport: Optional transport implementation. If provided, this will be used
instead of the default transport selection based on options.
The transport will be automatically configured with the prompt and options.

Yields:
Messages from the conversation
Expand Down Expand Up @@ -90,6 +95,23 @@ async def prompts():
async for message in query(prompt=prompts()):
print(message)
```

Example - With custom transport:
```python
from claude_code_sdk import query, Transport

class MyCustomTransport(Transport):
# Implement custom transport logic
pass

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

"""
if options is None:
options = ClaudeCodeOptions()
Expand All @@ -98,5 +120,7 @@ async def prompts():

client = InternalClient()

async for message in client.process_query(prompt=prompt, options=options):
async for message in client.process_query(
prompt=prompt, options=options, transport=transport
):
yield message
Loading