@novorb/mcp-core 2.1.1 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (240) hide show
  1. package/README.md +82 -161
  2. package/bin/mcp-core-jest.mjs +112 -0
  3. package/dist/auth.d.ts +57 -0
  4. package/dist/auth.d.ts.map +1 -0
  5. package/dist/auth.js +74 -0
  6. package/dist/auth.js.map +1 -0
  7. package/dist/bootstrap.d.ts +129 -0
  8. package/dist/bootstrap.d.ts.map +1 -0
  9. package/dist/bootstrap.js +206 -0
  10. package/dist/bootstrap.js.map +1 -0
  11. package/dist/client-input.d.ts +72 -0
  12. package/dist/client-input.d.ts.map +1 -0
  13. package/dist/client-input.js +109 -0
  14. package/dist/client-input.js.map +1 -0
  15. package/dist/credential-checks.d.ts +80 -0
  16. package/dist/credential-checks.d.ts.map +1 -0
  17. package/dist/credential-checks.js +189 -0
  18. package/dist/credential-checks.js.map +1 -0
  19. package/dist/credential-health.d.ts +12 -0
  20. package/dist/credential-health.d.ts.map +1 -0
  21. package/dist/credential-health.js +12 -0
  22. package/dist/credential-health.js.map +1 -0
  23. package/dist/credential-report.d.ts +46 -0
  24. package/dist/credential-report.d.ts.map +1 -0
  25. package/dist/credential-report.js +135 -0
  26. package/dist/credential-report.js.map +1 -0
  27. package/dist/credential-status-tool.d.ts +20 -0
  28. package/dist/credential-status-tool.d.ts.map +1 -0
  29. package/dist/credential-status-tool.js +33 -0
  30. package/dist/credential-status-tool.js.map +1 -0
  31. package/dist/credentials.d.ts +288 -0
  32. package/dist/credentials.d.ts.map +1 -0
  33. package/dist/credentials.js +652 -0
  34. package/dist/credentials.js.map +1 -0
  35. package/dist/express-peers.d.ts +29 -0
  36. package/dist/express-peers.d.ts.map +1 -0
  37. package/dist/express-peers.js +36 -0
  38. package/dist/express-peers.js.map +1 -0
  39. package/dist/express.d.ts +74 -0
  40. package/dist/express.d.ts.map +1 -0
  41. package/dist/express.js +164 -0
  42. package/dist/express.js.map +1 -0
  43. package/dist/http-client.d.ts +278 -43
  44. package/dist/http-client.d.ts.map +1 -1
  45. package/dist/http-client.js +620 -182
  46. package/dist/http-client.js.map +1 -1
  47. package/dist/index.d.ts +27 -6
  48. package/dist/index.d.ts.map +1 -1
  49. package/dist/index.js +49 -10
  50. package/dist/index.js.map +1 -1
  51. package/dist/limits.d.ts +28 -0
  52. package/dist/limits.d.ts.map +1 -0
  53. package/dist/limits.js +37 -0
  54. package/dist/limits.js.map +1 -0
  55. package/dist/list-pagination.d.ts +41 -0
  56. package/dist/list-pagination.d.ts.map +1 -0
  57. package/dist/list-pagination.js +104 -0
  58. package/dist/list-pagination.js.map +1 -0
  59. package/dist/net.d.ts +112 -0
  60. package/dist/net.d.ts.map +1 -0
  61. package/dist/net.js +490 -0
  62. package/dist/net.js.map +1 -0
  63. package/dist/notifications.d.ts +78 -0
  64. package/dist/notifications.d.ts.map +1 -0
  65. package/dist/notifications.js +173 -0
  66. package/dist/notifications.js.map +1 -0
  67. package/dist/pagination.d.ts +236 -5
  68. package/dist/pagination.d.ts.map +1 -1
  69. package/dist/pagination.js +393 -6
  70. package/dist/pagination.js.map +1 -1
  71. package/dist/prompts.d.ts +70 -0
  72. package/dist/prompts.d.ts.map +1 -0
  73. package/dist/prompts.js +109 -0
  74. package/dist/prompts.js.map +1 -0
  75. package/dist/protocol-errors.d.ts +15 -0
  76. package/dist/protocol-errors.d.ts.map +1 -0
  77. package/dist/protocol-errors.js +28 -0
  78. package/dist/protocol-errors.js.map +1 -0
  79. package/dist/protocol-logging.d.ts +37 -0
  80. package/dist/protocol-logging.d.ts.map +1 -0
  81. package/dist/protocol-logging.js +77 -0
  82. package/dist/protocol-logging.js.map +1 -0
  83. package/dist/rate-limiter.d.ts +36 -0
  84. package/dist/rate-limiter.d.ts.map +1 -0
  85. package/dist/rate-limiter.js +79 -0
  86. package/dist/rate-limiter.js.map +1 -0
  87. package/dist/request-state.d.ts +74 -0
  88. package/dist/request-state.d.ts.map +1 -0
  89. package/dist/request-state.js +190 -0
  90. package/dist/request-state.js.map +1 -0
  91. package/dist/resources.d.ts +181 -0
  92. package/dist/resources.d.ts.map +1 -0
  93. package/dist/resources.js +302 -0
  94. package/dist/resources.js.map +1 -0
  95. package/dist/result-limits.d.ts +80 -0
  96. package/dist/result-limits.d.ts.map +1 -0
  97. package/dist/result-limits.js +248 -0
  98. package/dist/result-limits.js.map +1 -0
  99. package/dist/retry.d.ts +79 -23
  100. package/dist/retry.d.ts.map +1 -1
  101. package/dist/retry.js +170 -57
  102. package/dist/retry.js.map +1 -1
  103. package/dist/sdk/client-stdio.d.ts +6 -0
  104. package/dist/sdk/client-stdio.d.ts.map +1 -0
  105. package/dist/sdk/client-stdio.js +6 -0
  106. package/dist/sdk/client-stdio.js.map +1 -0
  107. package/dist/sdk/client.d.ts +6 -0
  108. package/dist/sdk/client.d.ts.map +1 -0
  109. package/dist/sdk/client.js +6 -0
  110. package/dist/sdk/client.js.map +1 -0
  111. package/dist/sdk/express.d.ts +3 -0
  112. package/dist/sdk/express.d.ts.map +1 -0
  113. package/dist/sdk/express.js +11 -0
  114. package/dist/sdk/express.js.map +1 -0
  115. package/dist/sdk/node.d.ts +6 -0
  116. package/dist/sdk/node.d.ts.map +1 -0
  117. package/dist/sdk/node.js +6 -0
  118. package/dist/sdk/node.js.map +1 -0
  119. package/dist/sdk/server-stdio.d.ts +6 -0
  120. package/dist/sdk/server-stdio.d.ts.map +1 -0
  121. package/dist/sdk/server-stdio.js +6 -0
  122. package/dist/sdk/server-stdio.js.map +1 -0
  123. package/dist/sdk/server.d.ts +6 -0
  124. package/dist/sdk/server.d.ts.map +1 -0
  125. package/dist/sdk/server.js +6 -0
  126. package/dist/sdk/server.js.map +1 -0
  127. package/dist/server.d.ts +88 -36
  128. package/dist/server.d.ts.map +1 -1
  129. package/dist/server.js +98 -44
  130. package/dist/server.js.map +1 -1
  131. package/dist/task-request.d.ts +20 -0
  132. package/dist/task-request.d.ts.map +1 -0
  133. package/dist/task-request.js +43 -0
  134. package/dist/task-request.js.map +1 -0
  135. package/dist/task-store.d.ts +230 -0
  136. package/dist/task-store.d.ts.map +1 -0
  137. package/dist/task-store.js +459 -0
  138. package/dist/task-store.js.map +1 -0
  139. package/dist/task-tools.d.ts +115 -0
  140. package/dist/task-tools.d.ts.map +1 -0
  141. package/dist/task-tools.js +397 -0
  142. package/dist/task-tools.js.map +1 -0
  143. package/dist/testing/client.d.ts +25 -0
  144. package/dist/testing/client.d.ts.map +1 -0
  145. package/dist/testing/client.js +11 -0
  146. package/dist/testing/client.js.map +1 -0
  147. package/dist/testing/in-memory.d.ts +26 -0
  148. package/dist/testing/in-memory.d.ts.map +1 -0
  149. package/dist/testing/in-memory.js +41 -0
  150. package/dist/testing/in-memory.js.map +1 -0
  151. package/dist/testing/index.d.ts +20 -0
  152. package/dist/testing/index.d.ts.map +1 -0
  153. package/dist/testing/index.js +20 -0
  154. package/dist/testing/index.js.map +1 -0
  155. package/dist/testing/isolated-dirs.d.ts +27 -0
  156. package/dist/testing/isolated-dirs.d.ts.map +1 -0
  157. package/dist/testing/isolated-dirs.js +67 -0
  158. package/dist/testing/isolated-dirs.js.map +1 -0
  159. package/dist/testing/logs.d.ts +61 -0
  160. package/dist/testing/logs.d.ts.map +1 -0
  161. package/dist/testing/logs.js +113 -0
  162. package/dist/testing/logs.js.map +1 -0
  163. package/dist/testing/raw-http.d.ts +25 -0
  164. package/dist/testing/raw-http.d.ts.map +1 -0
  165. package/dist/testing/raw-http.js +41 -0
  166. package/dist/testing/raw-http.js.map +1 -0
  167. package/dist/testing/raw-peer.d.ts +43 -0
  168. package/dist/testing/raw-peer.d.ts.map +1 -0
  169. package/dist/testing/raw-peer.js +101 -0
  170. package/dist/testing/raw-peer.js.map +1 -0
  171. package/dist/testing/recording-server.d.ts +38 -0
  172. package/dist/testing/recording-server.d.ts.map +1 -0
  173. package/dist/testing/recording-server.js +38 -0
  174. package/dist/testing/recording-server.js.map +1 -0
  175. package/dist/testing/server-process.d.ts +76 -0
  176. package/dist/testing/server-process.d.ts.map +1 -0
  177. package/dist/testing/server-process.js +241 -0
  178. package/dist/testing/server-process.js.map +1 -0
  179. package/dist/testing/tools.d.ts +53 -0
  180. package/dist/testing/tools.d.ts.map +1 -0
  181. package/dist/testing/tools.js +98 -0
  182. package/dist/testing/tools.js.map +1 -0
  183. package/dist/testing/unit.d.ts +52 -0
  184. package/dist/testing/unit.d.ts.map +1 -0
  185. package/dist/testing/unit.js +95 -0
  186. package/dist/testing/unit.js.map +1 -0
  187. package/dist/tools.d.ts +205 -0
  188. package/dist/tools.d.ts.map +1 -0
  189. package/dist/tools.js +370 -0
  190. package/dist/tools.js.map +1 -0
  191. package/dist/transport.d.ts +144 -53
  192. package/dist/transport.d.ts.map +1 -1
  193. package/dist/transport.js +305 -122
  194. package/dist/transport.js.map +1 -1
  195. package/dist/url-path.d.ts +49 -0
  196. package/dist/url-path.d.ts.map +1 -0
  197. package/dist/url-path.js +165 -0
  198. package/dist/url-path.js.map +1 -0
  199. package/dist/utils/dataStore.d.ts +143 -0
  200. package/dist/utils/dataStore.d.ts.map +1 -0
  201. package/dist/utils/dataStore.js +429 -0
  202. package/dist/utils/dataStore.js.map +1 -0
  203. package/dist/utils/envLoader.d.ts +129 -0
  204. package/dist/utils/envLoader.d.ts.map +1 -0
  205. package/dist/utils/envLoader.js +399 -0
  206. package/dist/utils/envLoader.js.map +1 -0
  207. package/dist/utils/logger.d.ts +181 -0
  208. package/dist/utils/logger.d.ts.map +1 -0
  209. package/dist/utils/logger.js +664 -0
  210. package/dist/utils/logger.js.map +1 -0
  211. package/dist/utils/redact.d.ts +50 -0
  212. package/dist/utils/redact.d.ts.map +1 -0
  213. package/dist/utils/redact.js +318 -0
  214. package/dist/utils/redact.js.map +1 -0
  215. package/docs/api-reference.md +29 -0
  216. package/docs/building-a-server.md +63 -0
  217. package/docs/credentials.md +131 -0
  218. package/docs/data-store.md +37 -0
  219. package/docs/env.md +38 -0
  220. package/docs/features.md +28 -0
  221. package/docs/http-client.md +116 -0
  222. package/docs/logger.md +100 -0
  223. package/docs/migrating-to-v3.md +45 -0
  224. package/docs/outbound-urls.md +104 -0
  225. package/docs/pagination.md +45 -0
  226. package/docs/protocol-features.md +62 -0
  227. package/docs/resources-prompts-tasks.md +95 -0
  228. package/docs/sdk.md +33 -0
  229. package/docs/server.md +68 -0
  230. package/docs/testing-harness.md +139 -0
  231. package/docs/testing.md +151 -0
  232. package/docs/tools.md +88 -0
  233. package/docs/transport.md +85 -0
  234. package/examples/testing/tools.integration.test.example.ts +312 -0
  235. package/examples/testing/tools.unit.test.example.ts +149 -0
  236. package/package.json +140 -18
  237. package/dist/logger.d.ts +0 -80
  238. package/dist/logger.d.ts.map +0 -1
  239. package/dist/logger.js +0 -236
  240. package/dist/logger.js.map +0 -1
@@ -0,0 +1,459 @@
1
+ /**
2
+ * @novorb/mcp-core - Task stores (server side of MCP Tasks)
3
+ *
4
+ * The task wire types and the `TaskStore` contract mirror the open SDK PR
5
+ * modelcontextprotocol/typescript-sdk#2782 (`@modelcontextprotocol/server/ext/tasks`: `TaskStore`,
6
+ * `CreateTaskParams`, `TaskAccess`, `InMemoryTaskStore` with its writer `TaskHandle`) field for field,
7
+ * so a consumer can move to the SDK module when it ships. What mcp-core adds lives on
8
+ * `ManagedTaskStore`, a superset the PR does not define: `list` (the 2025-11-25 `tasks/list`), `watch`
9
+ * (status notifications and the blocking 2025 `tasks/result`), `updateContext` and `close`.
10
+ *
11
+ * - `InMemoryTaskStore`: records in a Map, TTL purge on a timer (the PR's reference store).
12
+ * - `FileTaskStore`: one JSON file per task under the data store (`tasks/<id>.json`, atomic writes), so
13
+ * tasks survive a restart and several processes on one host share them; cancellation written by
14
+ * another process reaches the running work through a status poll. `createTaskStore` falls back to
15
+ * memory when DATA_STORAGE=false.
16
+ *
17
+ * Isolation: a task created by an authenticated request carries the caller's `clientId` as
18
+ * `principal`; every read or write from another principal behaves exactly like an unknown task (no
19
+ * existence leak). A task created without a principal (stdio) is visible to every caller of the store.
20
+ */
21
+ import { randomUUID } from 'node:crypto';
22
+ import { readdir } from 'node:fs/promises';
23
+ import { decodeCursor, encodeCursor } from './pagination.js';
24
+ /** The MCP Tasks extension identifier (2026-07-28). */
25
+ export const TASKS_EXTENSION_ID = 'io.modelcontextprotocol/tasks';
26
+ /** All task statuses, in lifecycle order (terminal states last). */
27
+ export const TASK_STATUSES = ['working', 'input_required', 'completed', 'failed', 'cancelled'];
28
+ const TERMINAL = new Set(['completed', 'failed', 'cancelled']);
29
+ /** Whether `status` is terminal (completed, failed, cancelled). */
30
+ export function isTerminalStatus(status) {
31
+ return TERMINAL.has(status);
32
+ }
33
+ function validateParams(params) {
34
+ if (params.ttlMs !== null && (!Number.isSafeInteger(params.ttlMs) || params.ttlMs < 0)) {
35
+ throw new RangeError(`ttlMs must be a non-negative integer or null, got ${params.ttlMs}`);
36
+ }
37
+ if (params.pollIntervalMs !== undefined &&
38
+ (!Number.isSafeInteger(params.pollIntervalMs) || params.pollIntervalMs < 0)) {
39
+ throw new RangeError(`pollIntervalMs must be a non-negative integer, got ${params.pollIntervalMs}`);
40
+ }
41
+ }
42
+ function clearInput(record) {
43
+ record.inputRequests = undefined;
44
+ record.inputResponses = undefined;
45
+ record.inputRound = undefined;
46
+ }
47
+ function snapshot(record) {
48
+ return {
49
+ taskId: record.taskId,
50
+ status: record.status,
51
+ ...(record.statusMessage !== undefined ? { statusMessage: record.statusMessage } : {}),
52
+ createdAt: new Date(record.createdAt).toISOString(),
53
+ lastUpdatedAt: new Date(record.lastUpdatedAt).toISOString(),
54
+ ttlMs: record.ttlMs,
55
+ ...(record.pollIntervalMs !== undefined ? { pollIntervalMs: record.pollIntervalMs } : {}),
56
+ };
57
+ }
58
+ function detailed(record) {
59
+ const base = snapshot(record);
60
+ switch (record.status) {
61
+ case 'working':
62
+ return { ...base, status: 'working' };
63
+ case 'input_required': {
64
+ const inputRequests = {};
65
+ for (const [key, request] of Object.entries(record.inputRequests ?? {})) {
66
+ if (!(key in (record.inputResponses ?? {})))
67
+ inputRequests[key] = request;
68
+ }
69
+ return { ...base, status: 'input_required', inputRequests };
70
+ }
71
+ case 'completed':
72
+ return { ...base, status: 'completed', result: (record.result ?? { content: [] }) };
73
+ case 'failed':
74
+ return { ...base, status: 'failed', error: record.error ?? { code: -32603, message: 'Task failed' } };
75
+ case 'cancelled':
76
+ return { ...base, status: 'cancelled' };
77
+ }
78
+ }
79
+ function visible(record, access) {
80
+ return record !== undefined && (record.principal === undefined || record.principal === access?.principal);
81
+ }
82
+ function isListCursor(data) {
83
+ return (typeof data === 'object' &&
84
+ data !== null &&
85
+ !Array.isArray(data) &&
86
+ typeof data.o === 'number' &&
87
+ Number.isInteger(data.o) &&
88
+ data.o >= 0);
89
+ }
90
+ function pageOf(records, options = {}) {
91
+ const limit = Math.max(1, Math.min(options.limit ?? 100, 1000));
92
+ const offset = options.cursor ? decodeCursor(options.cursor, { validate: isListCursor }).o : 0;
93
+ const sorted = [...records].sort((a, b) => b.createdAt - a.createdAt || a.taskId.localeCompare(b.taskId));
94
+ const slice = sorted.slice(offset, offset + limit).map(snapshot);
95
+ const end = offset + limit;
96
+ return { tasks: slice, ...(end < sorted.length ? { nextCursor: encodeCursor({ o: end }) } : {}) };
97
+ }
98
+ /** Shared bookkeeping for both stores: listeners, abort controllers, input waiters. */
99
+ class BaseTaskStore {
100
+ createTaskId;
101
+ now;
102
+ aborts = new Map();
103
+ listeners = new Map();
104
+ waiters = new Map();
105
+ constructor(options = {}) {
106
+ this.createTaskId = options.createTaskId ?? (() => randomUUID());
107
+ this.now = options.now ?? (() => Date.now());
108
+ }
109
+ abortController(taskId) {
110
+ let controller = this.aborts.get(taskId);
111
+ if (!controller) {
112
+ controller = new AbortController();
113
+ this.aborts.set(taskId, controller);
114
+ }
115
+ return controller;
116
+ }
117
+ emit(record) {
118
+ const set = this.listeners.get(record.taskId);
119
+ if (!set)
120
+ return;
121
+ const task = detailed(record);
122
+ for (const listener of [...set]) {
123
+ try {
124
+ listener(task);
125
+ }
126
+ catch {
127
+ // A failing observer never affects the task.
128
+ }
129
+ }
130
+ }
131
+ async save(record) {
132
+ record.lastUpdatedAt = this.now();
133
+ await this.write(record);
134
+ this.emit(record);
135
+ }
136
+ expired(record) {
137
+ return record.ttlMs !== null && record.createdAt + record.ttlMs <= this.now();
138
+ }
139
+ async live(taskId) {
140
+ const record = await this.read(taskId);
141
+ if (!record)
142
+ return undefined;
143
+ if (this.expired(record)) {
144
+ await this.purge(taskId);
145
+ return undefined;
146
+ }
147
+ return record;
148
+ }
149
+ /**
150
+ * Hand a completed round of answers to this process's waiting `requireInput`. The answers may have
151
+ * been written by another process sharing the store (the file store calls this from its poll).
152
+ */
153
+ settleInput(record) {
154
+ const waiter = this.waiters.get(record.taskId);
155
+ if (!waiter || record.status !== 'working' || record.inputRound !== waiter.round || !record.inputResponses) {
156
+ return;
157
+ }
158
+ this.waiters.delete(record.taskId);
159
+ waiter.resolve(record.inputResponses);
160
+ }
161
+ async purge(taskId) {
162
+ this.aborts.get(taskId)?.abort();
163
+ this.aborts.delete(taskId);
164
+ this.waiters.delete(taskId);
165
+ await this.forget(taskId);
166
+ }
167
+ async create(params) {
168
+ validateParams(params);
169
+ const now = this.now();
170
+ const record = {
171
+ taskId: this.createTaskId(),
172
+ ...(params.principal !== undefined ? { principal: params.principal } : {}),
173
+ ...(params.context !== undefined ? { context: params.context } : {}),
174
+ status: 'working',
175
+ createdAt: now,
176
+ lastUpdatedAt: now,
177
+ ttlMs: params.ttlMs,
178
+ ...(params.pollIntervalMs !== undefined ? { pollIntervalMs: params.pollIntervalMs } : {}),
179
+ };
180
+ await this.write(record);
181
+ this.abortController(record.taskId);
182
+ this.scheduled(record);
183
+ return snapshot(record);
184
+ }
185
+ /** Hook: the in-memory store arms its TTL timer here. */
186
+ scheduled(_record) { }
187
+ async get(taskId, access) {
188
+ const record = await this.live(taskId);
189
+ return visible(record, access) ? detailed(record) : undefined;
190
+ }
191
+ async update(taskId, inputResponses, access) {
192
+ const record = await this.live(taskId);
193
+ if (!visible(record, access))
194
+ return false;
195
+ if (record.status !== 'input_required' || !record.inputRequests)
196
+ return true;
197
+ const responses = { ...(record.inputResponses ?? {}) };
198
+ for (const [key, response] of Object.entries(inputResponses)) {
199
+ // Unknown keys are ignored; the first answer to a key wins.
200
+ if (key in record.inputRequests && !(key in responses))
201
+ responses[key] = response;
202
+ }
203
+ record.inputResponses = responses;
204
+ const complete = Object.keys(record.inputRequests).every((key) => key in responses);
205
+ if (complete) {
206
+ record.status = 'working';
207
+ record.inputRequests = undefined;
208
+ }
209
+ await this.save(record);
210
+ if (complete)
211
+ this.settleInput(record);
212
+ return true;
213
+ }
214
+ async cancel(taskId, access) {
215
+ const record = await this.live(taskId);
216
+ if (!visible(record, access))
217
+ return false;
218
+ if (isTerminalStatus(record.status))
219
+ return true;
220
+ record.status = 'cancelled';
221
+ clearInput(record);
222
+ await this.save(record);
223
+ this.aborts.get(taskId)?.abort();
224
+ this.waiters.delete(taskId);
225
+ return true;
226
+ }
227
+ async list(access, options) {
228
+ const records = [];
229
+ for (const record of await this.all()) {
230
+ if (this.expired(record))
231
+ await this.purge(record.taskId);
232
+ else if (visible(record, access))
233
+ records.push(record);
234
+ }
235
+ return pageOf(records, options);
236
+ }
237
+ async context(taskId) {
238
+ return (await this.live(taskId))?.context;
239
+ }
240
+ async updateContext(taskId, patch) {
241
+ const record = await this.live(taskId);
242
+ if (!record)
243
+ return false;
244
+ record.context = { ...record.context, ...patch };
245
+ await this.save(record);
246
+ return true;
247
+ }
248
+ watch(taskId, listener) {
249
+ let set = this.listeners.get(taskId);
250
+ if (!set) {
251
+ set = new Set();
252
+ this.listeners.set(taskId, set);
253
+ }
254
+ set.add(listener);
255
+ return () => {
256
+ set.delete(listener);
257
+ if (set.size === 0)
258
+ this.listeners.delete(taskId);
259
+ };
260
+ }
261
+ handle(taskId) {
262
+ const signal = this.abortController(taskId).signal;
263
+ const running = async () => {
264
+ const record = await this.live(taskId);
265
+ if (!record || isTerminalStatus(record.status))
266
+ return undefined;
267
+ return record;
268
+ };
269
+ return {
270
+ taskId,
271
+ signal,
272
+ status: async (message) => {
273
+ const record = await running();
274
+ if (!record)
275
+ return;
276
+ record.statusMessage = message;
277
+ await this.save(record);
278
+ },
279
+ requireInput: async (requests) => {
280
+ const record = await running();
281
+ if (!record)
282
+ throw new Error(`Task "${taskId}" is no longer running`);
283
+ const round = randomUUID();
284
+ record.status = 'input_required';
285
+ record.inputRequests = requests;
286
+ record.inputResponses = {};
287
+ record.inputRound = round;
288
+ const answered = new Promise((resolve, reject) => {
289
+ this.waiters.set(taskId, { round, resolve });
290
+ signal.addEventListener('abort', () => reject(new Error(`Task "${taskId}" was cancelled`)), { once: true });
291
+ });
292
+ await this.save(record);
293
+ return answered;
294
+ },
295
+ complete: async (result) => {
296
+ const record = await running();
297
+ if (!record)
298
+ return;
299
+ record.status = 'completed';
300
+ record.result = result;
301
+ clearInput(record);
302
+ await this.save(record);
303
+ },
304
+ fail: async (error) => {
305
+ const record = await running();
306
+ if (!record)
307
+ return;
308
+ record.status = 'failed';
309
+ record.error = error;
310
+ clearInput(record);
311
+ await this.save(record);
312
+ },
313
+ };
314
+ }
315
+ }
316
+ /** The in-process reference store (PR #2782 `InMemoryTaskStore`, plus the `ManagedTaskStore` extras). */
317
+ export class InMemoryTaskStore extends BaseTaskStore {
318
+ tasks = new Map();
319
+ timers = new Map();
320
+ async read(taskId) {
321
+ return this.tasks.get(taskId);
322
+ }
323
+ async write(record) {
324
+ this.tasks.set(record.taskId, record);
325
+ }
326
+ async all() {
327
+ return [...this.tasks.values()];
328
+ }
329
+ async forget(taskId) {
330
+ const timer = this.timers.get(taskId);
331
+ if (timer)
332
+ clearTimeout(timer);
333
+ this.timers.delete(taskId);
334
+ this.tasks.delete(taskId);
335
+ }
336
+ scheduled(record) {
337
+ if (record.ttlMs === null)
338
+ return;
339
+ const timer = setTimeout(() => void this.purge(record.taskId), record.ttlMs);
340
+ timer.unref?.();
341
+ this.timers.set(record.taskId, timer);
342
+ }
343
+ close() {
344
+ for (const timer of this.timers.values())
345
+ clearTimeout(timer);
346
+ this.timers.clear();
347
+ for (const controller of this.aborts.values())
348
+ controller.abort();
349
+ this.aborts.clear();
350
+ this.tasks.clear();
351
+ this.listeners.clear();
352
+ }
353
+ }
354
+ const TASK_DIR = 'tasks';
355
+ /** A store of JSON files under the data store (`<DATA_PATH>/tasks/<taskId>.json`). */
356
+ export class FileTaskStore extends BaseTaskStore {
357
+ data;
358
+ pollers = new Map();
359
+ sweeper;
360
+ cancelPollMs;
361
+ constructor(data, options = {}) {
362
+ super(options);
363
+ this.data = data;
364
+ if (!data.enabled)
365
+ throw new Error('FileTaskStore needs an enabled data store (DATA_STORAGE=true)');
366
+ this.cancelPollMs = options.cancelPollMs ?? 1000;
367
+ this.sweeper = setInterval(() => void this.list().catch(() => undefined), options.sweepMs ?? 60_000);
368
+ this.sweeper.unref?.();
369
+ }
370
+ file(taskId) {
371
+ if (!/^[A-Za-z0-9_-]{1,128}$/.test(taskId))
372
+ throw new Error('invalid task id');
373
+ return `${TASK_DIR}/${taskId}.json`;
374
+ }
375
+ async read(taskId) {
376
+ let file;
377
+ try {
378
+ file = this.file(taskId);
379
+ }
380
+ catch {
381
+ return undefined;
382
+ }
383
+ const raw = await this.data.readFile(file);
384
+ if (!raw)
385
+ return undefined;
386
+ try {
387
+ return JSON.parse(raw.toString('utf8'));
388
+ }
389
+ catch {
390
+ return undefined;
391
+ }
392
+ }
393
+ async write(record) {
394
+ await this.data.writeFile(this.file(record.taskId), JSON.stringify(record));
395
+ }
396
+ async all() {
397
+ let names;
398
+ try {
399
+ names = await readdir(this.data.resolveInside(TASK_DIR));
400
+ }
401
+ catch {
402
+ return [];
403
+ }
404
+ const records = [];
405
+ for (const name of names) {
406
+ if (!name.endsWith('.json'))
407
+ continue;
408
+ const record = await this.read(name.slice(0, -'.json'.length));
409
+ if (record)
410
+ records.push(record);
411
+ }
412
+ return records;
413
+ }
414
+ async forget(taskId) {
415
+ this.stopPolling(taskId);
416
+ await this.data.remove(this.file(taskId));
417
+ }
418
+ stopPolling(taskId) {
419
+ const poller = this.pollers.get(taskId);
420
+ if (poller)
421
+ clearInterval(poller);
422
+ this.pollers.delete(taskId);
423
+ }
424
+ handle(taskId) {
425
+ const handle = super.handle(taskId);
426
+ // Another process may cancel or answer input through the shared files: poll while the work runs.
427
+ if (!this.pollers.has(taskId)) {
428
+ const poller = setInterval(() => {
429
+ void this.read(taskId).then((record) => {
430
+ if (!record || record.status === 'cancelled' || this.expired(record)) {
431
+ this.aborts.get(taskId)?.abort();
432
+ }
433
+ if (record)
434
+ this.settleInput(record);
435
+ if (!record || isTerminalStatus(record.status))
436
+ this.stopPolling(taskId);
437
+ });
438
+ }, this.cancelPollMs);
439
+ poller.unref?.();
440
+ this.pollers.set(taskId, poller);
441
+ }
442
+ return handle;
443
+ }
444
+ close() {
445
+ clearInterval(this.sweeper);
446
+ for (const poller of this.pollers.values())
447
+ clearInterval(poller);
448
+ this.pollers.clear();
449
+ for (const controller of this.aborts.values())
450
+ controller.abort();
451
+ this.aborts.clear();
452
+ this.listeners.clear();
453
+ }
454
+ }
455
+ /** A file store when the data store is enabled, otherwise the in-memory store. */
456
+ export function createTaskStore(data, options = {}) {
457
+ return data?.enabled ? new FileTaskStore(data, options) : new InMemoryTaskStore(options);
458
+ }
459
+ //# sourceMappingURL=task-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-store.js","sourceRoot":"","sources":["../src/task-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAE3C,OAAO,EAAE,YAAY,EAAE,YAAY,EAAkB,MAAM,iBAAiB,CAAC;AAG7E,uDAAuD;AACvD,MAAM,CAAC,MAAM,kBAAkB,GAAG,+BAA+B,CAAC;AAElE,oEAAoE;AACpE,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,SAAS,EAAE,gBAAgB,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,CAAU,CAAC;AA0GxG,MAAM,QAAQ,GAA4B,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC;AAExF,mEAAmE;AACnE,MAAM,UAAU,gBAAgB,CAAC,MAAkB;IACjD,OAAO,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AAC9B,CAAC;AAqBD,SAAS,cAAc,CAAC,MAAwB;IAC9C,IAAI,MAAM,CAAC,KAAK,KAAK,IAAI,IAAI,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,EAAE,CAAC;QACvF,MAAM,IAAI,UAAU,CAAC,qDAAqD,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;IAC5F,CAAC;IACD,IACE,MAAM,CAAC,cAAc,KAAK,SAAS;QACnC,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,cAAc,CAAC,IAAI,MAAM,CAAC,cAAc,GAAG,CAAC,CAAC,EAC3E,CAAC;QACD,MAAM,IAAI,UAAU,CAAC,sDAAsD,MAAM,CAAC,cAAc,EAAE,CAAC,CAAC;IACtG,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CAAC,MAAkB;IACpC,MAAM,CAAC,aAAa,GAAG,SAAS,CAAC;IACjC,MAAM,CAAC,cAAc,GAAG,SAAS,CAAC;IAClC,MAAM,CAAC,UAAU,GAAG,SAAS,CAAC;AAChC,CAAC;AAED,SAAS,QAAQ,CAAC,MAAkB;IAClC,OAAO;QACL,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,GAAG,CAAC,MAAM,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACtF,SAAS,EAAE,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE;QACnD,aAAa,EAAE,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,WAAW,EAAE;QAC3D,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,GAAG,CAAC,MAAM,CAAC,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,MAAM,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC1F,CAAC;AACJ,CAAC;AAED,SAAS,QAAQ,CAAC,MAAkB;IAClC,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC9B,QAAQ,MAAM,CAAC,MAAM,EAAE,CAAC;QACtB,KAAK,SAAS;YACZ,OAAO,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;QACxC,KAAK,gBAAgB,CAAC,CAAC,CAAC;YACtB,MAAM,aAAa,GAAkB,EAAE,CAAC;YACxC,KAAK,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,aAAa,IAAI,EAAE,CAAC,EAAE,CAAC;gBACxE,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,cAAc,IAAI,EAAE,CAAC,CAAC;oBAAE,aAAa,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC;YAC5E,CAAC;YACD,OAAO,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,gBAAgB,EAAE,aAAa,EAAE,CAAC;QAC9D,CAAC;QACD,KAAK,WAAW;YACd,OAAO,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,CAA+B,EAAE,CAAC;QACpH,KAAK,QAAQ;YACX,OAAO,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,EAAE,CAAC;QACxG,KAAK,WAAW;YACd,OAAO,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;IAC5C,CAAC;AACH,CAAC;AAED,SAAS,OAAO,CAAC,MAA8B,EAAE,MAA8B;IAC7E,OAAO,MAAM,KAAK,SAAS,IAAI,CAAC,MAAM,CAAC,SAAS,KAAK,SAAS,IAAI,MAAM,CAAC,SAAS,KAAK,MAAM,EAAE,SAAS,CAAC,CAAC;AAC5G,CAAC;AAED,SAAS,YAAY,CAAC,IAAe;IACnC,OAAO,CACL,OAAO,IAAI,KAAK,QAAQ;QACxB,IAAI,KAAK,IAAI;QACb,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;QACpB,OAAO,IAAI,CAAC,CAAC,KAAK,QAAQ;QAC1B,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;QACxB,IAAI,CAAC,CAAC,IAAI,CAAC,CACZ,CAAC;AACJ,CAAC;AAED,SAAS,MAAM,CAAC,OAAqB,EAAE,UAA+C,EAAE;IACtF,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,IAAI,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC;IAChE,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/F,MAAM,MAAM,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IAC1G,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACjE,MAAM,GAAG,GAAG,MAAM,GAAG,KAAK,CAAC;IAC3B,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,CAAC,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,YAAY,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;AACpG,CAAC;AAED,uFAAuF;AACvF,MAAe,aAAa;IACP,YAAY,CAAe;IAC3B,GAAG,CAAe;IAClB,MAAM,GAAG,IAAI,GAAG,EAA2B,CAAC;IAC5C,SAAS,GAAG,IAAI,GAAG,EAA6C,CAAC;IACnE,OAAO,GAAG,IAAI,GAAG,EAA2E,CAAC;IAE9G,YAAY,UAA4B,EAAE;QACxC,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,CAAC,GAAG,EAAE,CAAC,UAAU,EAAE,CAAC,CAAC;QACjE,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IAC/C,CAAC;IAQS,eAAe,CAAC,MAAc;QACtC,IAAI,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACzC,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;YACnC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;QACtC,CAAC;QACD,OAAO,UAAU,CAAC;IACpB,CAAC;IAES,IAAI,CAAC,MAAkB;QAC/B,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC9C,IAAI,CAAC,GAAG;YAAE,OAAO;QACjB,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC9B,KAAK,MAAM,QAAQ,IAAI,CAAC,GAAG,GAAG,CAAC,EAAE,CAAC;YAChC,IAAI,CAAC;gBACH,QAAQ,CAAC,IAAI,CAAC,CAAC;YACjB,CAAC;YAAC,MAAM,CAAC;gBACP,6CAA6C;YAC/C,CAAC;QACH,CAAC;IACH,CAAC;IAES,KAAK,CAAC,IAAI,CAAC,MAAkB;QACrC,MAAM,CAAC,aAAa,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAClC,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACzB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACpB,CAAC;IAES,OAAO,CAAC,MAAkB;QAClC,OAAO,MAAM,CAAC,KAAK,KAAK,IAAI,IAAI,MAAM,CAAC,SAAS,GAAG,MAAM,CAAC,KAAK,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;IAChF,CAAC;IAES,KAAK,CAAC,IAAI,CAAC,MAAc;QACjC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACvC,IAAI,CAAC,MAAM;YAAE,OAAO,SAAS,CAAC;QAC9B,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YACzB,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YACzB,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;;OAGG;IACO,WAAW,CAAC,MAAkB;QACtC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC/C,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,IAAI,MAAM,CAAC,UAAU,KAAK,MAAM,CAAC,KAAK,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC;YAC3G,OAAO;QACT,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACnC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;IACxC,CAAC;IAES,KAAK,CAAC,KAAK,CAAC,MAAc;QAClC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC;QACjC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC3B,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC5B,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC5B,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,MAAwB;QACnC,cAAc,CAAC,MAAM,CAAC,CAAC;QACvB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,MAAM,GAAe;YACzB,MAAM,EAAE,IAAI,CAAC,YAAY,EAAE;YAC3B,GAAG,CAAC,MAAM,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC1E,GAAG,CAAC,MAAM,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACpE,MAAM,EAAE,SAAS;YACjB,SAAS,EAAE,GAAG;YACd,aAAa,EAAE,GAAG;YAClB,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,GAAG,CAAC,MAAM,CAAC,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,MAAM,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC1F,CAAC;QACF,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACzB,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACpC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QACvB,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC1B,CAAC;IAED,yDAAyD;IAC/C,SAAS,CAAC,OAAmB,IAAS,CAAC;IAEjD,KAAK,CAAC,GAAG,CAAC,MAAc,EAAE,MAAmB;QAC3C,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACvC,OAAO,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAChE,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,MAAc,EAAE,cAA8B,EAAE,MAAmB;QAC9E,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACvC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC;YAAE,OAAO,KAAK,CAAC;QAC3C,IAAI,MAAM,CAAC,MAAM,KAAK,gBAAgB,IAAI,CAAC,MAAM,CAAC,aAAa;YAAE,OAAO,IAAI,CAAC;QAC7E,MAAM,SAAS,GAAmB,EAAE,GAAG,CAAC,MAAM,CAAC,cAAc,IAAI,EAAE,CAAC,EAAE,CAAC;QACvE,KAAK,MAAM,CAAC,GAAG,EAAE,QAAQ,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,CAAC;YAC7D,4DAA4D;YAC5D,IAAI,GAAG,IAAI,MAAM,CAAC,aAAa,IAAI,CAAC,CAAC,GAAG,IAAI,SAAS,CAAC;gBAAE,SAAS,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC;QACpF,CAAC;QACD,MAAM,CAAC,cAAc,GAAG,SAAS,CAAC;QAClC,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,IAAI,SAAS,CAAC,CAAC;QACpF,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,CAAC,MAAM,GAAG,SAAS,CAAC;YAC1B,MAAM,CAAC,aAAa,GAAG,SAAS,CAAC;QACnC,CAAC;QACD,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACxB,IAAI,QAAQ;YAAE,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QACvC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,MAAc,EAAE,MAAmB;QAC9C,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACvC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC;YAAE,OAAO,KAAK,CAAC;QAC3C,IAAI,gBAAgB,CAAC,MAAM,CAAC,MAAM,CAAC;YAAE,OAAO,IAAI,CAAC;QACjD,MAAM,CAAC,MAAM,GAAG,WAAW,CAAC;QAC5B,UAAU,CAAC,MAAM,CAAC,CAAC;QACnB,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACxB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC;QACjC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC5B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,MAAmB,EAAE,OAA6C;QAC3E,MAAM,OAAO,GAAiB,EAAE,CAAC;QACjC,KAAK,MAAM,MAAM,IAAI,MAAM,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;YACtC,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;gBAAE,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;iBACrD,IAAI,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC;gBAAE,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACzD,CAAC;QACD,OAAO,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAClC,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,MAAc;QAC1B,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC;IAC5C,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,MAAc,EAAE,KAA8B;QAChE,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACvC,IAAI,CAAC,MAAM;YAAE,OAAO,KAAK,CAAC;QAC1B,MAAM,CAAC,OAAO,GAAG,EAAE,GAAG,MAAM,CAAC,OAAO,EAAE,GAAG,KAAK,EAAE,CAAC;QACjD,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACxB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CAAC,MAAc,EAAE,QAAsC;QAC1D,IAAI,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACrC,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,GAAG,GAAG,IAAI,GAAG,EAAE,CAAC;YAChB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAClC,CAAC;QACD,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAClB,OAAO,GAAG,EAAE;YACV,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YACrB,IAAI,GAAG,CAAC,IAAI,KAAK,CAAC;gBAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACpD,CAAC,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,MAAc;QACnB,MAAM,MAAM,GAAG,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC;QACnD,MAAM,OAAO,GAAG,KAAK,IAAqC,EAAE;YAC1D,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACvC,IAAI,CAAC,MAAM,IAAI,gBAAgB,CAAC,MAAM,CAAC,MAAM,CAAC;gBAAE,OAAO,SAAS,CAAC;YACjE,OAAO,MAAM,CAAC;QAChB,CAAC,CAAC;QACF,OAAO;YACL,MAAM;YACN,MAAM;YACN,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;gBACxB,MAAM,MAAM,GAAG,MAAM,OAAO,EAAE,CAAC;gBAC/B,IAAI,CAAC,MAAM;oBAAE,OAAO;gBACpB,MAAM,CAAC,aAAa,GAAG,OAAO,CAAC;gBAC/B,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAC1B,CAAC;YACD,YAAY,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE;gBAC/B,MAAM,MAAM,GAAG,MAAM,OAAO,EAAE,CAAC;gBAC/B,IAAI,CAAC,MAAM;oBAAE,MAAM,IAAI,KAAK,CAAC,SAAS,MAAM,wBAAwB,CAAC,CAAC;gBACtE,MAAM,KAAK,GAAG,UAAU,EAAE,CAAC;gBAC3B,MAAM,CAAC,MAAM,GAAG,gBAAgB,CAAC;gBACjC,MAAM,CAAC,aAAa,GAAG,QAAQ,CAAC;gBAChC,MAAM,CAAC,cAAc,GAAG,EAAE,CAAC;gBAC3B,MAAM,CAAC,UAAU,GAAG,KAAK,CAAC;gBAC1B,MAAM,QAAQ,GAAG,IAAI,OAAO,CAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;oBAC/D,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;oBAC7C,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,SAAS,MAAM,iBAAiB,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;gBAC9G,CAAC,CAAC,CAAC;gBACH,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;gBACxB,OAAO,QAAQ,CAAC;YAClB,CAAC;YACD,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;gBACzB,MAAM,MAAM,GAAG,MAAM,OAAO,EAAE,CAAC;gBAC/B,IAAI,CAAC,MAAM;oBAAE,OAAO;gBACpB,MAAM,CAAC,MAAM,GAAG,WAAW,CAAC;gBAC5B,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC;gBACvB,UAAU,CAAC,MAAM,CAAC,CAAC;gBACnB,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAC1B,CAAC;YACD,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;gBACpB,MAAM,MAAM,GAAG,MAAM,OAAO,EAAE,CAAC;gBAC/B,IAAI,CAAC,MAAM;oBAAE,OAAO;gBACpB,MAAM,CAAC,MAAM,GAAG,QAAQ,CAAC;gBACzB,MAAM,CAAC,KAAK,GAAG,KAAK,CAAC;gBACrB,UAAU,CAAC,MAAM,CAAC,CAAC;gBACnB,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAC1B,CAAC;SACF,CAAC;IACJ,CAAC;CACF;AAED,yGAAyG;AACzG,MAAM,OAAO,iBAAkB,SAAQ,aAAa;IACjC,KAAK,GAAG,IAAI,GAAG,EAAsB,CAAC;IACtC,MAAM,GAAG,IAAI,GAAG,EAAyC,CAAC;IAEjE,KAAK,CAAC,IAAI,CAAC,MAAc;QACjC,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAChC,CAAC;IACS,KAAK,CAAC,KAAK,CAAC,MAAkB;QACtC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,CAAC;IACS,KAAK,CAAC,GAAG;QACjB,OAAO,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;IAClC,CAAC;IACS,KAAK,CAAC,MAAM,CAAC,MAAc;QACnC,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACtC,IAAI,KAAK;YAAE,YAAY,CAAC,KAAK,CAAC,CAAC;QAC/B,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC3B,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC5B,CAAC;IACkB,SAAS,CAAC,MAAkB;QAC7C,IAAI,MAAM,CAAC,KAAK,KAAK,IAAI;YAAE,OAAO;QAClC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;QAC7E,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC;QAChB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IACxC,CAAC;IAED,KAAK;QACH,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE;YAAE,YAAY,CAAC,KAAK,CAAC,CAAC;QAC9D,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QACpB,KAAK,MAAM,UAAU,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE;YAAE,UAAU,CAAC,KAAK,EAAE,CAAC;QAClE,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QACpB,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACnB,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;IACzB,CAAC;CACF;AASD,MAAM,QAAQ,GAAG,OAAO,CAAC;AAEzB,sFAAsF;AACtF,MAAM,OAAO,aAAc,SAAQ,aAAa;IAM3B;IALF,OAAO,GAAG,IAAI,GAAG,EAA0C,CAAC;IAC5D,OAAO,CAAiC;IACxC,YAAY,CAAS;IAEtC,YACmB,IAAe,EAChC,UAAgC,EAAE;QAElC,KAAK,CAAC,OAAO,CAAC,CAAC;QAHE,SAAI,GAAJ,IAAI,CAAW;QAIhC,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,+DAA+D,CAAC,CAAC;QACpG,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,IAAI,CAAC;QACjD,IAAI,CAAC,OAAO,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC,OAAO,IAAI,MAAM,CAAC,CAAC;QACrG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;IACzB,CAAC;IAEO,IAAI,CAAC,MAAc;QACzB,IAAI,CAAC,wBAAwB,CAAC,IAAI,CAAC,MAAM,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;QAC/E,OAAO,GAAG,QAAQ,IAAI,MAAM,OAAO,CAAC;IACtC,CAAC;IAES,KAAK,CAAC,IAAI,CAAC,MAAc;QACjC,IAAI,IAAY,CAAC;QACjB,IAAI,CAAC;YACH,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC3B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC3C,IAAI,CAAC,GAAG;YAAE,OAAO,SAAS,CAAC;QAC3B,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAe,CAAC;QACxD,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,SAAS,CAAC;QACnB,CAAC;IACH,CAAC;IACS,KAAK,CAAC,KAAK,CAAC,MAAkB;QACtC,MAAM,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;IAC9E,CAAC;IACS,KAAK,CAAC,GAAG;QACjB,IAAI,KAAe,CAAC;QACpB,IAAI,CAAC;YACH,KAAK,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC3D,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,MAAM,OAAO,GAAiB,EAAE,CAAC;QACjC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;gBAAE,SAAS;YACtC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;YAC/D,IAAI,MAAM;gBAAE,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACnC,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IACS,KAAK,CAAC,MAAM,CAAC,MAAc;QACnC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QACzB,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;IAC5C,CAAC;IAEO,WAAW,CAAC,MAAc;QAChC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACxC,IAAI,MAAM;YAAE,aAAa,CAAC,MAAM,CAAC,CAAC;QAClC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC9B,CAAC;IAEQ,MAAM,CAAC,MAAc;QAC5B,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACpC,iGAAiG;QACjG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YAC9B,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,EAAE;gBAC9B,KAAK,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE;oBACrC,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,KAAK,WAAW,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;wBACrE,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC;oBACnC,CAAC;oBACD,IAAI,MAAM;wBAAE,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;oBACrC,IAAI,CAAC,MAAM,IAAI,gBAAgB,CAAC,MAAM,CAAC,MAAM,CAAC;wBAAE,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;gBAC3E,CAAC,CAAC,CAAC;YACL,CAAC,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;YACtB,MAAM,CAAC,KAAK,EAAE,EAAE,CAAC;YACjB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACnC,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,KAAK;QACH,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC5B,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE;YAAE,aAAa,CAAC,MAAM,CAAC,CAAC;QAClE,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QACrB,KAAK,MAAM,UAAU,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE;YAAE,UAAU,CAAC,KAAK,EAAE,CAAC;QAClE,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QACpB,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;IACzB,CAAC;CACF;AAED,kFAAkF;AAClF,MAAM,UAAU,eAAe,CAAC,IAA2B,EAAE,UAAgC,EAAE;IAC7F,OAAO,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,aAAa,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,iBAAiB,CAAC,OAAO,CAAC,CAAC;AAC3F,CAAC"}
@@ -0,0 +1,115 @@
1
+ /**
2
+ * @novorb/mcp-core - Task tools (long-running tools on MCP Tasks, both protocol eras)
3
+ *
4
+ * A task tool answers a task handle instead of blocking: the client polls (or, on 2025-11-25, waits
5
+ * on `tasks/result`) and can cancel. The work runs in this process behind a `ManagedTaskStore`; the
6
+ * SDK 2.3.1 ships the wire types only, so mcp-core serves the methods itself, per era, with the
7
+ * shapes of the spec and of SDK PR #2782:
8
+ *
9
+ * | | 2025-11-25 (legacy) | 2026-07-28 (modern, `io.modelcontextprotocol/tasks` extension) |
10
+ * |---|---|---|
11
+ * | capability | `tasks: { list, cancel, requests: { tools: { call } } }` | `extensions: { 'io.modelcontextprotocol/tasks': {} }` |
12
+ * | start | `tools/call` with `params.task: { ttl? }` -> `{ task, content }` | `tools/call` from a client declaring the extension -> `{ resultType: 'task', ...task }` |
13
+ * | poll | `tasks/get` -> Task (`ttl`, `pollInterval`) | `tasks/get` -> DetailedTask (result / error / inputRequests inlined) |
14
+ * | result | `tasks/result` (blocks until terminal) | inlined in `tasks/get` |
15
+ * | list | `tasks/list` | none (not in the extension) |
16
+ * | cancel | `tasks/cancel` -> Task (terminal = -32602) | `tasks/cancel` -> ack (idempotent) |
17
+ * | input | not supported (no `tasks/result` side channel) | `tasks/update` answers `input_required` |
18
+ * | status | `notifications/tasks/status` (stdio: the connection is long-lived) | polling only (the extension has no notifications yet) |
19
+ *
20
+ * A client without task support (no `params.task`, no declared extension) gets the tool run
21
+ * synchronously: the same `run` with progress notifications, unless `taskSupport: 'required'`.
22
+ * Tasks are bound to the creating caller's `clientId`.
23
+ *
24
+ * registerTaskTools(server, [
25
+ * defineTaskTool({
26
+ * name: 'export_report', description: 'Export a report', inputSchema: z.object({ report: z.string() }),
27
+ * annotations: TOOL_ANNOTATIONS.mutableWriteOpenWorld,
28
+ * run: async ({ report }, task) => {
29
+ * for (let i = 1; i <= 10; i++) { task.signal.throwIfAborted(); await step(); await task.progress(i, 10); }
30
+ * return toolResult({ report, rows: 42 });
31
+ * },
32
+ * }),
33
+ * ], { store, request: req, env });
34
+ */
35
+ import { type AuthInfo, type InputRequests, type InputResponses, type ServerContext, type StandardSchemaWithJSON } from '@modelcontextprotocol/server';
36
+ import type { McpServer } from './server.js';
37
+ import { type ManagedTaskStore, type Task } from './task-store.js';
38
+ import { type RegisterToolsOptions, registerTools, type ToolArgs, type ToolDefinition, type ToolOutcome } from './tools.js';
39
+ import type { RequestContext } from './transport.js';
40
+ import { type Logger } from './utils/logger.js';
41
+ /** What a task tool's `run` receives (both modes). */
42
+ export interface TaskContext {
43
+ /** `task`: running behind a task handle; `sync`: the client has no task support. */
44
+ mode: 'task' | 'sync';
45
+ /** The task id (task mode only). */
46
+ taskId?: string;
47
+ /** Aborted on `tasks/cancel` (task mode) or the request's cancellation (sync mode). */
48
+ signal: AbortSignal;
49
+ authInfo?: AuthInfo;
50
+ logger: Logger;
51
+ /** Report progress: the task's `statusMessage` (task mode) or a progress notification (sync mode). */
52
+ progress(current: number, total?: number, message?: string): Promise<void>;
53
+ /** Set the task's `statusMessage` (task mode; a progress message in sync mode). */
54
+ status(message: string): Promise<void>;
55
+ /**
56
+ * Ask the client for input mid-task (2026-07-28 `input_required` + `tasks/update`). Rejects in sync
57
+ * mode and on 2025-era tasks (use `ToolContext.elicit` in a plain tool there).
58
+ */
59
+ requireInput(requests: InputRequests): Promise<InputResponses>;
60
+ }
61
+ export interface TaskToolDefinition<I extends StandardSchemaWithJSON = StandardSchemaWithJSON> extends Omit<ToolDefinition<I>, 'handler' | 'outputSchema' | 'paginated'> {
62
+ /** `optional` (default): sync for clients without task support; `required`: refuse them. */
63
+ taskSupport?: 'optional' | 'required';
64
+ /** Retention of a task from creation, ms (default 1 hour; a 2025 client's `ttl` may lower it). */
65
+ ttlMs?: number;
66
+ /** Suggested polling interval, ms (default 1000). */
67
+ pollIntervalMs?: number;
68
+ run: (args: ToolArgs<I>, task: TaskContext) => Promise<ToolOutcome>;
69
+ }
70
+ export type AnyTaskToolDefinition = Omit<TaskToolDefinition, 'run'> & {
71
+ run: (args: never, task: TaskContext) => Promise<ToolOutcome>;
72
+ };
73
+ /** Identity helper that types `run` from the tool's own input schema. */
74
+ export declare function defineTaskTool<I extends StandardSchemaWithJSON>(definition: TaskToolDefinition<I>): AnyTaskToolDefinition;
75
+ /** The 2025-11-25 wire shape of a task (`ttl`, `pollInterval`). */
76
+ export interface LegacyTask {
77
+ taskId: string;
78
+ status: Task['status'];
79
+ ttl: number | null;
80
+ createdAt: string;
81
+ lastUpdatedAt: string;
82
+ pollInterval?: number;
83
+ statusMessage?: string;
84
+ }
85
+ /** Map a task onto the 2025-11-25 wire shape. */
86
+ export declare function toLegacyTask(task: Task): LegacyTask;
87
+ /** Whether a 2026-07-28 request declared the tasks extension in its envelope capabilities. */
88
+ export declare function declaresTasksExtension(sdk: ServerContext): boolean;
89
+ export interface EnableTasksOptions {
90
+ /** The request era this instance serves (the factory's `req.era`). */
91
+ era: 'legacy' | 'modern';
92
+ /** How often a blocking 2025 `tasks/result` re-reads the store (ms, default 1000). */
93
+ resultPollMs?: number;
94
+ }
95
+ /**
96
+ * Serve the task methods for this instance's era and advertise the matching capability (call before
97
+ * the instance is connected; `registerTaskTools` does it). Idempotent.
98
+ */
99
+ export declare function enableTasks(server: McpServer, store: ManagedTaskStore, options: EnableTasksOptions): void;
100
+ export interface RegisterTaskToolsOptions extends Omit<RegisterToolsOptions, 'limits' | 'onOversize'> {
101
+ /** Where tasks live (shared state from `setup`: one store for every request of the process). */
102
+ store: ManagedTaskStore;
103
+ /** The factory's request context (selects the era's methods and capability). */
104
+ request: Pick<RequestContext, 'era'>;
105
+ /** Max serialized bytes of a stored task result (default MCP_MAX_RESULT_BYTES). */
106
+ maxResultBytes?: number;
107
+ /** How often a blocking 2025 `tasks/result` re-reads the store (ms). */
108
+ resultPollMs?: number;
109
+ }
110
+ /**
111
+ * Register task tools on `server` (through `registerTools`, so logging, masking, degraded mode and
112
+ * the enabled/prefix/surface options are the same) and enable the era's task methods.
113
+ */
114
+ export declare function registerTaskTools(server: McpServer, defs: readonly AnyTaskToolDefinition[], opts: RegisterTaskToolsOptions): ReturnType<typeof registerTools>;
115
+ //# sourceMappingURL=task-tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-tools.d.ts","sourceRoot":"","sources":["../src/task-tools.ts"],"names":[],"mappings":"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"}