Class: ClaudeAgentSDK::Client
- Inherits:
-
Object
- Object
- ClaudeAgentSDK::Client
- Defined in:
- lib/claude_agent_sdk.rb
Overview
Client for bidirectional, interactive conversations with Claude Code
This client provides full control over the conversation flow with support for streaming, hooks, permission callbacks, and dynamic message sending. The Client class always uses streaming mode for bidirectional communication.
Instance Attribute Summary collapse
-
#query_handler ⇒ Object
readonly
Returns the value of attribute query_handler.
Instance Method Summary collapse
-
#connect(prompt = nil) ⇒ Object
Connect to Claude with optional initial prompt.
-
#disconnect ⇒ Object
Disconnect from Claude.
-
#get_context_usage ⇒ Hash
Get a breakdown of current context window usage by category.
-
#get_mcp_status ⇒ Hash
Get current MCP server connection status (only works with streaming mode).
-
#get_server_info ⇒ Hash
Get server initialization info including available commands and output styles.
-
#initialize(options: nil, transport_class: SubprocessCLITransport, transport_args: {}) ⇒ Client
constructor
A new instance of Client.
-
#interrupt ⇒ Object
Send interrupt signal.
-
#query(prompt, session_id: 'default') ⇒ Object
Send a query to Claude.
-
#receive_messages {|Message| ... } ⇒ Object
Receive all messages from Claude.
-
#receive_response {|Message| ... } ⇒ Object
Receive messages until a ResultMessage is received.
-
#reconnect_mcp_server(server_name) ⇒ Object
Reconnect a failed MCP server.
-
#rewind_files(user_message_uuid) ⇒ Object
Rewind files to a previous checkpoint (v0.1.15+) Restores file state to what it was at the given user message Requires enable_file_checkpointing to be true in options.
-
#server_info ⇒ Hash?
Get server initialization info.
-
#set_model(model) ⇒ Object
Change the AI model during conversation.
-
#set_permission_mode(mode) ⇒ Object
Change permission mode during conversation.
-
#stop_task(task_id) ⇒ Object
Stop a running background task.
-
#toggle_mcp_server(server_name, enabled) ⇒ Object
Enable or disable an MCP server.
Constructor Details
#initialize(options: nil, transport_class: SubprocessCLITransport, transport_args: {}) ⇒ Client
Returns a new instance of Client.
298 299 300 301 302 303 304 305 |
# File 'lib/claude_agent_sdk.rb', line 298 def initialize(options: nil, transport_class: SubprocessCLITransport, transport_args: {}) @options = || ClaudeAgentOptions.new @transport_class = transport_class @transport_args = transport_args @transport = nil @query_handler = nil @connected = false end |
Instance Attribute Details
#query_handler ⇒ Object (readonly)
Returns the value of attribute query_handler.
292 293 294 |
# File 'lib/claude_agent_sdk.rb', line 292 def query_handler @query_handler end |
Instance Method Details
#connect(prompt = nil) ⇒ Object
Connect to Claude with optional initial prompt.
Client always uses streaming mode for bidirectional communication. If you pass a String, it will be sent as an initial user message after the connection is established. If you pass an Enumerator, it should yield JSONL messages (e.g., from ClaudeAgentSDK::Streaming.user_message).
315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 |
# File 'lib/claude_agent_sdk.rb', line 315 def connect(prompt = nil) return if @connected raise ArgumentError, "prompt must be a String, an Enumerator, or nil (got #{prompt.class})" unless prompt.nil? || prompt.is_a?(String) || prompt.respond_to?(:each) # Validate and configure permission settings = @options if @options.can_use_tool # can_use_tool and permission_prompt_tool_name are mutually exclusive raise ArgumentError, 'can_use_tool callback cannot be used with permission_prompt_tool_name' if @options. # Set permission_prompt_tool_name to stdio for control protocol = @options.dup_with(permission_prompt_tool_name: 'stdio') end # Client always uses streaming mode; keep stdin open for bidirectional communication. @transport = @transport_class.new(, **@transport_args) @transport.connect # Extract SDK MCP servers sdk_mcp_servers = {} if .mcp_servers.is_a?(Hash) .mcp_servers.each do |name, config| sdk_mcp_servers[name] = config[:instance] if config.is_a?(Hash) && config[:type] == 'sdk' end end # Convert hooks to internal format hooks = convert_hooks_to_internal_format(.hooks) if .hooks # Extract exclude_dynamic_sections from preset system prompt for the # initialize request (older CLIs ignore unknown initialize fields) exclude_dynamic_sections = extract_exclude_dynamic_sections(.system_prompt) # Create Query handler @query_handler = Query.new( transport: @transport, is_streaming_mode: true, can_use_tool: .can_use_tool, hooks: hooks, sdk_mcp_servers: sdk_mcp_servers, agents: .agents, exclude_dynamic_sections: exclude_dynamic_sections ) # Start query handler and initialize @query_handler.start @query_handler.initialize_protocol # Resolve callable observers into fresh instances (thread-safe for global defaults) @resolved_observers = ClaudeAgentSDK.resolve_observers(@options.observers) @connected = true # Optionally send initial prompt/messages after connection is ready. case prompt when nil nil when String query(prompt) else prompt.each do || = .to_s += "\n" unless .end_with?("\n") @transport.write() end end end |
#disconnect ⇒ Object
Disconnect from Claude
508 509 510 511 512 513 514 515 516 |
# File 'lib/claude_agent_sdk.rb', line 508 def disconnect return unless @connected ClaudeAgentSDK.notify_observers(@resolved_observers || [], :on_close) @query_handler&.close @query_handler = nil @transport = nil @connected = false end |
#get_context_usage ⇒ Hash
Get a breakdown of current context window usage by category. Returns token counts per category (system prompt, tools, messages, etc.), total/max tokens, model info, MCP tools, memory files, and more.
488 489 490 491 |
# File 'lib/claude_agent_sdk.rb', line 488 def get_context_usage raise CLIConnectionError, 'Not connected. Call connect() first' unless @connected @query_handler.get_context_usage end |
#get_mcp_status ⇒ Hash
Get current MCP server connection status (only works with streaming mode)
495 496 497 498 |
# File 'lib/claude_agent_sdk.rb', line 495 def get_mcp_status raise CLIConnectionError, 'Not connected. Call connect() first' unless @connected @query_handler.get_mcp_status end |
#get_server_info ⇒ Hash
Get server initialization info including available commands and output styles
502 503 504 505 |
# File 'lib/claude_agent_sdk.rb', line 502 def get_server_info raise CLIConnectionError, 'Not connected. Call connect() first' unless @connected server_info end |
#interrupt ⇒ Object
Send interrupt signal
428 429 430 431 |
# File 'lib/claude_agent_sdk.rb', line 428 def interrupt raise CLIConnectionError, 'Not connected. Call connect() first' unless @connected @query_handler.interrupt end |
#query(prompt, session_id: 'default') ⇒ Object
Send a query to Claude
387 388 389 390 391 392 393 394 395 396 397 398 |
# File 'lib/claude_agent_sdk.rb', line 387 def query(prompt, session_id: 'default') raise CLIConnectionError, 'Not connected. Call connect() first' unless @connected ClaudeAgentSDK.notify_observers(@resolved_observers, :on_user_prompt, prompt) = { type: 'user', message: { role: 'user', content: prompt }, parent_tool_use_id: nil, session_id: session_id } @transport.write(JSON.generate() + "\n") end |
#receive_messages {|Message| ... } ⇒ Object
Receive all messages from Claude
402 403 404 405 406 407 408 409 410 411 412 413 414 |
# File 'lib/claude_agent_sdk.rb', line 402 def (&block) return enum_for(:receive_messages) unless block raise CLIConnectionError, 'Not connected. Call connect() first' unless @connected @query_handler. do |data| = MessageParser.parse(data) if ClaudeAgentSDK.notify_observers(@resolved_observers, :on_message, ) FiberBoundary.invoke { block.call() } end end end |
#receive_response {|Message| ... } ⇒ Object
Receive messages until a ResultMessage is received
418 419 420 421 422 423 424 425 |
# File 'lib/claude_agent_sdk.rb', line 418 def receive_response(&block) return enum_for(:receive_response) unless block do || block.call() break if .is_a?(ResultMessage) end end |
#reconnect_mcp_server(server_name) ⇒ Object
Reconnect a failed MCP server
449 450 451 452 |
# File 'lib/claude_agent_sdk.rb', line 449 def reconnect_mcp_server(server_name) raise CLIConnectionError, 'Not connected. Call connect() first' unless @connected @query_handler.reconnect_mcp_server(server_name) end |
#rewind_files(user_message_uuid) ⇒ Object
Rewind files to a previous checkpoint (v0.1.15+) Restores file state to what it was at the given user message Requires enable_file_checkpointing to be true in options
473 474 475 476 |
# File 'lib/claude_agent_sdk.rb', line 473 def rewind_files() raise CLIConnectionError, 'Not connected. Call connect() first' unless @connected @query_handler.rewind_files() end |
#server_info ⇒ Hash?
Get server initialization info
480 481 482 |
# File 'lib/claude_agent_sdk.rb', line 480 def server_info @query_handler&.instance_variable_get(:@initialization_result) end |
#set_model(model) ⇒ Object
Change the AI model during conversation
442 443 444 445 |
# File 'lib/claude_agent_sdk.rb', line 442 def set_model(model) raise CLIConnectionError, 'Not connected. Call connect() first' unless @connected @query_handler.set_model(model) end |
#set_permission_mode(mode) ⇒ Object
Change permission mode during conversation
435 436 437 438 |
# File 'lib/claude_agent_sdk.rb', line 435 def (mode) raise CLIConnectionError, 'Not connected. Call connect() first' unless @connected @query_handler.(mode) end |
#stop_task(task_id) ⇒ Object
Stop a running background task
464 465 466 467 |
# File 'lib/claude_agent_sdk.rb', line 464 def stop_task(task_id) raise CLIConnectionError, 'Not connected. Call connect() first' unless @connected @query_handler.stop_task(task_id) end |
#toggle_mcp_server(server_name, enabled) ⇒ Object
Enable or disable an MCP server
457 458 459 460 |
# File 'lib/claude_agent_sdk.rb', line 457 def toggle_mcp_server(server_name, enabled) raise CLIConnectionError, 'Not connected. Call connect() first' unless @connected @query_handler.toggle_mcp_server(server_name, enabled) end |