I went looking for a Ruby port of Anthropic's Claude Agent SDK this week, the thing that ships as pip install claude-agent-sdk for Python and npm install @anthropic-ai/claude-agent-sdk for TypeScript. There is no gem in that list: Ruby has no official Claude Agent SDK, and one isn't in the works as far as any changelog shows.
That's a different gap than it sounds like at first. Ruby already has an official Anthropic library, the anthropic gem at anthropics/anthropic-sdk-ruby, but that one is the Client SDK: the plain API wrapper where you write the tool loop yourself. The Agent SDK is a different product: Claude Code's actual harness (agent loop, filesystem tools, permissions, hooks, subagents, MCP support) packaged as a library. Ruby has the first one and not the second, and most of the confusion I saw searching for this comes from tutorials that treat them as the same thing. Some of it is also naming: Anthropic called this the Claude Code SDK before renaming it the Claude Agent SDK, so "claude code sdk ruby" searches land in the same gap.
So "wait for the SDK" was the wrong question. The real one is which of three paths gets an agent running in Ruby with the least friction.
Path 1: the official gem, hand-rolled loop
This is what I reach for when the agent needs to act on my own app, not on a filesystem or a shell. Look up an invoice and draft a reply to it, that kind of thing.
class Anthropic::AgentRunner
def initialize(client: Anthropic::Client.new, tools:)
@client = client
@tools = tools
end
def run(messages, max_turns: 8)
max_turns.times do
response = @client.messages.create(
model: "claude-sonnet-5",
max_tokens: 1024,
messages: messages,
tools: @tools.map(&:schema)
)
return response unless response.stop_reason == :tool_use
messages << { role: "assistant", content: response.content }
messages << { role: "user", content: run_tools(response.content) }
end
raise "agent did not converge in #{max_turns} turns"
end
private
def run_tools(content)
content.select { |b| b.type == :tool_use }.map do |block|
tool = @tools.find { |t| t.name == block.name }
{ type: "tool_result", tool_use_id: block.id, content: tool.call(block.input) }
end
end
end
The max_turns cap is there because a confused agent that can loop forever will happily bill forever, and I would rather it raise loudly than retry the same tool call forty times in the background.
If you don't want to own the loop, the anthropic gem also ships a tool_runner (under the beta.messages namespace for now) that does the same thing for you, call the model, run the tool, feed the result back, repeat until the model stops asking. I write the loop by hand when I need a checkpoint mid-turn (human approval before a tool that sends an email, say), and use tool_runner otherwise.
Path 2: the unofficial claude-agent-sdk gem
If what you actually want is the Claude Code harness itself in Ruby, there's a community gem for that: ya-luotao/claude-agent-sdk-ruby, published as claude-agent-sdk. It deliberately mirrors the Python SDK's shape: ClaudeAgentSDK.query for one-off calls, ClaudeAgentSDK::Client for streaming sessions, ClaudeAgentSDK.create_tool for in-process tools.
One mechanical detail before you add it to a Gemfile: it doesn't call the Anthropic API directly. It shells out to the claude CLI as a subprocess and talks stream-JSON over stdin/stdout, the same protocol the official SDKs use internally. Which means your Ruby app now has a Node.js and CLI dependency everywhere it runs, CI included, and you're installing @anthropic-ai/claude-code alongside your gems.
It's also young: v0.19.0 as I write this, 42 stars, one maintainer, already on its 38th release. That pace is a good sign for a side project and a reason to pin the exact version if it's going anywhere load-bearing. The README says plainly it isn't affiliated with Anthropic, which is worth taking at face value. I compare all three paths in more depth, including how each one reaches Bedrock and Vertex, in the longer Claude Agent SDK in Ruby comparison on my site.
Path 3: shell out to the Claude Code CLI
The plainest option, and sometimes the right one for CI scripts or a one-off automation: run claude -p "your prompt" --output-format json as a subprocess and parse the JSON that comes back, with no gem in the middle. (Plain claude -p prints text; the flag is what makes the output parseable.) It's what the community gem is doing under the hood anyway, minus the Ruby object model wrapped around it.
Which one
If the agent's job is your database and your business logic, use the plain anthropic gem. The harness you actually want is your own Rails app with its existing authorization, not a generic filesystem-and-shell harness built for something else.
If the agent's job is files and a shell, a coding assistant, a refactor bot, a CI reviewer, that's what the Claude Code harness is built for, and the community gem or the raw CLI gets you there. I wouldn't build my own version of that harness from the plain API gem; that's reinventing a lot of surface area someone else already built and is actively maintaining.
If you're building agents in Rails more broadly, I also have a walkthrough of wiring a Claude agent into Rails background jobs and Turbo Streams.
Top comments (0)