claude_code 0.0.14

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.
data/docs/README.md ADDED
@@ -0,0 +1,254 @@
1
+ # Claude Code SDK for Ruby
2
+
3
+ Ruby SDK for Claude Code with streaming support and ergonomic MCP integration. See the [Claude Code SDK documentation](https://docs.anthropic.com/en/docs/claude-code/sdk) for more information.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'claude_code_sdk'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ ```bash
16
+ bundle install
17
+ ```
18
+
19
+ Or install it yourself as:
20
+
21
+ ```bash
22
+ gem install claude_code_sdk
23
+ ```
24
+
25
+ **Prerequisites:**
26
+ - Ruby 3.0+
27
+ - Node.js
28
+ - Claude Code: `npm install -g @anthropic-ai/claude-code`
29
+
30
+ ## Quick Start
31
+
32
+ ```ruby
33
+ require 'claude_code_sdk'
34
+
35
+ # Simple query with streaming
36
+ ClaudeCodeSDK.query(prompt: "What is 2 + 2?").each do |message|
37
+ if message.is_a?(ClaudeCodeSDK::AssistantMessage)
38
+ message.content.each do |block|
39
+ if block.is_a?(ClaudeCodeSDK::TextBlock)
40
+ puts block.text
41
+ end
42
+ end
43
+ end
44
+ end
45
+ ```
46
+
47
+ ## Features
48
+
49
+ ### 🌊 **Real-time Streaming**
50
+ - Messages arrive as they're generated (not after completion)
51
+ - Low memory footprint - process one message at a time
52
+ - Perfect for interactive applications and long-running operations
53
+
54
+ ### 🔧 **Ergonomic MCP Integration**
55
+ - Simple one-line MCP server configuration
56
+ - Support for HTTP, SSE, and stdio MCP servers
57
+ - Built-in helpers for common use cases
58
+
59
+ ### 🎯 **Model Selection**
60
+ - Support for model aliases (`sonnet`, `haiku`, `opus`)
61
+ - Full model name specification
62
+ - Easy switching between models
63
+
64
+ ### ⚙️ **Complete Configuration**
65
+ - All Claude Code CLI options supported
66
+ - Custom system prompts
67
+ - Tool permission management
68
+ - Working directory control
69
+
70
+ ## Examples
71
+
72
+ ### Basic Usage
73
+
74
+ ```ruby
75
+ require 'claude_code_sdk'
76
+
77
+ # With options
78
+ options = ClaudeCodeSDK::ClaudeCodeOptions.new(
79
+ model: "sonnet",
80
+ system_prompt: "You are a helpful assistant",
81
+ max_turns: 1
82
+ )
83
+
84
+ ClaudeCodeSDK.query(
85
+ prompt: "Explain Ruby blocks",
86
+ options: options,
87
+ cli_path: "/path/to/claude"
88
+ ).each do |message|
89
+ # Process streaming messages
90
+ end
91
+ ```
92
+
93
+ ### MCP Integration
94
+
95
+ ```ruby
96
+ # Ultra-convenient MCP usage
97
+ ClaudeCodeSDK.quick_mcp_query(
98
+ "Use the about tool to describe yourself",
99
+ server_name: "ninja",
100
+ server_url: "https://mcp-creator-ninja-v1-4-0.mcp.soy/",
101
+ tools: "about"
102
+ ).each do |message|
103
+ # Process MCP responses
104
+ end
105
+
106
+ # Advanced MCP configuration
107
+ mcp_servers = ClaudeCodeSDK.add_mcp_server("my_server", {
108
+ command: "node",
109
+ args: ["my-mcp-server.js"],
110
+ env: { "API_KEY" => "secret" }
111
+ })
112
+
113
+ options = ClaudeCodeSDK::ClaudeCodeOptions.new(
114
+ allowed_tools: ["mcp__my_server__my_tool"],
115
+ mcp_servers: mcp_servers
116
+ )
117
+ ```
118
+
119
+ ### Streaming with Custom Handling
120
+
121
+ ```ruby
122
+ # Auto-formatted streaming
123
+ ClaudeCodeSDK.stream_query(
124
+ prompt: "Count from 1 to 5",
125
+ options: ClaudeCodeSDK::ClaudeCodeOptions.new(max_turns: 1)
126
+ )
127
+
128
+ # Custom streaming with timestamps
129
+ start_time = Time.now
130
+ ClaudeCodeSDK.stream_query(
131
+ prompt: "Explain inheritance",
132
+ options: ClaudeCodeSDK::ClaudeCodeOptions.new(max_turns: 1)
133
+ ) do |message, index|
134
+ timestamp = Time.now - start_time
135
+ puts "[#{format('%.2f', timestamp)}s] #{message}"
136
+ end
137
+ ```
138
+
139
+ ### Rails + Sidekiq Integration
140
+
141
+ ```ruby
142
+ # Background job with real-time streaming
143
+ class ClaudeStreamingJob
144
+ include Sidekiq::Job
145
+
146
+ def perform(user_id, query_id, prompt, options = {})
147
+ channel = "claude_stream_#{user_id}_#{query_id}"
148
+
149
+ ClaudeCodeSDK.query(prompt: prompt, options: options).each do |message|
150
+ # Broadcast to ActionCable
151
+ ActionCable.server.broadcast(channel, {
152
+ type: 'message',
153
+ data: serialize_message(message),
154
+ timestamp: Time.current
155
+ })
156
+ end
157
+ end
158
+ end
159
+ ```
160
+
161
+ ## API Reference
162
+
163
+ ### Core Methods
164
+
165
+ #### `ClaudeCodeSDK.query(prompt:, options: nil, cli_path: nil, mcp_servers: {})`
166
+ Main method for querying Claude with streaming support.
167
+
168
+ #### `ClaudeCodeSDK.quick_mcp_query(prompt, server_name:, server_url:, tools:, **options)`
169
+ Convenient method for quick MCP server usage.
170
+
171
+ #### `ClaudeCodeSDK.stream_query(prompt:, options: nil, cli_path: nil, mcp_servers: {}, &block)`
172
+ Streaming helper with auto-formatting or custom block handling.
173
+
174
+ #### `ClaudeCodeSDK.add_mcp_server(name, config)`
175
+ Helper to create MCP server configurations.
176
+
177
+ ### Configuration Classes
178
+
179
+ #### `ClaudeCodeOptions`
180
+ Main configuration class with all CLI options:
181
+ - `model` - Model alias or full name
182
+ - `max_turns` - Limit conversation turns
183
+ - `system_prompt` - Custom system prompt
184
+ - `allowed_tools` - Tools to allow
185
+ - `mcp_servers` - MCP server configurations
186
+ - `permission_mode` - Permission handling mode
187
+ - `cwd` - Working directory
188
+
189
+ #### MCP Server Configurations
190
+ - `McpHttpServerConfig` - HTTP/HTTPS MCP servers
191
+ - `McpSSEServerConfig` - Server-Sent Events MCP servers
192
+ - `McpStdioServerConfig` - Stdio MCP servers
193
+
194
+ ### Message Types
195
+
196
+ #### `SystemMessage`
197
+ - `subtype` - Message subtype (e.g., "init")
198
+ - `data` - System data (session_id, tools, etc.)
199
+
200
+ #### `AssistantMessage`
201
+ - `content` - Array of content blocks
202
+
203
+ #### Content Blocks
204
+ - `TextBlock` - Text content
205
+ - `ToolUseBlock` - Tool usage with input
206
+ - `ToolResultBlock` - Tool results
207
+
208
+ #### `ResultMessage`
209
+ - `duration_ms` - Total duration
210
+ - `total_cost_usd` - API cost
211
+ - `session_id` - Conversation session
212
+ - `result` - Final result text
213
+
214
+ ## Error Handling
215
+
216
+ ```ruby
217
+ begin
218
+ ClaudeCodeSDK.query(prompt: "Hello").each do |message|
219
+ # Process message
220
+ end
221
+ rescue ClaudeCodeSDK::CLINotFoundError
222
+ puts "Please install Claude Code"
223
+ rescue ClaudeCodeSDK::ProcessError => e
224
+ puts "Process failed: #{e.exit_code}"
225
+ rescue ClaudeCodeSDK::CLIJSONDecodeError => e
226
+ puts "JSON parsing failed: #{e.message}"
227
+ end
228
+ ```
229
+
230
+ ## Examples Directory
231
+
232
+ - `examples/basic_usage.rb` - Basic SDK usage
233
+ - `examples/model_examples.rb` - Model specification examples
234
+ - `examples/mcp_examples.rb` - MCP integration examples
235
+ - `examples/streaming_examples.rb` - Streaming demonstrations
236
+ - `examples/rails_sidekiq_example.rb` - Rails/Sidekiq integration
237
+ - `examples/irb_helpers.rb` - IRB convenience functions
238
+
239
+ ## IRB Quick Start
240
+
241
+ ```ruby
242
+ # Load helpers
243
+ require_relative 'examples/irb_helpers'
244
+
245
+ # Try these commands:
246
+ quick_claude("What is Ruby?")
247
+ stream_claude("Explain blocks")
248
+ ninja_test("Tell me about yourself")
249
+ auto_stream("Count to 5")
250
+ ```
251
+
252
+ ## License
253
+
254
+ MIT
@@ -0,0 +1,404 @@
1
+ # MCP Integration
2
+
3
+ The Ruby Claude Code SDK provides ergonomic integration with Model Context Protocol (MCP) servers, allowing you to extend Claude's capabilities with custom tools and resources.
4
+
5
+ ## Quick Start
6
+
7
+ ### Ultra-Convenient Method
8
+
9
+ ```ruby
10
+ # Simplest way to use MCP
11
+ ClaudeCodeSDK.quick_mcp_query(
12
+ "Use the about tool to describe yourself",
13
+ server_name: "ninja",
14
+ server_url: "https://mcp-creator-ninja-v1-4-0.mcp.soy/",
15
+ tools: "about" # String or array of tools
16
+ ).each do |message|
17
+ # Process streaming MCP responses
18
+ end
19
+ ```
20
+
21
+ ## MCP Server Configuration
22
+
23
+ ### 1. HTTP/HTTPS Servers
24
+
25
+ ```ruby
26
+ # Simple URL string (auto-detected as HTTP)
27
+ mcp_servers = ClaudeCodeSDK.add_mcp_server(
28
+ "my_server",
29
+ "https://my-mcp-server.com/"
30
+ )
31
+
32
+ # Explicit HTTP configuration with headers
33
+ mcp_servers = ClaudeCodeSDK.add_mcp_server("api_server", {
34
+ type: "http",
35
+ url: "https://api.example.com/mcp",
36
+ headers: {
37
+ "Authorization" => "Bearer token123",
38
+ "X-API-Key" => "secret"
39
+ }
40
+ })
41
+ ```
42
+
43
+ ### 2. Server-Sent Events (SSE)
44
+
45
+ ```ruby
46
+ mcp_servers = ClaudeCodeSDK.add_mcp_server("sse_server", {
47
+ type: "sse",
48
+ url: "https://stream.example.com/mcp",
49
+ headers: {
50
+ "Authorization" => "Bearer token123"
51
+ }
52
+ })
53
+ ```
54
+
55
+ ### 3. Stdio (Command-line) Servers
56
+
57
+ ```ruby
58
+ # Simple command string
59
+ mcp_servers = ClaudeCodeSDK.add_mcp_server(
60
+ "local_server",
61
+ "node my-mcp-server.js"
62
+ )
63
+
64
+ # Full stdio configuration
65
+ mcp_servers = ClaudeCodeSDK.add_mcp_server("github_server", {
66
+ command: "npx",
67
+ args: ["@modelcontextprotocol/server-github"],
68
+ env: {
69
+ "GITHUB_TOKEN" => "your-github-token"
70
+ }
71
+ })
72
+ ```
73
+
74
+ ## Usage Patterns
75
+
76
+ ### Method 1: Separate MCP Servers Parameter
77
+
78
+ ```ruby
79
+ # Build server configuration
80
+ mcp_servers = ClaudeCodeSDK.add_mcp_server(
81
+ "ninja",
82
+ "https://mcp-creator-ninja-v1-4-0.mcp.soy/"
83
+ )
84
+
85
+ # Configure options
86
+ options = ClaudeCodeSDK::ClaudeCodeOptions.new(
87
+ allowed_tools: ["mcp__ninja__about"],
88
+ max_turns: 1
89
+ )
90
+
91
+ # Query with MCP servers
92
+ ClaudeCodeSDK.query(
93
+ prompt: "Use the about tool",
94
+ options: options,
95
+ mcp_servers: mcp_servers
96
+ ).each do |message|
97
+ # Process response
98
+ end
99
+ ```
100
+
101
+ ### Method 2: Options-based Configuration
102
+
103
+ ```ruby
104
+ # Configure everything in options
105
+ options = ClaudeCodeSDK::ClaudeCodeOptions.new(
106
+ mcp_servers: {
107
+ "ninja" => ClaudeCodeSDK::McpHttpServerConfig.new(
108
+ url: "https://mcp-creator-ninja-v1-4-0.mcp.soy/"
109
+ ),
110
+ "local" => ClaudeCodeSDK::McpStdioServerConfig.new(
111
+ command: "node",
112
+ args: ["my-server.js"]
113
+ )
114
+ },
115
+ allowed_tools: ["mcp__ninja__about", "mcp__local__my_tool"]
116
+ )
117
+
118
+ ClaudeCodeSDK.query(prompt: "Use available tools", options: options)
119
+ ```
120
+
121
+ ### Method 3: Multiple Servers
122
+
123
+ ```ruby
124
+ # Build multiple servers
125
+ servers = {}
126
+ servers.merge!(ClaudeCodeSDK.add_mcp_server("ninja", "https://..."))
127
+ servers.merge!(ClaudeCodeSDK.add_mcp_server("github", {
128
+ command: "npx",
129
+ args: ["@modelcontextprotocol/server-github"],
130
+ env: { "GITHUB_TOKEN" => ENV["GITHUB_TOKEN"] }
131
+ }))
132
+ servers.merge!(ClaudeCodeSDK.add_mcp_server("filesystem", "npx @modelcontextprotocol/server-filesystem /allowed/path"))
133
+
134
+ options = ClaudeCodeSDK::ClaudeCodeOptions.new(
135
+ allowed_tools: [
136
+ "mcp__ninja__about",
137
+ "mcp__github__search_repositories",
138
+ "mcp__filesystem__read_file"
139
+ ]
140
+ )
141
+
142
+ ClaudeCodeSDK.query(
143
+ prompt: "Use available tools to help me",
144
+ options: options,
145
+ mcp_servers: servers
146
+ )
147
+ ```
148
+
149
+ ## Tool Permission Management
150
+
151
+ ### Tool Naming Convention
152
+
153
+ MCP tools follow the pattern: `mcp__<server_name>__<tool_name>`
154
+
155
+ ```ruby
156
+ # Allow specific tools
157
+ allowed_tools: ["mcp__ninja__about", "mcp__github__search_repositories"]
158
+
159
+ # Allow all tools from a server (use with caution)
160
+ allowed_tools: ["mcp__ninja"] # Allows all ninja server tools
161
+ ```
162
+
163
+ ### Permission Modes
164
+
165
+ ```ruby
166
+ options = ClaudeCodeSDK::ClaudeCodeOptions.new(
167
+ permission_mode: "default", # Prompt for dangerous tools
168
+ # permission_mode: "acceptEdits", # Auto-accept file edits
169
+ # permission_mode: "bypassPermissions" # Allow all tools (dangerous)
170
+ )
171
+ ```
172
+
173
+ ## Streaming MCP Responses
174
+
175
+ MCP tool calls stream in real-time, showing tool usage and results as they happen:
176
+
177
+ ```ruby
178
+ ClaudeCodeSDK.quick_mcp_query(
179
+ "Use multiple tools to analyze this project",
180
+ server_name: "ninja",
181
+ server_url: "https://mcp-creator-ninja-v1-4-0.mcp.soy/",
182
+ tools: ["about", "create"], # Multiple tools
183
+ max_turns: 3
184
+ ).each do |message|
185
+ case message
186
+ when ClaudeCodeSDK::SystemMessage
187
+ puts "🔧 System: MCP servers: #{message.data['mcp_servers'].length}"
188
+
189
+ when ClaudeCodeSDK::AssistantMessage
190
+ message.content.each do |block|
191
+ case block
192
+ when ClaudeCodeSDK::TextBlock
193
+ puts "💬 #{block.text}"
194
+
195
+ when ClaudeCodeSDK::ToolUseBlock
196
+ puts "🔧 Using tool: #{block.name}"
197
+ puts "📥 Input: #{block.input}"
198
+
199
+ when ClaudeCodeSDK::ToolResultBlock
200
+ puts "📤 Tool result:"
201
+ puts " Content: #{block.content}"
202
+ puts " Error: #{block.is_error ? 'Yes' : 'No'}"
203
+ end
204
+ end
205
+
206
+ when ClaudeCodeSDK::ResultMessage
207
+ puts "✅ Completed - Cost: $#{format('%.6f', message.total_cost_usd || 0)}"
208
+ end
209
+ end
210
+ ```
211
+
212
+ ## Common MCP Servers
213
+
214
+ ### Creator Ninja (Example/Testing)
215
+ ```ruby
216
+ ClaudeCodeSDK.add_mcp_server(
217
+ "ninja",
218
+ "https://mcp-creator-ninja-v1-4-0.mcp.soy/"
219
+ )
220
+ # Tools: about, create
221
+ ```
222
+
223
+ ### Filesystem Server
224
+ ```ruby
225
+ ClaudeCodeSDK.add_mcp_server("filesystem", {
226
+ command: "npx",
227
+ args: ["-y", "@modelcontextprotocol/server-filesystem", "/allowed/path"],
228
+ })
229
+ # Tools: read_file, write_file, list_directory, etc.
230
+ ```
231
+
232
+ ### GitHub Server
233
+ ```ruby
234
+ ClaudeCodeSDK.add_mcp_server("github", {
235
+ command: "npx",
236
+ args: ["-y", "@modelcontextprotocol/server-github"],
237
+ env: {
238
+ "GITHUB_TOKEN" => ENV["GITHUB_TOKEN"]
239
+ }
240
+ })
241
+ # Tools: search_repositories, get_file_contents, create_issue, etc.
242
+ ```
243
+
244
+ ### Database Server (Example)
245
+ ```ruby
246
+ ClaudeCodeSDK.add_mcp_server("database", {
247
+ command: "node",
248
+ args: ["database-mcp-server.js"],
249
+ env: {
250
+ "DATABASE_URL" => ENV["DATABASE_URL"]
251
+ }
252
+ })
253
+ # Tools: query, schema, insert, update, etc.
254
+ ```
255
+
256
+ ## Error Handling
257
+
258
+ ```ruby
259
+ begin
260
+ ClaudeCodeSDK.quick_mcp_query(
261
+ "Use unavailable tool",
262
+ server_name: "ninja",
263
+ server_url: "https://bad-url.com/",
264
+ tools: "nonexistent"
265
+ ).each do |message|
266
+ # Process message
267
+ end
268
+ rescue ClaudeCodeSDK::ProcessError => e
269
+ puts "MCP server failed: #{e.message}"
270
+ puts "Exit code: #{e.exit_code}"
271
+ rescue ClaudeCodeSDK::CLIConnectionError => e
272
+ puts "Connection failed: #{e.message}"
273
+ end
274
+ ```
275
+
276
+ ## Rails Integration
277
+
278
+ ```ruby
279
+ class McpService
280
+ def self.query_with_mcp(prompt, mcp_config = {})
281
+ servers = build_mcp_servers(mcp_config)
282
+
283
+ options = ClaudeCodeSDK::ClaudeCodeOptions.new(
284
+ allowed_tools: mcp_config[:allowed_tools] || [],
285
+ permission_mode: "acceptEdits" # For automated environments
286
+ )
287
+
288
+ ClaudeCodeSDK.query(
289
+ prompt: prompt,
290
+ options: options,
291
+ mcp_servers: servers
292
+ )
293
+ end
294
+
295
+ private
296
+
297
+ def self.build_mcp_servers(config)
298
+ servers = {}
299
+
300
+ config[:servers]&.each do |name, server_config|
301
+ servers.merge!(ClaudeCodeSDK.add_mcp_server(name, server_config))
302
+ end
303
+
304
+ servers
305
+ end
306
+ end
307
+
308
+ # Usage in Rails
309
+ McpService.query_with_mcp(
310
+ "Analyze our GitHub repository",
311
+ servers: {
312
+ "github" => {
313
+ command: "npx",
314
+ args: ["@modelcontextprotocol/server-github"],
315
+ env: { "GITHUB_TOKEN" => Rails.application.credentials.github_token }
316
+ }
317
+ },
318
+ allowed_tools: ["mcp__github__search_repositories", "mcp__github__get_file_contents"]
319
+ ).each do |message|
320
+ # Process in background job with ActionCable broadcasting
321
+ end
322
+ ```
323
+
324
+ ## Configuration Examples
325
+
326
+ ### Development Environment
327
+ ```ruby
328
+ # config/claude_mcp.yml
329
+ development:
330
+ servers:
331
+ filesystem:
332
+ command: "npx"
333
+ args: ["-y", "@modelcontextprotocol/server-filesystem", "<%= Rails.root %>"]
334
+ github:
335
+ command: "npx"
336
+ args: ["-y", "@modelcontextprotocol/server-github"]
337
+ env:
338
+ GITHUB_TOKEN: "<%= Rails.application.credentials.github_token %>"
339
+
340
+ # Load in initializer
341
+ CLAUDE_MCP_CONFIG = YAML.load_file(Rails.root.join('config/claude_mcp.yml'))[Rails.env]
342
+ ```
343
+
344
+ ### Production Environment
345
+ ```ruby
346
+ # Use environment variables for security
347
+ ClaudeCodeSDK.add_mcp_server("production_api", {
348
+ type: "http",
349
+ url: ENV["MCP_API_URL"],
350
+ headers: {
351
+ "Authorization" => "Bearer #{ENV['MCP_API_TOKEN']}",
352
+ "X-Environment" => Rails.env
353
+ }
354
+ })
355
+ ```
356
+
357
+ ## Testing MCP Integration
358
+
359
+ ```ruby
360
+ # spec/support/mcp_helpers.rb
361
+ module McpHelpers
362
+ def mock_mcp_server(name, tools = ["about"])
363
+ allow(ClaudeCodeSDK).to receive(:add_mcp_server).with(name, anything).and_return({
364
+ name => double("MockMcpServer")
365
+ })
366
+
367
+ allow(ClaudeCodeSDK).to receive(:query).and_return([
368
+ mock_assistant_message_with_tools(tools)
369
+ ])
370
+ end
371
+
372
+ def mock_assistant_message_with_tools(tools)
373
+ content = tools.map do |tool|
374
+ ClaudeCodeSDK::ToolUseBlock.new(
375
+ id: "test-#{tool}",
376
+ name: "mcp__test__#{tool}",
377
+ input: {}
378
+ )
379
+ end
380
+
381
+ ClaudeCodeSDK::AssistantMessage.new(content)
382
+ end
383
+ end
384
+
385
+ # In tests
386
+ RSpec.describe "MCP Integration" do
387
+ include McpHelpers
388
+
389
+ it "uses MCP tools" do
390
+ mock_mcp_server("test", ["about"])
391
+
392
+ result = ClaudeCodeSDK.quick_mcp_query(
393
+ "Test prompt",
394
+ server_name: "test",
395
+ server_url: "http://test.com",
396
+ tools: "about"
397
+ )
398
+
399
+ expect(result).to include(have_attributes(class: ClaudeCodeSDK::AssistantMessage))
400
+ end
401
+ end
402
+ ```
403
+
404
+ The MCP integration provides a powerful way to extend Claude's capabilities with custom tools while maintaining the same streaming performance and ergonomic API as the core SDK.