This document provides an overview of the Ruby implementation of the Claude Agent SDK, based on the Python version.
The Ruby SDK has been fully implemented with the following components:
-
Transport Layer (411 lines)
transport.rb- Abstract transport interface (44 lines)subprocess_cli_transport.rb- CLI subprocess implementation (367 lines)- Features: Process management, stderr handling, version checking, command building
-
Query Class (424 lines)
query.rb- Full control protocol implementation- Features:
- Bidirectional control request/response routing
- Hook callback execution
- Permission callback handling
- Message streaming with async queues
- Initialization handshake
- Full SDK MCP server support ✨
- Control operations: interrupt, set_permission_mode, set_model
-
SDK MCP Server (~150 lines)
sdk_mcp_server.rb- In-process MCP server implementation- Features:
SdkMcpServerclass for managing toolscreate_toolhelper for defining toolscreate_sdk_mcp_serverfunction for server creation- JSON schema generation from Ruby types
- Tool execution with error handling
- Full MCP protocol support (initialize, tools/list, tools/call)
-
Type System (358 lines)
types.rb- Complete type definitions- Message types: UserMessage, AssistantMessage, SystemMessage, ResultMessage, StreamEvent
- Content blocks: TextBlock, ThinkingBlock, ToolUseBlock, ToolResultBlock
- Configuration: ClaudeAgentOptions with all major settings
- MCP server configs: McpStdioServerConfig, McpSSEServerConfig, McpHttpServerConfig, McpSdkServerConfig
- Permission types: PermissionResultAllow, PermissionResultDeny, PermissionUpdate
- Hook types: HookMatcher, HookCallback
-
Message Parser (103 lines)
message_parser.rb- JSON message parsing- Handles all message types with proper error handling
-
Error Handling (53 lines)
errors.rb- Comprehensive error classes- ClaudeSDKError, CLIConnectionError, CLINotFoundError, ProcessError, CLIJSONDecodeError, MessageParseError
-
Main Library (256 lines)
lib/claude_agent_sdk.rb- Entry point with query() and Client class- Features:
- Simple
query()function for one-shot queries - Full-featured
Clientclass for bidirectional conversations - Hooks support
- Permission callbacks support
- Advanced features: interrupt, set_permission_mode, set_model, server_info
- Simple
- quick_start.rb - Basic usage examples with query()
- client_example.rb - Interactive client usage
- mcp_calculator.rb - Custom tools with SDK MCP servers ✨
- hooks_example.rb - Hook callback examples
- permission_callback_example.rb - Permission callback examples
- README.md - Overview, install, comparison table, quick start, and minimal API examples
- docs/ - Topic subpages (client, MCP servers, hooks, configuration, sessions, observability, Rails, types, errors) linked from the README
- CHANGELOG.md - Version history
- IMPLEMENTATION.md - This file
The Ruby SDK follows the Python SDK's architecture closely:
┌─────────────────────────────────────────┐
│ User Application │
│ (query() or Client with callbacks) │
└─────────────────┬───────────────────────┘
│
▼
┌─────────────────────────────────────────┐
│ Query (Control Protocol) │
│ - Hook execution │
│ - Permission callbacks │
│ - Message routing │
│ - Control requests/responses │
└─────────────────┬───────────────────────┘
│
▼
┌─────────────────────────────────────────┐
│ SubprocessCLITransport │
│ - Process management │
│ - stdin/stdout/stderr handling │
│ - Command building │
└─────────────────┬───────────────────────┘
│
▼
┌─────────────────────────────────────────┐
│ Claude Code CLI │
│ (External Node.js process) │
└─────────────────────────────────────────┘
- Async Runtime: Uses the
asyncgem (Ruby's async/await runtime) instead of Python'sanyio - Process Management: Uses Ruby's built-in
Open3for subprocess management (no external process gems needed) - Message Passing: Uses
Async::Queuefor message streaming instead of memory object streams - Synchronization: Uses
Async::Conditionfor control request/response coordination - Threading: Uses standard Ruby threads for stderr handling
- Naming: Follows Ruby conventions (snake_case) while maintaining API similarity
- Callbacks: Uses Ruby procs/lambdas for hooks and permission callbacks
- Basic query() function for simple queries
- Full Client class for interactive conversations
- Transport abstraction with subprocess implementation using Open3
- Complete message type system
- Message parsing with error handling
- Control protocol (bidirectional communication)
- Hook support (PreToolUse, PostToolUse, etc.)
- Permission callback support
- Interrupt capability
- Dynamic permission mode changes
- Dynamic model changes
- Server info retrieval
- Comprehensive error handling
- SDK MCP server support (in-process custom tools) ✨
- Full MCP protocol (initialize, tools/list, tools/call) ✨
- Working examples for all features
- Comprehensive RSpec test suite ✨
- Session forking support
- Agent definitions support
- Setting sources control
- Partial messages streaming support
- Streaming input support (Enumerator-based prompts) ✨
- MCP resource support (Data sources for SDK servers) ✨
- MCP prompt support (Reusable prompt templates) ✨
All major features have been implemented! The SDK has complete feature parity with the Python SDK.
- Same overall architecture
- Same message types and structures
- Same control protocol
- Same hook and permission callback concepts
- Similar API design
| Feature | Python | Ruby |
|---|---|---|
| Async runtime | anyio | async gem |
| Process management | Async subprocess | Open3 (built-in) |
| Message queue | MemoryObjectStream | Async::Queue |
| Synchronization | anyio.Event | Async::Condition |
| Type hints | Yes (TypedDict, dataclass) | No (uses regular classes) |
| MCP integration | Full with mcp package | Full SDK MCP support |
| Async iterators | Built-in | Uses blocks/enumerators |
import anyio
from claude_agent_sdk import query, ClaudeAgentOptions
async def main():
async for message in query(prompt="Hello"):
print(message)
anyio.run(main)require 'claude_agent_sdk'
require 'async'
Async do
ClaudeAgentSDK.query(prompt: "Hello") do |message|
puts message
end
end.wait- async (~2.0) - Async I/O runtime for concurrent operations
- Ruby 3.2+ required
- No external process management gems needed (uses built-in Open3)
The SDK includes a comprehensive RSpec test suite (unit + integration). See spec/README.md for how to run and extend it.
Run tests with:
bundle exec rspec # Run all tests
bundle exec rspec --format documentation # Detailed output
PROFILE=1 bundle exec rspec # Show slowest tests-
Additional MCP Features
- MCP server lifecycle management (start/stop/restart)
- Resource subscriptions (watch for changes)
- Sampling support
-
Additional Features
- Connection pooling for multiple queries
- Session persistence and replay
-
Performance
- Optimize message parsing
- Better async task management
- Lazy loading of optional components
-
Developer Experience
- Debug logging support
- Type documentation (YARD)
- More examples and tutorials
- Performance profiling tools
The Ruby SDK now includes full support for in-process MCP servers, allowing developers to define custom tools that run directly in their Ruby applications.
# Define a tool
add_tool = ClaudeAgentSDK.create_tool('add', 'Add numbers', { a: :number, b: :number }) do |args|
result = args[:a] + args[:b]
{ content: [{ type: 'text', text: "Result: #{result}" }] }
end
# Create server
server = ClaudeAgentSDK.create_sdk_mcp_server(name: 'calc', tools: [add_tool])
# Use with Claude
options = ClaudeAgentOptions.new(
mcp_servers: { calc: server },
allowed_tools: ['mcp__calc__add']
)The SDK MCP implementation consists of:
- SdkMcpServer - Manages tool registry and execution
- create_tool - Helper for defining tools with schemas
- Query integration - Routes MCP messages to server instances
- JSON schema conversion - Converts Ruby types to JSON schemas
The Ruby SDK successfully implements complete feature parity with the Python SDK, including the advanced SDK MCP server functionality. The implementation prioritizes correctness and maintainability while following Ruby idioms and conventions.
- Core implementation: ~1,700 lines of production code
- Test suite: RSpec coverage for major components
- Examples: Multiple runnable scripts under
examples/ - Documentation: Slim README + 9 topic subpages in
docs/, CHANGELOG, and implementation guide - Dependencies: Minimal (only
asyncgem + Ruby stdlib) - Ruby version: 3.2+ required
✅ Full bidirectional communication with Claude Code CLI ✅ Complete SDK MCP server support for in-process tools ✅ Comprehensive hook and permission callback system ✅ Production-ready with a comprehensive test suite ✅ Zero external dependencies for subprocess management (uses Open3) ✅ Clean, idiomatic Ruby code following community conventions
The SDK is production-ready and actively maintained as an unofficial, community-driven project.