fast-mcp 1.2.0 → 1.3.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: e9a99e9fd2c611e1645bfda1cd3d4c924f86b4284e1018e53d8f55c7612c6d48
4
- data.tar.gz: bc9def81c86fb8db4ecdb32091209050a7d860c64d7204158ecfb98e27d01156
3
+ metadata.gz: 688719b076ec2db4860e3e8a0d40d5417b485cdafbaebb777975d680600c1b9b
4
+ data.tar.gz: e367624636eecd848a48fd89eff2fd0860b7b1468287d63da77e529d76e96f6f
5
5
  SHA512:
6
- metadata.gz: 44ba180b84383e3f0cff990136551101cea90181cb384634abecf72ab96ae0316ab53cf9e05eb09626642f647dac8cf2039edc808339dd11c579cd14a0333d13
7
- data.tar.gz: 03b61251ec444d33748a23c1a786f70fea8d54228017b2b1dec0eeae93cb1900afc9af8b19d3fb3c55bbfba26a8e52e2d5ddc266fd6a19f72de692b3ef880382
6
+ metadata.gz: c861b5abf1a982e435b5954075ebaeeece64559a79bae67e36a7d91313a05eba45d5bd61924b87eddc2f6a12f63e69187e3821c4856329e0b2f48b68834bec0f
7
+ data.tar.gz: 53b8d45da7985600f6b4bb8c131159c769c7458ad2b94471cbfbcd8497154f21c50061fba8a6ac3768bb54c21375035d3fd9f18bc79c008504e54e087017553e
data/CHANGELOG.md CHANGED
@@ -5,7 +5,15 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
- ## [1.2.0] - UNRELEASED
8
+ ## [1.3.0] - 2025-04-28
9
+ ### Added
10
+ - Added automatic forwarding of query params from to the messages endpoint [@yjacquin](https://github.com/yjacquin/fast-mcp/commit/011d968ac982d0b0084f7753dcac5789f66339ee)
11
+
12
+ ### Fixed
13
+ - Declare rack as an explicit dependency [#49 @subelsky](https://github.com/yjacquin/fast-mcp/pull/49)
14
+ - Fix notifications/initialized response [#51 @yjacquin](https://github.com/yjacquin/fast-mcp/pull/51)
15
+
16
+ ## [1.2.0] - 2025-04-21
9
17
  ### Added
10
18
  - Security enhancement: Bing only to localhost by default [#44 @yjacquin](https://github.com/yjacquin/fast-mcp/pull/44)
11
19
  - Prevent AuthenticatedRackMiddleware from blocking other rails routes[#35 @JulianPasquale](https://github.com/yjacquin/fast-mcp/pull/35)
data/lib/mcp/server.rb CHANGED
@@ -275,7 +275,7 @@ module FastMcp
275
275
  @client_initialized = true
276
276
  @logger.info('Client initialized, beginning normal operation')
277
277
 
278
- send_result({}, nil)
278
+ nil
279
279
  end
280
280
 
281
281
  # Handle tools/list request
@@ -13,6 +13,21 @@ module FastMcp
13
13
  DEFAULT_PATH_PREFIX = '/mcp'
14
14
  DEFAULT_ALLOWED_ORIGINS = ['localhost', '127.0.0.1', '[::1]'].freeze
15
15
  DEFAULT_ALLOWED_IPS = ['127.0.0.1', '::1'].freeze
16
+
17
+ SSE_HEADERS = {
18
+ 'Content-Type' => 'text/event-stream',
19
+ 'Cache-Control' => 'no-cache, no-store, must-revalidate',
20
+ 'Connection' => 'keep-alive',
21
+ 'X-Accel-Buffering' => 'no', # For Nginx
22
+ 'Access-Control-Allow-Origin' => '*', # Allow CORS
23
+ 'Access-Control-Allow-Methods' => 'GET, OPTIONS',
24
+ 'Access-Control-Allow-Headers' => 'Content-Type',
25
+ 'Access-Control-Max-Age' => '86400', # 24 hours
26
+ 'Keep-Alive' => 'timeout=600', # 10 minutes timeout
27
+ 'Pragma' => 'no-cache',
28
+ 'Expires' => '0'
29
+ }.freeze
30
+
16
31
  attr_reader :app, :path_prefix, :sse_clients, :messages_route, :sse_route, :allowed_origins, :localhost_only,
17
32
  :allowed_ips
18
33
 
@@ -232,24 +247,21 @@ module FastMcp
232
247
 
233
248
  return method_not_allowed_response unless request.get?
234
249
 
235
- # Set up SSE headers
236
- headers = setup_sse_headers
237
-
238
250
  # Handle streaming based on the framework
239
- handle_streaming(env, headers)
251
+ handle_streaming(env)
240
252
  end
241
253
 
242
254
  # Handle streaming based on the framework
243
- def handle_streaming(env, headers)
255
+ def handle_streaming(env)
244
256
  @logger.info("Handling streaming for env: #{env['HTTP_USER_AGENT']}")
245
257
  if env['rack.hijack']
246
258
  # Rack hijacking (e.g., Puma)
247
259
  @logger.info('Handling rack hijack SSE')
248
- handle_rack_hijack_sse(env, headers)
260
+ handle_rack_hijack_sse(env)
249
261
  elsif rails_live_streaming?(env)
250
262
  # Rails ActionController::Live
251
263
  @logger.info('Handling rails live streaming SSE')
252
- handle_rails_sse(env, headers)
264
+ handle_rails_sse(env)
253
265
  else
254
266
  # Fallback for servers that don't support streaming
255
267
  @logger.info('Falling back to default SSE')
@@ -264,23 +276,6 @@ module FastMcp
264
276
  env['action_controller.instance'].response.respond_to?(:stream)
265
277
  end
266
278
 
267
- # Set up headers for SSE connection
268
- def setup_sse_headers
269
- {
270
- 'Content-Type' => 'text/event-stream',
271
- 'Cache-Control' => 'no-cache, no-store, must-revalidate',
272
- 'Connection' => 'keep-alive',
273
- 'X-Accel-Buffering' => 'no', # For Nginx
274
- 'Access-Control-Allow-Origin' => '*', # Allow CORS
275
- 'Access-Control-Allow-Methods' => 'GET, OPTIONS',
276
- 'Access-Control-Allow-Headers' => 'Content-Type',
277
- 'Access-Control-Max-Age' => '86400', # 24 hours
278
- 'Keep-Alive' => 'timeout=600', # 10 minutes timeout
279
- 'Pragma' => 'no-cache',
280
- 'Expires' => '0'
281
- }
282
- end
283
-
284
279
  # Set up CORS headers for preflight requests
285
280
  def setup_cors_headers
286
281
  {
@@ -354,7 +349,7 @@ module FastMcp
354
349
  end
355
350
 
356
351
  # Handle SSE with Rack hijacking (e.g., Puma)
357
- def handle_rack_hijack_sse(env, headers)
352
+ def handle_rack_hijack_sse(env)
358
353
  client_id = extract_client_id(env)
359
354
  @logger.debug("Setting up Rack hijack SSE connection for client #{client_id}")
360
355
 
@@ -362,7 +357,7 @@ module FastMcp
362
357
  io = env['rack.hijack_io']
363
358
  @logger.debug("Obtained hijack IO for client #{client_id}")
364
359
 
365
- setup_sse_connection(client_id, io, headers)
360
+ setup_sse_connection(client_id, io, env)
366
361
  start_keep_alive_thread(client_id, io)
367
362
 
368
363
  # Return async response
@@ -370,11 +365,11 @@ module FastMcp
370
365
  end
371
366
 
372
367
  # Set up the SSE connection
373
- def setup_sse_connection(client_id, io, headers)
368
+ def setup_sse_connection(client_id, io, env)
374
369
  # Send headers
375
370
  @logger.debug("Sending HTTP headers for SSE connection #{client_id}")
376
371
  io.write("HTTP/1.1 200 OK\r\n")
377
- headers.each { |k, v| io.write("#{k}: #{v}\r\n") }
372
+ SSE_HEADERS.each { |k, v| io.write("#{k}: #{v}\r\n") }
378
373
  io.write("\r\n")
379
374
  io.flush
380
375
 
@@ -384,8 +379,12 @@ module FastMcp
384
379
  # Send an initial comment to keep the connection alive
385
380
  io.write(": SSE connection established\n\n")
386
381
 
387
- # Send endpoint information as the first message
382
+ # Extract query parameters from the request
383
+ query_string = env['QUERY_STRING']
384
+
385
+ # Send endpoint information as the first message with query parameters
388
386
  endpoint = "#{@path_prefix}/#{@messages_route}"
387
+ endpoint += "?#{query_string}" if query_string
389
388
  @logger.debug("Sending endpoint information to client #{client_id}: #{endpoint}")
390
389
  io.write("event: endpoint\ndata: #{endpoint}\n\n")
391
390
 
@@ -473,7 +472,7 @@ module FastMcp
473
472
  end
474
473
 
475
474
  # Handle SSE with Rails ActionController::Live
476
- def handle_rails_sse(env, headers)
475
+ def handle_rails_sse(env)
477
476
  client_id = extract_client_id(env)
478
477
  controller = env['action_controller.instance']
479
478
  stream = controller.response.stream
@@ -482,7 +481,7 @@ module FastMcp
482
481
  register_sse_client(client_id, stream)
483
482
 
484
483
  # The controller will handle the streaming
485
- [200, headers, []]
484
+ [200, SSE_HEADERS, []]
486
485
  end
487
486
 
488
487
  # Handle message POST request
data/lib/mcp/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module FastMcp
4
- VERSION = '1.2.0'
4
+ VERSION = '1.3.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fast-mcp
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yorick Jacquin
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-04-21 00:00:00.000000000 Z
11
+ date: 2025-04-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: base64
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '3.4'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rack
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '3.1'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '3.1'
69
83
  description: A flexible and powerful implementation of the MCP with multiple approaches
70
84
  for defining tools.
71
85
  email: