claude-code-sdk-ruby 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 154889ea495b7743bded0f1cf1ab96b74da5adc93bf19f1e226d6fd9f949dee1
4
+ data.tar.gz: 77039484cf7d9acbd273334aad182db014b8a5d471d41019d3565828479716a8
5
+ SHA512:
6
+ metadata.gz: 73ad8a8341c21ef6cbac699ee4ce211619a853676632c6072374821b08737ccacbe8007dd9de0971dacdf3b6bc9e4b69d21275dc2e4b13e7106a1b7f8a8d34e9
7
+ data.tar.gz: fc9e88788b6783fd4a335b4553fb6c3607b65083ff1fe898756c4cbb5ee4566012562748107e748ab08f1a1c3dc712eab7bb1e91032bb8ca3818539b6755a1d7
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --require spec_helper
2
+ --color
3
+ --format progress
data/.rubocop.yml ADDED
@@ -0,0 +1,19 @@
1
+ inherit_gem:
2
+ rubocop-shopify: rubocop.yml
3
+
4
+ plugins:
5
+ - rubocop-rspec
6
+ - rubocop-rake
7
+
8
+ AllCops:
9
+ TargetRubyVersion: 3.4
10
+ NewCops: enable
11
+ Exclude:
12
+ - '.ruby-lsp/**/*'
13
+
14
+
15
+ RSpec/MultipleExpectations:
16
+ Enabled: false
17
+
18
+ RSpec/ExampleLength:
19
+ Enabled: false
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ ruby-3.4.2
data/.yardopts ADDED
@@ -0,0 +1,8 @@
1
+ --markup markdown
2
+ --readme README.md
3
+ --files CHANGELOG.md,LICENSE
4
+ --output-dir doc
5
+ --protected
6
+ --private
7
+ --exclude spec/
8
+ --exclude examples/
data/CHANGELOG.md ADDED
@@ -0,0 +1,43 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ### Changed
11
+ - Removed unused `async-process` dependency
12
+
13
+ ## [0.0.1] - 2024-07-14
14
+
15
+ ### Added
16
+ - Initial release of claude-sdk-ruby
17
+ - Core SDK functionality for interacting with Claude Code CLI
18
+ - Support for async query processing
19
+ - Message types: User, Assistant, System, and Result
20
+ - Content blocks: Text, ToolUse, and ToolResult
21
+ - Configuration options via ClaudeCodeOptions
22
+ - Error handling with specific error types:
23
+ - CLINotFoundError
24
+ - CLIConnectionError
25
+ - ProcessError
26
+ - Internal client for direct subprocess communication
27
+ - Comprehensive test suite with RSpec
28
+ - Examples and documentation
29
+
30
+ ### Dependencies
31
+ - async (~> 2.0)
32
+
33
+ ### Development Dependencies
34
+ - bundler (~> 2.0)
35
+ - rake (~> 13.0)
36
+ - rspec (~> 3.0)
37
+ - rubocop (~> 1.50)
38
+ - rubocop-rspec (~> 2.20)
39
+ - simplecov (~> 0.22)
40
+ - yard (~> 0.9)
41
+
42
+ [Unreleased]: https://github.com/anthropics/claude-code-sdk-ruby/compare/v0.0.1...HEAD
43
+ [0.0.1]: https://github.com/anthropics/claude-code-sdk-ruby/releases/tag/v0.0.1
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025-present Paulo Arruda
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,220 @@
1
+ # Claude SDK Ruby
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/claude-sdk-ruby.svg)](https://badge.fury.io/rb/claude-sdk-ruby)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+
6
+ Official Ruby SDK for interacting with Claude Code CLI. This gem provides a Ruby-idiomatic interface to Claude Code with full async support, proper error handling, and comprehensive type definitions.
7
+
8
+ ## Installation
9
+
10
+ Add this line to your application's Gemfile:
11
+
12
+ ```ruby
13
+ gem 'claude-sdk-ruby'
14
+ ```
15
+
16
+ And then execute:
17
+
18
+ ```bash
19
+ bundle install
20
+ ```
21
+
22
+ Or install it yourself as:
23
+
24
+ ```bash
25
+ gem install claude-sdk-ruby
26
+ ```
27
+
28
+ ## Prerequisites
29
+
30
+ This SDK requires the Claude Code CLI to be installed:
31
+
32
+ ```bash
33
+ npm install -g @anthropic-ai/claude-code
34
+ ```
35
+
36
+ You'll also need to configure your API key. Please refer to the [Claude Code documentation](https://docs.anthropic.com/en/docs/claude-code) for detailed setup instructions.
37
+
38
+ ## Quick Start
39
+
40
+ ```ruby
41
+ require 'claude_sdk'
42
+
43
+ # Simple query
44
+ ClaudeSDK.query("What is 2+2?") do |message|
45
+ case message
46
+ when ClaudeSDK::Messages::Assistant
47
+ message.content.each do |block|
48
+ puts block.text if block.is_a?(ClaudeSDK::ContentBlock::Text)
49
+ end
50
+ when ClaudeSDK::Messages::Result
51
+ puts "Session completed in #{message.duration_ms}ms"
52
+ end
53
+ end
54
+ ```
55
+
56
+ ## Usage
57
+
58
+ ### Basic Query
59
+
60
+ ```ruby
61
+ require 'claude_sdk'
62
+
63
+ ClaudeSDK.query("Hello, Claude!") do |message|
64
+ puts message
65
+ end
66
+ ```
67
+
68
+ ### With Options
69
+
70
+ ```ruby
71
+ require 'claude_sdk'
72
+
73
+ options = ClaudeSDK::ClaudeCodeOptions.new(
74
+ allowed_tools: ['Read', 'Write', 'Bash'],
75
+ max_turns: 3,
76
+ system_prompt: 'You are a helpful coding assistant.',
77
+ cwd: '/path/to/working/directory'
78
+ )
79
+
80
+ ClaudeSDK.query("Help me write a Ruby script", options: options) do |message|
81
+ case message
82
+ when ClaudeSDK::Messages::Assistant
83
+ message.content.each do |block|
84
+ case block
85
+ when ClaudeSDK::ContentBlock::Text
86
+ puts block.text
87
+ when ClaudeSDK::ContentBlock::ToolUse
88
+ puts "Tool: #{block.name}"
89
+ puts "Input: #{block.input}"
90
+ end
91
+ end
92
+ when ClaudeSDK::Messages::Result
93
+ puts "Completed in #{message.num_turns} turns"
94
+ puts "Total cost: $#{message.total_cost_usd}"
95
+ end
96
+ end
97
+ ```
98
+
99
+ ### Without Block (Returns Enumerator)
100
+
101
+ ```ruby
102
+ require 'claude_sdk'
103
+
104
+ messages = ClaudeSDK.query("Hello")
105
+ messages.each do |message|
106
+ puts message
107
+ end
108
+ ```
109
+
110
+ ### Advanced: Using the Internal Client Directly
111
+
112
+ ```ruby
113
+ require 'claude_sdk/internal/client'
114
+
115
+ client = ClaudeSDK::Internal::InternalClient.new
116
+ options = ClaudeSDK::ClaudeCodeOptions.new(
117
+ allowed_tools: ['Read', 'Bash'],
118
+ max_turns: 5
119
+ )
120
+
121
+ Async do
122
+ client.process_query(prompt: "What files are in this directory?", options: options) do |message|
123
+ case message
124
+ when ClaudeSDK::Messages::Assistant
125
+ puts "Assistant response received"
126
+ when ClaudeSDK::Messages::System
127
+ puts "System message: #{message.subtype}"
128
+ when ClaudeSDK::Messages::Result
129
+ puts "Query completed"
130
+ end
131
+ end
132
+ end
133
+ ```
134
+
135
+ ## Message Types
136
+
137
+ The SDK provides several message types:
138
+
139
+ - `ClaudeSDK::Messages::User` - User input messages
140
+ - `ClaudeSDK::Messages::Assistant` - Assistant responses containing content blocks
141
+ - `ClaudeSDK::Messages::System` - System messages (tool results, errors)
142
+ - `ClaudeSDK::Messages::Result` - Query completion results with timing and cost info
143
+ - `ClaudeSDK::Messages::Error` - Error messages from the CLI
144
+
145
+ ## Content Blocks
146
+
147
+ Assistant messages contain content blocks:
148
+
149
+ - `ClaudeSDK::ContentBlock::Text` - Text content
150
+ - `ClaudeSDK::ContentBlock::ToolUse` - Tool usage
151
+ - `ClaudeSDK::ContentBlock::ToolResult` - Tool results
152
+
153
+ ## Configuration Options
154
+
155
+ The `ClaudeCodeOptions` class supports all Claude Code CLI options:
156
+
157
+ - `allowed_tools` - Array of allowed tool names (e.g., `['Read', 'Write', 'Bash']`)
158
+ - `disallowed_tools` - Array of disallowed tool names
159
+ - `max_turns` - Maximum conversation turns
160
+ - `system_prompt` - System prompt for the conversation
161
+ - `append_system_prompt` - Additional system prompt to append
162
+ - `cwd` - Working directory for file operations
163
+ - `model` - Model to use (e.g., `'claude-3-opus'`)
164
+ - `permission_mode` - Permission mode (`:default`, `:accept_edits`, `:auto`, `:ask`)
165
+ - `permission_prompt_tool_name` - Tool for permission prompts
166
+ - `continue_conversation` - Whether to continue from previous conversation
167
+ - `resume` - Resume from a specific conversation ID
168
+ - `mcp_servers` - MCP server configuration
169
+
170
+ ## Error Handling
171
+
172
+ The SDK provides specific error types:
173
+
174
+ ```ruby
175
+ begin
176
+ ClaudeSDK.query("Hello") do |message|
177
+ puts message
178
+ end
179
+ rescue ClaudeSDK::CLINotFoundError => e
180
+ puts "Claude Code CLI not found: #{e.message}"
181
+ rescue ClaudeSDK::CLIConnectionError => e
182
+ puts "Connection error: #{e.message}"
183
+ rescue ClaudeSDK::ProcessError => e
184
+ puts "Process error: #{e.message}"
185
+ end
186
+ ```
187
+
188
+ ## Requirements
189
+
190
+ - Ruby 3.0 or higher
191
+ - Node.js (for Claude Code CLI)
192
+ - async gem for async support
193
+
194
+ ## Development
195
+
196
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
197
+
198
+ ```bash
199
+ # Run tests
200
+ bundle exec rspec
201
+
202
+ # Run tests with coverage
203
+ COVERAGE=true bundle exec rspec
204
+
205
+ # Build the gem
206
+ gem build claude-sdk-ruby.gemspec
207
+
208
+ # Install locally
209
+ gem install ./claude-sdk-ruby-0.1.0.gem
210
+ ```
211
+
212
+ To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
213
+
214
+ ## Contributing
215
+
216
+ Bug reports and pull requests are welcome on GitHub at https://github.com/anthropics/claude-code-sdk-ruby.
217
+
218
+ ## License
219
+
220
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+ require "rubocop/rake_task"
6
+
7
+ RSpec::Core::RakeTask.new(:spec)
8
+ RuboCop::RakeTask.new
9
+
10
+ task default: [:spec, :rubocop]
11
+
12
+ desc "Run all tests and linting"
13
+ task test: [:spec, :rubocop]
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lib/claude_sdk/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "claude-code-sdk-ruby"
7
+ spec.version = ClaudeSDK::VERSION
8
+ spec.authors = ["Paulo Arruda"]
9
+ spec.email = ["parrudaj@gmail.com"]
10
+
11
+ spec.summary = "Ruby SDK for Claude Code"
12
+ spec.description = "Ruby SDK for interacting with Claude Code"
13
+ spec.homepage = "https://github.com/parruda/claude-code-sdk-ruby"
14
+ spec.license = "MIT"
15
+ spec.required_ruby_version = ">= 3.0.0"
16
+
17
+ spec.metadata["allowed_push_host"] = "https://rubygems.org"
18
+ spec.metadata["homepage_uri"] = spec.homepage
19
+ spec.metadata["source_code_uri"] = spec.homepage
20
+ spec.metadata["changelog_uri"] = "#{spec.homepage}/blob/main/CHANGELOG.md"
21
+
22
+ # Specify which files should be added to the gem when it is released.
23
+ spec.files = Dir.chdir(__dir__) do
24
+ %x(git ls-files -z).split("\x0").reject do |f|
25
+ (File.expand_path(f) == __FILE__) ||
26
+ f.start_with?("bin/", "test/", "spec/", "features/", ".git", ".github", "appveyor", "Gemfile")
27
+ end
28
+ end
29
+ spec.bindir = "exe"
30
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
31
+ spec.require_paths = ["lib"]
32
+
33
+ # Runtime dependencies
34
+ spec.add_dependency("async", "~> 2.26")
35
+ spec.add_dependency("logger", "~> 1.7")
36
+ end
@@ -0,0 +1,36 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "claude_sdk"
5
+ require "async"
6
+
7
+ # Example: Running multiple queries concurrently
8
+
9
+ Async do |task|
10
+ queries = [
11
+ "What is the capital of France?",
12
+ "Explain Ruby blocks in one sentence",
13
+ "List 3 benefits of async programming",
14
+ ]
15
+
16
+ # Run queries concurrently
17
+ results = queries.map do |prompt|
18
+ task.async do
19
+ responses = []
20
+ ClaudeSDK.query(prompt) do |message|
21
+ if message.is_a?(ClaudeSDK::Messages::Assistant)
22
+ message.content.each do |block|
23
+ responses << block.text if block.is_a?(ClaudeSDK::ContentBlock::Text)
24
+ end
25
+ end
26
+ end
27
+ { prompt: prompt, response: responses.join(" ") }
28
+ end
29
+ end.map(&:wait)
30
+
31
+ # Display results
32
+ results.each do |result|
33
+ puts "\nšŸ’­ Question: #{result[:prompt]}"
34
+ puts "šŸ’” Answer: #{result[:response]}"
35
+ end
36
+ end
@@ -0,0 +1,82 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # Add lib to load path for development
5
+ $LOAD_PATH.unshift(File.expand_path("../lib", __dir__))
6
+
7
+ require "async"
8
+ require "claude_sdk/types"
9
+ require "claude_sdk/errors"
10
+ require "claude_sdk/internal/client"
11
+
12
+ # Example of using the Ruby Claude SDK internal client
13
+ #
14
+ # This demonstrates:
15
+ # - Creating an internal client
16
+ # - Processing a query with options
17
+ # - Handling different message types
18
+ # - Error handling
19
+
20
+ # Create options
21
+ options = ClaudeSDK::ClaudeCodeOptions.new(
22
+ allowed_tools: ["bash", "read"],
23
+ max_turns: 3,
24
+ system_prompt: "You are a helpful coding assistant.",
25
+ )
26
+
27
+ # Create client
28
+ client = ClaudeSDK::Internal::InternalClient.new
29
+
30
+ # Process query
31
+ Async do
32
+ puts "Sending query to Claude..."
33
+ puts "=" * 50
34
+
35
+ client.process_query("What is 2+2?", options) do |message|
36
+ case message
37
+ when ClaudeSDK::Messages::User
38
+ puts "\n[USER]"
39
+ puts message.content
40
+
41
+ when ClaudeSDK::Messages::Assistant
42
+ puts "\n[ASSISTANT]"
43
+ message.content.each do |block|
44
+ case block
45
+ when ClaudeSDK::ContentBlock::Text
46
+ puts block.text
47
+ when ClaudeSDK::ContentBlock::ToolUse
48
+ puts "Tool Use: #{block.name}"
49
+ puts "Input: #{block.input.inspect}"
50
+ when ClaudeSDK::ContentBlock::ToolResult
51
+ puts "Tool Result for #{block.tool_use_id}"
52
+ puts "Content: #{block.content}"
53
+ puts "Error: #{block.is_error}" if block.is_error
54
+ end
55
+ end
56
+
57
+ when ClaudeSDK::Messages::System
58
+ puts "\n[SYSTEM: #{message.subtype}]"
59
+ puts message.data.inspect
60
+
61
+ when ClaudeSDK::Messages::Result
62
+ puts "\n[RESULT]"
63
+ puts "Session ID: #{message.session_id}"
64
+ puts "Duration: #{message.duration_ms}ms (API: #{message.duration_api_ms}ms)"
65
+ puts "Turns: #{message.num_turns}"
66
+ puts "Cost: $#{message.total_cost_usd}" if message.total_cost_usd
67
+ puts "Error: #{message.is_error}" if message.is_error
68
+ end
69
+ end
70
+ rescue ClaudeSDK::CLINotFoundError => e
71
+ puts "Error: #{e.message}"
72
+ puts "Please install Claude Code CLI first"
73
+ rescue ClaudeSDK::CLIConnectionError => e
74
+ puts "Connection error: #{e.message}"
75
+ rescue ClaudeSDK::ProcessError => e
76
+ puts "Process error: #{e.message}"
77
+ puts "Exit code: #{e.exit_code}" if e.exit_code
78
+ puts "Stderr: #{e.stderr}" if e.stderr
79
+ rescue StandardError => e
80
+ puts "Unexpected error: #{e.class} - #{e.message}"
81
+ puts e.backtrace
82
+ end
@@ -0,0 +1,50 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "claude_sdk"
5
+
6
+ # Example: Using enumerators for fine-grained control
7
+
8
+ # Get an enumerator instead of using a block
9
+ messages = ClaudeSDK.query("Write a haiku about Ruby programming")
10
+
11
+ # Process messages with more control
12
+ message_count = 0
13
+ assistant_messages = []
14
+
15
+ begin
16
+ loop do
17
+ message = messages.next
18
+ message_count += 1
19
+
20
+ case message
21
+ when ClaudeSDK::Messages::User
22
+ puts "šŸ“Ø Message #{message_count}: User prompt received"
23
+
24
+ when ClaudeSDK::Messages::Assistant
25
+ assistant_messages << message
26
+ text_blocks = message.content.select { |b| b.is_a?(ClaudeSDK::ContentBlock::Text) }
27
+ puts "šŸ¤– Message #{message_count}: Assistant responded with #{text_blocks.count} text blocks"
28
+
29
+ # We could break early if we wanted
30
+ # break if text_blocks.any? { |b| b.text.include?("haiku") }
31
+
32
+ when ClaudeSDK::Messages::System
33
+ puts "āš™ļø Message #{message_count}: System message (#{message.subtype})"
34
+
35
+ when ClaudeSDK::Messages::Result
36
+ puts "āœ… Message #{message_count}: Completed in #{message.duration_ms}ms"
37
+ break # End of conversation
38
+ end
39
+ end
40
+ rescue StopIteration
41
+ # Normal end of enumeration
42
+ end
43
+
44
+ # Display the haiku
45
+ puts "\nšŸ“ Generated Haiku:"
46
+ assistant_messages.each do |msg|
47
+ msg.content.each do |block|
48
+ puts block.text if block.is_a?(ClaudeSDK::ContentBlock::Text)
49
+ end
50
+ end
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "claude_sdk"
5
+
6
+ # Example: Proper error handling with ClaudeSDK
7
+
8
+ begin
9
+ ClaudeSDK.query("Hello, Claude!") do |message|
10
+ puts message.inspect
11
+ end
12
+ rescue ClaudeSDK::CLINotFoundError => e
13
+ puts "āŒ Claude CLI not found!"
14
+ puts e.message
15
+ puts "\nTo install Claude CLI:"
16
+ puts " npm install -g @anthropic-ai/claude-code"
17
+ rescue ClaudeSDK::CLIConnectionError => e
18
+ puts "āŒ Failed to connect to Claude CLI"
19
+ puts e.message
20
+ rescue ClaudeSDK::ProcessError => e
21
+ puts "āŒ Process failed"
22
+ puts "Exit code: #{e.exit_code}"
23
+ puts "Error output: #{e.stderr}"
24
+ rescue ClaudeSDK::Error => e
25
+ # Catch any other ClaudeSDK errors
26
+ puts "āŒ An error occurred: #{e.message}"
27
+ rescue StandardError => e
28
+ # Catch unexpected errors
29
+ puts "āŒ Unexpected error: #{e.class} - #{e.message}"
30
+ puts e.backtrace.first(5).join("\n")
31
+ end
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "claude_sdk"
5
+
6
+ # Example: Using MCP (Model Context Protocol) servers
7
+
8
+ # Configure MCP servers
9
+ mcp_servers = {
10
+ "filesystem" => {
11
+ type: "stdio",
12
+ command: "npx",
13
+ args: ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"],
14
+ },
15
+ "git" => {
16
+ type: "stdio",
17
+ command: "npx",
18
+ args: ["-y", "@modelcontextprotocol/server-git", "--repository", "."],
19
+ },
20
+ }
21
+
22
+ # Create options with MCP servers
23
+ options = ClaudeSDK::ClaudeCodeOptions.new(
24
+ mcp_servers: mcp_servers,
25
+ mcp_tools: ["read_file", "write_file", "git_status", "git_diff"],
26
+ )
27
+
28
+ # Query using MCP tools
29
+ ClaudeSDK.query("Read the README.md file and summarize it", options: options) do |message|
30
+ case message
31
+ when ClaudeSDK::Messages::Assistant
32
+ message.content.each do |block|
33
+ if block.is_a?(ClaudeSDK::ContentBlock::ToolUse) && block.name.start_with?("mcp_")
34
+ puts "šŸ”Œ Using MCP tool: #{block.name}"
35
+ puts " Server: #{block.name.split("_")[1]}"
36
+ puts " Input: #{block.input.inspect}"
37
+ elsif block.is_a?(ClaudeSDK::ContentBlock::Text)
38
+ puts "šŸ“ #{block.text}"
39
+ end
40
+ end
41
+ when ClaudeSDK::Messages::Result
42
+ puts "\nāœ… Done! Used #{message.num_turns} turns"
43
+ end
44
+ end
@@ -0,0 +1,41 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "claude_sdk"
5
+
6
+ # Example: Using ClaudeSDK with various options
7
+
8
+ # Create options with custom settings
9
+ options = ClaudeSDK::ClaudeCodeOptions.new(
10
+ system_prompt: "You are a helpful Ruby programming assistant",
11
+ cwd: Dir.pwd,
12
+ max_thinking_tokens: 10_000,
13
+ permission_mode: :accept_edits, # Auto-accept file edits
14
+ allowed_tools: ["bash", "read", "write"],
15
+ model: "claude-3.5-sonnet",
16
+ )
17
+
18
+ # Query with options
19
+ ClaudeSDK.query("Write a Ruby function to calculate fibonacci numbers", options: options) do |message|
20
+ case message
21
+ when ClaudeSDK::Messages::User
22
+ puts "\nšŸ‘¤ User: #{message.content}"
23
+ when ClaudeSDK::Messages::Assistant
24
+ message.content.each do |block|
25
+ case block
26
+ when ClaudeSDK::ContentBlock::Text
27
+ puts "\nšŸ¤– Claude: #{block.text}"
28
+ when ClaudeSDK::ContentBlock::ToolUse
29
+ puts "\nšŸ”§ Using tool: #{block.name}"
30
+ puts " Input: #{block.input.inspect}"
31
+ when ClaudeSDK::ContentBlock::ToolResult
32
+ puts "\nšŸ“Š Tool result: #{block.content}"
33
+ end
34
+ end
35
+ when ClaudeSDK::Messages::Result
36
+ puts "\nāœ… Completed!"
37
+ puts " Duration: #{message.duration_ms}ms"
38
+ puts " API calls: #{message.duration_api_ms}ms"
39
+ puts " Total cost: $#{format("%.4f", message.total_cost_usd || 0)}"
40
+ end
41
+ end