From c8fdf25cdb77e5d0419268b483bcb16ffb070924 Mon Sep 17 00:00:00 2001 From: Ates Goral Date: Mon, 14 Jul 2025 20:43:43 -0400 Subject: [PATCH] Use the new --json arg of curl --- examples/README.md | 53 +++++++++++++++++++++--------- examples/http_server.rb | 2 +- examples/streamable_http_server.rb | 12 +++---- 3 files changed, 45 insertions(+), 22 deletions(-) diff --git a/examples/README.md b/examples/README.md index 3f6e9424..17de63bf 100644 --- a/examples/README.md +++ b/examples/README.md @@ -5,18 +5,22 @@ This directory contains examples of how to use the Model Context Protocol (MCP) ## 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:** + ```console $ 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 @@ -24,11 +28,13 @@ A standalone HTTP server built with Rack that implements the MCP Streamable HTTP - Full MCP protocol compliance **Usage:** + ```console $ ruby examples/http_server.rb ``` The server will start on `http://localhost:9292` and provide: + - **Tools**: - `ExampleTool` - adds two numbers - `echo` - echoes back messages @@ -36,10 +42,13 @@ The server will start on `http://localhost:9292` and provide: - **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: + ```console $ ruby examples/http_server.rb ``` @@ -50,6 +59,7 @@ A client that demonstrates how to interact with the HTTP server using all MCP pr ``` The client will demonstrate: + - Session initialization - Ping requests - Listing and calling tools @@ -58,18 +68,22 @@ The client will demonstrate: - 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:** + ```console $ ruby examples/streamable_http_server.rb ``` @@ -77,16 +91,20 @@ $ 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: + ```console $ ruby examples/streamable_http_server.rb ``` @@ -97,6 +115,7 @@ An interactive client that connects to the SSE stream and provides a menu-driven ``` The client will: + - Initialize a session automatically - Connect to the SSE stream - Provide an interactive menu to trigger notifications @@ -107,24 +126,25 @@ The client will: You can also test SSE functionality manually using cURL: 1. Initialize a session: + ```console -SESSION_ID=$(curl -D - -s -o /dev/null -X POST http://localhost:9393 \ - -H "Content-Type: application/json" \ - -d '{"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') +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') ``` 2. Connect to SSE stream (in one terminal): + ```console curl -i -N -H "Mcp-Session-Id: $SESSION_ID" http://localhost:9393 ``` 3. Trigger notifications (in another terminal): + ```console # Send immediate notification -curl -i -X POST http://localhost:9393 \ - -H "Content-Type: application/json" \ +curl -i http://localhost:9393 \ -H "Mcp-Session-Id: $SESSION_ID" \ - -d '{"jsonrpc":"2.0","method":"tools/call","id":2,"params":{"name":"notification_tool","arguments":{"message":"Hello from cURL!"}}}' + --json '{"jsonrpc":"2.0","method":"tools/call","id":2,"params":{"name":"notification_tool","arguments":{"message":"Hello from cURL!"}}}' ``` ## Streamable HTTP Transport Details @@ -134,14 +154,17 @@ curl -i -X POST http://localhost:9393 \ 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 @@ -151,24 +174,24 @@ The HTTP server implements the MCP Streamable HTTP transport protocol: ### Example cURL Commands Initialize a session: + ```console -curl -i -X POST http://localhost:9292 \ - -H "Content-Type: application/json" \ - -d '{"jsonrpc":"2.0","method":"initialize","id":1,"params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}' +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): + ```console -curl -i -X POST http://localhost:9292 \ - -H "Content-Type: application/json" \ +curl -i http://localhost:9292 \ -H "Mcp-Session-Id: YOUR_SESSION_ID" \ - -d '{"jsonrpc":"2.0","method":"tools/list","id":2}' + --json '{"jsonrpc":"2.0","method":"tools/list","id":2}' ``` Call a tool: + ```console -curl -i -X POST http://localhost:9292 \ - -H "Content-Type: application/json" \ +curl -i http://localhost:9292 \ -H "Mcp-Session-Id: YOUR_SESSION_ID" \ - -d '{"jsonrpc":"2.0","method":"tools/call","id":3,"params":{"name":"ExampleTool","arguments":{"a":5,"b":3}}}' + --json '{"jsonrpc":"2.0","method":"tools/call","id":3,"params":{"name":"ExampleTool","arguments":{"a":5,"b":3}}}' ``` diff --git a/examples/http_server.rb b/examples/http_server.rb index f460db3f..7c26f7b0 100644 --- a/examples/http_server.rb +++ b/examples/http_server.rb @@ -156,7 +156,7 @@ def template(args, server_context:) puts "Starting MCP HTTP server on http://localhost:9292" puts "Use POST requests to initialize and send JSON-RPC commands" puts "Example initialization:" -puts ' curl -i -X POST http://localhost:9292 -H "Content-Type: application/json" -d \'{"jsonrpc":"2.0","method":"initialize","id":1,"params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}\'' +puts ' 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"}}}\'' puts "" puts "The server will return a session ID in the Mcp-Session-Id header." puts "Use this session ID for subsequent requests." diff --git a/examples/streamable_http_server.rb b/examples/streamable_http_server.rb index 5b124b8b..b61fe066 100644 --- a/examples/streamable_http_server.rb +++ b/examples/streamable_http_server.rb @@ -147,8 +147,8 @@ def call(message:, delay: 0) puts "Testing SSE:" puts "" puts "1. Initialize session:" -puts ' curl -i -X POST http://localhost:9393 -H "Content-Type: application/json" \\' -puts ' -d \'{"jsonrpc":"2.0","method":"initialize","id":1,"params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"sse-test","version":"1.0"}}}\'' +puts " curl -i http://localhost:9393 \\" +puts ' --json \'{"jsonrpc":"2.0","method":"initialize","id":1,"params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"sse-test","version":"1.0"}}}\'' puts "" puts "2. Connect SSE stream (use the session ID from step 1):" puts ' curl -i -N -H "Mcp-Session-Id: YOUR_SESSION_ID" http://localhost:9393' @@ -156,12 +156,12 @@ def call(message:, delay: 0) puts "3. In another terminal, test tools (responses will be sent via SSE if stream is active):" puts "" puts " Echo tool:" -puts ' curl -i -X POST http://localhost:9393 -H "Content-Type: application/json" -H "Mcp-Session-Id: YOUR_SESSION_ID" \\' -puts ' -d \'{"jsonrpc":"2.0","method":"tools/call","id":2,"params":{"name":"echo","arguments":{"message":"Hello SSE!"}}}\'' +puts ' curl -i http://localhost:9393 -H "Mcp-Session-Id: YOUR_SESSION_ID" \\' +puts ' --json \'{"jsonrpc":"2.0","method":"tools/call","id":2,"params":{"name":"echo","arguments":{"message":"Hello SSE!"}}}\'' puts "" puts " Notification tool (with 2 second delay):" -puts ' curl -i -X POST http://localhost:9393 -H "Content-Type: application/json" -H "Mcp-Session-Id: YOUR_SESSION_ID" \\' -puts ' -d \'{"jsonrpc":"2.0","method":"tools/call","id":3,"params":{"name":"notification_tool","arguments":{"message":"Hello SSE!", "delay": 2}}}\'' +puts ' curl -i http://localhost:9393 -H "Mcp-Session-Id: YOUR_SESSION_ID" \\' +puts ' --json \'{"jsonrpc":"2.0","method":"tools/call","id":3,"params":{"name":"notification_tool","arguments":{"message":"Hello SSE!", "delay": 2}}}\'' puts "" puts "Note: When an SSE stream is active, tool responses will appear in the SSE stream and the POST request will return {\"accepted\": true}" puts ""