0.0
The project is in a healthy, maintained state
Enables FastMcp RackTransport to work in cluster mode by broadcasting messages via PostgreSQL NOTIFY/LISTEN across multiple Puma workers
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
 Dependencies

Development

Runtime

>= 1.0
>= 7.0
 Project Readme

FastMcp PubSub

Multi-worker cluster support extension for fast-mcp gem.

This gem extends the FastMcp gem to work with multiple Puma workers by adding PostgreSQL NOTIFY/LISTEN clustering support for FastMcp::Transports::RackTransport in Rails applications.

Problem

FastMcp::Transports::RackTransport stores SSE clients in an in-memory hash @sse_clients. In cluster mode (multiple Puma workers), messages don't reach between workers because each has its own memory space.

Solution

This gem provides PostgreSQL NOTIFY/LISTEN system for broadcasting messages between workers:

  1. send_message → PostgreSQL NOTIFY
  2. Listener thread in each worker → PostgreSQL LISTEN
  3. On notification → send_local_message to local clients

Installation

Prerequisites: This gem requires the fast-mcp gem to be installed first.

Add both gems to your application's Gemfile:

gem 'fast-mcp', '~> 1.5.0'      # Required base gem
gem 'fast_mcp_pubsub'           # This extension

And then execute:

bundle install

Note: The fast-mcp gem provides the core MCP (Model Context Protocol) server functionality, while this gem extends it with multi-worker support.

Usage

Automatic Integration

No configuration needed! Just add the gem to your Gemfile and it works automatically.

The gem will:

  • Automatically patch FastMcp::Transports::RackTransport during Rails initialization
  • Start listener automatically when Rails server starts
  • Use Rails.logger for logging (no configuration required)
  • Work in both single-worker and cluster mode

Optional Configuration

If you need custom settings:

# config/initializers/fast_mcp_pubsub.rb (optional)
FastMcpPubsub.configure do |config|
  config.enabled = Rails.env.production?    # Enable only in production
  config.channel_name = 'my_custom_channel' # Custom PostgreSQL NOTIFY channel
  config.auto_start = true                  # Start listener automatically (default: true)
  config.connection_pool_size = 10          # Database connection pool size
end

Puma Cluster Mode

For cluster mode (multiple workers), you need to manually start the listener in each worker process:

# config/puma/production.rb
workers ENV.fetch("WEB_CONCURRENCY") { 2 }
preload_app!

on_worker_boot do
  Rails.logger.info "MCP Transport: Starting PubSub listener for cluster mode worker #{Process.pid}"
  
  # Start FastMcpPubsub listener in each worker
  FastMcpPubsub::Service.start_listener
  
  # Your other worker boot code...
end

Why manual setup is required:

  • 🔧 Master process automatically detects cluster mode and skips listener startup
  • 👷 Worker processes need explicit listener startup in on_worker_boot hook
  • 📡 Each worker gets its own listener thread for receiving broadcasts
  • 🔄 Automatic cleanup happens on worker shutdown

Manual Control

# Manually start/stop listener
FastMcpPubsub::Service.start_listener
FastMcpPubsub::Service.stop_listener

# Check listener status
FastMcpPubsub::Service.listener_thread&.alive?

How It Works

  1. Patches FastMcp::Transports::RackTransport: Overrides send_message method
  2. Broadcasts via PostgreSQL: Uses NOTIFY channel, payload
  3. Listener threads: Each worker has a dedicated listener thread
  4. Local delivery: Messages are delivered to local SSE clients in each worker

Configuration Options

Option Default Description
enabled true Enable/disable PubSub functionality
channel_name 'mcp_broadcast' PostgreSQL NOTIFY channel name
auto_start true Start listener automatically
connection_pool_size 5 Database connection pool size

Note: Logging is handled automatically via FastMcpPubsub.logger which returns Rails.logger.

Error Handling

  • Payload size limit: 7800 bytes (PostgreSQL NOTIFY limit)
  • Fallback mechanism: Falls back to local delivery if PubSub fails
  • Automatic restart: Listener restarts on connection errors
  • Graceful shutdown: Proper cleanup on process exit

Requirements

This gem is an extension for Rails applications using FastMcp and requires:

  • FastMcp gem ~> 1.5.0 (the base MCP server this gem extends)
  • Rails 7.0+ (required for Railtie integration)
  • PostgreSQL database (for NOTIFY/LISTEN functionality)
  • Puma web server in cluster mode (multi-worker setup)

Important Notes:

  • This gem will not work in standalone Ruby applications or non-Rails frameworks, as it relies heavily on Rails infrastructure (ActiveRecord, Railtie, Rails.logger, etc.)
  • PostgreSQL is mandatory - this gem will NOT work with MySQL, SQLite, or other databases as it requires PostgreSQL's NOTIFY/LISTEN functionality. Support for other databases would require significant additional development.

Thread Safety

All operations are thread-safe and designed for multi-worker environments:

  • Connection pooling for database operations
  • Proper thread lifecycle management
  • Automatic cleanup on process termination

Development

After checking out the repo, run:

bin/setup      # Install dependencies
rake test      # Run tests
bin/console    # Interactive prompt

To install locally:

bundle exec rake install

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/jchsoft/fast_mcp_pubsub.

License

The gem is available as open source under the terms of the MIT License.