@j0hanz/fetch-url-mcp 1.13.0 → 2.0.1
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/LICENSE +21 -21
- package/README.md +815 -807
- package/dist/assets/logo.svg +53 -53
- package/dist/http/auth.d.ts +7 -3
- package/dist/http/auth.d.ts.map +1 -1
- package/dist/http/auth.js +65 -37
- package/dist/http/helpers.d.ts +21 -0
- package/dist/http/helpers.d.ts.map +1 -0
- package/dist/http/helpers.js +31 -0
- package/dist/http/index.d.ts +1 -0
- package/dist/http/index.d.ts.map +1 -1
- package/dist/http/index.js +1 -0
- package/dist/http/native.d.ts +6 -24
- package/dist/http/native.d.ts.map +1 -1
- package/dist/http/native.js +141 -86
- package/dist/http/rate-limit.d.ts +1 -1
- package/dist/http/rate-limit.d.ts.map +1 -1
- package/dist/http/rate-limit.js +3 -9
- package/dist/index.js +0 -0
- package/dist/lib/config.d.ts +1 -0
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +1 -0
- package/dist/lib/core.d.ts +4 -3
- package/dist/lib/core.d.ts.map +1 -1
- package/dist/lib/core.js +4 -1
- package/dist/lib/error/classify.d.ts.map +1 -1
- package/dist/lib/error/classify.js +27 -6
- package/dist/lib/error/payload.d.ts +2 -2
- package/dist/lib/error/payload.d.ts.map +1 -1
- package/dist/lib/error/payload.js +2 -2
- package/dist/lib/mcp-interop.d.ts +9 -108
- package/dist/lib/mcp-interop.d.ts.map +1 -1
- package/dist/lib/mcp-interop.js +39 -240
- package/dist/lib/net/http.d.ts.map +1 -1
- package/dist/lib/net/http.js +4 -17
- package/dist/resources/index.d.ts +1 -1
- package/dist/resources/index.d.ts.map +1 -1
- package/dist/resources/index.js +67 -60
- package/dist/server.d.ts +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +39 -34
- package/dist/tasks/adapter.d.ts +15 -0
- package/dist/tasks/adapter.d.ts.map +1 -0
- package/dist/tasks/adapter.js +138 -0
- package/dist/tasks/manager.d.ts +14 -82
- package/dist/tasks/manager.d.ts.map +1 -1
- package/dist/tasks/manager.js +48 -607
- package/dist/tasks/store.d.ts +33 -19
- package/dist/tasks/store.d.ts.map +1 -1
- package/dist/tasks/store.js +143 -80
- package/dist/tools/index.d.ts +7 -13
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +153 -58
- package/dist/transform/index.js +1 -1
- package/package.json +110 -108
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import type
|
|
2
|
-
import { McpError } from '@modelcontextprotocol/sdk/types.js';
|
|
1
|
+
import { type JSONRPCRequest, type Progress, type ProgressNotification, type ProgressNotificationParams, ProtocolError, type ServerContext } from '@modelcontextprotocol/server';
|
|
3
2
|
import type { ServerResponse } from 'node:http';
|
|
4
|
-
import { z } from 'zod';
|
|
5
|
-
export declare function
|
|
3
|
+
import type { z } from 'zod';
|
|
4
|
+
export declare function createProtocolError(code: number, message: string, data?: unknown): ProtocolError;
|
|
6
5
|
interface JsonRpcErrorPayload {
|
|
7
6
|
code: number;
|
|
8
7
|
message: string;
|
|
@@ -15,114 +14,16 @@ export declare function buildJsonRpcErrorBody(code: number, message: string, id?
|
|
|
15
14
|
};
|
|
16
15
|
export declare function sendJsonRpcError(res: ServerResponse, status: number, code: number, message: string, id?: JsonRpcId, data?: unknown): void;
|
|
17
16
|
export type JsonRpcId = string | number | null;
|
|
18
|
-
declare const jsonRpcRequestSchema: z.ZodObject<{
|
|
19
|
-
jsonrpc: z.ZodLiteral<"2.0">;
|
|
20
|
-
method: z.ZodString;
|
|
21
|
-
id: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>;
|
|
22
|
-
params: z.ZodOptional<z.ZodObject<{
|
|
23
|
-
_meta: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
24
|
-
}, z.core.$loose>>;
|
|
25
|
-
}, z.core.$strict>;
|
|
26
|
-
declare const jsonRpcResponseSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
27
|
-
jsonrpc: z.ZodLiteral<"2.0">;
|
|
28
|
-
id: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
|
|
29
|
-
result: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
30
|
-
}, z.core.$strict>, z.ZodObject<{
|
|
31
|
-
jsonrpc: z.ZodLiteral<"2.0">;
|
|
32
|
-
id: z.ZodOptional<z.ZodUnion<[z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>, z.ZodNull]>>;
|
|
33
|
-
error: z.ZodObject<{
|
|
34
|
-
code: z.ZodNumber;
|
|
35
|
-
message: z.ZodString;
|
|
36
|
-
data: z.ZodOptional<z.ZodUnknown>;
|
|
37
|
-
}, z.core.$strict>;
|
|
38
|
-
}, z.core.$strict>]>;
|
|
39
|
-
declare const jsonRpcMessageSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
40
|
-
jsonrpc: z.ZodLiteral<"2.0">;
|
|
41
|
-
method: z.ZodString;
|
|
42
|
-
id: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>;
|
|
43
|
-
params: z.ZodOptional<z.ZodObject<{
|
|
44
|
-
_meta: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
45
|
-
}, z.core.$loose>>;
|
|
46
|
-
}, z.core.$strict>, z.ZodUnion<readonly [z.ZodObject<{
|
|
47
|
-
jsonrpc: z.ZodLiteral<"2.0">;
|
|
48
|
-
id: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
|
|
49
|
-
result: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
50
|
-
}, z.core.$strict>, z.ZodObject<{
|
|
51
|
-
jsonrpc: z.ZodLiteral<"2.0">;
|
|
52
|
-
id: z.ZodOptional<z.ZodUnion<[z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>, z.ZodNull]>>;
|
|
53
|
-
error: z.ZodObject<{
|
|
54
|
-
code: z.ZodNumber;
|
|
55
|
-
message: z.ZodString;
|
|
56
|
-
data: z.ZodOptional<z.ZodUnknown>;
|
|
57
|
-
}, z.core.$strict>;
|
|
58
|
-
}, z.core.$strict>]>]>;
|
|
59
|
-
type McpRequestBody = z.infer<typeof jsonRpcRequestSchema>;
|
|
60
|
-
type JsonRpcResponseBody = z.infer<typeof jsonRpcResponseSchema>;
|
|
61
|
-
type JsonRpcMessageBody = z.infer<typeof jsonRpcMessageSchema>;
|
|
62
17
|
export declare function isJsonRpcBatchRequest(body: unknown): boolean;
|
|
63
|
-
export declare function isMcpRequestBody(body: unknown): body is
|
|
64
|
-
export declare function isJsonRpcResponseBody(body: unknown):
|
|
65
|
-
export declare function isMcpMessageBody(body: unknown):
|
|
18
|
+
export declare function isMcpRequestBody(body: unknown): body is JSONRPCRequest;
|
|
19
|
+
export declare function isJsonRpcResponseBody(body: unknown): boolean;
|
|
20
|
+
export declare function isMcpMessageBody(body: unknown): boolean;
|
|
66
21
|
export declare function acceptsEventStream(header: string | null | undefined): boolean;
|
|
67
22
|
export declare function acceptsJsonAndEventStream(header: string | null | undefined): boolean;
|
|
68
|
-
type
|
|
69
|
-
type RequestHandlerFn = (request: unknown, extra?: unknown) => Promise<unknown>;
|
|
70
|
-
interface ToolPresentation {
|
|
71
|
-
icons?: {
|
|
72
|
-
src: string;
|
|
73
|
-
mimeType?: string;
|
|
74
|
-
sizes?: string[];
|
|
75
|
-
}[];
|
|
76
|
-
}
|
|
77
|
-
export declare function registerServerLifecycleCleanup(server: McpServer, callback: CleanupCallback): void;
|
|
78
|
-
/**
|
|
79
|
-
* Retrieves the SDK's internal request-handler map.
|
|
80
|
-
*
|
|
81
|
-
* Depends on SDK private API `_requestHandlers` (verified against ^1.28).
|
|
82
|
-
* If the SDK changes this internal, the sdk-compat-guard.test.ts tests will fail.
|
|
83
|
-
*/
|
|
84
|
-
export declare function getSdkCallToolHandler(server: McpServer): RequestHandlerFn | null;
|
|
85
|
-
/**
|
|
86
|
-
* Patches the SDK's internal capabilities to enable/disable task-mode tool calls.
|
|
87
|
-
*
|
|
88
|
-
* Depends on SDK private API `_capabilities.tasks.requests` (verified against ^1.28).
|
|
89
|
-
* If the SDK changes this internal, the sdk-compat-guard.test.ts tests will fail.
|
|
90
|
-
*/
|
|
91
|
-
export declare function setTaskToolCallCapability(server: McpServer, enabled: boolean): void;
|
|
92
|
-
export declare function registerToolPresentation(server: McpServer, name: string, presentation: ToolPresentation): void;
|
|
93
|
-
type ProgressToken = string | number;
|
|
94
|
-
interface RequestMeta {
|
|
95
|
-
progressToken?: ProgressToken | undefined;
|
|
96
|
-
[key: string]: unknown;
|
|
97
|
-
}
|
|
98
|
-
export interface ProgressNotificationParams {
|
|
99
|
-
progressToken: ProgressToken;
|
|
100
|
-
progress: number;
|
|
101
|
-
total?: number;
|
|
102
|
-
message?: string;
|
|
103
|
-
_meta?: Record<string, unknown>;
|
|
104
|
-
}
|
|
105
|
-
export interface ProgressNotification {
|
|
106
|
-
method: 'notifications/progress';
|
|
107
|
-
params: ProgressNotificationParams;
|
|
108
|
-
}
|
|
109
|
-
export interface ToolHandlerExtra {
|
|
110
|
-
signal?: AbortSignal;
|
|
111
|
-
requestId?: string | number;
|
|
112
|
-
sessionId?: unknown;
|
|
113
|
-
requestInfo?: unknown;
|
|
114
|
-
_meta?: RequestMeta;
|
|
115
|
-
progressState?: {
|
|
116
|
-
closed: boolean;
|
|
117
|
-
};
|
|
118
|
-
sendNotification?: (notification: ProgressNotification) => Promise<void>;
|
|
119
|
-
onProgress?: (progress: number, message: string, total?: number) => void;
|
|
120
|
-
canReportProgress?: () => boolean;
|
|
121
|
-
}
|
|
23
|
+
export { type ProgressNotification, type ProgressNotificationParams };
|
|
122
24
|
export interface ProgressReporter {
|
|
123
|
-
report: (progress:
|
|
25
|
+
report: (progress: Progress) => void;
|
|
124
26
|
}
|
|
125
|
-
export declare const createProgressReporter: (
|
|
27
|
+
export declare const createProgressReporter: (ctx?: ServerContext) => ProgressReporter;
|
|
126
28
|
export declare function validateOrThrow<T>(schema: z.ZodType<T>, data: unknown, errorCode: number, msg: string, logger: string): T;
|
|
127
|
-
export {};
|
|
128
29
|
//# sourceMappingURL=mcp-interop.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-interop.d.ts","sourceRoot":"","sources":["../../src/lib/mcp-interop.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"mcp-interop.d.ts","sourceRoot":"","sources":["../../src/lib/mcp-interop.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,cAAc,EACnB,KAAK,QAAQ,EACb,KAAK,oBAAoB,EACzB,KAAK,0BAA0B,EAE/B,aAAa,EACb,KAAK,aAAa,EACnB,MAAM,8BAA8B,CAAC;AAEtC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAGhD,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAM7B,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,IAAI,CAAC,EAAE,OAAO,GACb,aAAa,CAEf;AAED,UAAU,mBAAmB;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,EAAE,GAAE,SAAgB,EACpB,IAAI,CAAC,EAAE,OAAO,GACb;IACD,OAAO,EAAE,KAAK,CAAC;IACf,KAAK,EAAE,mBAAmB,CAAC;IAC3B,EAAE,EAAE,SAAS,CAAC;CACf,CAUA;AAED,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,cAAc,EACnB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,EAAE,GAAE,SAAgB,EACpB,IAAI,CAAC,EAAE,OAAO,GACb,IAAI,CAMN;AAMD,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;AAC/C,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAE5D;AACD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,IAAI,cAAc,CAEtE;AACD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAE5D;AACD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAOvD;AAUD,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAG7E;AACD,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAChC,OAAO,CAUT;AAMD,OAAO,EAAE,KAAK,oBAAoB,EAAE,KAAK,0BAA0B,EAAE,CAAC;AAEtE,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAAC;CACtC;AA0JD,eAAO,MAAM,sBAAsB,GAAI,MAAM,aAAa,KAAG,gBAC3B,CAAC;AAEnC,wBAAgB,eAAe,CAAC,CAAC,EAC/B,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EACpB,IAAI,EAAE,OAAO,EACb,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,GACb,CAAC,CAQH"}
|
package/dist/lib/mcp-interop.js
CHANGED
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isJSONRPCErrorResponse, isJSONRPCNotification, isJSONRPCRequest, isJSONRPCResultResponse, ProtocolError, } from '@modelcontextprotocol/server';
|
|
2
2
|
import { setTimeout as setTimeoutPromise } from 'node:timers/promises';
|
|
3
|
-
import {
|
|
4
|
-
import { logError, Loggers, logWarn } from './core.js';
|
|
3
|
+
import { Loggers, logWarn } from './core.js';
|
|
5
4
|
import { getErrorMessage } from './error/index.js';
|
|
6
|
-
import { formatZodError
|
|
7
|
-
export function
|
|
8
|
-
|
|
9
|
-
error.message = message;
|
|
10
|
-
return error;
|
|
5
|
+
import { formatZodError } from './utils.js';
|
|
6
|
+
export function createProtocolError(code, message, data) {
|
|
7
|
+
return ProtocolError.fromError(code, message, data);
|
|
11
8
|
}
|
|
12
9
|
export function buildJsonRpcErrorBody(code, message, id = null, data) {
|
|
13
10
|
return {
|
|
@@ -27,49 +24,20 @@ export function sendJsonRpcError(res, status, code, message, id = null, data) {
|
|
|
27
24
|
res.setHeader('Cache-Control', 'no-store');
|
|
28
25
|
res.end(JSON.stringify(buildJsonRpcErrorBody(code, message, id, data)));
|
|
29
26
|
}
|
|
30
|
-
const paramsSchema = z.looseObject({
|
|
31
|
-
_meta: z.record(z.string(), z.unknown()).optional(),
|
|
32
|
-
});
|
|
33
|
-
const jsonRpcRequestIdSchema = z.union([z.string(), z.number()]);
|
|
34
|
-
const jsonRpcRequestSchema = z.strictObject({
|
|
35
|
-
jsonrpc: z.literal('2.0'),
|
|
36
|
-
method: z.string().min(1),
|
|
37
|
-
id: jsonRpcRequestIdSchema.optional(),
|
|
38
|
-
params: paramsSchema.optional(),
|
|
39
|
-
});
|
|
40
|
-
const jsonRpcResultResponseSchema = z.strictObject({
|
|
41
|
-
jsonrpc: z.literal('2.0'),
|
|
42
|
-
id: jsonRpcRequestIdSchema,
|
|
43
|
-
result: z.record(z.string(), z.unknown()),
|
|
44
|
-
});
|
|
45
|
-
const jsonRpcErrorResponseSchema = z.strictObject({
|
|
46
|
-
jsonrpc: z.literal('2.0'),
|
|
47
|
-
id: jsonRpcRequestIdSchema.or(z.null()).optional(),
|
|
48
|
-
error: z.strictObject({
|
|
49
|
-
code: z.number().int(),
|
|
50
|
-
message: z.string(),
|
|
51
|
-
data: z.unknown().optional(),
|
|
52
|
-
}),
|
|
53
|
-
});
|
|
54
|
-
const jsonRpcResponseSchema = z.union([
|
|
55
|
-
jsonRpcResultResponseSchema,
|
|
56
|
-
jsonRpcErrorResponseSchema,
|
|
57
|
-
]);
|
|
58
|
-
const jsonRpcMessageSchema = z.union([
|
|
59
|
-
jsonRpcRequestSchema,
|
|
60
|
-
jsonRpcResponseSchema,
|
|
61
|
-
]);
|
|
62
27
|
export function isJsonRpcBatchRequest(body) {
|
|
63
28
|
return Array.isArray(body);
|
|
64
29
|
}
|
|
65
30
|
export function isMcpRequestBody(body) {
|
|
66
|
-
return
|
|
31
|
+
return isJSONRPCRequest(body);
|
|
67
32
|
}
|
|
68
33
|
export function isJsonRpcResponseBody(body) {
|
|
69
|
-
return
|
|
34
|
+
return isJSONRPCResultResponse(body) || isJSONRPCErrorResponse(body);
|
|
70
35
|
}
|
|
71
36
|
export function isMcpMessageBody(body) {
|
|
72
|
-
return
|
|
37
|
+
return (isJSONRPCRequest(body) ||
|
|
38
|
+
isJSONRPCNotification(body) ||
|
|
39
|
+
isJSONRPCResultResponse(body) ||
|
|
40
|
+
isJSONRPCErrorResponse(body));
|
|
73
41
|
}
|
|
74
42
|
function parseAcceptMediaTypes(header) {
|
|
75
43
|
if (!header)
|
|
@@ -90,178 +58,38 @@ export function acceptsJsonAndEventStream(header) {
|
|
|
90
58
|
return false;
|
|
91
59
|
return mediaTypes.some((m) => m === '*/*' || m === 'text/event-stream' || m === 'text/*');
|
|
92
60
|
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
}
|
|
97
|
-
const patchedCleanupServers = new WeakSet();
|
|
98
|
-
const serverCleanupCallbacks = new WeakMap();
|
|
99
|
-
function getServerCleanupCallbackSet(server) {
|
|
100
|
-
let callbacks = serverCleanupCallbacks.get(server);
|
|
101
|
-
if (!callbacks) {
|
|
102
|
-
callbacks = new Set();
|
|
103
|
-
serverCleanupCallbacks.set(server, callbacks);
|
|
104
|
-
}
|
|
105
|
-
return callbacks;
|
|
106
|
-
}
|
|
107
|
-
function drainServerCleanupCallbacks(server) {
|
|
108
|
-
const callbacks = serverCleanupCallbacks.get(server);
|
|
109
|
-
if (!callbacks || callbacks.size === 0)
|
|
110
|
-
return;
|
|
111
|
-
const pending = [...callbacks];
|
|
112
|
-
callbacks.clear();
|
|
113
|
-
for (const callback of pending) {
|
|
114
|
-
try {
|
|
115
|
-
callback();
|
|
116
|
-
}
|
|
117
|
-
catch (error) {
|
|
118
|
-
logWarn('Server cleanup callback failed', { error }, Loggers.LOG_MCP);
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
function ensureServerCleanupHooks(server) {
|
|
123
|
-
if (patchedCleanupServers.has(server))
|
|
124
|
-
return;
|
|
125
|
-
patchedCleanupServers.add(server);
|
|
126
|
-
const originalOnClose = server.server.onclose;
|
|
127
|
-
server.server.onclose = () => {
|
|
128
|
-
drainServerCleanupCallbacks(server);
|
|
129
|
-
originalOnClose?.();
|
|
130
|
-
};
|
|
131
|
-
const originalClose = server.close.bind(server);
|
|
132
|
-
server.close = async () => {
|
|
133
|
-
drainServerCleanupCallbacks(server);
|
|
134
|
-
await originalClose();
|
|
135
|
-
};
|
|
136
|
-
}
|
|
137
|
-
export function registerServerLifecycleCleanup(server, callback) {
|
|
138
|
-
ensureServerCleanupHooks(server);
|
|
139
|
-
getServerCleanupCallbackSet(server).add(callback);
|
|
140
|
-
}
|
|
141
|
-
/**
|
|
142
|
-
* Retrieves the SDK's internal request-handler map.
|
|
143
|
-
*
|
|
144
|
-
* Depends on SDK private API `_requestHandlers` (verified against ^1.28).
|
|
145
|
-
* If the SDK changes this internal, the sdk-compat-guard.test.ts tests will fail.
|
|
146
|
-
*/
|
|
147
|
-
export function getSdkCallToolHandler(server) {
|
|
148
|
-
const maybeHandlers = Reflect.get(server.server, '_requestHandlers');
|
|
149
|
-
if (!(maybeHandlers instanceof Map))
|
|
150
|
-
return null;
|
|
151
|
-
const handler = maybeHandlers.get('tools/call');
|
|
152
|
-
return typeof handler === 'function' ? handler : null;
|
|
153
|
-
}
|
|
154
|
-
function getSdkListToolsHandler(server) {
|
|
155
|
-
const maybeHandlers = Reflect.get(server.server, '_requestHandlers');
|
|
156
|
-
if (!(maybeHandlers instanceof Map))
|
|
157
|
-
return null;
|
|
158
|
-
const handler = maybeHandlers.get('tools/list');
|
|
159
|
-
return typeof handler === 'function' ? handler : null;
|
|
160
|
-
}
|
|
161
|
-
/**
|
|
162
|
-
* Patches the SDK's internal capabilities to enable/disable task-mode tool calls.
|
|
163
|
-
*
|
|
164
|
-
* Depends on SDK private API `_capabilities.tasks.requests` (verified against ^1.28).
|
|
165
|
-
* If the SDK changes this internal, the sdk-compat-guard.test.ts tests will fail.
|
|
166
|
-
*/
|
|
167
|
-
export function setTaskToolCallCapability(server, enabled) {
|
|
168
|
-
const capabilities = Reflect.get(server.server, '_capabilities');
|
|
169
|
-
if (!isObject(capabilities))
|
|
170
|
-
return;
|
|
171
|
-
const tasks = getNestedRecord(capabilities, 'tasks');
|
|
172
|
-
if (!tasks)
|
|
173
|
-
return;
|
|
174
|
-
const requests = getNestedRecord(tasks, 'requests');
|
|
175
|
-
if (!requests)
|
|
176
|
-
return;
|
|
177
|
-
if (enabled) {
|
|
178
|
-
requests['tools'] = { call: {} };
|
|
179
|
-
return;
|
|
180
|
-
}
|
|
181
|
-
delete requests['tools'];
|
|
182
|
-
}
|
|
183
|
-
const toolPresentationByServer = new WeakMap();
|
|
184
|
-
const patchedToolListServers = new WeakSet();
|
|
185
|
-
function getServerToolPresentationMap(server) {
|
|
186
|
-
let toolMap = toolPresentationByServer.get(server);
|
|
187
|
-
if (toolMap)
|
|
188
|
-
return toolMap;
|
|
189
|
-
toolMap = new Map();
|
|
190
|
-
toolPresentationByServer.set(server, toolMap);
|
|
191
|
-
registerServerLifecycleCleanup(server, () => {
|
|
192
|
-
toolPresentationByServer.delete(server);
|
|
193
|
-
});
|
|
194
|
-
return toolMap;
|
|
195
|
-
}
|
|
196
|
-
function patchSdkToolListHandler(server) {
|
|
197
|
-
if (patchedToolListServers.has(server))
|
|
198
|
-
return;
|
|
199
|
-
const sdkListToolsHandler = getSdkListToolsHandler(server);
|
|
200
|
-
if (!sdkListToolsHandler)
|
|
201
|
-
return;
|
|
202
|
-
patchedToolListServers.add(server);
|
|
203
|
-
server.server.setRequestHandler(ListToolsRequestSchema, async (request, extra) => {
|
|
204
|
-
const parsed = ListToolsResultSchema.parse(await sdkListToolsHandler(request, extra));
|
|
205
|
-
const presentations = getServerToolPresentationMap(server);
|
|
206
|
-
return {
|
|
207
|
-
...parsed,
|
|
208
|
-
tools: parsed.tools.map((tool) => {
|
|
209
|
-
if (typeof tool.name !== 'string') {
|
|
210
|
-
return tool;
|
|
211
|
-
}
|
|
212
|
-
const presentation = presentations.get(tool.name);
|
|
213
|
-
if (!presentation?.icons?.length)
|
|
214
|
-
return tool;
|
|
215
|
-
return {
|
|
216
|
-
...tool,
|
|
217
|
-
icons: presentation.icons,
|
|
218
|
-
};
|
|
219
|
-
}),
|
|
220
|
-
};
|
|
221
|
-
});
|
|
222
|
-
}
|
|
223
|
-
export function registerToolPresentation(server, name, presentation) {
|
|
224
|
-
getServerToolPresentationMap(server).set(name, presentation);
|
|
225
|
-
patchSdkToolListHandler(server);
|
|
226
|
-
}
|
|
61
|
+
/* =================================================================================================
|
|
62
|
+
* Progress reporting
|
|
63
|
+
* ================================================================================================= */
|
|
64
|
+
export {};
|
|
227
65
|
const PROGRESS_NOTIFICATION_TIMEOUT_MS = 5000;
|
|
228
66
|
const PROGRESS_NOTIFICATION_MIN_INTERVAL_MS = 100;
|
|
229
|
-
function resolveRelatedTaskMeta(meta) {
|
|
230
|
-
const related = meta?.['modelcontextprotocol.io/related-task'];
|
|
231
|
-
if (!isObject(related))
|
|
232
|
-
return undefined;
|
|
233
|
-
const { taskId } = related;
|
|
234
|
-
return typeof taskId === 'string' ? { taskId } : undefined;
|
|
235
|
-
}
|
|
236
67
|
class ToolProgressReporter {
|
|
237
68
|
token;
|
|
238
|
-
|
|
239
|
-
progressState;
|
|
240
|
-
taskMeta;
|
|
69
|
+
send;
|
|
241
70
|
lastProgress = -1;
|
|
242
|
-
lastMessage;
|
|
243
71
|
lastTotal;
|
|
244
72
|
pendingNotification;
|
|
245
73
|
isDispatching = false;
|
|
246
74
|
lastDispatchedAt = 0;
|
|
247
|
-
constructor(token,
|
|
75
|
+
constructor(token, send) {
|
|
248
76
|
this.token = token;
|
|
249
|
-
this.
|
|
250
|
-
this.progressState = progressState;
|
|
251
|
-
this.taskMeta = taskMeta;
|
|
77
|
+
this.send = send;
|
|
252
78
|
}
|
|
253
|
-
static create(
|
|
254
|
-
|
|
255
|
-
const { onProgress } = extra;
|
|
256
|
-
if (token === null && !onProgress) {
|
|
79
|
+
static create(ctx) {
|
|
80
|
+
if (!ctx) {
|
|
257
81
|
return { report: () => { } };
|
|
258
82
|
}
|
|
259
|
-
const
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
}
|
|
264
|
-
|
|
83
|
+
const meta = ctx.mcpReq._meta;
|
|
84
|
+
const token = meta?.progressToken ?? null;
|
|
85
|
+
if (token === null) {
|
|
86
|
+
return { report: () => { } };
|
|
87
|
+
}
|
|
88
|
+
const send = (notification) => ctx.mcpReq.notify({
|
|
89
|
+
method: notification.method,
|
|
90
|
+
params: { ...notification.params },
|
|
91
|
+
});
|
|
92
|
+
return new ToolProgressReporter(token, send);
|
|
265
93
|
}
|
|
266
94
|
/**
|
|
267
95
|
* Report progress toward completion. Steps are monotonic (never decrease)
|
|
@@ -269,52 +97,30 @@ class ToolProgressReporter {
|
|
|
269
97
|
* intermediate steps). Clients should treat progress as "at least this far"
|
|
270
98
|
* rather than expecting every step to fire sequentially.
|
|
271
99
|
*/
|
|
272
|
-
report(
|
|
273
|
-
|
|
274
|
-
this.handlers.canReport?.() === false) {
|
|
275
|
-
return;
|
|
276
|
-
}
|
|
100
|
+
report(input) {
|
|
101
|
+
const { progress, message, total } = input;
|
|
277
102
|
const effectiveProgress = Math.max(progress, this.lastProgress);
|
|
278
103
|
const effectiveTotal = total === undefined ? this.lastTotal : Math.max(total, effectiveProgress);
|
|
279
104
|
const isIncreasing = effectiveProgress > this.lastProgress;
|
|
280
|
-
const isMessageChanged = message !== this.lastMessage;
|
|
281
|
-
const isTotalChanged = effectiveTotal !== this.lastTotal;
|
|
282
105
|
this.lastProgress = effectiveProgress;
|
|
283
|
-
this.lastMessage = message;
|
|
284
106
|
this.lastTotal = effectiveTotal;
|
|
285
|
-
if (isIncreasing
|
|
286
|
-
try {
|
|
287
|
-
this.handlers.onProgress?.(effectiveProgress, message, effectiveTotal);
|
|
288
|
-
}
|
|
289
|
-
catch (error) {
|
|
290
|
-
logError('Progress callback failed', {
|
|
291
|
-
error: getErrorMessage(error),
|
|
292
|
-
progress: effectiveProgress,
|
|
293
|
-
message,
|
|
294
|
-
}, Loggers.LOG_MCP);
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
if (!isIncreasing || this.token === null || !this.handlers.send)
|
|
107
|
+
if (!isIncreasing)
|
|
298
108
|
return;
|
|
299
109
|
this.pendingNotification = this.createProgressNotification({
|
|
300
110
|
token: this.token,
|
|
301
111
|
progress: effectiveProgress,
|
|
302
|
-
message,
|
|
112
|
+
...(message !== undefined ? { message } : {}),
|
|
303
113
|
...(effectiveTotal !== undefined ? { total: effectiveTotal } : {}),
|
|
304
114
|
});
|
|
305
115
|
this.flushNotifications();
|
|
306
116
|
}
|
|
307
117
|
flushNotifications() {
|
|
308
|
-
if (this.isDispatching
|
|
118
|
+
if (this.isDispatching)
|
|
309
119
|
return;
|
|
310
120
|
this.isDispatching = true;
|
|
311
121
|
void (async () => {
|
|
312
122
|
try {
|
|
313
123
|
while (this.pendingNotification) {
|
|
314
|
-
if (this.handlers.canReport?.() === false) {
|
|
315
|
-
this.pendingNotification = undefined;
|
|
316
|
-
return;
|
|
317
|
-
}
|
|
318
124
|
const remainingDelay = this.lastDispatchedAt +
|
|
319
125
|
PROGRESS_NOTIFICATION_MIN_INTERVAL_MS -
|
|
320
126
|
Date.now();
|
|
@@ -333,8 +139,6 @@ class ToolProgressReporter {
|
|
|
333
139
|
})();
|
|
334
140
|
}
|
|
335
141
|
async sendWithTimeout(notification) {
|
|
336
|
-
if (!this.handlers.send)
|
|
337
|
-
return;
|
|
338
142
|
const ac = new AbortController();
|
|
339
143
|
const timeoutPromise = setTimeoutPromise(PROGRESS_NOTIFICATION_TIMEOUT_MS, { timeout: true }, { signal: ac.signal, ref: false }).catch((err) => {
|
|
340
144
|
if (err.name === 'AbortError')
|
|
@@ -343,7 +147,7 @@ class ToolProgressReporter {
|
|
|
343
147
|
});
|
|
344
148
|
try {
|
|
345
149
|
const outcome = await Promise.race([
|
|
346
|
-
this.
|
|
150
|
+
this.send(notification).then(() => {
|
|
347
151
|
ac.abort();
|
|
348
152
|
return { ok: true };
|
|
349
153
|
}),
|
|
@@ -371,23 +175,18 @@ class ToolProgressReporter {
|
|
|
371
175
|
progressToken: params.token,
|
|
372
176
|
progress: params.progress,
|
|
373
177
|
...(params.total !== undefined ? { total: params.total } : {}),
|
|
374
|
-
message: params.message,
|
|
375
|
-
...(this.taskMeta && {
|
|
376
|
-
_meta: {
|
|
377
|
-
'modelcontextprotocol.io/related-task': this.taskMeta,
|
|
378
|
-
},
|
|
379
|
-
}),
|
|
178
|
+
...(params.message !== undefined ? { message: params.message } : {}),
|
|
380
179
|
},
|
|
381
180
|
};
|
|
382
181
|
}
|
|
383
182
|
}
|
|
384
|
-
export const createProgressReporter = (
|
|
183
|
+
export const createProgressReporter = (ctx) => ToolProgressReporter.create(ctx);
|
|
385
184
|
export function validateOrThrow(schema, data, errorCode, msg, logger) {
|
|
386
185
|
const result = schema.safeParse(data);
|
|
387
186
|
if (!result.success) {
|
|
388
187
|
const issues = formatZodError(result.error);
|
|
389
188
|
logWarn(`Zod validation failed: ${msg}`, { issues }, logger);
|
|
390
|
-
throw
|
|
189
|
+
throw createProtocolError(errorCode, msg, { issues });
|
|
391
190
|
}
|
|
392
191
|
return result.data;
|
|
393
192
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../../src/lib/net/http.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,KAAK,
|
|
1
|
+
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../../src/lib/net/http.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,KAAK,EAAyC,MAAM,QAAQ,CAAC;AAwBtE,OAAO,EAQL,KAAK,eAAe,EAErB,MAAM,UAAU,CAAC;AA4vClB,UAAU,qBAAqB;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAoKD,UAAU,YAAY;IACpB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAiOD,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAE/C;AACD,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG;IAC/C,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAEA;AACD,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEjE;AACD,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,CAE9D;AACD,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAExD;AACD,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,GACb,qBAAqB,CAEvB;AACD,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,qBAAqB,EAC9B,QAAQ,EAAE,QAAQ,EAClB,WAAW,CAAC,EAAE,MAAM,GACnB,IAAI,CAEN;AACD,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,qBAAqB,EAC9B,KAAK,EAAE,OAAO,EACd,MAAM,CAAC,EAAE,MAAM,GACd,IAAI,CAEN;AACD,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,WAAW,EACjB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC;IAAE,QAAQ,EAAE,QAAQ,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,KAAK,CAAA;CAAE,CAAC,CAE7D;AACD,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,QAAQ,EAClB,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,WAAW,EACpB,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CASzC;AACD,wBAAsB,kBAAkB,CACtC,aAAa,EAAE,MAAM,EACrB,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,MAAM,CAAC,CAEjB;AACD,wBAAsB,wBAAwB,CAC5C,aAAa,EAAE,MAAM,EACrB,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC;IACT,MAAM,EAAE,UAAU,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC,CAED"}
|
package/dist/lib/net/http.js
CHANGED
|
@@ -6,7 +6,7 @@ import { finished, pipeline } from 'node:stream/promises';
|
|
|
6
6
|
import {} from 'node:stream/web';
|
|
7
7
|
import tls from 'node:tls';
|
|
8
8
|
import { createBrotliDecompress, createGunzip, createInflate } from 'node:zlib';
|
|
9
|
-
import { Agent } from 'undici';
|
|
9
|
+
import { Agent, fetch as undiciFetch } from 'undici';
|
|
10
10
|
import { config } from '../config.js';
|
|
11
11
|
import { getOperationId, getRequestId, logDebug, logError, Loggers, logWarn, redactUrl, } from '../core.js';
|
|
12
12
|
import { FetchError, invalidRedirectError, isAbortError, isError, isSystemError, redirectCredentialsError, SystemErrors, toError, unsupportedProtocolError, } from '../error/index.js';
|
|
@@ -28,26 +28,13 @@ function getCharsetFromContentType(contentType) {
|
|
|
28
28
|
}
|
|
29
29
|
return charset.trim();
|
|
30
30
|
}
|
|
31
|
-
const MAX_CACHED_DECODERS = 50;
|
|
32
|
-
const decoderCache = new Map();
|
|
33
31
|
function createDecoder(encoding) {
|
|
34
32
|
const label = normalizeEncodingLabel(encoding) || 'utf-8';
|
|
35
|
-
const cached = decoderCache.get(label);
|
|
36
|
-
if (cached)
|
|
37
|
-
return cached;
|
|
38
33
|
try {
|
|
39
|
-
|
|
40
|
-
if (decoderCache.size < MAX_CACHED_DECODERS) {
|
|
41
|
-
decoderCache.set(label, decoder);
|
|
42
|
-
}
|
|
43
|
-
return decoder;
|
|
34
|
+
return new TextDecoder(label);
|
|
44
35
|
}
|
|
45
36
|
catch {
|
|
46
|
-
|
|
47
|
-
if (decoderCache.size < MAX_CACHED_DECODERS) {
|
|
48
|
-
decoderCache.set('utf-8', fallback);
|
|
49
|
-
}
|
|
50
|
-
return fallback;
|
|
37
|
+
return new TextDecoder('utf-8');
|
|
51
38
|
}
|
|
52
39
|
}
|
|
53
40
|
function decodeBuffer(buffer, encoding) {
|
|
@@ -1062,7 +1049,7 @@ const defaultContext = {
|
|
|
1062
1049
|
const defaultRedactor = {
|
|
1063
1050
|
redact: redactUrl,
|
|
1064
1051
|
};
|
|
1065
|
-
const defaultFetch = (input, init) =>
|
|
1052
|
+
const defaultFetch = async (input, init) => undiciFetch(input, init);
|
|
1066
1053
|
class HttpFetcher {
|
|
1067
1054
|
fetcherConfig;
|
|
1068
1055
|
redirectFollower;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type McpServer } from '@modelcontextprotocol/server';
|
|
2
2
|
import { type IconInfo } from '../lib/utils.js';
|
|
3
3
|
export declare function registerInstructionResource(server: McpServer, instructions: string, iconInfo?: IconInfo): void;
|
|
4
4
|
export declare const HELP_TOPICS: readonly ["capabilities", "workflows", "constraints", "errors"];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/resources/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/resources/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,SAAS,EAEf,MAAM,8BAA8B,CAAC;AAKtC,OAAO,EAAsB,KAAK,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAOpE,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,SAAS,EACjB,YAAY,EAAE,MAAM,EACpB,QAAQ,CAAC,EAAE,QAAQ,GAClB,IAAI,CAwBN;AAED,eAAO,MAAM,WAAW,iEAKd,CAAC;AAEX,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC;AAErD,wBAAgB,cAAc,CAC5B,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,SAAS,GACf,MAAM,GAAG,SAAS,CAIpB;AAED,wBAAgB,kBAAkB,CAChC,YAAY,EAAE,MAAM,EACpB,KAAK,CAAC,EAAE,MAAM,GACb,MAAM,CAKR;AAED,wBAAgB,uBAAuB,IAAI,MAAM,CAmEhD;AAiBD,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,SAAS,EACjB,YAAY,EAAE,MAAM,EACpB,QAAQ,CAAC,EAAE,QAAQ,GAClB,IAAI,CA2BN"}
|