MCP Connector

Expose Ruby Commands as MCP Tools for AI Assistants

Ruby gem exposing Foobara commands and entities as MCP tools, over a stdio server, for reading and mutating data.

Works with foobaraclaude

26
Spark score
out of 100
Updated 5 months ago
Source checked Sep 10, 2026
Version 1.0.1

Add to Favorites

Why it matters

Enable AI assistants like Claude to discover and execute your Foobara Ruby commands by exposing them through the Model Context Protocol (MCP), turning backend logic into callable tools that AI can use to answer questions and perform actions.

Outcomes

What it gets done

01

Connect Foobara commands to an MCP server with simple Ruby configuration

02

Run stdio-based MCP servers that AI assistants can communicate with

03

Expose read-only commands for AI to query data and answer questions

04

Enable destructive commands so AI can update and fix data on your behalf

Source

Get it from source

Spark does not host a copy of it.

Open source

Reports

Agent outcome reports

No reports yet

Overview

Foobara MCP Connector

Foobara::McpConnector is a Ruby gem that exposes Foobara commands and entity-backed queries as MCP tools over a stdio server, letting an assistant call typed, validated business logic directly, including mutating commands. Use it when you already have Foobara commands and want an assistant to read or update the data behind them. It is specific to the Foobara framework, not general-purpose Ruby code.

What it does

Foobara::McpConnector exposes Foobara commands - a Ruby framework's typed, validated units of business logic - as MCP tools. You define a command (inputs, a result type, an execute method), register it with Foobara::McpConnector.new.connect(YourCommand), and run a stdio server; any MCP client can then call that command by name with validated arguments.

When to use - and when NOT to

Use it when you already have (or want to build) business logic as Foobara commands and want an assistant to call them directly - reading data via query-style commands, or even mutating it via commands like UpdateCapybara, with the same input validation Foobara commands already enforce. The project's own examples show an assistant finding and correcting a bad data entry (a 2-digit year that should have been 4 digits) purely by calling exposed commands. It's specific to the Foobara ecosystem - you get MCP exposure for commands and entities you've defined in Foobara, not a generic tool-building framework for arbitrary Ruby code.

Capabilities

  • Connect one or more Foobara commands to an MCP server with mcp_connector.connect(SomeCommand).
  • Run as a stdio MCP server via mcp_connector.run_stdio_server.
  • Works with Foobara's typed command inputs/results and with Foobara entities (e.g. exposing a FindAllCapybaras query command backed by a Capybara entity with id, name, and year_of_birth attributes).
  • Supports both read-only (query) and destructive (mutating) commands - connecting an UpdateCapybara-style command lets an assistant both find and fix bad data, not just read it.

How to install

gem install foobara-mcp-connector

or add gem "foobara-mcp-connector" to a Gemfile or .gemspec. A minimal server looks like defining a Foobara command, then:

require "foobara/mcp_connector"

mcp_connector = Foobara::McpConnector.new
mcp_connector.connect(BuildSuperDuperSecret)
mcp_connector.run_stdio_server

Register the resulting script with an MCP client via claude mcp add, or a .mcp.json entry with "type": "stdio" and "command" pointing at the script's path. It is licensed under MPL-2.0.

Who it's for

Ruby developers already using the Foobara framework who want to expose their existing commands - queries and mutations alike - to Claude Code or another MCP client with minimal glue code. The project ships a code demo video and a set of runnable examples covering basic commands, entity-backed queries, and destructive updates. A super-basic example in the README defines a BuildSuperDuperSecret command that cubes an integer seed, connects it to an McpConnector, and runs it as a stdio server - enough to see the whole flow, from command definition to a client like Claude Code calling it by name, in a single script.

Source README

Foobara::McpConnector

Exposes Foobara commands according to the Model Context Protocol (MCP) specification

Installation

Typical stuff: add gem "foobara-mcp-connector to your Gemfile or .gemspec file. Or even just
gem install foobara-mcp-connector if just playing with it directly in scripts.

Usage

Code demo video!

You can watch a code demo here: https://youtu.be/_w3ZHdiJEGU

Code examples

You can find examples in examples/

Super basic example

Let's create a simple Foobara command:

class BuildSuperDuperSecret < Foobara::Command
  inputs do
    seed :integer, :required
  end
  result :integer

  def execute
    seed * seed * seed
  end
end

This just cubes the integer we pass to it. You can run it with BuildSuperDuperSecret.run!(seed: 3) which
would give 27. See the foobara gem for more info about Foobara commands.

Now, let's connect it to an McpConnector:

require "foobara/mcp_connector"

mcp_connector = Foobara::McpConnector.new
mcp_connector.connect(BuildSuperDuperSecret)

And we can start a stdio server like so:

mcp_connector.run_stdio_server

Putting it all together in a single script called simple-mcp-server-example we get:

#!/usr/bin/env ruby

require "foobara/mcp_connector"

class BuildSuperDuperSecret < Foobara::Command
  inputs do
    seed :integer, :required
  end
  result :integer

  def execute
    seed * seed * seed
  end
end

mcp_connector = Foobara::McpConnector.new
mcp_connector.connect(BuildSuperDuperSecret)
mcp_connector.run_stdio_server

We can now add it to programs that can consume MCP servers. For example, with claude code, we can
tell claude code about it by running claude mcp add and following the instructions or we
can create a .mcp.json file like this:

{
  "mcpServers": {
    "mcp-test": {
      "type": "stdio",
      "command": "simple-mcp-server-example",
      "args": [],
      "env": {}
    }
  }
}

You need to set "command" to the path of your script.

Now when we run claude, we can ask it a question that would result in it running our command:

$ claude
> Hi! Could you please build me a super duper secret using a seed of 5?
● mcp-test:BuildSuperDuperSecret (MCP)(seed: 5)…
  ⎿  125
● 125
> Thanks!
● You're welcome!

An example with entities

Let's say we have a model (see examples/capybaras.rb):

class Capybara < Foobara::Entity
  attributes do
    id :integer
    name :string, :required
    year_of_birth :integer, :required
  end

  primary_key :id
end

As well as some commands like FindAllCapybaras, CreateCapybara, and UpdateCapybara
(see examples/capybara_commands.rb)

We can write an MCP connector to expose those commands so we can ask questions that require
running those commands to answer:

require "foobara/mcp_connector"
require_relative "capybara_commands"

CreateCapybara.run!(name: "Fumiko", year_of_birth: 2020)
CreateCapybara.run!(name: "Barbara", year_of_birth: 2019)
CreateCapybara.run!(name: "Basil", year_of_birth: 2021)

mcp_connector = Foobara::McpConnector.new
mcp_connector.connect(FindAllCapybaras)

mcp_connector.run_stdio_server

We can now ask a tool like claude a relevant question:

$ claude
> Which Capybara is the oldest?
● mcp-test:FindAllCapybaras (MCP)()…
  ⎿  [
       {
         "name": "Fumiko",
         "year_of_birth": 2020,
         "id": 1

     … +7 lines (ctrl+r to expand)

         "name": "Basil",
         "year_of_birth": 2021,
         "id": 3
       }
     ]

● Barbara (born in 2019)
> Thanks!
● You're welcome!

A destructive example

Let's say we would like to mutate data. Let's pretend we've accidentally entered a year-of-birth
in a 2-digit format where a 4-digit format was expected. Let's do that and also expose our UpdateCapybara
command:

# We will simulate a year accidentally being entered with a 2-digit format where a 4-digit format was expected
UpdateCapybara.run!(id: barbara.id, year_of_birth: 19)

mcp_connector = Foobara::McpConnector.new

mcp_connector.connect(FindAllCapybaras)
mcp_connector.connect(UpdateCapybara)

mcp_connector.run_stdio_server

Now we can ask a tool like claude to find and fix our data:

$ claude
> Hi! There's a Capybara whose birth year was entered incorrectly. Can you find which one
  and fix it? Thanks!
● I'll help find and fix the capybara with the incorrect birth year. Let me search for the
  capybaras first.
● mcp-test:FindAllCapybaras (MCP)()…
  ⎿  [
       {
         "name": "Fumiko",
         "year_of_birth": 2020,
         "id": 1

     … +7 lines (ctrl+r to expand)

         "name": "Basil",
         "year_of_birth": 2021,
         "id": 3
       }
     ]
● It looks like Barbara (id 2) has an incorrect birth year of 19, which is too low. Let me
  fix that to 2019.
● mcp-test:UpdateCapybara (MCP)(id: 2, year_of_birth: 2019)…
  ⎿  {
       "name": "Barbara",
       "year_of_birth": 2019,
       "id": 2
     }
● Fixed! Barbara's birth year has been updated from 19 to 2019.
> Great! Thanks!
● You're welcome!

Moar examples

Please see the examples/ directory for executable scripts of these examples.

FAQ

Common questions

Discussion

Questions & comments · 0

Sign In Sign in to leave a comment.