Skip to content

Releases: patvice/ruby_llm-mcp

v0.8.0

11 Nov 15:00
9bb0d93

Choose a tag to compare

RubyLLM::MCP v0.8 - OAuth 2.1 Support!!

Version 0.8.0 adds comprehensive OAuth 2.1 support for secure authentication with MCP servers.

OAuth 2.1 Authentication

This release implements OAuth 2.1 compliance with the security features you'd expect in production:

Key Features

  • Spec Compliant: Full implementation for OAuth 2.1 support as outlined MCP Spec
  • PKCE (RFC 7636): Proof Key for Code Exchange with SHA256 for secure authorization flows
  • Dynamic Client Registration (RFC 7591): Automatic client registration with OAuth servers
  • Server Discovery (RFC 8414): Automatic authorization server metadata discovery
  • Browser-Based Authentication: Built-in local callback server with a clean UI (pure Ruby, no external dependencies)
  • Automatic Token Refresh: Proactive token refresh with configurable buffers
  • Pluggable Storage: Flexible storage interface for tokens, client info, and metadata
  • Custom Storage: Implement your own storage backend for Redis, databases, or any persistence layer
  • Multi-Transport Support: Works with SSE and StreamableHTTP transports, including generator example in rails

Quick Example

require "ruby_llm/mcp"

# Create client with OAuth config
client = RubyLLM::MCP.client(
  name: "protected-server",
  transport_type: :sse,
  start: false,
  config: {
    url: "https://mcp.example.com/api",
    oauth: { scope: "mcp:read mcp:write" }
  }
)

# Authenticate via browser - that's it!
client.oauth(type: :browser).authenticate

# Use client normally
client.start
tools = client.tools

Documentation

For complete details, configuration options, and integration guides:

Installation

Update your Gemfile:

gem 'ruby_llm-mcp', '~> 0.8.0'

Then run:

bundle update ruby_llm-mcp

Acknowledgments

Big shoutout for @parruda for provided the initial implementation, and ideas on how this could be implementation and used effectively!

What's Changed

  • Fixed Gem Release Warnings by @patvice in #87
  • Add OAuth 2.1 support for MCP servers by @parruda in #88
  • OAuth Improvements: Refactor, Full MCP OAuth Spec Compliances and OAuth generator improvements by @patvice in #91
  • Version bump to 0.8 by @patvice in #92

Full Changelog: v0.7.1...v0.8.0

v0.7.1

06 Nov 17:56
0f0b769

Choose a tag to compare

What's Changed

  • Fix STDIO transport stream closure errors during graceful shutdown by @parruda in #85
  • Bump version to 0.7.1 by @patvice in #86

New Contributors

Full Changelog: v0.7.0...v0.7.1

v0.7.0

04 Nov 02:42
b264843

Choose a tag to compare

v0.7 - Support for RubyLLM v1.9

  • Full support for RubyLLM v1.9
  • Removes the need for support_complex_parameters!. Starting with this release, all future versions of RubyLLM::MCP will include full MCP tool capabilities out of the box.

What's Changed

Full Changelog: v0.6.4...v0.7.0

V0.6.4

01 Nov 16:25
cb53555

Choose a tag to compare

What's Changed

  • Fix intermittent CI failures due to missing Bun dependencies by @patvice in #80
  • Support both base and MCP Parameters in ComplexParameterSupport via Delegation by @patvice in #82

Full Changelog: v0.6.3...v0.6.4

v0.6.3 Release

28 Oct 19:17
57d7a69

Choose a tag to compare

What's Changed

Full Changelog: v0.6.2...v0.6.3

v0.6.2 Release

25 Oct 00:45
d61adeb

Choose a tag to compare

What's Changed

  • Fixed client usage and improved generator install message by @patvice in #63
  • Ensure SSE Transport handles multiple events with one raw stream by @patvice in #64
  • Fix complex anyOf parameter parsing with shorthand array types by @ericproulx in #71
  • MCP Ruby SDK fix by @patvice in #72
  • Support both Unix and Windows line separators for SSE streams by @patvice in #73
  • Added id in request to the notification/initialize MCP call by @patvice in #74
  • Fix missing type field handling and add title support for parameters by @patvice in #75
  • Bumped version to 0.6.2 by @patvice in #76

New Contributors

Full Changelog: v0.6.1...v0.6.2

V0.6.1

14 Jul 23:52
4e82580

Choose a tag to compare

V0.6.1

What's Changed

Full Changelog: v0.6.0...v0.6.1

V0.6.0

14 Jul 15:31
a545036

Choose a tag to compare

V0.6: Full support for MCP spec 2025-06-18, Global Callbacks, a new Doc Site and more

Full 2025-06-18 Support

This is the newest version of the MCP spec, which includes some iterations on core server objects and a new client interaction, Elicitation.

Major Changes

  • Add support for structured tool output
  • Build an OAuth story (use HTTPX OAuth functionality + config options and specs)
  • Verify we are doing the new security best practices.
  • Elicitation support, client features enabling servers to request additional information from users during interactions
  • Add support for resource links in tool call results
  • Require negotiated protocol version to be specified via MCP-Protocol-Version header in subsequent requests when using HTTP.

Other schema changes

  • Add _meta field to additional interface types, and specify proper usage.
  • Add context field to CompletionRequest, providing for completion requests to include previously-resolved variables.
  • Add title field for human-friendly display names, so that name can be used as a programmatic identifier

New Doc Site

This release we have created a full doc site to outline how to use the Gem and all the features that are packed inside it. We outgrew our readme.md last version and so now we have a way to give more examples, how to get started and content on specific areas.

Check it out at [https:://ruby](https://www.rubyllm-mcp.com/)

Global Callback configuration

In some cases you may want to use able to configure standard callbacks for MCPs across the services you connect to (for example maybe you have one shared human in the loop call). Now, instead defining all calls client by client, it can be done once at the RubyLLM::MCP::Configuration level.

 # Event handlers, these will be used for all clients, unless overridden on the client level
  config.on_progress do |progress|
    puts "Progress: #{progress}"
  end
  config.on_human_in_the_loop do |human_in_the_loop|
    puts "Human in the loop: #{human_in_the_loop}"
  end
  config.on_logging do |level, message|
    puts "Logging: #{level} - #{message}"
  end

For more information you can read about configuration here: https://www.rubyllm-mcp.com/configuration

Minor Improvements

  • RubyLLM::MCP#clients acts as a getter now. Meaning that it will always return all configured clients. We still keep the behaviour creating all configured MCP (from a file config or directly from the Configuration class), however, add and remove methods will also maintain the same state.
  • Some inconstancy was happening with SSE and http2 in some environments. We now support the available to force http1 if you are experiencing issues with http2. It's still recommend to keep http2 at the default.
  • Some improvements to SSE transport where also released. This was to match some behaviours of different server implementations and make sure we can support there behaviour (in this case it was the Typescript MCP SSE implementation).

Detailed Changes

Full Changelog: v0.5.1...v0.6.0

V0.5.1

07 Jul 21:37
65f0248

Choose a tag to compare

Bug fix and Improved MCP Interface Connection

MCP Interface

RubyLLM::MCP#establish_connection will not optionally take a block. If you want to use the clients outside of the block, you can use the clients method to get the clients.

clients = RubyLLM::MCP.establish_connection
chat = RubyLLM.chat(model: "gpt-4")
chat.with_tools(*clients.tools)

response = chat.ask("Hello, world!")
puts response

Then you are responsible for closing the MCP connections when you are done. We also added a connivence method RubyLLM::MCP#close_connection to do that on your behalf.

RubyLLM::MCP.close_connection

Bug Fix

  • Generator fold was not included in the gem build. This was fixed in v0.5.1

What's Changed

  • Improved MCP Connection Interface by @patvice in #43
  • Bug: Include Generator file in MCP gem by @patvice in #42

Full Changelog: v0.5.0...v0.5.1

v0.5.0

07 Jul 14:30
c0ef3fe

Choose a tag to compare

Rails Integration, Module Interface improvements and Transport Layer Refactoring

This release adds comprehensive Rails support to the RubyLLM MCP library and refactors the transport layer for better extensibility.

✨ What's New

Client Feature Support

This is the first piece of MCP client functionality that can be exposed to MCP servers. For both Root and Sampling support, the RubyLLM::MCP client must be configured before clients objects are created. This ensuring that people are opting into this functionality before we would expose anything to a remote server.

Roots

Roots give access to underlaying file system information. Due to the nature of the MCP spec being limited on what roots are used for and what could be done with them, our implementation of roots will start off very lite.

When a root is added into the MCP configuration we will expose the the MCP server that roots is a capability we support. We then will support adding and remove roots (with a list_change notification being fired to the server) from the client dynamic lifecycle the lifecycle of a client.

RubyLLM::MCP.config do |config|
  config.roots = ["to/a/path", Rails.root]
end

client = RubyLLM::MCP::Client.new(...)

client.roots.paths #  ["to/a/path", #<Pathname:/to/rails/root/path>]

client.roots.add("new/path") # notifications/roots/list_changed is fired
client.roots.paths # ["to/a/path",  #<Pathname:/to/rails/root/path>, "new/path"]

client.roots.remove("to/a/path") # notifications/roots/list_changed is fired
client.roots.paths # [#<Pathname:/to/rails/root/path>, "new/path"]

Sampling

Sampling allows for an MCP server to offload requests to an LLM to be made from the MCP client either than from the server. As this allows MCP server to optionally use an LLM connection, we are ensuring that client explicitly opt into this functionality before we would expose access.

We included a sub config object called sampling to allow for sampling specific configuration.

RubyLLM::MCP.configure do |config|
  config.sampling.enabled = true
  config.sampling.preferred_model = "gpt-4.1"
  
  # or
  config.sampling.preferred_model do |model_preferences|
    model_preferences.hints.first
  end

  config.sampling.guard do |sample|
    sample.message.include("Hello")
  end
end

Clients will then response to all incoming sample requests with gpt-4.1 and only approve a sample message if it contains the word "Hello".

Rails Integration

  • Rails Railtie: Automatic MCP client lifecycle management

    • Starts all configured MCP clients when Rails initializes (configurable)
    • Gracefully shuts down clients when Rails application exits
    • Automatic generator registration
  • Rails Generator: Easy setup with rails generate ruby_llm:mcp:install

    • Creates config/initializers/ruby_llm_mcp.rb with comprehensive configuration
    • Generates config/mcps.yml with sample MCP server configuration
    • Includes setup instructions and usage examples

MCP module interface

  • Added some support methods to MCP to make it easy to work with multiple MCPs.
  • Added a global tools method to more easily work with tools across multiple MCPs.

Transport Layer Improvements

  • New Transport Factory Pattern: Centralized transport type registration and management
  • Better Process Management: Improved handling of transport instances across process boundaries
  • Enhanced Configuration: Support for YAML configuration files with ERB templating

Configuration Enhancements

  • YAML Support: Use .yml files instead of JSON for more readable configuration
  • Rails-Specific Options:
    • launch_control: :automatic or :manual MCP client management
    • config_path: Rails-aware configuration file paths
  • Template Support: ERB processing in configuration files (e.g., <%= Rails.root %>)

Pagination Support

  • MCPs can optionally add pagination for any list requests. We now will automatically paginate lists to get the fully setup from a given MCP.

Contributions

  • Changing Zeitwerk setup by @patvice in #32
  • Client Features: Support for Roots and Sampling by @patvice in #30
  • List Pagination Support by @patvice in #33
  • Improvements to CI and Github actions by @patvice in #35
  • Enable external client management by @MadBomber in #38
  • Fix nil handling in item_type method and add parameter specs by @MadBomber in #37
  • Better MCP module interface rails support by @patvice in #39

New Contributors

Full Changelog: v0.4.1...v0.5.0