1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
//! The [`Extension`] seam: a multi-method server plugin (PLAN D10).
//!
//! An extension owns a set of request methods (e.g. the draft Tasks extension's
//! `tasks/get`/`tasks/update`/`tasks/cancel`), advertises itself in
//! `server/discover` under `capabilities.extensions[id]`, and is dispatched by
//! the [`VersionDispatcher`](crate::VersionDispatcher) on the modern
//! (`2026-07-28`) path once the client has declared the extension in its
//! per-request capabilities.
//!
//! Extensions are **draft-only**: the legacy `2025-11-25` path serves its
//! built-in equivalents (core Tasks) instead. The trait is object-safe and
//! dispatched behind `Arc<dyn Extension>`, so extensions live in their own
//! crates (e.g. `turbomcp-ext-tasks`) and register via
//! [`ServerBuilder::with_extension`](crate::ServerBuilder::with_extension) /
//! [`VersionDispatcher::with_extension`](crate::VersionDispatcher::with_extension).
//!
//! The trait is the durable architectural asset; the D10 sketch's
//! `intercept_response`/`notification_topics` are folded into the real seams an
//! extension actually needs — [`dispatch`](Extension::dispatch) for its owned
//! methods, and (Phase 9b) a task-augmentation hook for `tools/call` — rather
//! than modeled as standalone trait methods with no consumer.
use Arc;
use async_trait;
use BoxFuture;
use Value;
use ;
/// One inbound request routed to an [`Extension`]. The dispatcher has already
/// version-gated it to the modern path and verified the client declared the
/// extension capability, so a handler can trust both.
/// The in-execution task-input seam (SEP-2663 §Task Update Requests).
///
/// A taskified call's `ClientHandle` delegates its input requests
/// (elicitation, …) here instead of MRTR-aborting or sending inline: the
/// broker publishes the request under a **task-unique** key (flipping the task
/// to `input_required`, so it surfaces via `tasks/get` `inputRequests`) and
/// resolves the returned future when the client answers via `tasks/update`
/// `inputResponses`. The future must also resolve (with an error) when the
/// task is cancelled or discarded, so an awaiting handler can unwind.
/// The late-bound [`TaskInputBroker`] slot. The dispatcher creates one per
/// `tools/call` offered for augmentation and wires it into the call's
/// `ClientHandle`; an extension that decides to taskify the call attaches its
/// broker via [`CallRunner::attach_input_broker`] **before spawning**. If no
/// broker is ever attached (the call ran synchronously), the handle's input
/// methods fail as unavailable.
pub type TaskInputSlot = ;
/// The underlying `tools/call`, prepared for an extension to run as a task.
///
/// The dispatcher builds the call's handler future (with the task's
/// cancellation token already wired into its context) and hands it over. An
/// extension that decides to taskify the call reads [`cancel_token`] (to drive
/// `tasks/cancel`), registers the task, optionally attaches a
/// [`TaskInputBroker`] (mid-task client input), and spawns [`run`] in the
/// background; the future resolves to the wire `CallToolResult` JSON on
/// success, or the JSON-RPC error the call would have answered with.
///
/// [`cancel_token`]: CallRunner::cancel_token
/// [`run`]: CallRunner::run
/// A `tools/call` offered to a call-augmenting [`Extension`]. The dispatcher
/// only constructs this for clients that declared the extension capability, so
/// returning a `CreateTaskResult` honors SEP-2663's "MUST NOT task a
/// non-declaring client".
/// The result of offering a `subscriptions/listen` request to an extension
/// (SEP-2663 task-status notifications ride this stream).
/// A multi-method server extension (PLAN D10).
///
/// An extension bundles a cohesive feature that lives outside the core protocol
/// surface — owning its own wire types and request methods — and plugs into the
/// dispatcher without the core needing to know about it. The draft Tasks
/// extension (`io.modelcontextprotocol/tasks`, SEP-2663) is the reference
/// implementation; see `turbomcp-ext-tasks`.