Claude Agent SDK in Ruby: Your 3 Real Options
Anthropic ships no official Claude Agent SDK for Ruby. Compare three real paths: the official anthropic gem, a community gem, and shelling to the Claude CLI.
If you searched for "claude agent sdk ruby" hoping for a gem install, the answer is that Anthropic does not ship one. That does not leave you stuck, though. There are three real ways to build a Claude agent in Ruby today, and picking the right one is mostly about how much of the Claude Code harness you actually need.
Is There an Official Claude Agent SDK for Ruby?
No. Anthropic ships the Claude Agent SDK for Python and TypeScript only; Ruby has no official port. The SDK (formerly called the Claude Code SDK) is Claude Code packaged as a library: the same agent loop, built-in tools, context management, hooks, subagents, and MCP support that power the CLI, exposed as pip install claude-agent-sdk or npm install @anthropic-ai/claude-agent-sdk. There is no gem in that list, and the official changelog and bug tracker cover only the two languages.
This distinction matters, because a lot of tutorials blur the line between the Agent SDK and the plain API SDK. They are different products. The Anthropic Client SDK gives you direct API access where you implement the tool loop yourself; the Agent SDK gives you Claude with the tool loop, filesystem tools, and permissioning already built. Ruby has an official version of the first one (the anthropic gem) and no official version of the second.
So "wait for the SDK" is the wrong question for a Rubyist. The useful one is which of the three available paths gets you an agent with the least friction. Two of them are officially supported building blocks; one is a community gem that gets you closest to the Python and TypeScript developer experience.
The Unofficial Option: the claude-agent-sdk Gem
The claude-agent-sdk gem is an unofficial, community-maintained Ruby gem by ya-luotao that mirrors the Python Agent SDK's surface. It fills the gap Anthropic left. ya-luotao/claude-agent-sdk-ruby publishes as the claude-agent-sdk gem, and the mirroring is deliberate: a ClaudeAgentSDK.query for single-turn calls, a ClaudeAgentSDK::Client for bidirectional streaming sessions with hooks and callbacks, ClaudeAgentSDK.create_tool for defining in-process tools, and a ClaudeAgentOptions configuration object. If you have used the Python SDK, the shapes will feel familiar.
The important mechanical detail: it does not call the Anthropic API directly. It wraps the claude CLI as a subprocess and communicates over stream-JSON on stdin and stdout, which is the same wire protocol the official SDKs use under the hood. The practical consequence is that the gem does not bundle a binary. You have to install the CLI separately (npm install -g @anthropic-ai/claude-code), which means your Ruby agent now has a Node.js and CLI dependency in every environment it runs in, including CI and production containers. It targets Ruby 3.2 and up.
Then there is the maturity question. As of this writing the gem is pre-1.0 and moving fast, with frequent releases (check the changelog for the current version). That is genuinely useful and clearly maintained, but it is a pre-1.0 project by one maintainer, not a supported Anthropic library. It is not affiliated with or supported by Anthropic, and the README says so. For a side project or an internal coding-automation tool, that trade is often fine. For something load-bearing in production, pin the exact version, read the changelog before every bump, and know that you own the risk if the underlying CLI protocol shifts.
Your Three Real Paths
The three real paths are the official anthropic gem with a hand-rolled agent loop, the unofficial claude-agent-sdk community gem, and shelling out to the claude CLI. The table runs top to bottom, from the simplest thing that works to the most capable.
| Path | Gem or tool | Official? | Best for | Main trade-off |
|---|---|---|---|---|
| Hand-rolled agent loop | Official anthropic gem |
Yes (API SDK) | Rails apps: agents over your own models, tools, and Pundit policies | You write and own the loop (or use its tool_runner); no built-in filesystem harness |
| Agent-harness gem | claude-agent-sdk (community) |
No | Coding and shell automation that wants the Claude Code tools and loop in Ruby | Pre-1.0, single maintainer, and a Node.js plus CLI dependency |
| Shell out to the CLI | claude CLI (claude -p) |
Yes (CLI) | CI scripts, one-off automations, and glue where a subprocess is acceptable | You parse JSON out of a subprocess; not an in-process object model |
The dividing question is what kind of agent you are building. If the agent acts on your database and business logic (look up an invoice, draft a reply, update a record), the plain anthropic gem is the right tool, because the "harness" you want is your own Rails app. If the agent acts on files, a repo, and the shell (a coding assistant, a refactor bot, a CI reviewer), the Claude Code harness is exactly what you want, and either the community gem or the CLI gives it to you.
How It Compares to Claude Code and to LangGraph
"Claude Agent SDK vs Claude Code" is close to a non-question: they are the same harness with different interfaces. Claude Code is the interactive CLI; the Agent SDK is that harness as a library. Anthropic's own guidance is to use the CLI for interactive development and one-off tasks, and the SDK for CI/CD and production automation.
"Claude Agent SDK vs LangGraph" is a different axis. LangGraph is a low-level, graph-based orchestration framework for stateful, long-running agents, built by the LangChain team. It is model-agnostic and centers on nodes, edges, and shared state with durable execution and human-in-the-loop checkpoints. But it is a Python framework (with a JS port), so for a Ruby shop it is not actually on the table unless you are willing to stand up a Python service. That is often the real reason Rubyists end up on one of the three paths above rather than a heavier orchestration framework.
Replicating the Agent Loop with the Official anthropic Gem
The official Anthropic Ruby SDK is the client (plain API) SDK, and the "agent" is a loop you run over it. For most Rails work, this is the path I reach for. The loop itself is small. You send the conversation, check whether the model asked for a tool, run it, feed the result back, and repeat until the model stops asking.
# Gemfile
gem "anthropic"
# config/initializers/anthropic.rb
# The client is threadsafe and pools connections, so create one and reuse it.
ANTHROPIC = Anthropic::Client.new(api_key: ENV.fetch("ANTHROPIC_API_KEY"))
The core loop, written by hand so you can see what the abstraction hides:
def run_agent(client:, tools:, messages:, model: "claude-sonnet-5", max_turns: 10)
max_turns.times do
response = client.messages.create(
model: model,
max_tokens: 1024,
tools: tools.map(&:definition),
messages: messages
)
# The model is done when it stops asking to use tools.
break response if response.stop_reason != :tool_use
messages << { role: "assistant", content: response.content }
# Execute every tool the model requested and return one result each.
tool_results = response.content
.select { |block| block.type == :tool_use }
.map { |block| execute_tool(tools, block) }
messages << { role: "user", content: tool_results }
end
end
Do not drop the max_turns cap. It is the cheapest guardrail against a confused agent that keeps calling tools and running up a bill. The official gem also ships a tool_runner (currently under the beta.messages namespace) that owns this exact loop for you, so in practice you hand-write the loop only when you need to intercept a tool call mid-turn, for example to gate an irreversible action behind human approval.
I have written the full version of this, including tool design, MCP, background jobs, human-in-the-loop, and testing, in building AI agents in Ruby with the Anthropic SDK. If you want a companion API reference for the gem itself, the Anthropic Ruby SDK guide covers the client, streaming, and error hierarchy in more depth. The short pitch: a mature Rails monolith already has the tools, the authorization, and the job infrastructure an agent needs, so the "agent" is a thin layer, not a rewrite.
Shelling Out to the Claude CLI
The claude CLI in non-interactive mode (claude -p), called from Ruby with Open3, lets you run a Claude agent with no gem at all. It is the right answer when the job is "run Claude over this repo in CI" or "pipe a build log through Claude and write the explanation to a file." It is an official tool, and it is the same harness the SDK exposes.
require "open3"
require "json"
# claude -p runs non-interactively; --output-format json gives structured output.
stdout, status = Open3.capture2(
"claude", "-p", "Summarize the staged diff and flag risky changes",
"--output-format", "json",
"--allowedTools", "Bash(git diff *),Read"
)
raise "claude failed" unless status.success?
payload = JSON.parse(stdout)
puts payload.fetch("result")
# payload also carries session metadata and, with json output, cost figures.
When this is the right call: CI linters and reviewers, scheduled maintenance scripts, and any glue where a subprocess boundary is acceptable and you would rather not carry a gem. The CLI supports --output-format json for a structured result with a session_id and cost data, --continue and --resume to thread conversations, and --bare to skip auto-discovery of hooks and MCP servers for reproducible runs.
When it is the wrong call: anything that wants a real object model, in-process custom tools, or tight streaming into a Rails UI. Parsing JSON out of a subprocess is fine for scripts and grating for an application. That is the line where the community gem or the plain anthropic gem earns its place.
When Each Path Falls Down
Every one of these has a failure mode, so pick with the downside in view.
The community gem carries a Node.js and CLI dependency into every environment, and it is pre-1.0 by a single maintainer. If the CLI's stream-JSON protocol changes upstream, you are waiting on a community fix. Pin the version, and do not put it on a critical path you cannot afford to babysit.
Shelling to the CLI means process spawn overhead per call, a subprocess to supervise, and stdout parsing that is brittle if you do not use --output-format json. It also inherits whatever .claude config and MCP servers exist in the working directory unless you pass --bare, which can make CI behave differently from a laptop.
The hand-rolled loop on the official gem gives you no filesystem harness at all: no built-in Read, Edit, Bash, Grep, or WebSearch tools. You build the tools you need. For agents over your own domain that is a feature, because you did not want the model running arbitrary shell commands anyway. For a coding agent it is a lot of reinvention, and you would be better served by the harness paths.
On Amazon Bedrock specifically ("claude agent sdk bedrock" is a common query): the official Agent SDK and CLI reach Bedrock through CLAUDE_CODE_USE_BEDROCK=1 and AWS credentials, and Vertex through CLAUDE_CODE_USE_VERTEX=1. The community Ruby gem inherits that because it shells to the same CLI. The official anthropic gem takes the other route with a dedicated Bedrock client for the plain API. Either way, Bedrock is reachable from Ruby; just know which layer is doing the talking.
Which Should You Choose?
Here is what I would actually reach for. If you are building an agent inside a Rails app that acts on your own data, use the official anthropic gem and run the loop (or its tool_runner). It is officially supported, it has no extra runtime dependencies, and it reuses the authorization and job infrastructure you already have. This is the default, and it is where most production Rails agents belong.
If you want the Claude Code experience in Ruby (an agent that reads files, runs commands, and edits code) and you are comfortable owning a pre-1.0 dependency, try the community claude-agent-sdk gem. It is the closest thing to the Python and TypeScript developer experience, and for coding automation it saves you from rebuilding the harness. Just pin the version and keep the Node.js dependency in mind.
If the task is a script or a CI step and you do not want a gem in the loop at all, shell out to the claude CLI with --output-format json. It is official and stable, and it never pretends to be more than a subprocess.
The one path I would not take is waiting. There is no announced official Ruby Agent SDK, and you can build a solid agent today on any of the three.
After You Pick a Path
Whichever path you take, the remaining work is the same: tool design, background jobs, human approval, prompt-injection defenses, and testing. Those concerns live in your code, not the SDK, so nothing about the choice above lets you skip them. That is also why the choice is lower-stakes than it looks: you can switch paths later without redoing the parts that took real effort.
Which of the three paths fits is not really a preference question. Write down what you need from five rows - Claude-specific features, provider portability, local CLI control, tool authorization, and background execution - and one path usually survives. Choosing before that list exists is how projects end up on the unofficial gem for a Claude-only app, or shelling to the CLI for something the SDK does directly.
Further Reading
- Rails AI Agents with the Anthropic SDK - the full agent loop, tools, MCP, background jobs, and testing on the official gem
- Anthropic Ruby SDK: A Practical Guide - the client, streaming, tool runner, and error handling for the official gem
- Rails AI Agents - the hub for SDK boundaries, tool design, background jobs, approvals, and cost tracking in Rails
- Claude Agent SDK overview - Anthropic's official docs (Python and TypeScript)
- ya-luotao/claude-agent-sdk-ruby - the unofficial community gem
- anthropic-sdk-ruby on GitHub - the official Ruby API SDK