@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.
Files changed (55) hide show
  1. package/dist/http/native.d.ts.map +1 -1
  2. package/dist/http/native.js +20 -26
  3. package/dist/http/session-teardown.d.ts +17 -0
  4. package/dist/http/session-teardown.d.ts.map +1 -0
  5. package/dist/http/session-teardown.js +30 -0
  6. package/dist/lib/core.d.ts.map +1 -1
  7. package/dist/lib/core.js +2 -0
  8. package/dist/lib/dom-prep.d.ts.map +1 -1
  9. package/dist/lib/dom-prep.js +19 -14
  10. package/dist/lib/progress.d.ts.map +1 -1
  11. package/dist/lib/progress.js +59 -32
  12. package/dist/lib/sdk-interop.d.ts +8 -0
  13. package/dist/lib/sdk-interop.d.ts.map +1 -0
  14. package/dist/lib/sdk-interop.js +73 -0
  15. package/dist/lib/task-handlers.d.ts +0 -2
  16. package/dist/lib/task-handlers.d.ts.map +1 -1
  17. package/dist/lib/task-handlers.js +9 -94
  18. package/dist/resources/index.js +1 -1
  19. package/dist/server.d.ts.map +1 -1
  20. package/dist/server.js +10 -3
  21. package/dist/tasks/call-contract.d.ts +25 -0
  22. package/dist/tasks/call-contract.d.ts.map +1 -0
  23. package/dist/tasks/call-contract.js +58 -0
  24. package/dist/tasks/cursor-codec.d.ts +5 -0
  25. package/dist/tasks/cursor-codec.d.ts.map +1 -0
  26. package/dist/tasks/cursor-codec.js +41 -0
  27. package/dist/tasks/execution.d.ts +1 -20
  28. package/dist/tasks/execution.d.ts.map +1 -1
  29. package/dist/tasks/execution.js +7 -32
  30. package/dist/tasks/manager.d.ts +1 -5
  31. package/dist/tasks/manager.d.ts.map +1 -1
  32. package/dist/tasks/manager.js +16 -144
  33. package/dist/tasks/owner.d.ts +12 -2
  34. package/dist/tasks/owner.d.ts.map +1 -1
  35. package/dist/tasks/owner.js +52 -3
  36. package/dist/tasks/tool-registry.d.ts +1 -0
  37. package/dist/tasks/tool-registry.d.ts.map +1 -1
  38. package/dist/tasks/waiters.d.ts +27 -0
  39. package/dist/tasks/waiters.d.ts.map +1 -0
  40. package/dist/tasks/waiters.js +113 -0
  41. package/dist/tools/fetch-url-progress.d.ts +17 -0
  42. package/dist/tools/fetch-url-progress.d.ts.map +1 -0
  43. package/dist/tools/fetch-url-progress.js +78 -0
  44. package/dist/tools/fetch-url.d.ts +5 -9
  45. package/dist/tools/fetch-url.d.ts.map +1 -1
  46. package/dist/tools/fetch-url.js +43 -96
  47. package/dist/transform/next-flight.d.ts +2 -0
  48. package/dist/transform/next-flight.d.ts.map +1 -0
  49. package/dist/transform/next-flight.js +285 -0
  50. package/dist/transform/transform.d.ts.map +1 -1
  51. package/dist/transform/transform.js +21 -336
  52. package/package.json +4 -4
  53. package/dist/tools/index.d.ts +0 -3
  54. package/dist/tools/index.d.ts.map +0 -1
  55. package/dist/tools/index.js +0 -4
@@ -2,56 +2,13 @@ import { randomUUID } from 'node:crypto';
2
2
  import {} from '@modelcontextprotocol/sdk/server/mcp.js';
3
3
  import { CallToolRequestSchema, ErrorCode, McpError, } from '@modelcontextprotocol/sdk/types.js';
4
4
  import { z } from 'zod';
5
- import { abortTaskExecution, emitTaskStatusNotification, handleToolCallRequest, throwTaskNotFound, toTaskSummary, withRelatedTaskMeta, } from '../tasks/execution.js';
5
+ import { parseExtendedCallToolRequest, withRelatedTaskMeta, } from '../tasks/call-contract.js';
6
+ import { abortTaskExecution, emitTaskStatusNotification, handleToolCallRequest, throwTaskNotFound, toTaskSummary, } from '../tasks/execution.js';
6
7
  import { taskManager } from '../tasks/manager.js';
7
8
  import { isServerResult, parseHandlerExtra, resolveTaskOwnerKey, resolveToolCallContext, } from '../tasks/owner.js';
8
9
  import { hasRegisteredTaskCapableTools, hasTaskCapableTool, } from '../tasks/tool-registry.js';
9
10
  import { logWarn, runWithRequestContext } from './core.js';
10
- import { formatZodError } from './zod.js';
11
- const patchedCleanupServers = new WeakSet();
12
- const serverCleanupCallbacks = new WeakMap();
13
- function getServerCleanupCallbackSet(server) {
14
- let callbacks = serverCleanupCallbacks.get(server);
15
- if (!callbacks) {
16
- callbacks = new Set();
17
- serverCleanupCallbacks.set(server, callbacks);
18
- }
19
- return callbacks;
20
- }
21
- function drainServerCleanupCallbacks(server) {
22
- const callbacks = serverCleanupCallbacks.get(server);
23
- if (!callbacks || callbacks.size === 0)
24
- return;
25
- const pending = [...callbacks];
26
- callbacks.clear();
27
- for (const callback of pending) {
28
- try {
29
- callback();
30
- }
31
- catch (error) {
32
- logWarn('Server cleanup callback failed', { error });
33
- }
34
- }
35
- }
36
- function ensureServerCleanupHooks(server) {
37
- if (patchedCleanupServers.has(server))
38
- return;
39
- patchedCleanupServers.add(server);
40
- const originalOnClose = server.server.onclose;
41
- server.server.onclose = () => {
42
- drainServerCleanupCallbacks(server);
43
- originalOnClose?.();
44
- };
45
- const originalClose = server.close.bind(server);
46
- server.close = async () => {
47
- drainServerCleanupCallbacks(server);
48
- await originalClose();
49
- };
50
- }
51
- export function registerServerLifecycleCleanup(server, callback) {
52
- ensureServerCleanupHooks(server);
53
- getServerCleanupCallbackSet(server).add(callback);
54
- }
11
+ import { getSdkCallToolHandler } from './sdk-interop.js';
55
12
  export { cancelTasksForOwner, abortAllTaskExecutions, } from '../tasks/execution.js';
56
13
  /* -------------------------------------------------------------------------------------------------
57
14
  * Task handler schemas and registration
@@ -76,41 +33,6 @@ const TaskResultSchema = z.looseObject({
76
33
  method: z.literal('tasks/result'),
77
34
  params: z.looseObject({ taskId: z.string() }),
78
35
  });
79
- const MIN_TASK_TTL_MS = 1_000;
80
- const MAX_TASK_TTL_MS = 86_400_000;
81
- const ExtendedCallToolRequestSchema = z.looseObject({
82
- method: z.literal('tools/call'),
83
- params: z.strictObject({
84
- name: z.string().min(1),
85
- arguments: z.record(z.string(), z.unknown()).optional(),
86
- task: z
87
- .strictObject({
88
- ttl: z
89
- .number()
90
- .int()
91
- .min(MIN_TASK_TTL_MS)
92
- .max(MAX_TASK_TTL_MS)
93
- .optional(),
94
- })
95
- .optional(),
96
- _meta: z
97
- .looseObject({
98
- progressToken: z.union([z.string(), z.number()]).optional(),
99
- 'io.modelcontextprotocol/related-task': z
100
- .strictObject({
101
- taskId: z.string(),
102
- })
103
- .optional(),
104
- })
105
- .optional(),
106
- }),
107
- });
108
- function parseExtendedCallToolRequest(request) {
109
- const parsed = ExtendedCallToolRequestSchema.safeParse(request);
110
- if (parsed.success)
111
- return parsed.data;
112
- throw new McpError(ErrorCode.InvalidParams, `Invalid tool request params: ${formatZodError(parsed.error)}`);
113
- }
114
36
  function resolveOwnerScopedExtra(extra) {
115
37
  const parsedExtra = parseHandlerExtra(extra);
116
38
  return {
@@ -118,14 +40,6 @@ function resolveOwnerScopedExtra(extra) {
118
40
  ownerKey: resolveTaskOwnerKey(parsedExtra),
119
41
  };
120
42
  }
121
- function getSdkCallToolHandler(server) {
122
- // S-2: see tests/sdk-compat-guard.test.ts
123
- const maybeHandlers = Reflect.get(server.server, '_requestHandlers');
124
- if (!(maybeHandlers instanceof Map))
125
- return null;
126
- const handler = maybeHandlers.get('tools/call');
127
- return typeof handler === 'function' ? handler : null;
128
- }
129
43
  export function registerTaskHandlers(server, options) {
130
44
  const sdkCallToolHandler = getSdkCallToolHandler(server);
131
45
  const taskCapableToolsRegistered = hasRegisteredTaskCapableTools();
@@ -139,15 +53,15 @@ export function registerTaskHandlers(server, options) {
139
53
  if (sdkCallToolHandler) {
140
54
  server.server.setRequestHandler(CallToolRequestSchema, async (request, extra) => {
141
55
  const parsedExtra = parseHandlerExtra(extra);
142
- const context = resolveToolCallContext(parsedExtra);
143
- const requestId = context.requestId !== undefined
144
- ? String(context.requestId)
56
+ const requestId = parsedExtra?.requestId !== undefined
57
+ ? String(parsedExtra.requestId)
145
58
  : randomUUID();
146
- const sessionId = parsedExtra?.sessionId;
147
59
  return runWithRequestContext({
148
60
  requestId,
149
61
  operationId: requestId,
150
- ...(sessionId ? { sessionId } : {}),
62
+ ...(parsedExtra?.sessionId
63
+ ? { sessionId: parsedExtra.sessionId }
64
+ : {}),
151
65
  }, () => {
152
66
  const toolName = request.params.name;
153
67
  // Only intercept task-capable tools managed by the local task registry.
@@ -156,6 +70,7 @@ export function registerTaskHandlers(server, options) {
156
70
  return sdkCallToolHandler(request, extra);
157
71
  }
158
72
  const parsed = parseExtendedCallToolRequest(request);
73
+ const context = resolveToolCallContext(parsedExtra, parsed.params._meta);
159
74
  return handleToolCallRequest(server, parsed, context);
160
75
  });
161
76
  });
@@ -2,7 +2,7 @@ import { ResourceTemplate, } from '@modelcontextprotocol/sdk/server/mcp.js';
2
2
  import { ErrorCode, McpError, SubscribeRequestSchema, UnsubscribeRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
3
3
  import { get as getCacheEntry, getEntryMeta, keys as listCacheKeys, onCacheUpdate, parseCacheKey, } from '../lib/core.js';
4
4
  import { logWarn } from '../lib/core.js';
5
- import { registerServerLifecycleCleanup } from '../lib/task-handlers.js';
5
+ import { registerServerLifecycleCleanup } from '../lib/sdk-interop.js';
6
6
  import { buildOptionalIcons } from '../lib/types.js';
7
7
  import { isObject } from '../lib/utils.js';
8
8
  import { parseCachedPayload, resolveCachedPayloadContent } from '../schemas.js';
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAkGpE,wBAAsB,eAAe,IAAI,OAAO,CAAC,SAAS,CAAC,CAE1D;AA8CD,wBAAsB,6BAA6B,IAAI,OAAO,CAAC,SAAS,CAAC,CAExE;AAkFD,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAMtD"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AA0GpE,wBAAsB,eAAe,IAAI,OAAO,CAAC,SAAS,CAAC,CAE1D;AAiDD,wBAAsB,6BAA6B,IAAI,OAAO,CAAC,SAAS,CAAC,CAExE;AAkFD,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAMtD"}
package/dist/server.js CHANGED
@@ -5,12 +5,13 @@ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
5
5
  import { SetLevelRequestSchema } from '@modelcontextprotocol/sdk/types.js';
6
6
  import { config } from './lib/core.js';
7
7
  import { getSessionId, logError, logInfo, setLogLevel, setMcpServer, } from './lib/core.js';
8
+ import { setTaskToolCallCapability } from './lib/sdk-interop.js';
8
9
  import { abortAllTaskExecutions, registerTaskHandlers, } from './lib/task-handlers.js';
9
10
  import { toError } from './lib/utils.js';
10
11
  import { registerGetHelpPrompt } from './prompts/index.js';
11
12
  import { registerCacheResourceTemplate, registerInstructionResource, } from './resources/index.js';
12
13
  import { buildServerInstructions } from './resources/instructions.js';
13
- import { registerAllTools } from './tools/index.js';
14
+ import { registerTools as registerFetchUrlTool } from './tools/fetch-url.js';
14
15
  import { shutdownTransformWorkerPool } from './transform/transform.js';
15
16
  /* -------------------------------------------------------------------------------------------------
16
17
  * Icons + server info
@@ -50,6 +51,9 @@ function createServerCapabilities() {
50
51
  },
51
52
  };
52
53
  }
54
+ function syncTaskCapabilityAdvertisement(server, taskToolCallEnabled) {
55
+ setTaskToolCallCapability(server, taskToolCallEnabled);
56
+ }
53
57
  function createServerInfo(icons) {
54
58
  return {
55
59
  name: config.server.name,
@@ -83,13 +87,16 @@ async function createMcpServerWithOptions(options) {
83
87
  if (shouldRegisterObservabilityServer(options)) {
84
88
  setMcpServer(server);
85
89
  }
86
- registerAllTools(server);
90
+ const toolControls = registerFetchUrlTool(server);
87
91
  registerGetHelpPrompt(server, serverInstructions, localIcon);
88
92
  registerInstructionResource(server, serverInstructions, localIcon);
89
93
  registerCacheResourceTemplate(server, localIcon);
90
- registerTaskHandlers(server, {
94
+ const taskRegistration = registerTaskHandlers(server, {
91
95
  requireInterception: config.tasks.requireInterception,
92
96
  });
97
+ const taskToolCallEnabled = taskRegistration.interceptedToolsCall;
98
+ toolControls.setTaskSupport(taskToolCallEnabled ? 'optional' : 'forbidden');
99
+ syncTaskCapabilityAdvertisement(server, taskToolCallEnabled);
93
100
  registerLoggingSetLevelHandler(server);
94
101
  attachServerErrorHandler(server);
95
102
  return server;
@@ -0,0 +1,25 @@
1
+ import type { ServerResult } from '@modelcontextprotocol/sdk/types.js';
2
+ import { z } from 'zod';
3
+ export declare const extendedCallToolRequestSchema: z.ZodObject<{
4
+ method: z.ZodLiteral<"tools/call">;
5
+ params: z.ZodObject<{
6
+ name: z.ZodString;
7
+ arguments: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
8
+ task: z.ZodOptional<z.ZodObject<{
9
+ ttl: z.ZodOptional<z.ZodNumber>;
10
+ }, z.core.$strict>>;
11
+ _meta: z.ZodOptional<z.ZodObject<{
12
+ progressToken: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>;
13
+ 'io.modelcontextprotocol/related-task': z.ZodOptional<z.ZodObject<{
14
+ taskId: z.ZodString;
15
+ }, z.core.$strict>>;
16
+ }, z.core.$loose>>;
17
+ }, z.core.$strict>;
18
+ }, z.core.$loose>;
19
+ export type ExtendedCallToolRequest = z.infer<typeof extendedCallToolRequestSchema>;
20
+ export type ToolCallRequestMeta = ExtendedCallToolRequest['params']['_meta'];
21
+ export declare function parseExtendedCallToolRequest(request: unknown): ExtendedCallToolRequest;
22
+ export declare function sanitizeToolCallMeta(meta?: ToolCallRequestMeta): ToolCallRequestMeta | undefined;
23
+ export declare function buildRelatedTaskMeta(taskId: string, meta?: ToolCallRequestMeta): Record<string, unknown>;
24
+ export declare function withRelatedTaskMeta(result: ServerResult, taskId: string): ServerResult;
25
+ //# sourceMappingURL=call-contract.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"call-contract.d.ts","sourceRoot":"","sources":["../../src/tasks/call-contract.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAEvE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAgBxB,eAAO,MAAM,6BAA6B;;;;;;;;;;;;;;;iBAiBxC,CAAC;AAEH,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAC3C,OAAO,6BAA6B,CACrC,CAAC;AACF,MAAM,MAAM,mBAAmB,GAAG,uBAAuB,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC;AAE7E,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,OAAO,GACf,uBAAuB,CAQzB;AAED,wBAAgB,oBAAoB,CAClC,IAAI,CAAC,EAAE,mBAAmB,GACzB,mBAAmB,GAAG,SAAS,CAMjC;AAED,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,MAAM,EACd,IAAI,CAAC,EAAE,mBAAmB,GACzB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAKzB;AAED,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,YAAY,EACpB,MAAM,EAAE,MAAM,GACb,YAAY,CAQd"}
@@ -0,0 +1,58 @@
1
+ import { ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';
2
+ import { z } from 'zod';
3
+ import { formatZodError } from '../lib/zod.js';
4
+ const MIN_TASK_TTL_MS = 1_000;
5
+ const MAX_TASK_TTL_MS = 86_400_000;
6
+ const relatedTaskMetaSchema = z.strictObject({
7
+ taskId: z.string(),
8
+ });
9
+ const toolCallMetaSchema = z.looseObject({
10
+ progressToken: z.union([z.string(), z.number()]).optional(),
11
+ 'io.modelcontextprotocol/related-task': relatedTaskMetaSchema.optional(),
12
+ });
13
+ export const extendedCallToolRequestSchema = z.looseObject({
14
+ method: z.literal('tools/call'),
15
+ params: z.strictObject({
16
+ name: z.string().min(1),
17
+ arguments: z.record(z.string(), z.unknown()).optional(),
18
+ task: z
19
+ .strictObject({
20
+ ttl: z
21
+ .number()
22
+ .int()
23
+ .min(MIN_TASK_TTL_MS)
24
+ .max(MAX_TASK_TTL_MS)
25
+ .optional(),
26
+ })
27
+ .optional(),
28
+ _meta: toolCallMetaSchema.optional(),
29
+ }),
30
+ });
31
+ export function parseExtendedCallToolRequest(request) {
32
+ const parsed = extendedCallToolRequestSchema.safeParse(request);
33
+ if (parsed.success)
34
+ return parsed.data;
35
+ throw new McpError(ErrorCode.InvalidParams, `Invalid tool request params: ${formatZodError(parsed.error)}`);
36
+ }
37
+ export function sanitizeToolCallMeta(meta) {
38
+ if (!meta)
39
+ return undefined;
40
+ const sanitized = { ...meta };
41
+ delete sanitized['io.modelcontextprotocol/related-task'];
42
+ return Object.keys(sanitized).length > 0 ? sanitized : undefined;
43
+ }
44
+ export function buildRelatedTaskMeta(taskId, meta) {
45
+ return {
46
+ ...(sanitizeToolCallMeta(meta) ?? {}),
47
+ 'io.modelcontextprotocol/related-task': { taskId },
48
+ };
49
+ }
50
+ export function withRelatedTaskMeta(result, taskId) {
51
+ return {
52
+ ...result,
53
+ _meta: {
54
+ ...result._meta,
55
+ 'io.modelcontextprotocol/related-task': { taskId },
56
+ },
57
+ };
58
+ }
@@ -0,0 +1,5 @@
1
+ export declare function encodeTaskCursor(anchorTaskId: string): string;
2
+ export declare function decodeTaskCursor(cursor: string): {
3
+ anchorTaskId: string;
4
+ } | null;
5
+ //# sourceMappingURL=cursor-codec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cursor-codec.d.ts","sourceRoot":"","sources":["../../src/tasks/cursor-codec.ts"],"names":[],"mappings":"AAkBA,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAO7D;AAED,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,MAAM,GACb;IAAE,YAAY,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAuBjC"}
@@ -0,0 +1,41 @@
1
+ import { createHmac, randomBytes, timingSafeEqual } from 'node:crypto';
2
+ const MAX_CURSOR_LENGTH = 256;
3
+ const CURSOR_SECRET = randomBytes(32);
4
+ function signPayload(payload) {
5
+ return createHmac('sha256', CURSOR_SECRET)
6
+ .update(payload)
7
+ .digest('base64url');
8
+ }
9
+ function safeCompare(left, right) {
10
+ const leftBuffer = Buffer.from(left);
11
+ const rightBuffer = Buffer.from(right);
12
+ if (leftBuffer.length !== rightBuffer.length)
13
+ return false;
14
+ return timingSafeEqual(leftBuffer, rightBuffer);
15
+ }
16
+ export function encodeTaskCursor(anchorTaskId) {
17
+ const payload = Buffer.from(JSON.stringify({ anchorTaskId }), 'utf8').toString('base64url');
18
+ const signature = signPayload(payload);
19
+ return `${payload}.${signature}`;
20
+ }
21
+ export function decodeTaskCursor(cursor) {
22
+ if (!cursor || cursor.length > MAX_CURSOR_LENGTH)
23
+ return null;
24
+ const [payload, signature, ...rest] = cursor.split('.');
25
+ if (!payload || !signature || rest.length > 0)
26
+ return null;
27
+ if (!safeCompare(signPayload(payload), signature))
28
+ return null;
29
+ try {
30
+ const decoded = JSON.parse(Buffer.from(payload, 'base64url').toString('utf8'));
31
+ if (typeof decoded.anchorTaskId !== 'string' ||
32
+ decoded.anchorTaskId.length === 0 ||
33
+ decoded.anchorTaskId.length > 128) {
34
+ return null;
35
+ }
36
+ return { anchorTaskId: decoded.anchorTaskId };
37
+ }
38
+ catch {
39
+ return null;
40
+ }
41
+ }
@@ -1,26 +1,8 @@
1
1
  import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
2
  import { type ServerResult } from '@modelcontextprotocol/sdk/types.js';
3
+ import { type ExtendedCallToolRequest } from './call-contract.js';
3
4
  import { type CreateTaskResult, type TaskState } from './manager.js';
4
5
  import { type ToolCallContext } from './owner.js';
5
- export interface ExtendedCallToolRequest {
6
- method: 'tools/call';
7
- params: {
8
- name: string;
9
- arguments?: Record<string, unknown> | undefined;
10
- task?: {
11
- ttl?: number | undefined;
12
- } | undefined;
13
- _meta?: {
14
- progressToken?: string | number | undefined;
15
- 'io.modelcontextprotocol/related-task'?: {
16
- taskId: string;
17
- } | undefined;
18
- [key: string]: unknown;
19
- } | undefined;
20
- [key: string]: unknown;
21
- };
22
- [key: string]: unknown;
23
- }
24
6
  export declare function abortTaskExecution(taskId: string): void;
25
7
  export declare function cancelTasksForOwner(ownerKey: string, statusMessage?: string): number;
26
8
  export declare function abortAllTaskExecutions(): void;
@@ -34,7 +16,6 @@ export declare function toTaskSummary(task: {
34
16
  ttl: number;
35
17
  pollInterval: number;
36
18
  }): TaskSummary;
37
- export declare function withRelatedTaskMeta(result: ServerResult, taskId: string): ServerResult;
38
19
  export declare function emitTaskStatusNotification(server: McpServer, task: TaskState): void;
39
20
  export declare function throwTaskNotFound(): never;
40
21
  export declare function handleToolCallRequest(server: McpServer, request: ExtendedCallToolRequest, context: ToolCallContext): Promise<ServerResult>;
@@ -1 +1 @@
1
- {"version":3,"file":"execution.d.ts","sourceRoot":"","sources":["../../src/tasks/execution.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,EAGL,KAAK,YAAY,EAClB,MAAM,oCAAoC,CAAC;AAW5C,OAAO,EACL,KAAK,gBAAgB,EAErB,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;AACtB,OAAO,EAEL,KAAK,eAAe,EAErB,MAAM,YAAY,CAAC;AAapB,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,YAAY,CAAC;IACrB,MAAM,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;QAChD,IAAI,CAAC,EACD;YACE,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;SAC1B,GACD,SAAS,CAAC;QACd,KAAK,CAAC,EACF;YACE,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;YAC5C,sCAAsC,CAAC,EACnC;gBAAE,MAAM,EAAE,MAAM,CAAA;aAAE,GAClB,SAAS,CAAC;YACd,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;SACxB,GACD,SAAS,CAAC;QACd,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,CAAC;IACF,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAyBD,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAKvD;AAMD,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,EAChB,aAAa,SAA4D,GACxE,MAAM,CASR;AAED,wBAAgB,sBAAsB,IAAI,IAAI,CAE7C;AAgBD,KAAK,WAAW,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC;AAE5C,wBAAgB,aAAa,CAAC,IAAI,EAAE;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,SAAS,CAAC,QAAQ,CAAC,CAAC;IAC5B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,EAAE,MAAM,CAAC;CACtB,GAAG,WAAW,CAUd;AAED,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,YAAY,EACpB,MAAM,EAAE,MAAM,GACb,YAAY,CAYd;AAED,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,SAAS,EACjB,IAAI,EAAE,SAAS,GACd,IAAI,CAmBN;AAoBD,wBAAgB,iBAAiB,IAAI,KAAK,CAEzC;AAmND,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,uBAAuB,EAChC,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,YAAY,CAAC,CAYvB"}
1
+ {"version":3,"file":"execution.d.ts","sourceRoot":"","sources":["../../src/tasks/execution.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,EAGL,KAAK,YAAY,EAClB,MAAM,oCAAoC,CAAC;AAQ5C,OAAO,EAEL,KAAK,uBAAuB,EAC7B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,KAAK,gBAAgB,EAErB,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;AACtB,OAAO,EAGL,KAAK,eAAe,EAErB,MAAM,YAAY,CAAC;AAgCpB,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAKvD;AAMD,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,EAChB,aAAa,SAA4D,GACxE,MAAM,CASR;AAED,wBAAgB,sBAAsB,IAAI,IAAI,CAE7C;AAgBD,KAAK,WAAW,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC;AAE5C,wBAAgB,aAAa,CAAC,IAAI,EAAE;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,SAAS,CAAC,QAAQ,CAAC,CAAC;IAC5B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,EAAE,MAAM,CAAC;CACtB,GAAG,WAAW,CAUd;AAED,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,SAAS,EACjB,IAAI,EAAE,SAAS,GACd,IAAI,CAmBN;AAoBD,wBAAgB,iBAAiB,IAAI,KAAK,CAEzC;AA+LD,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,uBAAuB,EAChC,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,YAAY,CAAC,CAYvB"}
@@ -3,8 +3,9 @@ import { config } from '../lib/core.js';
3
3
  import { logWarn, runWithRequestContext } from '../lib/core.js';
4
4
  import { getErrorMessage } from '../lib/utils.js';
5
5
  import { isObject } from '../lib/utils.js';
6
+ import { buildRelatedTaskMeta, } from './call-contract.js';
6
7
  import { taskManager, } from './manager.js';
7
- import { compact, tryReadToolStructuredError, } from './owner.js';
8
+ import { buildToolHandlerExtra, compact, tryReadToolStructuredError, } from './owner.js';
8
9
  import { getTaskCapableTool, hasTaskCapableTool, } from './tool-registry.js';
9
10
  const TASK_NOT_FOUND_ERROR_CODE = ErrorCode.InvalidParams;
10
11
  /* -------------------------------------------------------------------------------------------------
@@ -61,18 +62,6 @@ export function toTaskSummary(task) {
61
62
  pollInterval: task.pollInterval,
62
63
  };
63
64
  }
64
- export function withRelatedTaskMeta(result, taskId) {
65
- const relatedTaskMeta = {
66
- 'io.modelcontextprotocol/related-task': { taskId },
67
- };
68
- return {
69
- ...result,
70
- _meta: {
71
- ...result._meta,
72
- ...relatedTaskMeta,
73
- },
74
- };
75
- }
76
65
  export function emitTaskStatusNotification(server, task) {
77
66
  if (!config.tasks.emitStatusNotifications)
78
67
  return;
@@ -124,15 +113,6 @@ function assertKnownTool(name) {
124
113
  throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: '${name}'`);
125
114
  }
126
115
  }
127
- /* -------------------------------------------------------------------------------------------------
128
- * Task result builders
129
- * ------------------------------------------------------------------------------------------------- */
130
- function buildRelatedTaskMeta(taskId, meta) {
131
- return {
132
- ...(meta ?? {}),
133
- 'io.modelcontextprotocol/related-task': { taskId },
134
- };
135
- }
136
116
  function buildCreateTaskResult(task) {
137
117
  return { task };
138
118
  }
@@ -178,13 +158,14 @@ function resolveToolAndArgs(params) {
178
158
  const args = tool.parseArguments(params.arguments);
179
159
  return { tool, args };
180
160
  }
181
- function buildTaskCompletionUpdate(result) {
161
+ function buildTaskCompletionUpdate(result, tool) {
182
162
  const isToolError = isObject(result) && 'isError' in result && result.isError === true;
183
163
  return {
184
164
  status: isToolError ? 'failed' : 'completed',
185
165
  statusMessage: isToolError
186
166
  ? (tryReadToolStructuredError(result) ?? 'Tool execution failed')
187
- : 'Task completed successfully.',
167
+ : (tool.getCompletionStatusMessage?.(result) ??
168
+ 'Task completed successfully.'),
188
169
  result,
189
170
  };
190
171
  }
@@ -208,7 +189,7 @@ async function runTaskToolExecution(params) {
208
189
  updateWorkingTaskStatus(server, taskId, message);
209
190
  },
210
191
  });
211
- updateTaskAndEmitStatus(server, taskId, buildTaskCompletionUpdate(result));
192
+ updateTaskAndEmitStatus(server, taskId, buildTaskCompletionUpdate(result, tool));
212
193
  }
213
194
  catch (error) {
214
195
  const failure = buildTaskFailureState(error);
@@ -241,13 +222,7 @@ function handleTaskToolCall(server, params, context) {
241
222
  }
242
223
  async function handleDirectToolCall(params, context) {
243
224
  const { tool, args } = resolveToolAndArgs(params);
244
- const extra = compact({
245
- signal: context.signal,
246
- requestId: context.requestId,
247
- sendNotification: context.sendNotification,
248
- _meta: params._meta,
249
- });
250
- return tool.execute(args, extra);
225
+ return tool.execute(args, buildToolHandlerExtra(context, params._meta));
251
226
  }
252
227
  export async function handleToolCallRequest(server, request, context) {
253
228
  const { params } = request;
@@ -34,7 +34,7 @@ export interface CreateTaskResult {
34
34
  declare class TaskManager {
35
35
  private tasks;
36
36
  private ownerCounts;
37
- private waiters;
37
+ private readonly waiters;
38
38
  private cleanupInterval;
39
39
  private ensureCleanupLoop;
40
40
  private stopCleanupLoop;
@@ -63,15 +63,11 @@ declare class TaskManager {
63
63
  nextCursor?: string;
64
64
  };
65
65
  private resolveAnchorTaskId;
66
- private addWaiter;
67
- private removeWaiter;
68
66
  waitForTerminalTask(taskId: string, ownerKey: string, signal?: AbortSignal): Promise<TaskState | undefined>;
69
67
  private notifyWaiters;
70
68
  private isExpired;
71
69
  private maybeUpdateLastUpdatedAt;
72
70
  shrinkTtlAfterDelivery(taskId: string): void;
73
- private encodeCursor;
74
- private decodeCursor;
75
71
  private resolveNextCursor;
76
72
  }
77
73
  export declare const taskManager: TaskManager;
@@ -1 +1 @@
1
- {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/tasks/manager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/tasks/manager.ts"],"names":[],"mappings":"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"}