claude-agent-ruby
Implement or modify Ruby code that uses the claude-agent-sdk gem, including query() one-shot calls, Client-based interactive sessions, streaming input, option configuration, tools/permissions, hooks, SDK MCP servers, structured output, budgets, sandboxing, session resumption, session browsing (list_sessions/get_session_messages), task lifecycle messages, MCP server control (reconnect/toggle/stop), Rails integration, and error handling.
Packaged view
This page reorganizes the original catalog entry around fit, installability, and workflow context first. The original raw source lives below.
Install command
npx @skill-hub/cli install ya-luotao-claude-agent-sdk-ruby-claude-agent-ruby
Repository
Skill path: .claude/skills/claude-agent-ruby
Implement or modify Ruby code that uses the claude-agent-sdk gem, including query() one-shot calls, Client-based interactive sessions, streaming input, option configuration, tools/permissions, hooks, SDK MCP servers, structured output, budgets, sandboxing, session resumption, session browsing (list_sessions/get_session_messages), task lifecycle messages, MCP server control (reconnect/toggle/stop), Rails integration, and error handling.
Open repositoryBest for
Primary workflow: Ship Full Stack.
Technical facets: Full Stack, Backend, Integration.
Target audience: everyone.
License: Unknown.
Original source
Catalog source: SkillHub Club.
Repository owner: ya-luotao.
This is still a mirrored public skill entry. Review the repository before installing into production workflows.
What it helps with
- Install claude-agent-ruby into Claude Code, Codex CLI, Gemini CLI, or OpenCode workflows
- Review https://github.com/ya-luotao/claude-agent-sdk-ruby before adding claude-agent-ruby to shared team environments
- Use claude-agent-ruby for development workflows
Works across
Favorites: 0.
Sub-skills: 0.
Aggregator: No.
Original source / Raw SKILL.md
---
name: claude-agent-ruby
description: Implement or modify Ruby code that uses the claude-agent-sdk gem, including query() one-shot calls, Client-based interactive sessions, streaming input, option configuration, tools/permissions, hooks, SDK MCP servers, structured output, budgets, sandboxing, session resumption, session browsing (list_sessions/get_session_messages), task lifecycle messages, MCP server control (reconnect/toggle/stop), Rails integration, and error handling.
---
# Claude Agent Ruby SDK
## Overview
Use this skill to build or refactor Ruby integrations with Claude Code via `claude-agent-sdk`, favoring the gem's README and types for exact APIs.
## Decision Guide
- Choose `ClaudeAgentSDK.query` for one-shot queries or streaming input. Internally uses the control protocol (streaming mode) since v0.7.0.
- Choose `ClaudeAgentSDK::Client` for multi-turn sessions, hooks, permission callbacks, MCP server control, or dynamic model switching; wrap in `Async do ... end.wait`.
- Choose SDK MCP servers (`create_tool`, `create_sdk_mcp_server`) for in-process tools; choose external MCP configs for subprocess/HTTP servers.
- Choose `ClaudeAgentSDK.list_sessions` / `ClaudeAgentSDK.get_session_messages` for browsing previous session transcripts (pure filesystem, no CLI needed).
## Implementation Checklist
- Confirm prerequisites (Ruby 3.2+, Node.js, Claude Code CLI).
- Build `ClaudeAgentSDK::ClaudeAgentOptions` and pass it to `query` or `Client.new`.
- Handle messages by type (`AssistantMessage`, `ResultMessage`, `UserMessage`, etc.) and content blocks (`TextBlock`, `ToolUseBlock`, `UnknownBlock`, etc.). Use `is_a?` filtering — unknown content block types are returned as `UnknownBlock` (with `.type` and `.data` accessors) and unknown message types are returned as `nil`.
- Handle task lifecycle messages: `TaskStartedMessage`, `TaskProgressMessage`, `TaskNotificationMessage` are `SystemMessage` subclasses — existing `is_a?(SystemMessage)` checks still match them. Use `is_a?(TaskStartedMessage)` for specific dispatch.
- Use `ResultMessage#stop_reason` to check why Claude stopped (e.g., `'end_turn'`, `'max_tokens'`, `'stop_sequence'`).
- Use `output_format` and read `StructuredOutput` tool-use blocks for JSON schema responses.
- Use `thinking:` with `ThinkingConfigAdaptive`, `ThinkingConfigEnabled(budget_tokens:)`, or `ThinkingConfigDisabled` to control extended thinking. Use `effort:` (`'low'`, `'medium'`, `'high'`) for effort level.
- Define hooks and permission callbacks as Ruby procs/lambdas; do not combine `can_use_tool` with `permission_prompt_tool_name`. Hook inputs include `tool_use_id` on `PreToolUseHookInput` and `PostToolUseHookInput`. Tool-lifecycle hooks (`PreToolUse`, `PostToolUse`, `PostToolUseFailure`, `PermissionRequest`) also carry `agent_id` and `agent_type` when firing inside subagents.
- For SDK MCP tools, include `mcp__<server>__<tool>` in `allowed_tools`. Use `annotations:` on `create_tool` for MCP tool annotations. Both symbol-keyed and string-keyed `input_schema` hashes are accepted (e.g., from RubyLLM or `JSON.parse`); the SDK normalizes to symbol keys internally.
- Use `tools` or `ToolsPreset` for base tool selection; use `append_allowed_tools` when extending defaults.
- Configure sandboxing via `SandboxSettings` and `SandboxNetworkConfig` when requested.
- Use `resume`, `session_id`, and `fork_session` for session handling; enable file checkpointing only when explicitly needed.
- Use `Client#reconnect_mcp_server(name)`, `Client#toggle_mcp_server(name, enabled)`, and `Client#stop_task(task_id)` for live MCP and task control.
- Use typed MCP status types: `McpStatusResponse.parse(client.get_mcp_status)` returns `McpServerStatus` objects with `server_info`, `tools`, `error`, etc.
- Note: when `system_prompt` is nil (default), the SDK passes `--system-prompt ""` to suppress the default Claude Code system prompt.
## Where To Look For Exact Details
- Locate the gem path with `bundle show claude-agent-sdk` or `ruby -e 'puts Gem::Specification.find_by_name(\"claude-agent-sdk\").full_gem_path'`.
- Read `<gem_path>/README.md` for canonical usage and option examples.
- Inspect `<gem_path>/lib/claude_agent_sdk/types.rb` for the full options and type list.
- Inspect `<gem_path>/lib/claude_agent_sdk/sessions.rb` for session browsing types and functions.
- Inspect `<gem_path>/lib/claude_agent_sdk/errors.rb` for error classes and handling.
- Use `references/usage-map.md` for a README section map and minimal skeletons.
## Resources
### references/
Use `references/usage-map.md` to map tasks to README sections and gem paths.
---
## Referenced Files
> The following files are referenced in this skill and included for context.
### references/usage-map.md
```markdown
# Usage Map (Gem Install)
## Locate gem docs (no repo needed)
- Bundler: `bundle show claude-agent-sdk`
- RubyGems: `ruby -e 'puts Gem::Specification.find_by_name("claude-agent-sdk").full_gem_path'`
- Open `<gem_path>/README.md`, `<gem_path>/lib/claude_agent_sdk/types.rb`, and `<gem_path>/lib/claude_agent_sdk/errors.rb`.
## README section map
- Installation
- Quick Start
- Basic Usage: query()
- Client
- Custom Tools (SDK MCP Servers)
- Hooks
- Permission Callbacks
- Structured Output
- Thinking Configuration
- Budget Control
- Fallback Model
- Beta Features
- Tools Configuration
- Sandbox Settings
- File Checkpointing & Rewind
- Session Browsing
- Rails Integration
- Types
- Error Handling
## Minimal skeletons
One-shot query:
```ruby
require 'claude_agent_sdk'
ClaudeAgentSDK.query(prompt: "Hello") { |msg| puts msg }
```
Interactive client:
```ruby
require 'claude_agent_sdk'
require 'async'
Async do
client = ClaudeAgentSDK::Client.new
client.connect
client.query("Hello")
client.receive_response { |msg| puts msg }
client.disconnect
end.wait
```
SDK MCP tool (with optional annotations):
```ruby
tool = ClaudeAgentSDK.create_tool(
'greet', 'Greet a user', { name: :string },
annotations: { title: 'Greeter', readOnlyHint: true }
) do |args|
{ content: [{ type: 'text', text: "Hello, #{args[:name]}!" }] }
end
server = ClaudeAgentSDK.create_sdk_mcp_server(name: 'tools', tools: [tool])
options = ClaudeAgentSDK::ClaudeAgentOptions.new(
mcp_servers: { tools: server },
allowed_tools: ['mcp__tools__greet']
)
```
SDK MCP tool (pre-built JSON schema, e.g. from RubyLLM):
```ruby
tool = ClaudeAgentSDK.create_tool('save', 'Save a fact', {
'type' => 'object',
'properties' => { 'fact' => { 'type' => 'string' } },
'required' => ['fact']
}) { |args| { content: [{ type: 'text', text: "Saved: #{args[:fact]}" }] } }
```
SDK MCP tool (no parameters):
```ruby
tool = ClaudeAgentSDK.create_tool('ping', 'Ping the server', {}) do |_args|
{ content: [{ type: 'text', text: 'pong' }] }
end
```
Thinking configuration:
```ruby
# Adaptive (32k default budget)
options = ClaudeAgentSDK::ClaudeAgentOptions.new(
thinking: ClaudeAgentSDK::ThinkingConfigAdaptive.new
)
# Custom budget
options = ClaudeAgentSDK::ClaudeAgentOptions.new(
thinking: ClaudeAgentSDK::ThinkingConfigEnabled.new(budget_tokens: 10_000)
)
# Effort level
options = ClaudeAgentSDK::ClaudeAgentOptions.new(effort: 'high')
```
MCP server control (Client only):
```ruby
Async do
client = ClaudeAgentSDK::Client.new
client.connect
# Reconnect a failed server
client.reconnect_mcp_server('my-server')
# Disable a server
client.toggle_mcp_server('my-server', false)
# Stop a background task
client.stop_task('task_abc123')
# Get typed MCP status
raw = client.get_mcp_status
status = ClaudeAgentSDK::McpStatusResponse.parse(raw)
status.mcp_servers.each do |s|
puts "#{s.name}: #{s.status}"
end
client.disconnect
end.wait
```
Task lifecycle messages:
```ruby
ClaudeAgentSDK.query(prompt: "Do something") do |msg|
case msg
when ClaudeAgentSDK::TaskStartedMessage
puts "Task #{msg.task_id} started: #{msg.description}"
when ClaudeAgentSDK::TaskProgressMessage
puts "Task #{msg.task_id} progress: #{msg.usage}"
when ClaudeAgentSDK::TaskNotificationMessage
puts "Task #{msg.task_id} #{msg.status}: #{msg.summary}"
when ClaudeAgentSDK::ResultMessage
puts "Done (stop_reason: #{msg.stop_reason})"
end
end
```
Session browsing (no CLI needed):
```ruby
require 'claude_agent_sdk'
# List recent sessions
sessions = ClaudeAgentSDK.list_sessions(limit: 10)
sessions.each do |s|
puts "#{s.session_id}: #{s.summary} (#{s.git_branch})"
end
# Read messages from a session
messages = ClaudeAgentSDK.get_session_messages(session_id: sessions.first.session_id)
messages.each do |m|
puts "[#{m.type}] #{m.message}"
end
# List sessions for a specific directory
sessions = ClaudeAgentSDK.list_sessions(directory: '/path/to/project', include_worktrees: true)
```
```