| layout | default |
|---|---|
| title | Chapter 5: Transports: stdio, Streamable HTTP, and Session Modes |
| nav_order | 5 |
| parent | MCP Ruby SDK Tutorial |
Welcome to Chapter 5: Transports: stdio, Streamable HTTP, and Session Modes. In this part of MCP Ruby SDK Tutorial: Building MCP Servers and Clients in Ruby, you will build an intuitive mental model first, then move into concrete implementation details and practical production tradeoffs.
This chapter maps transport options to local development and distributed runtime scenarios.
- choose between stdio and streamable HTTP deployment modes
- understand stateful vs stateless streamable HTTP behavior
- handle session headers and lifecycle flow correctly
- test SSE notification paths with realistic tooling
| Mode | Best Fit |
|---|---|
| stdio | local subprocess integrations and desktop tooling |
| streamable HTTP (stateful) | session-based services with SSE notifications |
| streamable HTTP (stateless) | horizontally scaled request/response-only deployments |
- client initializes and receives
Mcp-Session-Id - optional SSE stream opens for notifications
- client sends JSON-RPC POST requests with session context
- client closes session when done
- Ruby SDK README - Transport Support
- Ruby SDK README - Stateless Streamable HTTP
- Ruby Examples - Streamable HTTP Details
You now have a transport/session framework for Ruby MCP runtime planning.
Next: Chapter 6: Client Workflows, HTTP Integration, and Auth Considerations
The dev module in dev.yml handles a key part of this chapter's functionality:
name: mcp-ruby
type: ruby
up:
- ruby
- bundler
commands:
console:
desc: Open console with the gem loaded
run: bin/console
build:
desc: Build the gem using rake build
run: bin/rake build
test:
desc: Run tests
syntax:
argument: file
optional: args...
run: |
if [[ $# -eq 0 ]]; then
bin/rake test
else
bin/rake -I test "$@"
fi
style:
desc: Run rubocop
aliases: [rubocop, lint]
run: bin/rake rubocop
This module is important because it defines how MCP Ruby SDK Tutorial: Building MCP Servers and Clients in Ruby implements the patterns covered in this chapter.
The streamable_http_server module in examples/streamable_http_server.rb handles a key part of this chapter's functionality:
# frozen_string_literal: true
$LOAD_PATH.unshift(File.expand_path("../lib", __dir__))
require "mcp"
require "rack/cors"
require "rackup"
require "json"
require "logger"
# Create a logger for SSE-specific logging
sse_logger = Logger.new($stdout)
sse_logger.formatter = proc do |severity, datetime, _progname, msg|
"[SSE] #{severity} #{datetime.strftime("%H:%M:%S.%L")} - #{msg}\n"
end
# Tool that returns a response that will be sent via SSE if a stream is active
class NotificationTool < MCP::Tool
tool_name "notification_tool"
description "Returns a notification message that will be sent via SSE if stream is active"
input_schema(
properties: {
message: { type: "string", description: "Message to send via SSE" },
delay: { type: "number", description: "Delay in seconds before returning (optional)" },
},
required: ["message"],
)
class << self
attr_accessor :logger
def call(message:, delay: 0)
sleep(delay) if delay > 0
logger&.info("Returning notification message: #{message}")This module is important because it defines how MCP Ruby SDK Tutorial: Building MCP Servers and Clients in Ruby implements the patterns covered in this chapter.
The .rubocop module in .rubocop.yml handles a key part of this chapter's functionality:
inherit_gem:
rubocop-shopify: rubocop.yml
plugins:
- rubocop-minitest
- rubocop-rake
AllCops:
TargetRubyVersion: 2.7
Gemspec/DevelopmentDependencies:
Enabled: true
Lint/IncompatibleIoSelectWithFiberScheduler:
Enabled: true
Minitest/LiteralAsActualArgument:
Enabled: true
This module is important because it defines how MCP Ruby SDK Tutorial: Building MCP Servers and Clients in Ruby implements the patterns covered in this chapter.
flowchart TD
A[dev]
B[streamable_http_server]
C[.rubocop]
A --> B
B --> C