This directory contains examples of how to use the Model Context Protocol (MCP) Ruby library.
A simple server that communicates over standard input/output. This is useful for desktop applications and command-line tools.
Usage:
$ ruby examples/stdio_server.rb
{"jsonrpc":"2.0","id":0,"method":"tools/list"}A client that connects to the stdio server using the MCP::Client::Stdio transport.
This demonstrates how to use the SDK's built-in client classes to interact with a server subprocess.
Usage:
$ ruby examples/stdio_client.rbThe client will automatically launch stdio_server.rb as a subprocess and demonstrate:
- Performing the MCP initialization handshake via
client.connect - Listing and calling tools
- Listing prompts
- Listing and reading resources
- Transport cleanup on exit
A standalone HTTP server built with Rack that implements the MCP Streamable HTTP transport protocol. This demonstrates how to create a web-based MCP server with session management and Server-Sent Events (SSE) support.
Features:
- HTTP transport with Server-Sent Events (SSE) for streaming
- Session management with unique session IDs
- Example tools, prompts, and resources
- JSON-RPC 2.0 protocol implementation
- Full MCP protocol compliance
Usage:
$ ruby examples/http_server.rbThe server will start on http://localhost:9292 and provide:
- Tools:
example_tool- adds two numbersecho- echoes back messages
- Prompts:
example_prompt- echoes back arguments as a prompt - Resources:
test_resource- returns example content
A client that demonstrates how to interact with the HTTP server using all MCP protocol methods.
Usage:
-
Start the HTTP server in one terminal:
$ ruby examples/http_server.rb -
Run the client example in another terminal:
$ ruby examples/http_client.rb
The client will demonstrate:
- Session initialization
- Ping requests
- Listing and calling tools
- Listing and getting prompts
- Listing and reading resources
- Session cleanup
A specialized HTTP server designed to test and demonstrate Server-Sent Events (SSE) functionality in the MCP protocol.
Features:
- Tools specifically designed to trigger SSE notifications
- Real-time progress updates and notifications
- Detailed SSE-specific logging
Available Tools:
notification_tool- Sends progress notifications over SSE, with optional delaysecho- Simple echo tool for basic testing
Usage:
$ ruby examples/streamable_http_server.rbThe server will start on http://localhost:9393 and provide detailed instructions for testing SSE functionality.
An interactive client that connects to the SSE stream and provides a menu-driven interface for testing SSE functionality.
Features:
- Automatic SSE stream connection
- Interactive menu for triggering various SSE events
- Real-time display of received SSE notifications
- Session management
Usage:
- Start the SSE test server in one terminal:
$ ruby examples/streamable_http_server.rb- Run the SSE test client in another terminal:
$ ruby examples/streamable_http_client.rbThe client will:
- Initialize a session automatically
- Connect to the SSE stream
- Provide an interactive menu to trigger notifications
- Display all received SSE events in real-time
A minimal Rails application that mounts StreamableHTTPTransport in its routes, following the "Rails (mount)" pattern from the top-level README.
It demonstrates class-based tools in app/tools/ and a resource with a read handler.
Usage:
$ cd examples/rails
$ bundle install
$ bundle exec puma --port 9292The MCP endpoint is available at http://localhost:9292/mcp. See rails/README.md for a full curl-based walkthrough.
A server and client pair demonstrating the 2026-07-28 modern lifecycle (SEP-2575), which replaces the initialize handshake and per-session state with sessionless, self-contained requests.
Features:
server/discovercapability discovery before (or instead of) a handshake- The per-request
_metaenvelope andMcp-Method/Mcp-Nameheaders, stamped by the SDK automatically resultTypestamping and SEP-2549 cache hints (ttlMs,cacheScope) on results- A multi round-trip
deploytool (SEP-2322), resumed automatically by the client's elicitation handler - The removal of legacy-only methods such as
ping
Usage:
- Start the server in one terminal:
$ ruby examples/modern_http_server.rb- Run the client in another terminal:
$ ruby examples/modern_http_client.rbThe same server still accepts the legacy initialize flow: the transport routes each request to the legacy or modern lifecycle by its MCP-Protocol-Version header.
MCP Inspector is a browser-based tool for testing and debugging MCP servers.
- Start the server:
$ ruby examples/streamable_http_server.rb- Start Inspector in another terminal:
$ npx @modelcontextprotocol/inspector- Open
http://localhost:6274in a browser:
- Set Transport Type to "Streamable HTTP"
- Set URL to
http://localhost:9393 - Disable the Authorization header toggle (the example server does not require authentication)
- Click "Connect"
Once connected, you can list tools, call them, and see SSE notifications in the Inspector UI.
You can also test SSE functionality manually using cURL:
- Initialize a session:
SESSION_ID=$(curl -D - -s -o /dev/null http://localhost:9393 \
-H "Accept: application/json, text/event-stream" \
--json '{"jsonrpc":"2.0","method":"initialize","id":1,"params":{"protocolVersion":"2025-11-25","capabilities":{},"clientInfo":{"name":"curl-test","version":"1.0"}}}' | grep -i "Mcp-Session-Id:" | cut -d' ' -f2- | tr -d '\r')- Optionally connect the standalone SSE stream, which carries server-initiated messages that are not tied to a request (in another terminal):
curl -i -N -H "Mcp-Session-Id: $SESSION_ID" http://localhost:9393- Call the notification tool. The
notifications/progressevents (requested via theprogressTokenin_meta) and the final response arrive as SSE events on the POST response itself:
curl -i http://localhost:9393 \
-H "Accept: application/json, text/event-stream" \
-H "Mcp-Session-Id: $SESSION_ID" \
--json '{"jsonrpc":"2.0","method":"tools/call","id":2,"params":{"name":"notification_tool","arguments":{"message":"Hello from cURL!","delay":0.5},"_meta":{"progressToken":"curl-progress"}}}'The modern lifecycle (2026-07-28, SEP-2575) is sessionless: there is no initialize handshake and no Mcp-Session-Id. Start examples/modern_http_server.rb and walk it manually:
- Probe capabilities with
server/discover:
curl -s http://localhost:9494 \
-H "Accept: application/json, text/event-stream" \
--json '{"jsonrpc":"2.0","id":0,"method":"server/discover"}'- List tools (the
MCP-Protocol-Versionheader selects the era,Mcp-Methodmirrors the method, andparams._metacarries the SEP-2575 envelope):
curl -s http://localhost:9494 \
-H "Accept: application/json, text/event-stream" \
-H "MCP-Protocol-Version: 2026-07-28" \
-H "Mcp-Method: tools/list" \
--json '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{"_meta":{"io.modelcontextprotocol/protocolVersion":"2026-07-28","io.modelcontextprotocol/clientCapabilities":{}}}}'- Call a tool (name-bearing methods additionally mirror the name in the
Mcp-Nameheader):
curl -s http://localhost:9494 \
-H "Accept: application/json, text/event-stream" \
-H "MCP-Protocol-Version: 2026-07-28" \
-H "Mcp-Method: tools/call" \
-H "Mcp-Name: greet" \
--json '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"greet","arguments":{"name":"curl"},"_meta":{"io.modelcontextprotocol/protocolVersion":"2026-07-28","io.modelcontextprotocol/clientCapabilities":{}}}}'- Observe a multi round-trip result (SEP-2322), then resume it by echoing the
requestStateback together with the answer. Declaring theelicitationcapability in the envelope is required before the server may embed elicitation requests:
curl -s http://localhost:9494 \
-H "Accept: application/json, text/event-stream" \
-H "MCP-Protocol-Version: 2026-07-28" \
-H "Mcp-Method: tools/call" \
-H "Mcp-Name: deploy" \
--json '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"deploy","arguments":{"app":"storefront"},"_meta":{"io.modelcontextprotocol/protocolVersion":"2026-07-28","io.modelcontextprotocol/clientCapabilities":{"elicitation":{}}}}}'
curl -s http://localhost:9494 \
-H "Accept: application/json, text/event-stream" \
-H "MCP-Protocol-Version: 2026-07-28" \
-H "Mcp-Method: tools/call" \
-H "Mcp-Name: deploy" \
--json '{"jsonrpc":"2.0","id":4,"method":"tools/call","params":{"name":"deploy","arguments":{"app":"storefront"},"inputResponses":{"environment":{"action":"accept","content":{"environment":"staging"}}},"requestState":"{\"app\":\"storefront\"}","_meta":{"io.modelcontextprotocol/protocolVersion":"2026-07-28","io.modelcontextprotocol/clientCapabilities":{"elicitation":{}}}}}'The same server still accepts the legacy flow from the previous sections, routed by the MCP-Protocol-Version header.
The HTTP server implements the MCP Streamable HTTP transport protocol:
-
Initialize Session:
- Client sends POST request with
initializemethod - Server responds with session ID in
Mcp-Session-Idheader
- Client sends POST request with
-
Establish SSE Connection (optional):
- Client sends GET request with
Mcp-Session-Idheader - Server establishes Server-Sent Events stream for notifications
- Client sends GET request with
-
Send Requests:
- Client sends POST requests with JSON-RPC 2.0 format
- Server processes and responds with results
-
Close Session:
- Client sends DELETE request with
Mcp-Session-Idheader
- Client sends DELETE request with
Initialize a session:
curl -i http://localhost:9292 \
-H "Accept: application/json, text/event-stream" \
--json '{"jsonrpc":"2.0","method":"initialize","id":1,"params":{"protocolVersion":"2025-11-25","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}'List tools (using the session ID from initialization):
curl -i http://localhost:9292 \
-H "Accept: application/json, text/event-stream" \
-H "Mcp-Session-Id: YOUR_SESSION_ID" \
--json '{"jsonrpc":"2.0","method":"tools/list","id":2}'Call a tool:
curl -i http://localhost:9292 \
-H "Accept: application/json, text/event-stream" \
-H "Mcp-Session-Id: YOUR_SESSION_ID" \
--json '{"jsonrpc":"2.0","method":"tools/call","id":3,"params":{"name":"example_tool","arguments":{"a":5,"b":3}}}'