## Motivation and Context
The runnable examples drifted from the SDK they ship with:
- POST requests whose `Accept` header does not cover both `application/json` and `text/event-stream` are answered 406,
so the cURL walkthroughs no longer worked as printed.
- `MCP::Client#connect` now defaults to `mode: :auto`, which adopts the sessionless modern lifecycle (2026-07-28)
against a dual-era server; the Streamable HTTP client example requires a session and broke against its own server.
- POST responses on an established session arrive as an SSE stream, which the hand-rolled HTTP client did not parse.
- `notification_tool` claimed to send SSE notifications but only returned a `Tool::Response`.
- `http_client.rb` read a resource URI the server never registered and skipped `notifications/initialized`.
Handshake examples now offer the latest handshake protocol version (`2025-11-25`) instead of `2024-11-05`,
the Streamable HTTP client pins `mode: :legacy` for its session-based demo, `notification_tool` reports
real `notifications/progress` events requested through `_meta.progressToken`, and the interactive client streams
those events from the POST response so they are visible on screen.
The modern lifecycle itself had no runnable example, so a new server and client pair (`modern_http_server.rb`,
`modern_http_client.rb`) shows the sessionless flow end to end: `server/discover` capability discovery,
the per-request `_meta` envelope with the `Mcp-Method` and `Mcp-Name` headers (stamped by the SDK client automatically),
`resultType` stamping, SEP-2549 cache hints, a SEP-2322 multi round-trip `deploy` tool resumed automatically by
the client's elicitation handler, and the removal of legacy-only methods such as `ping`. The same server keeps serving
the legacy `initialize` flow, routed per request by the `MCP-Protocol-Version` header. `examples/README.md` documents
the pair and adds a cURL walkthrough covering the modern headers, the envelope, and the multi round-trip exchange.
## How Has This Been Tested?
- `ruby examples/stdio_client.rb` against `stdio_server.rb`
- `ruby examples/http_client.rb` against `http_server.rb`
- `ruby examples/streamable_http_client.rb` against `streamable_http_server.rb`, including the progress stream
- `ruby examples/modern_http_client.rb` against `modern_http_server.rb` (discover, modern adoption, cache hints,
`resultType`, the multi round-trip resume, `ping` rejection)
- The cURL walkthroughs in the banners and `examples/README.md`, including the `requestState` echo and a legacy `initialize`
against the modern example server
## Breaking Changes
None.
## 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.