You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat: transport deprecation markers — SEP-2596 + 2026-lane enable_get_sse
- Client SseTransport (HTTP+SSE, protocol ≤ 2024-11-05) now carries
#[deprecated]: the transport is deprecated upstream (SEP-2596,
2025-03-26 — "new implementations SHOULD NOT adopt it; existing
implementations SHOULD migrate to Streamable HTTP"). Crate docs and
README carry migration notes; the type stays functional for unmigrated
servers (factory/fallback sites carry scoped allows).
- The server's legacy session_handler module documents the same SEP-2596
status (it serves ≤ 2024-11-05 clients on the 2025 lane only; the 2026
lane never routes there).
- ServerConfig.enable_get_sse and HttpMcpServerBuilder::get_sse() are
deprecated on the 2026-07-28 lane only (cfg_attr): the stateless
endpoint is POST-only (GET = 405) and the long-lived notification
stream is subscriptions/listen. No warning on the protocol-2025-11-25
opt-in, where stateful GET SSE remains first-class. Internal 2025-lane
plumbing carries scoped allows.
Gates: scripts/ci-gates.sh all → ALL GATES PASSED.
Closes spec-compliance driver gap DEP-GAP-1 (P2).
Copy file name to clipboardExpand all lines: CHANGELOG.md
+1Lines changed: 1 addition & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -20,6 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
20
20
21
21
### Added
22
22
23
+
-**Transport deprecation markers (2026-06-11, SEP-2596 + 2026 lane).** The client's `SseTransport` (HTTP+SSE, ≤ 2024-11-05) now carries `#[deprecated]` with migration notes in the crate docs and README — the transport is deprecated upstream (SEP-2596, 2025-03-26: "new implementations SHOULD NOT adopt it"); it remains functional for unmigrated servers. The server's legacy `session_handler` module documents the same. `ServerConfig.enable_get_sse` and the `get_sse()` builder setter are deprecated on the 2026-07-28 lane only (`cfg_attr`): the stateless endpoint is POST-only (GET = 405) and the long-lived stream is `subscriptions/listen`; stateful GET SSE remains first-class on the `protocol-2025-11-25` opt-in. Closes spec-compliance driver gap **DEP-GAP-1 (P2)**.
23
24
-**Client disconnect now cancels the in-flight request (2026-06-11).** Streamable HTTP §Cancellation: "Closing the SSE response stream MUST be treated by the server as cancellation of that request. The server SHOULD stop work … and MUST NOT send any further messages for it." The streaming dispatch task previously ran detached to completion after a disconnect; it now races the dispatch future against the response channel's `closed()` signal — on disconnect the future is dropped (the handler stops at its next await point), the progress task is shut down, and nothing further is sent. Wire test: a slow tool's completion flag stays unset when the client drops mid-execution (`cancellation_2026.rs`; control test pins the connected path). Closes spec-compliance driver gaps **PAT/G1 + TX/GAP-2 (both P1)** — the final open P1s.
24
25
-**Request-scoped progress on the 2026 path (2026-06-11).** Tools and resources can now emit spec-compliant `notifications/progress`: the request's `_meta.progressToken` is surfaced through the session extensions (`SessionContext::progress_token()`), and the new `notify_request_progress(progress, total)` references exactly that token — no-op when the request declared none ("Progress notifications MUST only reference tokens that were provided in an active request"). Numeric tokens now round-trip as JSON numbers end-to-end; the session→StreamManager bridge previously dropped non-string tokens (`as_str()`) and stringified the rest. Wire tests in `progress_2026.rs` (string echo, numeric round-trip, no-token-no-notifications); revert-and-fail recorded. Closes spec-compliance driver gap **PAT/G2 (P1)**.
25
26
-**Real-HTTP OAuth acceptance on the 2026 default transport (2026-06-11, tests + manifest).** New `crates/turul-mcp-server/tests/oauth_2026.rs`: missing/garbage bearers → 401 with the RFC 9728 `WWW-Authenticate` challenge (`resource_metadata=`, `error="invalid_token"`), 401 outranks the missing-`_meta` 400 (auth before validation), and both RFC 9728 well-known routes (root + path form) serve the metadata unauthenticated — all through Builder → `server.run()` → wire. To ride `turul-mcp-server`'s dev-deps without tripping the ADR-029 spec mutex, `turul-mcp-oauth` is now spec-neutral: its transport/storage deps drop default features and it gains its own `protocol-2025-11-25`/`protocol-2026-07-28` forwarding features (default 2026 standalone; unification supplies the spec when used with `default-features = false`). Closes spec-compliance driver gap **AUTH-1 (P1)**.
Copy file name to clipboardExpand all lines: crates/turul-http-mcp-server/src/server.rs
+29-3Lines changed: 29 additions & 3 deletions
Original file line number
Diff line number
Diff line change
@@ -32,7 +32,19 @@ pub struct ServerConfig {
32
32
pubenable_cors:bool,
33
33
/// Maximum request body size
34
34
pubmax_body_size:usize,
35
-
/// Enable GET SSE support (persistent event streams)
35
+
/// Enable GET SSE support (persistent event streams).
36
+
///
37
+
/// 2025-11-25 stateful lane only. On the 2026-07-28 stateless lane this
38
+
/// flag has no effect: the MCP endpoint is POST-only (GET returns 405
39
+
/// Method Not Allowed) and the long-lived notification stream is the
40
+
/// `subscriptions/listen` POST stream instead.
41
+
#[cfg_attr(
42
+
feature = "protocol-2026-07-28",
43
+
deprecated(
44
+
since = "0.4.0",
45
+
note = "no effect on the 2026-07-28 stateless lane (POST-only endpoint; GET = 405) — use subscriptions/listen for the long-lived stream; stateful GET SSE remains on the protocol-2025-11-25 opt-in"
46
+
)
47
+
)]
36
48
pubenable_get_sse:bool,
37
49
/// Enable POST SSE support (streaming tool call responses) - disabled by default for compatibility
38
50
pubenable_post_sse:bool,
@@ -54,6 +66,7 @@ pub struct ServerConfig {
54
66
}
55
67
56
68
implDefaultforServerConfig{
69
+
#[allow(deprecated)]// enable_get_sse is 2026-lane-deprecated but must default
57
70
fndefault() -> Self{
58
71
Self{
59
72
bind_address:"127.0.0.1:8000".parse().unwrap(),
@@ -172,7 +185,17 @@ impl HttpMcpServerBuilder {
172
185
self
173
186
}
174
187
175
-
/// Enable or disable GET SSE for persistent event streams
188
+
/// Enable or disable GET SSE for persistent event streams.
189
+
///
190
+
/// 2025-11-25 stateful lane only — see [`ServerConfig::enable_get_sse`].
191
+
#[cfg_attr(
192
+
feature = "protocol-2026-07-28",
193
+
deprecated(
194
+
since = "0.4.0",
195
+
note = "no effect on the 2026-07-28 stateless lane (POST-only endpoint; GET = 405)"
196
+
)
197
+
)]
198
+
#[allow(deprecated)]
176
199
pubfnget_sse(mutself,enable:bool) -> Self{
177
200
self.config.enable_get_sse = enable;
178
201
self
@@ -184,7 +207,10 @@ impl HttpMcpServerBuilder {
184
207
self
185
208
}
186
209
187
-
/// Enable or disable both GET and POST SSE (convenience method)
210
+
/// Enable or disable both GET and POST SSE (convenience method).
211
+
///
212
+
/// The GET half is 2025-11-25-lane-only — see [`ServerConfig::enable_get_sse`].
0 commit comments