mcp 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5dc4aa079d5850a58ca03b8cd6c8ef980bbc7ea2a4d7f8980b424b96a76e34f6
4
- data.tar.gz: b6ae9619b56ddde201d94c3ca2353da03f6acef7895e0af947c97c8e89b85355
3
+ metadata.gz: b72cdaffe97298a6d6d8b88973b4ea2236909dfb9bf46cc6694ae9331a102a5a
4
+ data.tar.gz: dbab122901fa44329aa03d355fcf35df70087ab88a3f919100740d46261b1319
5
5
  SHA512:
6
- metadata.gz: 7978c2e9c45fd62fcf5e3030897ded84ba372862519819990fd4a8deda8c98adb03f06449dbcd30d017692ba01ef11c02099c07c8b92b9569a6e9e359b8f6bcc
7
- data.tar.gz: 026a813c62da210e928b0d6cc7c55abbd84d447b2edb9f2ac034ef5f8d1d5ed6d5b2c2091cf568e7f11e40eed5b5adf55458ea2b649b5f0d2417e2fc28fbed63
6
+ metadata.gz: 4f3200c4d2520fa6b1c720b7e1547be5cbaea15d2ba76f8491dedd5ef840f8fae59017cd3ea965796c7cda0ab353e78579291e3f3559250412ae9f1f901eb0b7
7
+ data.tar.gz: 91c4dff59524cd390a2cfc92921862cb1dc9446b483b699d7ac722a40438716c56c494b34d84d211aeafd4fc152fcfaf9ae10c354c1c3c104c27ca0a0f4f83a1
@@ -1,30 +1,17 @@
1
1
  ---
2
- description: writing changelog markdown when cutting a new release of the gem
3
- globs:
2
+ description: Updating CHANGELOG.md before cutting a new release of the gem
3
+ globs: CHANGELOG.md
4
4
  alwaysApply: false
5
5
  ---
6
- - output the changelog as markdown when asked.
6
+
7
+ - start by refreshing your knowledge on the Keep a Changelog convention by reading the format spec referenced at the top of CHANGELOG.md
8
+ - stick to Keep a Changelog
9
+ - entries should be terse and in a top-level flat list: do not nest
10
+ - follow this format for entries:
11
+ - Terse description of the change (#nnn)
7
12
  - git tags are used to mark the commit that cut a new release of the gem
8
13
  - the gem version is located in [version.rb](mdc:lib/mcp/version.rb)
9
14
  - use the git history, especially merge commits from PRs to construct the changelog
10
- - when necessary, look at the diff of files changed to determine whether a PR should be listed in
11
- - ## Added; adds new functionality
12
- - ## Changed; alters functionality; especially backward compatible changes
13
- - ## Fixed; bugfixes that are forward compatible
14
-
15
- use the following format for changelogs:
16
-
17
- ```
18
- ## Added
19
- - New functionality added that was not present before
20
-
21
- ## Changed
22
- - Alterations to functionality that may indicate breaking changes
23
-
24
- ## Fixed
25
- - Bug fixes
26
-
27
- #### Full change list:
28
- - [Name of the PR #123](https:/github.com/modelcontextprotocol/ruby-sdk/pull/123) @github-author-username
29
- - [Name of the PR #456](https:/github.com/modelcontextprotocol/ruby-sdk/pull/456) @another-github-author
30
- ```
15
+ - when necessary, look at the diff of files changed to determine the true nature of the change
16
+ - maintenance PRs that don't concern end users of the gem should not be listed in the changelog
17
+ - when checking PRs, see if there's an upstream remote, and if so, fetch PRs from upstream instead of origin
@@ -0,0 +1,25 @@
1
+ name: Release new version
2
+ on:
3
+ push:
4
+ branches: [main]
5
+ paths:
6
+ - "lib/mcp/version.rb"
7
+ jobs:
8
+ publish_gem:
9
+ if: github.repository_owner == 'modelcontextprotocol'
10
+ name: Release Gem Version to RubyGems.org
11
+ runs-on: ubuntu-latest
12
+
13
+ environment: release
14
+
15
+ permissions:
16
+ id-token: write # IMPORTANT: this permission is mandatory for trusted publishing
17
+ contents: write # IMPORTANT: this permission is required for `rake release` to push the release tag
18
+ steps:
19
+ - uses: actions/checkout@v4
20
+ - name: Set up Ruby
21
+ uses: ruby/setup-ruby@v1
22
+ with:
23
+ bundler-cache: true
24
+ ruby-version: 3.4
25
+ - uses: rubygems/release-gem@v1
data/.rubocop.yml CHANGED
@@ -5,6 +5,5 @@ plugins:
5
5
  - rubocop-minitest
6
6
  - rubocop-rake
7
7
 
8
- Naming/FileName:
9
- Exclude:
10
- - 'lib/mcp-ruby.rb'
8
+ Gemspec/DevelopmentDependencies:
9
+ Enabled: true
data/CHANGELOG.md ADDED
@@ -0,0 +1,31 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [0.2.0] - 2025-07-15
11
+
12
+ ### Added
13
+
14
+ - Custom methods support via `define_custom_method` (#75)
15
+ - Streamable HTTP transport implementation (#33)
16
+ - Tool argument validation against schemas (#43)
17
+
18
+ ### Changed
19
+
20
+ - Server context is now optional for Tools and Prompts (#54)
21
+ - Improved capability handling and removed automatic capability determination (#61, #63)
22
+ - Refactored architecture in preparation for client support (#27)
23
+
24
+ ### Fixed
25
+
26
+ - Input schema validation for schemas without required fields (#73)
27
+ - Error handling when sending notifications (#70)
28
+
29
+ ## [0.1.0] - 2025-05-30
30
+
31
+ Initial release
data/Gemfile CHANGED
@@ -7,11 +7,18 @@ gemspec
7
7
 
8
8
  # Specify development dependencies below
9
9
  gem "minitest", "~> 5.1", require: false
10
- gem "rake", "~> 13.0"
11
- gem "rubocop-minitest"
12
- gem "rubocop-rake"
13
- gem "rubocop-shopify", require: false
14
-
15
10
  gem "minitest-reporters"
16
11
  gem "mocha"
12
+
13
+ gem "rubocop-minitest", require: false
14
+ gem "rubocop-rake", require: false
15
+ gem "rubocop-shopify", require: false
16
+
17
+ gem "puma", ">= 5.0.0"
18
+ gem "rack", ">= 2.0.0"
19
+ gem "rackup", ">= 2.1.0"
20
+
21
+ gem "activesupport"
17
22
  gem "debug"
23
+ gem "rake", "~> 13.0"
24
+ gem "sorbet-static-and-runtime"
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
- # Model Context Protocol
1
+ # MCP Ruby SDK [![Gem Version](https://img.shields.io/gem/v/mcp)](https://rubygems.org/gems/mcp) [![MIT licensed](https://img.shields.io/badge/license-MIT-green)](https://github.com/modelcontextprotocol/ruby-sdk/blob/main/LICENSE.txt) [![CI](https://github.com/modelcontextprotocol/ruby-sdk/actions/workflows/ci.yml/badge.svg)](https://github.com/modelcontextprotocol/ruby-sdk/actions/workflows/ci.yml)
2
2
 
3
- A Ruby gem for implementing Model Context Protocol servers
3
+ The official Ruby SDK for Model Context Protocol servers and clients.
4
4
 
5
5
  ## Installation
6
6
 
@@ -12,13 +12,13 @@ gem 'mcp'
12
12
 
13
13
  And then execute:
14
14
 
15
- ```bash
15
+ ```console
16
16
  $ bundle install
17
17
  ```
18
18
 
19
19
  Or install it yourself as:
20
20
 
21
- ```bash
21
+ ```console
22
22
  $ gem install mcp
23
23
  ```
24
24
 
@@ -28,13 +28,17 @@ The `MCP::Server` class is the core component that handles JSON-RPC requests and
28
28
  It implements the Model Context Protocol specification, handling model context requests and responses.
29
29
 
30
30
  ### Key Features
31
+
31
32
  - Implements JSON-RPC 2.0 message handling
32
33
  - Supports protocol initialization and capability negotiation
33
34
  - Manages tool registration and invocation
34
35
  - Supports prompt registration and execution
35
36
  - Supports resource registration and retrieval
37
+ - Supports stdio & Streamable HTTP (including SSE) transports
38
+ - Supports notifications for list changes (tools, prompts, resources)
36
39
 
37
40
  ### Supported Methods
41
+
38
42
  - `initialize` - Initializes the protocol and returns server capabilities
39
43
  - `ping` - Simple health check
40
44
  - `tools/list` - Lists all registered tools and their schemas
@@ -45,20 +49,106 @@ It implements the Model Context Protocol specification, handling model context r
45
49
  - `resources/read` - Retrieves a specific resource by name
46
50
  - `resources/templates/list` - Lists all registered resource templates and their schemas
47
51
 
52
+ ### Custom Methods
53
+
54
+ The server allows you to define custom JSON-RPC methods beyond the standard MCP protocol methods using the `define_custom_method` method:
55
+
56
+ ```ruby
57
+ server = MCP::Server.new(name: "my_server")
58
+
59
+ # Define a custom method that returns a result
60
+ server.define_custom_method(method_name: "add") do |params|
61
+ params[:a] + params[:b]
62
+ end
63
+
64
+ # Define a custom notification method (returns nil)
65
+ server.define_custom_method(method_name: "notify") do |params|
66
+ # Process notification
67
+ nil
68
+ end
69
+ ```
70
+
71
+ **Key Features:**
72
+
73
+ - Accepts any method name as a string
74
+ - Block receives the request parameters as a hash
75
+ - Can handle both regular methods (with responses) and notifications
76
+ - Prevents overriding existing MCP protocol methods
77
+ - Supports instrumentation callbacks for monitoring
78
+
79
+ **Usage Example:**
80
+
81
+ ```ruby
82
+ # Client request
83
+ {
84
+ "jsonrpc": "2.0",
85
+ "id": 1,
86
+ "method": "add",
87
+ "params": { "a": 5, "b": 3 }
88
+ }
89
+
90
+ # Server response
91
+ {
92
+ "jsonrpc": "2.0",
93
+ "id": 1,
94
+ "result": 8
95
+ }
96
+ ```
97
+
98
+ **Error Handling:**
99
+
100
+ - Raises `MCP::Server::MethodAlreadyDefinedError` if trying to override an existing method
101
+ - Supports the same exception reporting and instrumentation as standard methods
102
+
103
+ ### Notifications
104
+
105
+ The server supports sending notifications to clients when lists of tools, prompts, or resources change. This enables real-time updates without polling.
106
+
107
+ #### Notification Methods
108
+
109
+ The server provides three notification methods:
110
+
111
+ - `notify_tools_list_changed()` - Send a notification when the tools list changes
112
+ - `notify_prompts_list_changed()` - Send a notification when the prompts list changes
113
+ - `notify_resources_list_changed()` - Send a notification when the resources list changes
114
+
115
+ #### Notification Format
116
+
117
+ Notifications follow the JSON-RPC 2.0 specification and use these method names:
118
+
119
+ - `notifications/tools/list_changed`
120
+ - `notifications/prompts/list_changed`
121
+ - `notifications/resources/list_changed`
122
+
123
+ #### Transport Support
124
+
125
+ - **HTTP Transport**: Notifications are sent as Server-Sent Events (SSE) to all connected sessions
126
+ - **Stdio Transport**: Notifications are sent as JSON-RPC 2.0 messages to stdout
127
+
128
+ #### Usage Example
129
+
130
+ ```ruby
131
+ server = MCP::Server.new(name: "my_server")
132
+ transport = MCP::Transports::HTTP.new(server)
133
+ server.transport = transport
134
+
135
+ # When tools change, notify clients
136
+ server.define_tool(name: "new_tool") { |**args| { result: "ok" } }
137
+ server.notify_tools_list_changed()
138
+ ```
139
+
48
140
  ### Unsupported Features ( to be implemented in future versions )
49
141
 
50
- - Notifications
51
142
  - Log Level
52
143
  - Resource subscriptions
53
144
  - Completions
54
- - Complete StreamableHTTP implementation with streaming responses
55
145
 
56
146
  ### Usage
57
147
 
58
148
  #### Rails Controller
59
149
 
60
150
  When added to a Rails controller on a route that handles POST requests, your server will be compliant with non-streaming
61
- [StreamableHTTP](https://modelcontextprotocol.io/specification/2025-03-26/basic/transports#streamable-http) transport
151
+ [Streamable HTTP](https://modelcontextprotocol.io/specification/2025-03-26/basic/transports#streamable-http) transport
62
152
  requests.
63
153
 
64
154
  You can use the `Server#handle_json` method to handle requests.
@@ -84,9 +174,8 @@ end
84
174
  If you want to build a local command-line application, you can use the stdio transport:
85
175
 
86
176
  ```ruby
87
- #!/usr/bin/env ruby
88
177
  require "mcp"
89
- require "mcp/transports/stdio"
178
+ require "mcp/server/transports/stdio_transport"
90
179
 
91
180
  # Create a simple tool
92
181
  class ExampleTool < MCP::Tool
@@ -115,17 +204,16 @@ server = MCP::Server.new(
115
204
  )
116
205
 
117
206
  # Create and start the transport
118
- transport = MCP::Transports::StdioTransport.new(server)
207
+ transport = MCP::Server::Transports::StdioTransport.new(server)
119
208
  transport.open
120
209
  ```
121
210
 
122
211
  You can run this script and then type in requests to the server at the command line.
123
212
 
124
- ```
125
- $ ./stdio_server.rb
126
- {"jsonrpc":"2.0","id":"1","result":"pong"}
127
- {"jsonrpc":"2.0","id":"2","result":["ExampleTool"]}
128
- {"jsonrpc":"2.0","id":"3","result":["ExampleTool"]}
213
+ ```console
214
+ $ ruby examples/stdio_server.rb
215
+ {"jsonrpc":"2.0","id":"1","method":"ping"}
216
+ {"jsonrpc":"2.0","id":"2","method":"tools/list"}
129
217
  ```
130
218
 
131
219
  ## Configuration
@@ -179,11 +267,13 @@ server = MCP::Server.new(
179
267
  The `server_context` is a user-defined hash that is passed into the server instance and made available to tools, prompts, and exception/instrumentation callbacks. It can be used to provide contextual information such as authentication state, user IDs, or request-specific data.
180
268
 
181
269
  **Type:**
270
+
182
271
  ```ruby
183
272
  server_context: { [String, Symbol] => Any }
184
273
  ```
185
274
 
186
275
  **Example:**
276
+
187
277
  ```ruby
188
278
  server = MCP::Server.new(
189
279
  name: "my_server",
@@ -203,6 +293,7 @@ The exception reporter receives:
203
293
  - `server_context`: The context hash provided to the server
204
294
 
205
295
  **Signature:**
296
+
206
297
  ```ruby
207
298
  exception_reporter = ->(exception, server_context) { ... }
208
299
  ```
@@ -219,12 +310,14 @@ The instrumentation callback receives a hash with the following possible keys:
219
310
  - `duration`: (Float) Duration of the call in seconds
220
311
 
221
312
  **Type:**
313
+
222
314
  ```ruby
223
315
  instrumentation_callback = ->(data) { ... }
224
316
  # where data is a Hash with keys as described above
225
317
  ```
226
318
 
227
319
  **Example:**
320
+
228
321
  ```ruby
229
322
  config.instrumentation_callback = ->(data) {
230
323
  puts "Instrumentation: #{data.inspect}"
@@ -245,7 +338,7 @@ This will make all new server instances use the specified protocol version inste
245
338
  MCP::Server.protocol_version = nil
246
339
  ```
247
340
 
248
- Be sure to check the [MCP spec](https://spec.modelcontextprotocol.io/specification/2024-11-05/) for the protocol version to understand the supported features for the version being set.
341
+ Be sure to check the [MCP spec](https://modelcontextprotocol.io/specification/2025-03-26) for the protocol version to understand the supported features for the version being set.
249
342
 
250
343
  ### Exception Reporting
251
344
 
@@ -438,8 +531,8 @@ To register a handler pass a proc/lambda to as `instrumentation_callback` into t
438
531
  MCP.configure do |config|
439
532
  config.instrumentation_callback = ->(data) {
440
533
  puts "Got instrumentation data #{data.inspect}"
441
- end
442
- }
534
+ }
535
+ end
443
536
  ```
444
537
 
445
538
  The data contains the following keys:
@@ -461,9 +554,10 @@ The `MCP::Resource` class provides a way to register resources with the server.
461
554
 
462
555
  ```ruby
463
556
  resource = MCP::Resource.new(
464
- uri: "example.com/my_resource",
465
- mime_type: "text/plain",
466
- text: "Lorem ipsum dolor sit amet"
557
+ uri: "https://example.com/my_resource",
558
+ name: "My Resource",
559
+ description: "Lorem ipsum dolor sit amet",
560
+ mime_type: "text/html",
467
561
  )
468
562
 
469
563
  server = MCP::Server.new(
@@ -479,13 +573,13 @@ server.resources_read_handler do |params|
479
573
  [{
480
574
  uri: params[:uri],
481
575
  mimeType: "text/plain",
482
- text: "Hello, world!",
576
+ text: params[:uri],
483
577
  }]
484
578
  end
485
579
 
486
580
  ```
487
581
 
488
- otherwise 'resources/read' requests will be a no-op.
582
+ otherwise `resources/read` requests will be a no-op.
489
583
 
490
584
  ## Releases
491
585
 
@@ -494,7 +588,8 @@ This gem is published to [RubyGems.org](https://rubygems.org/gems/mcp)
494
588
  Releases are triggered by PRs to the `main` branch updating the version number in `lib/mcp/version.rb`.
495
589
 
496
590
  1. **Update the version number** in `lib/mcp/version.rb`, following [semver](https://semver.org/)
497
- 2. **Create A PR and get approval from a maintainer**
498
- 3. **Merge your PR to the main branch** - This will automatically trigger the release workflow via GitHub Actions
591
+ 1. **Update CHANGELOG.md**, backfilling the changes since the last release if necessary, and adding a new section for the new version, clearing out the Unreleased section
592
+ 1. **Create a PR and get approval from a maintainer**
593
+ 1. **Merge your PR to the main branch** - This will automatically trigger the release workflow via GitHub Actions
499
594
 
500
595
  When changes are merged to the `main` branch, the GitHub Actions workflow (`.github/workflows/release.yml`) is triggered and the gem is published to RubyGems.
@@ -0,0 +1,197 @@
1
+ # MCP Ruby Examples
2
+
3
+ This directory contains examples of how to use the Model Context Protocol (MCP) Ruby library.
4
+
5
+ ## Available Examples
6
+
7
+ ### 1. STDIO Server (`stdio_server.rb`)
8
+
9
+ A simple server that communicates over standard input/output. This is useful for desktop applications and command-line tools.
10
+
11
+ **Usage:**
12
+
13
+ ```console
14
+ $ ruby examples/stdio_server.rb
15
+ {"jsonrpc":"2.0","id":0,"method":"tools/list"}
16
+ ```
17
+
18
+ ### 2. HTTP Server (`http_server.rb`)
19
+
20
+ 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.
21
+
22
+ **Features:**
23
+
24
+ - HTTP transport with Server-Sent Events (SSE) for streaming
25
+ - Session management with unique session IDs
26
+ - Example tools, prompts, and resources
27
+ - JSON-RPC 2.0 protocol implementation
28
+ - Full MCP protocol compliance
29
+
30
+ **Usage:**
31
+
32
+ ```console
33
+ $ ruby examples/http_server.rb
34
+ ```
35
+
36
+ The server will start on `http://localhost:9292` and provide:
37
+
38
+ - **Tools**:
39
+ - `ExampleTool` - adds two numbers
40
+ - `echo` - echoes back messages
41
+ - **Prompts**: `ExamplePrompt` - echoes back arguments as a prompt
42
+ - **Resources**: `test_resource` - returns example content
43
+
44
+ ### 3. HTTP Client Example (`http_client.rb`)
45
+
46
+ A client that demonstrates how to interact with the HTTP server using all MCP protocol methods.
47
+
48
+ **Usage:**
49
+
50
+ 1. Start the HTTP server in one terminal:
51
+
52
+ ```console
53
+ $ ruby examples/http_server.rb
54
+ ```
55
+
56
+ 2. Run the client example in another terminal:
57
+ ```console
58
+ $ ruby examples/http_client.rb
59
+ ```
60
+
61
+ The client will demonstrate:
62
+
63
+ - Session initialization
64
+ - Ping requests
65
+ - Listing and calling tools
66
+ - Listing and getting prompts
67
+ - Listing and reading resources
68
+ - Session cleanup
69
+
70
+ ### 4. Streamable HTTP Server (`streamable_http_server.rb`)
71
+
72
+ A specialized HTTP server designed to test and demonstrate Server-Sent Events (SSE) functionality in the MCP protocol.
73
+
74
+ **Features:**
75
+
76
+ - Tools specifically designed to trigger SSE notifications
77
+ - Real-time progress updates and notifications
78
+ - Detailed SSE-specific logging
79
+
80
+ **Available Tools:**
81
+
82
+ - `NotificationTool` - Send custom SSE notifications with optional delays
83
+ - `echo` - Simple echo tool for basic testing
84
+
85
+ **Usage:**
86
+
87
+ ```console
88
+ $ ruby examples/streamable_http_server.rb
89
+ ```
90
+
91
+ The server will start on `http://localhost:9393` and provide detailed instructions for testing SSE functionality.
92
+
93
+ ### 5. Streamable HTTP Client (`streamable_http_client.rb`)
94
+
95
+ An interactive client that connects to the SSE stream and provides a menu-driven interface for testing SSE functionality.
96
+
97
+ **Features:**
98
+
99
+ - Automatic SSE stream connection
100
+ - Interactive menu for triggering various SSE events
101
+ - Real-time display of received SSE notifications
102
+ - Session management
103
+
104
+ **Usage:**
105
+
106
+ 1. Start the SSE test server in one terminal:
107
+
108
+ ```console
109
+ $ ruby examples/streamable_http_server.rb
110
+ ```
111
+
112
+ 2. Run the SSE test client in another terminal:
113
+ ```console
114
+ $ ruby examples/streamable_http_client.rb
115
+ ```
116
+
117
+ The client will:
118
+
119
+ - Initialize a session automatically
120
+ - Connect to the SSE stream
121
+ - Provide an interactive menu to trigger notifications
122
+ - Display all received SSE events in real-time
123
+
124
+ ### Testing SSE with cURL
125
+
126
+ You can also test SSE functionality manually using cURL:
127
+
128
+ 1. Initialize a session:
129
+
130
+ ```console
131
+ SESSION_ID=$(curl -D - -s -o /dev/null http://localhost:9393 \
132
+ --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')
133
+ ```
134
+
135
+ 2. Connect to SSE stream (in one terminal):
136
+
137
+ ```console
138
+ curl -i -N -H "Mcp-Session-Id: $SESSION_ID" http://localhost:9393
139
+ ```
140
+
141
+ 3. Trigger notifications (in another terminal):
142
+
143
+ ```console
144
+ # Send immediate notification
145
+ curl -i http://localhost:9393 \
146
+ -H "Mcp-Session-Id: $SESSION_ID" \
147
+ --json '{"jsonrpc":"2.0","method":"tools/call","id":2,"params":{"name":"notification_tool","arguments":{"message":"Hello from cURL!"}}}'
148
+ ```
149
+
150
+ ## Streamable HTTP Transport Details
151
+
152
+ ### Protocol Flow
153
+
154
+ The HTTP server implements the MCP Streamable HTTP transport protocol:
155
+
156
+ 1. **Initialize Session**:
157
+
158
+ - Client sends POST request with `initialize` method
159
+ - Server responds with session ID in `Mcp-Session-Id` header
160
+
161
+ 2. **Establish SSE Connection** (optional):
162
+
163
+ - Client sends GET request with `Mcp-Session-Id` header
164
+ - Server establishes Server-Sent Events stream for notifications
165
+
166
+ 3. **Send Requests**:
167
+
168
+ - Client sends POST requests with JSON-RPC 2.0 format
169
+ - Server processes and responds with results
170
+
171
+ 4. **Close Session**:
172
+ - Client sends DELETE request with `Mcp-Session-Id` header
173
+
174
+ ### Example cURL Commands
175
+
176
+ Initialize a session:
177
+
178
+ ```console
179
+ curl -i http://localhost:9292 \
180
+ --json '{"jsonrpc":"2.0","method":"initialize","id":1,"params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}'
181
+ ```
182
+
183
+ List tools (using the session ID from initialization):
184
+
185
+ ```console
186
+ curl -i http://localhost:9292 \
187
+ -H "Mcp-Session-Id: YOUR_SESSION_ID" \
188
+ --json '{"jsonrpc":"2.0","method":"tools/list","id":2}'
189
+ ```
190
+
191
+ Call a tool:
192
+
193
+ ```console
194
+ curl -i http://localhost:9292 \
195
+ -H "Mcp-Session-Id: YOUR_SESSION_ID" \
196
+ --json '{"jsonrpc":"2.0","method":"tools/call","id":3,"params":{"name":"ExampleTool","arguments":{"a":5,"b":3}}}'
197
+ ```