ruby-sdk/examples
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Koichi ITO e5d3b2c135 Support CORS and Accept wildcard for browser-based MCP clients
## Summary

When using browser-based MCP clients such as MCP Inspector, connections to
the example HTTP server failed due to two issues:

1. CORS preflight (OPTIONS) requests returned 405 Method Not Allowed,
causing browsers to block all cross-origin requests.
2. `Accept: */*` (commonly sent by browsers and fetch API) returned 406 Not Acceptable
because the transport required the Accept header to explicitly list `application/json`
and `text/event-stream`.

Add `rack-cors` middleware to the example HTTP servers so that preflight requests are handled correctly
and `Mcp-Session-Id` is exposed to browser clients. Also fix `validate_accept_header` in `StreamableHTTPTransport`
to treat `*/*` as satisfying all required Accept types.

Fixes #141.

## Repro Steps

### 1. Start the example server (Terminal 1)

```console
$ bundle exec ruby examples/streamable_http_server.rb
```

### 2. Start MCP Inspector (Terminal 2)

```console
$ npx @modelcontextprotocol/inspector
```

### 3. Open the Inspector Web UI (http://localhost:6274) in 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"

Before this change, the connection fails due to CORS or 406 errors.
After this change, the connection succeeds and tools are listed.

These steps have been added to examples/README.md.
2026-03-09 10:45:53 +09:00
..
http_client.rb Reduce stdout hedge in examples 2025-09-02 11:30:31 +09:00
http_server.rb Support CORS and Accept wildcard for browser-based MCP clients 2026-03-09 10:45:53 +09:00
README.md Support CORS and Accept wildcard for browser-based MCP clients 2026-03-09 10:45:53 +09:00
stdio_server.rb Remove unnecessary transport requires 2025-10-07 14:10:48 +09:00
streamable_http_client.rb Add logging support 2026-01-26 22:23:46 +09:00
streamable_http_server.rb Support CORS and Accept wildcard for browser-based MCP clients 2026-03-09 10:45:53 +09:00

MCP Ruby Examples

This directory contains examples of how to use the Model Context Protocol (MCP) Ruby library.

Available Examples

1. STDIO Server (stdio_server.rb)

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"}

2. HTTP Server (http_server.rb)

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.rb

The server will start on http://localhost:9292 and provide:

  • Tools:
    • ExampleTool - adds two numbers
    • echo - echoes back messages
  • Prompts: ExamplePrompt - echoes back arguments as a prompt
  • Resources: test_resource - returns example content

3. HTTP Client Example (http_client.rb)

A client that demonstrates how to interact with the HTTP server using all MCP protocol methods.

Usage:

  1. Start the HTTP server in one terminal:

    $ ruby examples/http_server.rb
    
  2. 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

4. Streamable HTTP Server (streamable_http_server.rb)

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:

  • NotificationTool - Send custom SSE notifications with optional delays
  • echo - Simple echo tool for basic testing

Usage:

$ ruby examples/streamable_http_server.rb

The server will start on http://localhost:9393 and provide detailed instructions for testing SSE functionality.

5. Streamable HTTP Client (streamable_http_client.rb)

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:

  1. Start the SSE test server in one terminal:

    $ ruby examples/streamable_http_server.rb
    
  2. Run the SSE test client in another terminal:

    $ ruby examples/streamable_http_client.rb
    

The 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

Testing with MCP Inspector

MCP Inspector is a browser-based tool for testing and debugging MCP servers.

  1. Start the server:
$ ruby examples/streamable_http_server.rb
  1. Start Inspector in another terminal:
$ npx @modelcontextprotocol/inspector
  1. Open http://localhost:6274 in 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.

Testing SSE with cURL

You can also test SSE functionality manually using cURL:

  1. Initialize a session:
SESSION_ID=$(curl -D - -s -o /dev/null http://localhost:9393 \
  --json '{"jsonrpc":"2.0","method":"initialize","id":1,"params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"curl-test","version":"1.0"}}}' | grep -i "Mcp-Session-Id:" | cut -d' ' -f2- | tr -d '\r')
  1. Connect to SSE stream (in one terminal):
curl -i -N -H "Mcp-Session-Id: $SESSION_ID" http://localhost:9393
  1. Trigger notifications (in another terminal):
# Send immediate notification
curl -i http://localhost:9393 \
  -H "Mcp-Session-Id: $SESSION_ID" \
  --json '{"jsonrpc":"2.0","method":"tools/call","id":2,"params":{"name":"notification_tool","arguments":{"message":"Hello from cURL!"}}}'

Streamable HTTP Transport Details

Protocol Flow

The HTTP server implements the MCP Streamable HTTP transport protocol:

  1. Initialize Session:

    • Client sends POST request with initialize method
    • Server responds with session ID in Mcp-Session-Id header
  2. Establish SSE Connection (optional):

    • Client sends GET request with Mcp-Session-Id header
    • Server establishes Server-Sent Events stream for notifications
  3. Send Requests:

    • Client sends POST requests with JSON-RPC 2.0 format
    • Server processes and responds with results
  4. Close Session:

    • Client sends DELETE request with Mcp-Session-Id header

Example cURL Commands

Initialize a session:

curl -i http://localhost:9292 \
  --json '{"jsonrpc":"2.0","method":"initialize","id":1,"params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}'

List tools (using the session ID from initialization):

curl -i http://localhost:9292 \
  -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 "Mcp-Session-Id: YOUR_SESSION_ID" \
  --json '{"jsonrpc":"2.0","method":"tools/call","id":3,"params":{"name":"ExampleTool","arguments":{"a":5,"b":3}}}'