@j0hanz/fetch-url-mcp 1.10.2 → 1.10.3
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.
- package/dist/http/native.d.ts.map +1 -1
- package/dist/http/native.js +20 -26
- package/dist/http/session-teardown.d.ts +17 -0
- package/dist/http/session-teardown.d.ts.map +1 -0
- package/dist/http/session-teardown.js +30 -0
- package/dist/lib/core.d.ts.map +1 -1
- package/dist/lib/core.js +2 -0
- package/dist/lib/dom-prep.d.ts.map +1 -1
- package/dist/lib/dom-prep.js +19 -14
- package/dist/lib/progress.d.ts.map +1 -1
- package/dist/lib/progress.js +59 -32
- package/dist/lib/sdk-interop.d.ts +8 -0
- package/dist/lib/sdk-interop.d.ts.map +1 -0
- package/dist/lib/sdk-interop.js +73 -0
- package/dist/lib/task-handlers.d.ts +0 -2
- package/dist/lib/task-handlers.d.ts.map +1 -1
- package/dist/lib/task-handlers.js +9 -94
- package/dist/resources/index.js +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +10 -3
- package/dist/tasks/call-contract.d.ts +25 -0
- package/dist/tasks/call-contract.d.ts.map +1 -0
- package/dist/tasks/call-contract.js +58 -0
- package/dist/tasks/cursor-codec.d.ts +5 -0
- package/dist/tasks/cursor-codec.d.ts.map +1 -0
- package/dist/tasks/cursor-codec.js +41 -0
- package/dist/tasks/execution.d.ts +1 -20
- package/dist/tasks/execution.d.ts.map +1 -1
- package/dist/tasks/execution.js +7 -32
- package/dist/tasks/manager.d.ts +1 -5
- package/dist/tasks/manager.d.ts.map +1 -1
- package/dist/tasks/manager.js +16 -144
- package/dist/tasks/owner.d.ts +12 -2
- package/dist/tasks/owner.d.ts.map +1 -1
- package/dist/tasks/owner.js +52 -3
- package/dist/tasks/tool-registry.d.ts +1 -0
- package/dist/tasks/tool-registry.d.ts.map +1 -1
- package/dist/tasks/waiters.d.ts +27 -0
- package/dist/tasks/waiters.d.ts.map +1 -0
- package/dist/tasks/waiters.js +113 -0
- package/dist/tools/fetch-url-progress.d.ts +17 -0
- package/dist/tools/fetch-url-progress.d.ts.map +1 -0
- package/dist/tools/fetch-url-progress.js +78 -0
- package/dist/tools/fetch-url.d.ts +5 -9
- package/dist/tools/fetch-url.d.ts.map +1 -1
- package/dist/tools/fetch-url.js +43 -96
- package/dist/transform/next-flight.d.ts +2 -0
- package/dist/transform/next-flight.d.ts.map +1 -0
- package/dist/transform/next-flight.js +285 -0
- package/dist/transform/transform.d.ts.map +1 -1
- package/dist/transform/transform.js +21 -336
- package/package.json +4 -4
- package/dist/tools/index.d.ts +0 -3
- package/dist/tools/index.d.ts.map +0 -1
- package/dist/tools/index.js +0 -4
package/dist/tasks/manager.js
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
2
|
-
import { Buffer } from 'node:buffer';
|
|
3
1
|
import { randomUUID } from 'node:crypto';
|
|
4
2
|
import { setInterval } from 'node:timers';
|
|
5
3
|
import { ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';
|
|
6
4
|
import { config } from '../lib/core.js';
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
5
|
+
import { decodeTaskCursor, encodeTaskCursor } from './cursor-codec.js';
|
|
6
|
+
import { TaskWaiterRegistry, waitForTerminalTask as waitForTerminalTaskWithDeadline, } from './waiters.js';
|
|
9
7
|
const DEFAULT_TTL_MS = 60_000;
|
|
10
8
|
const MIN_TTL_MS = 1_000;
|
|
11
9
|
const MAX_TTL_MS = 86_400_000;
|
|
@@ -13,7 +11,6 @@ const DEFAULT_POLL_INTERVAL_MS = 1_000;
|
|
|
13
11
|
const DEFAULT_OWNER_KEY = 'default';
|
|
14
12
|
const DEFAULT_PAGE_SIZE = 50;
|
|
15
13
|
const CLEANUP_INTERVAL_MS = 60_000;
|
|
16
|
-
const MAX_CURSOR_LENGTH = 256;
|
|
17
14
|
const RESULT_DELIVERY_GRACE_MS = 10_000;
|
|
18
15
|
const TASK_STATUS_VALUES = new Set([
|
|
19
16
|
'working',
|
|
@@ -59,7 +56,7 @@ function normalizeTaskTtl(ttl) {
|
|
|
59
56
|
class TaskManager {
|
|
60
57
|
tasks = new Map();
|
|
61
58
|
ownerCounts = new Map();
|
|
62
|
-
waiters = new
|
|
59
|
+
waiters = new TaskWaiterRegistry(isTerminalStatus);
|
|
63
60
|
cleanupInterval = null;
|
|
64
61
|
ensureCleanupLoop() {
|
|
65
62
|
if (this.cleanupInterval)
|
|
@@ -259,116 +256,27 @@ class TaskManager {
|
|
|
259
256
|
resolveAnchorTaskId(cursor) {
|
|
260
257
|
if (cursor === undefined)
|
|
261
258
|
return null;
|
|
262
|
-
const decoded =
|
|
259
|
+
const decoded = decodeTaskCursor(cursor);
|
|
263
260
|
if (decoded === null) {
|
|
264
261
|
throw new McpError(ErrorCode.InvalidParams, 'Invalid cursor');
|
|
265
262
|
}
|
|
266
263
|
return decoded.anchorTaskId;
|
|
267
264
|
}
|
|
268
|
-
addWaiter(taskId, waiter) {
|
|
269
|
-
let set = this.waiters.get(taskId);
|
|
270
|
-
if (!set) {
|
|
271
|
-
set = new Set();
|
|
272
|
-
this.waiters.set(taskId, set);
|
|
273
|
-
}
|
|
274
|
-
set.add(waiter);
|
|
275
|
-
}
|
|
276
|
-
removeWaiter(taskId, waiter) {
|
|
277
|
-
if (!waiter)
|
|
278
|
-
return;
|
|
279
|
-
const set = this.waiters.get(taskId);
|
|
280
|
-
if (!set)
|
|
281
|
-
return;
|
|
282
|
-
set.delete(waiter);
|
|
283
|
-
if (set.size === 0) {
|
|
284
|
-
this.waiters.delete(taskId);
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
265
|
async waitForTerminalTask(taskId, ownerKey, signal) {
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
const resolveInContext = AsyncLocalStorage.bind((value) => {
|
|
299
|
-
resolve(value);
|
|
300
|
-
});
|
|
301
|
-
const rejectInContext = AsyncLocalStorage.bind((error) => {
|
|
302
|
-
reject(toError(error));
|
|
303
|
-
});
|
|
304
|
-
let settled = false;
|
|
305
|
-
let waiter = null;
|
|
306
|
-
let deadlineTimeout;
|
|
307
|
-
const cleanup = () => {
|
|
308
|
-
if (deadlineTimeout) {
|
|
309
|
-
deadlineTimeout.cancel();
|
|
310
|
-
deadlineTimeout = undefined;
|
|
311
|
-
}
|
|
312
|
-
if (signal) {
|
|
313
|
-
signal.removeEventListener('abort', onAbort);
|
|
314
|
-
}
|
|
315
|
-
};
|
|
316
|
-
const settleOnce = (fn) => {
|
|
317
|
-
if (settled)
|
|
318
|
-
return;
|
|
319
|
-
settled = true;
|
|
320
|
-
fn();
|
|
321
|
-
};
|
|
322
|
-
const onAbort = () => {
|
|
323
|
-
settleOnce(() => {
|
|
324
|
-
cleanup();
|
|
325
|
-
this.removeWaiter(taskId, waiter);
|
|
326
|
-
rejectInContext(new McpError(ErrorCode.ConnectionClosed, 'Request was cancelled'));
|
|
327
|
-
});
|
|
328
|
-
};
|
|
329
|
-
waiter = (updated) => {
|
|
330
|
-
settleOnce(() => {
|
|
331
|
-
cleanup();
|
|
332
|
-
if (updated.ownerKey !== ownerKey) {
|
|
333
|
-
resolveInContext(undefined);
|
|
334
|
-
return;
|
|
335
|
-
}
|
|
336
|
-
resolveInContext(updated);
|
|
337
|
-
});
|
|
338
|
-
};
|
|
339
|
-
if (signal?.aborted) {
|
|
340
|
-
onAbort();
|
|
341
|
-
return;
|
|
342
|
-
}
|
|
343
|
-
this.addWaiter(taskId, waiter);
|
|
344
|
-
if (signal) {
|
|
345
|
-
signal.addEventListener('abort', onAbort, { once: true });
|
|
346
|
-
}
|
|
347
|
-
const timeoutMs = Math.max(0, deadlineMs - Date.now());
|
|
348
|
-
deadlineTimeout = createUnrefTimeout(timeoutMs, { timeout: true });
|
|
349
|
-
void deadlineTimeout.promise
|
|
350
|
-
.then(() => {
|
|
351
|
-
settleOnce(() => {
|
|
352
|
-
cleanup();
|
|
353
|
-
this.removeWaiter(taskId, waiter);
|
|
354
|
-
this.removeTask(taskId);
|
|
355
|
-
rejectInContext(new McpError(ErrorCode.InvalidParams, 'Task expired', {
|
|
356
|
-
taskId,
|
|
357
|
-
}));
|
|
358
|
-
});
|
|
359
|
-
})
|
|
360
|
-
.catch(rejectInContext);
|
|
266
|
+
return waitForTerminalTaskWithDeadline({
|
|
267
|
+
taskId,
|
|
268
|
+
ownerKey,
|
|
269
|
+
...(signal ? { signal } : {}),
|
|
270
|
+
lookupTask: (currentTaskId, currentOwnerKey) => this.lookupActiveTask(currentTaskId, currentOwnerKey),
|
|
271
|
+
removeTask: (currentTaskId) => {
|
|
272
|
+
this.removeTask(currentTaskId);
|
|
273
|
+
},
|
|
274
|
+
registry: this.waiters,
|
|
275
|
+
isTerminalStatus,
|
|
361
276
|
});
|
|
362
277
|
}
|
|
363
278
|
notifyWaiters(task) {
|
|
364
|
-
|
|
365
|
-
return;
|
|
366
|
-
const waiters = this.waiters.get(task.taskId);
|
|
367
|
-
if (!waiters)
|
|
368
|
-
return;
|
|
369
|
-
this.waiters.delete(task.taskId);
|
|
370
|
-
for (const waiter of waiters)
|
|
371
|
-
waiter(task);
|
|
279
|
+
this.waiters.notify(task);
|
|
372
280
|
}
|
|
373
281
|
isExpired(task, now = Date.now()) {
|
|
374
282
|
return now - task._createdAtMs > task.ttl;
|
|
@@ -389,47 +297,11 @@ class TaskManager {
|
|
|
389
297
|
this.maybeUpdateLastUpdatedAt(task);
|
|
390
298
|
}
|
|
391
299
|
}
|
|
392
|
-
encodeCursor(taskId) {
|
|
393
|
-
// Base64url-encode the taskId to produce a compact opaque cursor string.
|
|
394
|
-
// The taskId is a UUID, which is 36 ASCII chars, so the resulting cursor will be 48 chars (36 * 4/3) plus padding if any.
|
|
395
|
-
return Buffer.from(taskId, 'utf8').toString('base64url');
|
|
396
|
-
}
|
|
397
|
-
decodeCursor(cursor) {
|
|
398
|
-
try {
|
|
399
|
-
if (!isValidBase64UrlCursor(cursor))
|
|
400
|
-
return null;
|
|
401
|
-
const decoded = Buffer.from(cursor, 'base64url').toString('utf8');
|
|
402
|
-
// Basic sanity: non-empty and plausible taskId length (UUIDs are 36 chars)
|
|
403
|
-
if (!decoded || decoded.length > 128)
|
|
404
|
-
return null;
|
|
405
|
-
return { anchorTaskId: decoded };
|
|
406
|
-
}
|
|
407
|
-
catch {
|
|
408
|
-
return null;
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
300
|
resolveNextCursor(page, hasMore) {
|
|
412
301
|
if (!hasMore)
|
|
413
302
|
return undefined;
|
|
414
303
|
const lastTask = page.at(-1);
|
|
415
|
-
return lastTask ?
|
|
416
|
-
}
|
|
417
|
-
}
|
|
418
|
-
function isValidBase64UrlCursor(cursor) {
|
|
419
|
-
if (!cursor)
|
|
420
|
-
return false;
|
|
421
|
-
if (cursor.length > MAX_CURSOR_LENGTH)
|
|
422
|
-
return false;
|
|
423
|
-
if (!/^[A-Za-z0-9_-]+={0,2}$/u.test(cursor))
|
|
424
|
-
return false;
|
|
425
|
-
const firstPaddingIndex = cursor.indexOf('=');
|
|
426
|
-
if (firstPaddingIndex !== -1) {
|
|
427
|
-
for (let i = firstPaddingIndex; i < cursor.length; i += 1) {
|
|
428
|
-
if (cursor[i] !== '=')
|
|
429
|
-
return false;
|
|
430
|
-
}
|
|
431
|
-
return cursor.length % 4 === 0;
|
|
304
|
+
return lastTask ? encodeTaskCursor(lastTask.taskId) : undefined;
|
|
432
305
|
}
|
|
433
|
-
return cursor.length % 4 !== 1;
|
|
434
306
|
}
|
|
435
307
|
export const taskManager = new TaskManager();
|
package/dist/tasks/owner.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { ServerResult } from '@modelcontextprotocol/sdk/types.js';
|
|
2
2
|
import type { ProgressNotification } from '../lib/progress.js';
|
|
3
|
+
import type { ToolHandlerExtra } from '../lib/progress.js';
|
|
4
|
+
import { type ToolCallRequestMeta } from './call-contract.js';
|
|
3
5
|
interface HandlerExtra {
|
|
4
6
|
sessionId?: string;
|
|
5
7
|
authInfo?: {
|
|
@@ -9,14 +11,17 @@ interface HandlerExtra {
|
|
|
9
11
|
signal?: AbortSignal;
|
|
10
12
|
requestId?: string | number;
|
|
11
13
|
sendNotification?: (notification: ProgressNotification) => Promise<void>;
|
|
14
|
+
requestInfo?: unknown;
|
|
12
15
|
}
|
|
13
|
-
export interface
|
|
16
|
+
export interface ToolExecutionContext {
|
|
14
17
|
ownerKey: string;
|
|
15
18
|
sessionId?: string;
|
|
16
19
|
signal?: AbortSignal;
|
|
17
20
|
requestId?: string | number;
|
|
18
21
|
sendNotification?: (notification: ProgressNotification) => Promise<void>;
|
|
22
|
+
requestMeta?: ToolCallRequestMeta;
|
|
19
23
|
}
|
|
24
|
+
export type ToolCallContext = ToolExecutionContext;
|
|
20
25
|
/** Strip keys whose value is `undefined`, returning an object with only the
|
|
21
26
|
* present keys. Return type correctly omits the `undefined` union so the result
|
|
22
27
|
* is compatible with `exactOptionalPropertyTypes`. */
|
|
@@ -26,7 +31,12 @@ type Compacted<T extends object> = {
|
|
|
26
31
|
export declare function compact<T extends object>(obj: T): Compacted<T>;
|
|
27
32
|
export declare function parseHandlerExtra(extra: unknown): HandlerExtra | undefined;
|
|
28
33
|
export declare function resolveTaskOwnerKey(extra?: HandlerExtra): string;
|
|
29
|
-
export declare function
|
|
34
|
+
export declare function resolveRequestIdFromExtra(extra: unknown): string | undefined;
|
|
35
|
+
export declare function resolveSessionIdFromExtra(extra: unknown): string | undefined;
|
|
36
|
+
export declare function resolveToolExecutionContext(extra?: HandlerExtra, requestMeta?: ToolCallRequestMeta): ToolExecutionContext;
|
|
37
|
+
export declare function resolveToolCallContext(extra?: HandlerExtra, requestMeta?: ToolCallRequestMeta): ToolCallContext;
|
|
38
|
+
export declare function buildToolHandlerExtra(context: ToolExecutionContext, requestMeta?: ToolCallRequestMeta): ToolHandlerExtra;
|
|
39
|
+
export declare function withRequestContextIfMissing<TParams, TResult, TExtra = unknown>(handler: (params: TParams, extra?: TExtra) => Promise<TResult>): (params: TParams, extra?: TExtra) => Promise<TResult>;
|
|
30
40
|
export declare function isServerResult(value: unknown): value is ServerResult;
|
|
31
41
|
export declare function tryReadToolStructuredError(value: unknown): string | undefined;
|
|
32
42
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"owner.d.ts","sourceRoot":"","sources":["../../src/tasks/owner.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;
|
|
1
|
+
{"version":3,"file":"owner.d.ts","sourceRoot":"","sources":["../../src/tasks/owner.ts"],"names":[],"mappings":"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"}
|
package/dist/tasks/owner.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import { createHash } from 'node:crypto';
|
|
1
|
+
import { createHash, randomUUID } from 'node:crypto';
|
|
2
2
|
import { z } from 'zod';
|
|
3
|
-
import {
|
|
3
|
+
import { getRequestId, runWithRequestContext } from '../lib/core.js';
|
|
4
|
+
import { isObject, readNestedRecord } from '../lib/utils.js';
|
|
5
|
+
import { sanitizeToolCallMeta, } from './call-contract.js';
|
|
4
6
|
export function compact(obj) {
|
|
5
7
|
const result = {};
|
|
6
8
|
for (const key of Object.keys(obj)) {
|
|
@@ -60,15 +62,62 @@ export function resolveTaskOwnerKey(extra) {
|
|
|
60
62
|
return `token:${createHash('sha256').update(extra.authInfo.token).digest('hex')}`;
|
|
61
63
|
return 'default';
|
|
62
64
|
}
|
|
63
|
-
export function
|
|
65
|
+
export function resolveRequestIdFromExtra(extra) {
|
|
66
|
+
if (!isObject(extra))
|
|
67
|
+
return undefined;
|
|
68
|
+
const { requestId } = extra;
|
|
69
|
+
if (typeof requestId === 'string')
|
|
70
|
+
return requestId;
|
|
71
|
+
if (typeof requestId === 'number')
|
|
72
|
+
return String(requestId);
|
|
73
|
+
return undefined;
|
|
74
|
+
}
|
|
75
|
+
export function resolveSessionIdFromExtra(extra) {
|
|
76
|
+
if (!isObject(extra))
|
|
77
|
+
return undefined;
|
|
78
|
+
const { sessionId } = extra;
|
|
79
|
+
if (typeof sessionId === 'string')
|
|
80
|
+
return sessionId;
|
|
81
|
+
const headers = readNestedRecord(extra, ['requestInfo', 'headers']);
|
|
82
|
+
const headerValue = headers ? headers['mcp-session-id'] : undefined;
|
|
83
|
+
return typeof headerValue === 'string' ? headerValue : undefined;
|
|
84
|
+
}
|
|
85
|
+
export function resolveToolExecutionContext(extra, requestMeta) {
|
|
64
86
|
return compact({
|
|
65
87
|
ownerKey: resolveTaskOwnerKey(extra),
|
|
66
88
|
sessionId: extra?.sessionId,
|
|
67
89
|
signal: extra?.signal,
|
|
68
90
|
requestId: extra?.requestId,
|
|
69
91
|
sendNotification: extra?.sendNotification,
|
|
92
|
+
requestMeta: sanitizeToolCallMeta(requestMeta),
|
|
70
93
|
});
|
|
71
94
|
}
|
|
95
|
+
export function resolveToolCallContext(extra, requestMeta) {
|
|
96
|
+
return resolveToolExecutionContext(extra, requestMeta);
|
|
97
|
+
}
|
|
98
|
+
export function buildToolHandlerExtra(context, requestMeta) {
|
|
99
|
+
return compact({
|
|
100
|
+
signal: context.signal,
|
|
101
|
+
requestId: context.requestId,
|
|
102
|
+
sendNotification: context.sendNotification,
|
|
103
|
+
_meta: sanitizeToolCallMeta(requestMeta ?? context.requestMeta),
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
export function withRequestContextIfMissing(handler) {
|
|
107
|
+
return async (params, extra) => {
|
|
108
|
+
const existingRequestId = getRequestId();
|
|
109
|
+
if (existingRequestId) {
|
|
110
|
+
return handler(params, extra);
|
|
111
|
+
}
|
|
112
|
+
const derivedRequestId = resolveRequestIdFromExtra(extra) ?? randomUUID();
|
|
113
|
+
const derivedSessionId = resolveSessionIdFromExtra(extra);
|
|
114
|
+
return runWithRequestContext({
|
|
115
|
+
requestId: derivedRequestId,
|
|
116
|
+
operationId: derivedRequestId,
|
|
117
|
+
...(derivedSessionId ? { sessionId: derivedSessionId } : {}),
|
|
118
|
+
}, () => handler(params, extra));
|
|
119
|
+
};
|
|
120
|
+
}
|
|
72
121
|
export function isServerResult(value) {
|
|
73
122
|
return (isObject(value) && Array.isArray(value.content));
|
|
74
123
|
}
|
|
@@ -4,6 +4,7 @@ export interface TaskCapableToolDescriptor<TArgs = unknown> {
|
|
|
4
4
|
name: string;
|
|
5
5
|
parseArguments: (args: unknown) => TArgs;
|
|
6
6
|
execute: (args: TArgs, extra?: ToolHandlerExtra) => Promise<ServerResult>;
|
|
7
|
+
getCompletionStatusMessage?: (result: ServerResult) => string | undefined;
|
|
7
8
|
}
|
|
8
9
|
export declare function registerTaskCapableTool<TArgs>(descriptor: TaskCapableToolDescriptor<TArgs>): void;
|
|
9
10
|
export declare function unregisterTaskCapableTool(name: string): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool-registry.d.ts","sourceRoot":"","sources":["../../src/tasks/tool-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAEvE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAE3D,MAAM,WAAW,yBAAyB,CAAC,KAAK,GAAG,OAAO;IACxD,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,KAAK,CAAC;IACzC,OAAO,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,EAAE,gBAAgB,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;CAC3E;AAID,wBAAgB,uBAAuB,CAAC,KAAK,EAC3C,UAAU,EAAE,yBAAyB,CAAC,KAAK,CAAC,GAC3C,IAAI,CAKN;AAED,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAE5D;AAED,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,GACX,yBAAyB,GAAG,SAAS,CAEvC;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAExD;AAED,wBAAgB,6BAA6B,IAAI,OAAO,CAEvD"}
|
|
1
|
+
{"version":3,"file":"tool-registry.d.ts","sourceRoot":"","sources":["../../src/tasks/tool-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAEvE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAE3D,MAAM,WAAW,yBAAyB,CAAC,KAAK,GAAG,OAAO;IACxD,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,KAAK,CAAC;IACzC,OAAO,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,EAAE,gBAAgB,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;IAC1E,0BAA0B,CAAC,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,MAAM,GAAG,SAAS,CAAC;CAC3E;AAID,wBAAgB,uBAAuB,CAAC,KAAK,EAC3C,UAAU,EAAE,yBAAyB,CAAC,KAAK,CAAC,GAC3C,IAAI,CAKN;AAED,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAE5D;AAED,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,GACX,yBAAyB,GAAG,SAAS,CAEvC;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAExD;AAED,wBAAgB,6BAA6B,IAAI,OAAO,CAEvD"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
interface WaitableTask {
|
|
2
|
+
taskId: string;
|
|
3
|
+
ownerKey: string;
|
|
4
|
+
status: string;
|
|
5
|
+
ttl: number;
|
|
6
|
+
_createdAtMs: number;
|
|
7
|
+
}
|
|
8
|
+
type TaskWaiter<TTask extends WaitableTask> = (task: TTask) => void;
|
|
9
|
+
export declare class TaskWaiterRegistry<TTask extends WaitableTask> {
|
|
10
|
+
private readonly isTerminalStatus;
|
|
11
|
+
private waiters;
|
|
12
|
+
constructor(isTerminalStatus: (status: TTask['status']) => boolean);
|
|
13
|
+
add(taskId: string, waiter: TaskWaiter<TTask>): void;
|
|
14
|
+
remove(taskId: string, waiter: TaskWaiter<TTask> | null): void;
|
|
15
|
+
notify(task: TTask): void;
|
|
16
|
+
}
|
|
17
|
+
export declare function waitForTerminalTask<TTask extends WaitableTask>(options: {
|
|
18
|
+
taskId: string;
|
|
19
|
+
ownerKey: string;
|
|
20
|
+
signal?: AbortSignal;
|
|
21
|
+
lookupTask: (taskId: string, ownerKey: string) => TTask | undefined;
|
|
22
|
+
removeTask: (taskId: string) => void;
|
|
23
|
+
registry: TaskWaiterRegistry<TTask>;
|
|
24
|
+
isTerminalStatus: (status: TTask['status']) => boolean;
|
|
25
|
+
}): Promise<TTask | undefined>;
|
|
26
|
+
export {};
|
|
27
|
+
//# sourceMappingURL=waiters.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"waiters.d.ts","sourceRoot":"","sources":["../../src/tasks/waiters.ts"],"names":[],"mappings":"AAOA,UAAU,YAAY;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,KAAK,UAAU,CAAC,KAAK,SAAS,YAAY,IAAI,CAAC,IAAI,EAAE,KAAK,KAAK,IAAI,CAAC;AAEpE,qBAAa,kBAAkB,CAAC,KAAK,SAAS,YAAY;IAItD,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IAHnC,OAAO,CAAC,OAAO,CAA6C;gBAGzC,gBAAgB,EAAE,CAAC,MAAM,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,OAAO;IAGzE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,KAAK,CAAC,GAAG,IAAI;IASpD,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,KAAK,CAAC,GAAG,IAAI,GAAG,IAAI;IAY9D,MAAM,CAAC,IAAI,EAAE,KAAK,GAAG,IAAI;CAS1B;AAED,wBAAsB,mBAAmB,CAAC,KAAK,SAAS,YAAY,EAAE,OAAO,EAAE;IAC7E,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,KAAK,GAAG,SAAS,CAAC;IACpE,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,QAAQ,EAAE,kBAAkB,CAAC,KAAK,CAAC,CAAC;IACpC,gBAAgB,EAAE,CAAC,MAAM,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,OAAO,CAAC;CACxD,GAAG,OAAO,CAAC,KAAK,GAAG,SAAS,CAAC,CAwF7B"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
2
|
+
import { ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';
|
|
3
|
+
import { toError } from '../lib/utils.js';
|
|
4
|
+
import { createUnrefTimeout } from '../lib/utils.js';
|
|
5
|
+
export class TaskWaiterRegistry {
|
|
6
|
+
isTerminalStatus;
|
|
7
|
+
waiters = new Map();
|
|
8
|
+
constructor(isTerminalStatus) {
|
|
9
|
+
this.isTerminalStatus = isTerminalStatus;
|
|
10
|
+
}
|
|
11
|
+
add(taskId, waiter) {
|
|
12
|
+
let set = this.waiters.get(taskId);
|
|
13
|
+
if (!set) {
|
|
14
|
+
set = new Set();
|
|
15
|
+
this.waiters.set(taskId, set);
|
|
16
|
+
}
|
|
17
|
+
set.add(waiter);
|
|
18
|
+
}
|
|
19
|
+
remove(taskId, waiter) {
|
|
20
|
+
if (!waiter)
|
|
21
|
+
return;
|
|
22
|
+
const set = this.waiters.get(taskId);
|
|
23
|
+
if (!set)
|
|
24
|
+
return;
|
|
25
|
+
set.delete(waiter);
|
|
26
|
+
if (set.size === 0) {
|
|
27
|
+
this.waiters.delete(taskId);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
notify(task) {
|
|
31
|
+
if (!this.isTerminalStatus(task.status))
|
|
32
|
+
return;
|
|
33
|
+
const waiters = this.waiters.get(task.taskId);
|
|
34
|
+
if (!waiters)
|
|
35
|
+
return;
|
|
36
|
+
this.waiters.delete(task.taskId);
|
|
37
|
+
for (const waiter of waiters)
|
|
38
|
+
waiter(task);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
export async function waitForTerminalTask(options) {
|
|
42
|
+
const task = options.lookupTask(options.taskId, options.ownerKey);
|
|
43
|
+
if (!task)
|
|
44
|
+
return undefined;
|
|
45
|
+
if (options.isTerminalStatus(task.status))
|
|
46
|
+
return task;
|
|
47
|
+
const deadlineMs = task._createdAtMs + task.ttl;
|
|
48
|
+
return new Promise((resolve, reject) => {
|
|
49
|
+
const resolveInContext = AsyncLocalStorage.bind((value) => {
|
|
50
|
+
resolve(value);
|
|
51
|
+
});
|
|
52
|
+
const rejectInContext = AsyncLocalStorage.bind((error) => {
|
|
53
|
+
reject(toError(error));
|
|
54
|
+
});
|
|
55
|
+
let settled = false;
|
|
56
|
+
let waiter = null;
|
|
57
|
+
let deadlineTimeout;
|
|
58
|
+
const cleanup = () => {
|
|
59
|
+
if (deadlineTimeout) {
|
|
60
|
+
deadlineTimeout.cancel();
|
|
61
|
+
deadlineTimeout = undefined;
|
|
62
|
+
}
|
|
63
|
+
if (options.signal) {
|
|
64
|
+
options.signal.removeEventListener('abort', onAbort);
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
const settleOnce = (fn) => {
|
|
68
|
+
if (settled)
|
|
69
|
+
return;
|
|
70
|
+
settled = true;
|
|
71
|
+
fn();
|
|
72
|
+
};
|
|
73
|
+
const onAbort = () => {
|
|
74
|
+
settleOnce(() => {
|
|
75
|
+
cleanup();
|
|
76
|
+
options.registry.remove(options.taskId, waiter);
|
|
77
|
+
rejectInContext(new McpError(ErrorCode.ConnectionClosed, 'Request was cancelled'));
|
|
78
|
+
});
|
|
79
|
+
};
|
|
80
|
+
waiter = (updated) => {
|
|
81
|
+
settleOnce(() => {
|
|
82
|
+
cleanup();
|
|
83
|
+
if (updated.ownerKey !== options.ownerKey) {
|
|
84
|
+
resolveInContext(undefined);
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
resolveInContext(updated);
|
|
88
|
+
});
|
|
89
|
+
};
|
|
90
|
+
if (options.signal?.aborted) {
|
|
91
|
+
onAbort();
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
options.registry.add(options.taskId, waiter);
|
|
95
|
+
if (options.signal) {
|
|
96
|
+
options.signal.addEventListener('abort', onAbort, { once: true });
|
|
97
|
+
}
|
|
98
|
+
const timeoutMs = Math.max(0, deadlineMs - Date.now());
|
|
99
|
+
deadlineTimeout = createUnrefTimeout(timeoutMs, { timeout: true });
|
|
100
|
+
void deadlineTimeout.promise
|
|
101
|
+
.then(() => {
|
|
102
|
+
settleOnce(() => {
|
|
103
|
+
cleanup();
|
|
104
|
+
options.registry.remove(options.taskId, waiter);
|
|
105
|
+
options.removeTask(options.taskId);
|
|
106
|
+
rejectInContext(new McpError(ErrorCode.InvalidParams, 'Task expired', {
|
|
107
|
+
taskId: options.taskId,
|
|
108
|
+
}));
|
|
109
|
+
});
|
|
110
|
+
})
|
|
111
|
+
.catch(rejectInContext);
|
|
112
|
+
});
|
|
113
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ServerResult } from '@modelcontextprotocol/sdk/types.js';
|
|
2
|
+
import type { SharedFetchStage } from '../lib/fetch-pipeline.js';
|
|
3
|
+
import type { ProgressReporter } from '../lib/progress.js';
|
|
4
|
+
export declare function buildFetchSuccessSummary(contentSize: number): string;
|
|
5
|
+
export declare function getFetchCompletionStatusMessage(result: ServerResult): string | undefined;
|
|
6
|
+
export declare class FetchUrlProgressPlan {
|
|
7
|
+
private readonly reporter;
|
|
8
|
+
private readonly context;
|
|
9
|
+
private path;
|
|
10
|
+
constructor(reporter: ProgressReporter, context: string);
|
|
11
|
+
reportStart(): void;
|
|
12
|
+
reportStage(stage: SharedFetchStage): void;
|
|
13
|
+
reportSuccess(contentSize: number): void;
|
|
14
|
+
reportFailure(cancelled: boolean): void;
|
|
15
|
+
private mapStage;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=fetch-url-progress.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetch-url-progress.d.ts","sourceRoot":"","sources":["../../src/tools/fetch-url-progress.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAEvE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAW3D,wBAAgB,wBAAwB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEpE;AAED,wBAAgB,+BAA+B,CAC7C,MAAM,EAAE,YAAY,GACnB,MAAM,GAAG,SAAS,CAUpB;AAED,qBAAa,oBAAoB;IAI7B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAJ1B,OAAO,CAAC,IAAI,CAAwB;gBAGjB,QAAQ,EAAE,gBAAgB,EAC1B,OAAO,EAAE,MAAM;IAGlC,WAAW,IAAI,IAAI;IAInB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI;IAM1C,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAIxC,aAAa,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI;IAIvC,OAAO,CAAC,QAAQ;CAiCjB"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { isObject } from '../lib/utils.js';
|
|
2
|
+
function formatContentSize(contentSize) {
|
|
3
|
+
if (contentSize < 1000)
|
|
4
|
+
return `${contentSize} chars`;
|
|
5
|
+
if (contentSize < 1_000_000)
|
|
6
|
+
return `${(contentSize / 1024).toFixed(1)} KB`;
|
|
7
|
+
return `${(contentSize / (1024 * 1024)).toFixed(1)} MB`;
|
|
8
|
+
}
|
|
9
|
+
export function buildFetchSuccessSummary(contentSize) {
|
|
10
|
+
return `Done — ${formatContentSize(contentSize)}`;
|
|
11
|
+
}
|
|
12
|
+
export function getFetchCompletionStatusMessage(result) {
|
|
13
|
+
if (!isObject(result))
|
|
14
|
+
return undefined;
|
|
15
|
+
const { structuredContent } = result;
|
|
16
|
+
if (!isObject(structuredContent))
|
|
17
|
+
return undefined;
|
|
18
|
+
const { contentSize } = structuredContent;
|
|
19
|
+
return typeof contentSize === 'number'
|
|
20
|
+
? buildFetchSuccessSummary(contentSize)
|
|
21
|
+
: undefined;
|
|
22
|
+
}
|
|
23
|
+
export class FetchUrlProgressPlan {
|
|
24
|
+
reporter;
|
|
25
|
+
context;
|
|
26
|
+
path = 'unknown';
|
|
27
|
+
constructor(reporter, context) {
|
|
28
|
+
this.reporter = reporter;
|
|
29
|
+
this.context = context;
|
|
30
|
+
}
|
|
31
|
+
reportStart() {
|
|
32
|
+
this.reporter.report(1, 'Preparing request');
|
|
33
|
+
}
|
|
34
|
+
reportStage(stage) {
|
|
35
|
+
const mapped = this.mapStage(stage);
|
|
36
|
+
if (!mapped)
|
|
37
|
+
return;
|
|
38
|
+
this.reporter.report(mapped.step, mapped.message);
|
|
39
|
+
}
|
|
40
|
+
reportSuccess(contentSize) {
|
|
41
|
+
this.reporter.report(8, buildFetchSuccessSummary(contentSize));
|
|
42
|
+
}
|
|
43
|
+
reportFailure(cancelled) {
|
|
44
|
+
this.reporter.report(8, cancelled ? 'Cancelled' : 'Failed');
|
|
45
|
+
}
|
|
46
|
+
mapStage(stage) {
|
|
47
|
+
switch (stage) {
|
|
48
|
+
case 'resolve_url':
|
|
49
|
+
return { step: 2, message: 'Resolving URL' };
|
|
50
|
+
case 'check_cache':
|
|
51
|
+
return { step: 3, message: 'Checking cache' };
|
|
52
|
+
case 'cache_hit':
|
|
53
|
+
this.path = 'cache_hit';
|
|
54
|
+
return { step: 4, message: 'Loaded from cache' };
|
|
55
|
+
case 'cache_restore':
|
|
56
|
+
this.path = 'cache_hit';
|
|
57
|
+
return { step: 5, message: 'Restoring cached content' };
|
|
58
|
+
case 'fetch_remote':
|
|
59
|
+
this.path = 'cache_miss';
|
|
60
|
+
return { step: 4, message: `Fetching ${this.context}` };
|
|
61
|
+
case 'response_ready':
|
|
62
|
+
this.path = 'cache_miss';
|
|
63
|
+
return { step: 5, message: 'Received response' };
|
|
64
|
+
case 'transform_start':
|
|
65
|
+
this.path = 'cache_miss';
|
|
66
|
+
return { step: 6, message: 'Parsing HTML -> Markdown' };
|
|
67
|
+
case 'prepare_output':
|
|
68
|
+
return {
|
|
69
|
+
step: this.path === 'cache_miss' ? 7 : 6,
|
|
70
|
+
message: 'Preparing output',
|
|
71
|
+
};
|
|
72
|
+
case 'finalize_output':
|
|
73
|
+
if (this.path === 'cache_miss')
|
|
74
|
+
return undefined;
|
|
75
|
+
return { step: 7, message: 'Finalizing output' };
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
@@ -12,14 +12,10 @@ interface ToolResponseBase {
|
|
|
12
12
|
}
|
|
13
13
|
export declare const FETCH_URL_TOOL_NAME = "fetch-url";
|
|
14
14
|
export declare function fetchUrlToolHandler(input: FetchUrlInput, extra?: ToolHandlerExtra): Promise<ToolResponseBase>;
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
* the extra fields or generate a fresh UUID.
|
|
21
|
-
*/
|
|
22
|
-
export declare function withRequestContextIfMissing<TParams, TResult, TExtra = unknown>(handler: (params: TParams, extra?: TExtra) => Promise<TResult>): (params: TParams, extra?: TExtra) => Promise<TResult>;
|
|
23
|
-
export declare function registerTools(server: McpServer): void;
|
|
15
|
+
type TaskSupport = 'optional' | 'forbidden';
|
|
16
|
+
export interface ToolRegistrationControls {
|
|
17
|
+
setTaskSupport: (support: TaskSupport) => void;
|
|
18
|
+
}
|
|
19
|
+
export declare function registerTools(server: McpServer): ToolRegistrationControls;
|
|
24
20
|
export {};
|
|
25
21
|
//# sourceMappingURL=fetch-url.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch-url.d.ts","sourceRoot":"","sources":["../../src/tools/fetch-url.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"fetch-url.d.ts","sourceRoot":"","sources":["../../src/tools/fetch-url.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EACV,YAAY,EAEb,MAAM,oCAAoC,CAAC;AAE5C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAgBxB,OAAO,EAEL,KAAK,gBAAgB,EACtB,MAAM,oBAAoB,CAAC;AAI5B,OAAO,EACL,mBAAmB,EAIpB,MAAM,eAAe,CAAC;AAYvB,KAAK,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEzD,UAAU,gBAAgB;IACxB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;IACxD,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,eAAO,MAAM,mBAAmB,cAAc,CAAC;AAsL/C,wBAAsB,mBAAmB,CACvC,KAAK,EAAE,aAAa,EACpB,KAAK,CAAC,EAAE,gBAAgB,GACvB,OAAO,CAAC,gBAAgB,CAAC,CAQ3B;AAqBD,KAAK,WAAW,GAAG,UAAU,GAAG,WAAW,CAAC;AAE5C,MAAM,WAAW,wBAAwB;IACvC,cAAc,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,CAAC;CAChD;AA2BD,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,GAAG,wBAAwB,CAsCzE"}
|