## Motivation and Context The README.md documents the "Rails (mount)" integration pattern, but the repository had no runnable Rails example. This adds a minimal Rails application under examples/rails that mounts StreamableHTTPTransport at /mcp and demonstrates class-based tools and a resource with a read handler. The MCP server is built in config/routes.rb rather than in an initializer because Zeitwerk sets up autoloading after initializers run, so the tool classes in app/tools cannot be referenced there. Code reloading is disabled because the transport holds the server built at boot. The app is booted with puma instead of rackup because rackup inserts `Rack::Lint` in its development default, which rejects the capitalized response header names that the transport currently emits. Closes #44. ## How Has This Been Tested? The curl walkthrough in examples/rails/README.md has been verified end to end against the running app: initialize and the initialized notification, tools/list, tools/call for both tools, resources/list, resources/read, the standalone SSE stream, and session termination via DELETE. ## Breaking Changes None. This only adds an example application and documentation links.
27 lines
813 B
Ruby
27 lines
813 B
Ruby
# frozen_string_literal: true
|
|
|
|
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
|
|
|
|
require "bundler/setup"
|
|
|
|
require "rails"
|
|
require "action_controller/railtie"
|
|
|
|
require "mcp"
|
|
|
|
module McpRailsExample
|
|
class Application < Rails::Application
|
|
config.load_defaults(8.0)
|
|
|
|
# This example has no views, assets, or database.
|
|
config.api_only = true
|
|
|
|
# The MCP server is built once at boot (config/routes.rb) and holds references to the tool classes in app/tools,
|
|
# so code reloading is disabled; restart the server after changing tool or resource code.
|
|
# A reloading app would need `config.to_prepare` and a way to swap the transport's server instead.
|
|
config.enable_reloading = false
|
|
config.eager_load = true
|
|
|
|
config.logger = ActiveSupport::Logger.new($stdout)
|
|
end
|
|
end
|