Skip to main content

ClaudeSdkClient

Struct ClaudeSdkClient 

Source
pub struct ClaudeSdkClient { /* private fields */ }
Expand description

Session-based client for multi-turn Claude Code interactions.

ClaudeSdkClient maintains a connection to the Claude Code CLI subprocess, allowing multiple queries within the same conversation context. The session preserves conversation history across calls.

§Lifecycle

  1. Create a client with new()
  2. Call connect() to start the session
  3. Send queries with query() and receive responses with receive_message() or receive_response()
  4. Call disconnect() when done

§Concurrency

After connection, query(), interrupt(), and control methods take &self, allowing concurrent operations from different tasks. Only connect(), disconnect(), and receive_message() require &mut self.

§Example

    let mut client = ClaudeSdkClient::new(None, None);
    client.connect(None).await?;

    client.query(InputPrompt::Text("Hello!".into()), "session-1").await?;
    let messages = client.receive_response().await?;

    client.disconnect().await?;

Implementations§

Source§

impl ClaudeSdkClient

Source

pub fn new( options: Option<ClaudeAgentOptions>, transport_factory: Option<Box<dyn TransportFactory>>, ) -> Self

Creates a new ClaudeSdkClient with optional configuration and transport factory.

§Arguments
  • options — Optional ClaudeAgentOptions for configuring the session. If None, defaults are used.
  • transport_factory — Optional TransportFactory for creating transport instances on each connect() call. If None, the default SubprocessCliTransport is used. Using a factory enables reconnect after disconnect with the same client instance.
§Example
use claude_code::ClaudeSdkClient;

let _client = ClaudeSdkClient::new(None, None);
Source

pub fn new_with_transport( options: Option<ClaudeAgentOptions>, transport: Box<dyn Transport>, ) -> Self

Creates a new ClaudeSdkClient with a single-use custom transport.

The transport is consumed on the first connect(). Subsequent connect() calls after disconnect() will return an error. For reconnect support with custom transports, use new() with a TransportFactory.

§Example
use claude_code::transport::subprocess_cli::{Prompt, SubprocessCliTransport};
use claude_code::ClaudeSdkClient;

let transport = SubprocessCliTransport::new(Prompt::Messages, Default::default()).unwrap();
let _client = ClaudeSdkClient::new_with_transport(None, Box::new(transport));
Source

pub async fn connect(&mut self, prompt: Option<InputPrompt>) -> Result<()>

Establishes a connection to the Claude Code CLI and starts the session.

If an existing connection exists, it is disconnected first.

§Arguments
  • prompt — Optional initial prompt to send upon connection. When using can_use_tool, this must be InputPrompt::Messages, not Text.
§Errors

Returns an error if:

  • The CLI executable is not found
  • can_use_tool is set with a Text prompt (requires Messages)
  • can_use_tool is set alongside permission_prompt_tool_name
  • The subprocess fails to start
§Example
use claude_code::{ClaudeSdkClient, InputPrompt};

let mut client = ClaudeSdkClient::new(None, None);
client.connect(Some(InputPrompt::Text("Hello".to_string()))).await?;
client.disconnect().await?;
Source

pub async fn connect_with_messages<S>(&mut self, prompt: S) -> Result<()>
where S: Stream<Item = Value> + Send + Unpin + 'static,

Establishes a connection and sends initial prompt messages from a stream.

This is a Rust-idiomatic equivalent of Python SDK connect(AsyncIterable). The stream is consumed in a background task so this method returns once connection is established. Unlike one-off query streaming helpers, this keeps stdin open so the session can continue with follow-up query() calls.

To synchronously wait for stream completion and surface stream write errors, call wait_for_initial_messages().

§Errors

Returns the same errors as connect(), plus errors when starting the background stream task.

§Example
use claude_code::ClaudeSdkClient;
use futures::stream;
use serde_json::json;

let mut client = ClaudeSdkClient::new(None, None);
client.connect_with_messages(stream::iter(vec![
    json!({"type":"user","message":{"role":"user","content":"hello"}}),
])).await?;
client.wait_for_initial_messages().await?;
client.disconnect().await?;
Source

pub async fn wait_for_initial_messages(&mut self) -> Result<()>

Waits for completion of the initial background message stream task.

This is only relevant after calling connect_with_messages(). If no background stream is active, this returns immediately.

§Example
use claude_code::ClaudeSdkClient;

let mut client = ClaudeSdkClient::new(None, None);
client.wait_for_initial_messages().await?;
Source

pub async fn query(&self, prompt: InputPrompt, session_id: &str) -> Result<()>

Sends a query within the current session.

The session must be connected first via connect(). After sending, use receive_message() or receive_response() to get the response.

§Arguments
  • prompt — The prompt to send (text or structured messages).
  • session_id — Session identifier for the query.
§Errors

Returns CLIConnectionError if not connected.

§Example
use claude_code::{ClaudeSdkClient, InputPrompt};

let mut client = ClaudeSdkClient::new(None, None);
client.connect(None).await?;
client.query(InputPrompt::Text("Summarize this repo".into()), "default").await?;
client.disconnect().await?;
Source

pub async fn query_stream<S>(&self, prompt: S, session_id: &str) -> Result<()>
where S: Stream<Item = Value> + Unpin,

Streams JSON message prompts within the current session.

§Errors

Returns CLIConnectionError if not connected.

§Example
use claude_code::ClaudeSdkClient;
use futures::stream;
use serde_json::json;

let mut client = ClaudeSdkClient::new(None, None);
client.connect(None).await?;
client
    .query_stream(
        stream::iter(vec![json!({"type":"user","message":{"role":"user","content":"hello"}})]),
        "default",
    )
    .await?;
client.disconnect().await?;
Source

pub async fn receive_message(&mut self) -> Result<Option<Message>>

Receives a single message from the current query.

Returns None when no more messages are available.

§Errors

Returns CLIConnectionError if not connected.

§Example
use claude_code::ClaudeSdkClient;

let mut client = ClaudeSdkClient::new(None, None);
client.connect(None).await?;
let _next = client.receive_message().await?;
client.disconnect().await?;
Source

pub async fn receive_response(&mut self) -> Result<Vec<Message>>

Receives all messages for the current query until a Message::Result is received.

§Errors

Returns CLIConnectionError if not connected.

§Example
use claude_code::{ClaudeSdkClient, InputPrompt};

let mut client = ClaudeSdkClient::new(None, None);
client.connect(None).await?;
client.query(InputPrompt::Text("Hi".into()), "default").await?;
let _messages = client.receive_response().await?;
client.disconnect().await?;
Source

pub async fn interrupt(&self) -> Result<()>

Interrupts the current operation.

§Errors

Returns CLIConnectionError if not connected.

§Example
use claude_code::ClaudeSdkClient;

let mut client = ClaudeSdkClient::new(None, None);
client.connect(None).await?;
client.interrupt().await?;
client.disconnect().await?;
Source

pub async fn set_permission_mode(&self, mode: &str) -> Result<()>

Changes the permission mode for the current session.

§Errors

Returns CLIConnectionError if not connected.

§Example
use claude_code::ClaudeSdkClient;

let mut client = ClaudeSdkClient::new(None, None);
client.connect(None).await?;
client.set_permission_mode("plan").await?;
client.disconnect().await?;
Source

pub async fn set_model(&self, model: Option<&str>) -> Result<()>

Changes the model used for the current session.

§Errors

Returns CLIConnectionError if not connected.

§Example
use claude_code::ClaudeSdkClient;

let mut client = ClaudeSdkClient::new(None, None);
client.connect(None).await?;
client.set_model(Some("sonnet")).await?;
client.disconnect().await?;
Source

pub async fn rewind_files(&self, user_message_id: &str) -> Result<()>

Rewinds file changes to a specific user message checkpoint.

§Errors

Returns CLIConnectionError if not connected.

§Example
use claude_code::ClaudeSdkClient;

let mut client = ClaudeSdkClient::new(None, None);
client.connect(None).await?;
client.rewind_files("user-msg-1").await?;
client.disconnect().await?;
Source

pub async fn get_mcp_status(&self) -> Result<Value>

Queries the status of connected MCP servers.

§Errors

Returns CLIConnectionError if not connected.

§Example
use claude_code::ClaudeSdkClient;

let mut client = ClaudeSdkClient::new(None, None);
client.connect(None).await?;
let _status = client.get_mcp_status().await?;
client.disconnect().await?;
Source

pub fn get_server_info(&self) -> Result<Option<Value>>

Returns the server initialization response, if available.

§Errors

Returns CLIConnectionError if not connected.

§Example
use claude_code::ClaudeSdkClient;

let mut client = ClaudeSdkClient::new(None, None);
client.connect(None).await?;
let _info = client.get_server_info()?;
client.disconnect().await?;
Source

pub async fn disconnect(&mut self) -> Result<()>

Disconnects from the Claude Code CLI and closes the session.

After disconnecting, the client can be reconnected with connect().

§Example
use claude_code::ClaudeSdkClient;

let mut client = ClaudeSdkClient::new(None, None);
client.connect(None).await?;
client.disconnect().await?;

Trait Implementations§

Source§

impl Drop for ClaudeSdkClient

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more