Skip to content

Commit 17604be

Browse files
committed
[Doc] Update Rails controller example in README.md
The following two points have been updated: ## 1. Use ActionController::API in README controller example `ActionController::Base` includes CSRF protection which rejects POST requests without an authenticity token. MCP clients do not send CSRF tokens, so the controller example should inherit from `ActionController::API` instead. ## 2. Use `stateless: true` for `StreamableHTTPTransport.new` The controller creates a new transport per request, so the session stored on the previous transport is lost. Without `stateless: true`, the second request with `Mcp-Session-Id` returns 404 because the new transport has an empty session map. To share sessions via `Mcp-Session-Id` across requests, there are two approaches. One is persisting the transport in a class variable. The other is mounting the transport as a Rack app via #263. Both approaches maintain sessions, so features that depend on `server_context` within the SDK (Progress, Sampling) work correctly. However, per-request user-specific context such as `server_context: { user_id: current_user.id }` cannot be passed since the server is shared across all requests.
1 parent 2a1c9b7 commit 17604be

File tree

1 file changed

+3
-2
lines changed

1 file changed

+3
-2
lines changed

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ You can use `StreamableHTTPTransport#handle_request` to handle requests with pro
113113
status codes (e.g., 202 Accepted for notifications).
114114

115115
```ruby
116-
class McpController < ActionController::Base
116+
class McpController < ActionController::API
117117
def create
118118
server = MCP::Server.new(
119119
name: "my_server",
@@ -124,7 +124,8 @@ class McpController < ActionController::Base
124124
prompts: [MyPrompt],
125125
server_context: { user_id: current_user.id },
126126
)
127-
transport = MCP::Server::Transports::StreamableHTTPTransport.new(server)
127+
# Since the `MCP-Session-Id` is not shared across requests, `stateless: true` is set.
128+
transport = MCP::Server::Transports::StreamableHTTPTransport.new(server, stateless: true)
128129
server.transport = transport
129130
status, headers, body = transport.handle_request(request)
130131

0 commit comments

Comments
 (0)