DEV Community

Cover image for I Built an MCP Server That Lets AI Agents Debug Running Ruby Processes
Ryo Hayakawa
Ryo Hayakawa

Posted on

I Built an MCP Server That Lets AI Agents Debug Running Ruby Processes

girb-mcp is an MCP server that gives LLM agents access to running Ruby processes.

girb-mcp

日本語版 (Japanese)

MCP (Model Context Protocol) server that gives LLM agents access to the runtime context of executing Ruby processes.

LLM agents can connect to a paused Ruby process, inspect variables, evaluate code, set breakpoints, and control execution — all through MCP tool calls.

What it does

Existing Ruby/Rails MCP servers only provide static analysis or application-level APIs. girb-mcp goes further: it connects to running Ruby processes via the debug gem and exposes their runtime state to LLM agents.

Agent → connect(host: "localhost", port: 12345)
Agent → get_context()
  → local variables, instance variables, call stack
Agent → evaluate_code(code: "user.valid?")
  → false
Agent → evaluate_code(code: "user.errors.full_messages")
  → ["Email can't be blank"]
Agent → continue_execution()

Installation

gem "girb-mcp"
Enter fullscreen mode Exit fullscreen mode

Or install directly:

gem install girb-mcp

Requires Ruby >= 3.2.0.

Quick Start

1. Start a Ruby process with the debugger

# Script
rdbg --open --port=12345 my_script.rb
# Or with environment variables
RUBY_DEBUG_OPEN=true RUBY_DEBUG_PORT=12345
Enter fullscreen mode Exit fullscreen mode

It works with any client that supports MCP (Model Context Protocol). Tested with Claude Code and Gemini CLI.

For example, you can simply tell the agent "investigate this bug," and it will actually send requests, inspect runtime state, and identify the root cause:

You:   The users list page is returning a 500 error.
       Connect to the debug session and find out why.

Agent: I set a breakpoint in the controller and sent a request.
       After inspecting variables at the stop point, I found a record
       with a nil name in @users (User ID: 42).
       The view calls user.name.uppercase, which raises a
       NoMethodError at that point.
Enter fullscreen mode Exit fullscreen mode

The key here is the ability to see what's actually happening at runtime — something you can't get just by reading code.

Check out this video to see it in action:

How girb-mcp Differs from girb

girb, which I released recently, is a tool for humans to interactively call AI from within IRB or the Rails console.

girb (Generative IRB)

An AI assistant for Ruby development. Works with IRB, Rails console, and the debug gem.

日本語版 README

Features

  • Context Awareness: Understands local variables, instance variables, and runtime state
  • Tool Execution: AI autonomously executes code, inspects objects, and reads files
  • Autonomous Investigation: AI loops through investigate-execute-analyze cycles
  • Multi-environment Support: Works with IRB, Rails console, and debug gem (rdbg)
  • Provider Agnostic: Use any LLM (OpenAI, Anthropic, Gemini, Ollama, etc.)

Quick Start

# 1. Install
gem install girb girb-ruby_llm

# 2. Set your API key
export GEMINI_API_KEY="your-api-key"  # or OPENAI_API_KEY, ANTHROPIC_API_KEY

# 3. Create ~/.girbrc
```ruby
require 'girb-ruby_llm'
Girb.configure do |c|
  c.provider = Girb::Providers::RubyLlm.new(model: 'gemini-2.5-flash')
end
Enter fullscreen mode Exit fullscreen mode

4. Run

girb


Then type a question and press **Ctrl+Space**, or use `qq <question>`
## Table of Contents

1. [Configuration](#1-configuration) - Common setup for all environments

girb-mcp takes the same approach — "accessing the context of a running Ruby process" — and makes it available to LLM agents.

girb girb-mcp
Who uses it Humans (interactive in IRB) LLM agents (via MCP)
Interface Commands in the REPL MCP tool calls
How to run girb or binding.girb Add to MCP client config

If girb is a tool for "humans debugging with AI assistance," then girb-mcp is a tool for "AI debugging autonomously."

How It Differs from Existing MCP Servers

There are already several MCP servers for Ruby/Rails, but they mainly focus on static analysis and application-level APIs (DB queries, route inspection, etc.).

girb-mcp connects to a running Ruby process via the debug gem and exposes its runtime state to the agent.

Agent → connect(host: "localhost", port: 12345)
Agent → get_context()
  → local variables, instance variables, call stack
Agent → evaluate_code(code: "user.valid?")
  → false
Agent → evaluate_code(code: "user.errors.full_messages")
  → ["Email can't be blank"]
Agent → continue_execution()
Enter fullscreen mode Exit fullscreen mode

The decisive difference from static analysis is the ability to actually evaluate and return things like "what value does this variable hold right now?" or "what's the result of user.valid??"

In a dynamic language like Ruby, there are many bugs you can't figure out just by reading code, so I believe this approach is particularly effective.

Architecture

  1. The debug gem (rdbg --open) exposes a socket on the target Ruby process
  2. girb-mcp connects to that socket using the debug gem's protocol
  3. Tool calls from the MCP client are translated into debugger commands, and the results are returned

MCP is an open standard developed by Anthropic — a protocol for connecting LLMs to external tools. girb-mcp uses the mcp gem to comply with this specification, so it works with any MCP-compatible client.

Features

Investigation Tools

Tool Description
evaluate_code Execute Ruby code in the stopped binding
inspect_object Get an object's class, value, and instance variables
get_context Get local variables, instance variables, call stack, and breakpoints all at once
get_source Get the source code of a method or class

Execution Control

Tool Description
set_breakpoint Set breakpoints by line, method, or exception class
continue_execution Resume execution until the next breakpoint or termination
step / next / finish Step in / step over / run until method returns

Rails Support

Rails-specific tools are automatically added when a Rails process is detected.

Tool Description
rails_info Show app name, Rails version, environment, and DB info
rails_routes Show routes with filtering
rails_model Show a model's columns, associations, validations, and enums
trigger_request Send an HTTP request to the Rails app being debugged

trigger_request automatically disables CSRF protection temporarily for POST and other requests, so you can send requests without worrying about tokens.

Beyond Debugging: The Next Step in AI Coding

When you ask AI to implement something, it writes tests too. And the tests pass. But are those tests actually correct?

Tests written by AI only verify "the spec as the AI understood it." They don't necessarily verify the behavior the user intended. The tests pass, but when you actually run the app, it doesn't work the way you expected. I think this is a common experience in AI coding.

With girb-mcp, you can go one step further beyond tests:

  1. AI writes the implementation
  2. AI writes and passes the tests
  3. Use girb-mcp to actually run the app and verify it behaves as intended

For example, say you asked AI to implement "only admins can delete articles." After the tests pass, you can actually send a DELETE request and confirm that a regular user gets a 403, and an admin successfully deletes the article — verified through actual behavior.

Where before the story ended with "tests pass, now a human needs to manually verify," you can now delegate verification to the AI as well. Humans just need to look at the final working result and make a judgment.

Installation and Setup

Install the gem:

gem install girb-mcp
Enter fullscreen mode Exit fullscreen mode

Add girb-mcp to your MCP client's configuration.

For Claude Code (~/.claude/settings.json):

{
  "mcpServers": {
    "girb-mcp": {
      "command": "girb-mcp",
      "args": []
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

For Gemini CLI (~/.gemini/settings.json):

{
  "mcpServers": {
    "girb-mcp": {
      "command": "girb-mcp",
      "args": []
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Any MCP client that supports STDIO transport can use a similar configuration.
If using Bundler, change command to bundle and args to ["exec", "girb-mcp"].

Requires Ruby >= 3.2.0.

Try It Out

Debugging a Ruby Script

rdbg --open --port=12345 my_script.rb
Enter fullscreen mode Exit fullscreen mode

Then just ask the agent:

"Connect to the debug session and show me the current state."

There's also a run_script tool, so you can let the agent handle launching the Ruby script itself.

Debugging a Rails App

girb-mcp comes with a command to start a Rails server in debug mode:

girb-rails    # Equivalent to RUBY_DEBUG_OPEN=true bin/rails server
Enter fullscreen mode Exit fullscreen mode

Tell the agent:

"Set a breakpoint on line 15 of app/controllers/users_controller.rb and send a GET request to /users/1."

The agent will automatically handle the entire flow: setting the breakpoint → sending the request → inspecting variables at the stop point.

Works with Processes Inside Docker Too

You can connect to Ruby processes inside Docker via TCP or Unix socket volume mounts. When connecting via TCP, you can browse and read files inside the container even without having the source code locally.

Security Notes

A few things to keep in mind:

  • evaluate_code can execute arbitrary Ruby code. However, dangerous operations like file manipulation and system commands are restricted by the LLM agent's policies. girb-mcp is simply a "window to the debugger" and is designed to be used in combination with the agent's guardrails.
  • The debug gem has no authentication. When exposing a debug port via TCP, bind to 127.0.0.1 or otherwise restrict access.
  • Do not use in production. This is a tool for development and debugging purposes only.

The girb Family

girb-mcp is part of the girb family:

  • girb — AI-powered IRB assistant (interactive, for humans)
  • girb-mcp — MCP server for LLM agents (programmatic, for agents)
  • girb-ruby_llm — LLM provider via ruby_llm
  • girb-gemini — LLM provider via Gemini API

Feedback Welcome

girb-mcp is still a work in progress. If you try it out and notice anything, please let me know!

Any feedback is welcome — whether it's "this part is hard to use" or "I'd love to see this feature"!

Top comments (0)