@j0hanz/fetch-url-mcp 1.11.7 → 1.11.8
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/README.md +25 -33
- package/dist/http/health.d.ts.map +1 -1
- package/dist/http/health.js +0 -2
- package/dist/http/native.d.ts.map +1 -1
- package/dist/http/native.js +0 -25
- package/dist/lib/config.d.ts +0 -7
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +0 -9
- package/dist/lib/core.d.ts +0 -3
- package/dist/lib/core.d.ts.map +1 -1
- package/dist/lib/core.js +0 -7
- package/dist/lib/fetch-pipeline.d.ts +1 -14
- package/dist/lib/fetch-pipeline.d.ts.map +1 -1
- package/dist/lib/fetch-pipeline.js +4 -147
- package/dist/lib/http.d.ts +0 -3
- package/dist/lib/http.d.ts.map +1 -1
- package/dist/lib/http.js +2 -105
- package/dist/lib/utils.d.ts +0 -2
- package/dist/lib/utils.d.ts.map +1 -1
- package/dist/lib/utils.js +1 -36
- package/dist/resources/index.d.ts +1 -23
- package/dist/resources/index.d.ts.map +1 -1
- package/dist/resources/index.js +3 -294
- package/dist/schemas.d.ts +0 -14
- package/dist/schemas.d.ts.map +1 -1
- package/dist/schemas.js +1 -77
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +1 -2
- package/dist/tools/fetch-url.d.ts +0 -2
- package/dist/tools/fetch-url.d.ts.map +1 -1
- package/dist/tools/fetch-url.js +12 -43
- package/dist/transform/shared.js +4 -4
- package/dist/transform/transform.d.ts +1 -1
- package/dist/transform/transform.d.ts.map +1 -1
- package/dist/transform/transform.js +10 -10
- package/dist/transform/types.d.ts +2 -2
- package/dist/transform/types.d.ts.map +1 -1
- package/dist/transform/worker-pool.d.ts +3 -3
- package/dist/transform/worker-pool.d.ts.map +1 -1
- package/dist/transform/worker-pool.js +2 -2
- package/package.json +1 -1
- package/dist/lib/cache.d.ts +0 -48
- package/dist/lib/cache.d.ts.map +0 -1
- package/dist/lib/cache.js +0 -264
package/dist/lib/http.js
CHANGED
|
@@ -1,119 +1,16 @@
|
|
|
1
1
|
import { isUtf8 } from 'node:buffer';
|
|
2
|
-
import {
|
|
2
|
+
import { randomUUID } from 'node:crypto';
|
|
3
3
|
import diagnosticsChannel from 'node:diagnostics_channel';
|
|
4
|
-
import {} from 'node:http';
|
|
5
|
-
import { posix as pathPosix } from 'node:path';
|
|
6
4
|
import { PassThrough, Readable } from 'node:stream';
|
|
7
5
|
import { finished, pipeline } from 'node:stream/promises';
|
|
8
6
|
import {} from 'node:stream/web';
|
|
9
7
|
import tls from 'node:tls';
|
|
10
8
|
import { createBrotliDecompress, createGunzip, createInflate } from 'node:zlib';
|
|
11
9
|
import { Agent } from 'undici';
|
|
12
|
-
import {
|
|
13
|
-
import { parseCachedPayload, resolveCachedPayloadContent } from '../schemas.js';
|
|
14
|
-
import { get as cacheGet, config, getOperationId, getRequestId, logDebug, logError, logWarn, redactUrl, } from './core.js';
|
|
10
|
+
import { config, getOperationId, getRequestId, logDebug, logError, logWarn, redactUrl, } from './core.js';
|
|
15
11
|
import { isIP } from './url.js';
|
|
16
12
|
import { BLOCKED_HOST_SUFFIXES, createDnsPreflight, IpBlocker, RawUrlTransformer, SafeDnsResolver, UrlNormalizer, VALIDATION_ERROR_CODE, } from './url.js';
|
|
17
13
|
import { composeAbortSignal, createErrorWithCode, FetchError, isAbortError, isError, isObject, isSystemError, toError, } from './utils.js';
|
|
18
|
-
import { formatZodError } from './zod.js';
|
|
19
|
-
// ═══════════════════════════════════════════════════════════════════
|
|
20
|
-
// FILENAME GENERATION & DOWNLOAD
|
|
21
|
-
// ═══════════════════════════════════════════════════════════════════
|
|
22
|
-
const FILENAME_RULES = {
|
|
23
|
-
MAX_LEN: 200,
|
|
24
|
-
UNSAFE_CHARS: /[<>:"/\\|?*\p{C}]/gu,
|
|
25
|
-
WHITESPACE: /\s+/g,
|
|
26
|
-
EXTENSIONS: /\.(html?|php|aspx?|jsp)$/i,
|
|
27
|
-
};
|
|
28
|
-
function sanitizeString(input) {
|
|
29
|
-
return input
|
|
30
|
-
.toLowerCase()
|
|
31
|
-
.replace(FILENAME_RULES.UNSAFE_CHARS, '')
|
|
32
|
-
.replace(FILENAME_RULES.WHITESPACE, '-')
|
|
33
|
-
.replace(/-+/g, '-')
|
|
34
|
-
.replace(/(?:^-|-$)/g, '');
|
|
35
|
-
}
|
|
36
|
-
function resolveUrlFilenameCandidate(url) {
|
|
37
|
-
const parsed = new URL(url);
|
|
38
|
-
if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:')
|
|
39
|
-
return null;
|
|
40
|
-
const basename = pathPosix.basename(parsed.pathname);
|
|
41
|
-
if (!basename || basename === 'index')
|
|
42
|
-
return null;
|
|
43
|
-
const cleaned = basename.replace(FILENAME_RULES.EXTENSIONS, '');
|
|
44
|
-
const sanitized = sanitizeString(cleaned);
|
|
45
|
-
if (sanitized === 'index')
|
|
46
|
-
return null;
|
|
47
|
-
return sanitized || null;
|
|
48
|
-
}
|
|
49
|
-
function truncateFilenameBase(name, extension) {
|
|
50
|
-
const maxBase = FILENAME_RULES.MAX_LEN - extension.length;
|
|
51
|
-
return name.length > maxBase ? name.substring(0, maxBase) : name;
|
|
52
|
-
}
|
|
53
|
-
function resolveTitleFilenameCandidate(title) {
|
|
54
|
-
if (!title)
|
|
55
|
-
return null;
|
|
56
|
-
return sanitizeString(title) || null;
|
|
57
|
-
}
|
|
58
|
-
function resolveFilenameBase(url, title, hashFallback) {
|
|
59
|
-
try {
|
|
60
|
-
const fromUrl = resolveUrlFilenameCandidate(url);
|
|
61
|
-
if (fromUrl)
|
|
62
|
-
return fromUrl;
|
|
63
|
-
}
|
|
64
|
-
catch {
|
|
65
|
-
// Ignore URL parsing errors and continue fallbacks.
|
|
66
|
-
}
|
|
67
|
-
const fromTitle = resolveTitleFilenameCandidate(title);
|
|
68
|
-
if (fromTitle)
|
|
69
|
-
return fromTitle;
|
|
70
|
-
if (hashFallback)
|
|
71
|
-
return hashFallback.substring(0, 16);
|
|
72
|
-
return `download-${hash('sha256', url, 'hex').substring(0, 16)}`;
|
|
73
|
-
}
|
|
74
|
-
export function generateSafeFilename(url, title, hashFallback, extension = '.md') {
|
|
75
|
-
const name = resolveFilenameBase(url, title, hashFallback);
|
|
76
|
-
return `${truncateFilenameBase(name, extension)}${extension}`;
|
|
77
|
-
}
|
|
78
|
-
const DownloadParamsSchema = z.strictObject({
|
|
79
|
-
namespace: z.literal('markdown'),
|
|
80
|
-
hash: z
|
|
81
|
-
.string()
|
|
82
|
-
.regex(/^[a-f0-9.]+$/i)
|
|
83
|
-
.min(8)
|
|
84
|
-
.max(64),
|
|
85
|
-
});
|
|
86
|
-
function writeJsonError(res, status, message, code) {
|
|
87
|
-
res.writeHead(status, { 'Content-Type': 'application/json' });
|
|
88
|
-
res.end(JSON.stringify({ error: message, code }));
|
|
89
|
-
}
|
|
90
|
-
export function handleDownload(res, namespace, hash) {
|
|
91
|
-
const parsed = DownloadParamsSchema.safeParse({ namespace, hash });
|
|
92
|
-
if (!parsed.success) {
|
|
93
|
-
writeJsonError(res, 400, `Invalid download parameters: ${formatZodError(parsed.error)}`, 'BAD_REQUEST');
|
|
94
|
-
return;
|
|
95
|
-
}
|
|
96
|
-
const cacheKey = `${parsed.data.namespace}:${parsed.data.hash}`;
|
|
97
|
-
const entry = cacheGet(cacheKey, { force: true });
|
|
98
|
-
if (!entry) {
|
|
99
|
-
writeJsonError(res, 404, 'Not found or expired', 'NOT_FOUND');
|
|
100
|
-
return;
|
|
101
|
-
}
|
|
102
|
-
const payload = parseCachedPayload(entry.content);
|
|
103
|
-
const content = payload ? resolveCachedPayloadContent(payload) : null;
|
|
104
|
-
if (!content) {
|
|
105
|
-
writeJsonError(res, 404, 'Content missing', 'NOT_FOUND');
|
|
106
|
-
return;
|
|
107
|
-
}
|
|
108
|
-
const fileName = generateSafeFilename(entry.url, payload?.title, parsed.data.hash);
|
|
109
|
-
// Safe header generation — RFC 5987 encoding for non-ASCII filenames
|
|
110
|
-
const encoded = encodeURIComponent(fileName).replace(/'/g, '%27');
|
|
111
|
-
res.setHeader('Content-Type', 'text/markdown; charset=utf-8');
|
|
112
|
-
res.setHeader('Content-Disposition', `attachment; filename="${fileName}"; filename*=UTF-8''${encoded}`);
|
|
113
|
-
res.setHeader('Cache-Control', `private, max-age=${config.cache.ttl}`);
|
|
114
|
-
res.setHeader('X-Content-Type-Options', 'nosniff');
|
|
115
|
-
res.end(content);
|
|
116
|
-
}
|
|
117
14
|
// ═══════════════════════════════════════════════════════════════════
|
|
118
15
|
// ENCODING DETECTION
|
|
119
16
|
// ═══════════════════════════════════════════════════════════════════
|
package/dist/lib/utils.d.ts
CHANGED
|
@@ -3,7 +3,6 @@ export declare function parseUrlOrNull(input: string, base?: string): URL | null
|
|
|
3
3
|
export declare function throwIfAborted(signal: AbortSignal | undefined, url: string, stage: string): void;
|
|
4
4
|
export declare function createAbortError(url: string, stage: string): FetchError;
|
|
5
5
|
export declare function timingSafeEqualUtf8(a: string, b: string): boolean;
|
|
6
|
-
export declare function sha256Hex(input: string | Uint8Array): string;
|
|
7
6
|
export declare function hmacSha256Hex(key: string | Uint8Array, input: string | Uint8Array): string;
|
|
8
7
|
export declare class FetchError extends Error {
|
|
9
8
|
readonly url: string;
|
|
@@ -17,7 +16,6 @@ export declare function toError(error: unknown): Error;
|
|
|
17
16
|
export declare function isAbortError(error: unknown): boolean;
|
|
18
17
|
export declare function createErrorWithCode(message: string, code: string, options?: ErrorOptions): NodeJS.ErrnoException;
|
|
19
18
|
export declare function isSystemError(error: unknown): error is NodeJS.ErrnoException;
|
|
20
|
-
export declare function stableStringify(obj: unknown): string;
|
|
21
19
|
interface TunableHttpServer {
|
|
22
20
|
headersTimeout?: number;
|
|
23
21
|
requestTimeout?: number;
|
package/dist/lib/utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/lib/utils.ts"],"names":[],"mappings":"AAaA,wBAAgB,kBAAkB,CAChC,MAAM,CAAC,EAAE,WAAW,EACpB,SAAS,CAAC,EAAE,MAAM,GACjB,WAAW,GAAG,SAAS,CAOzB;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,GAAG,GAAG,IAAI,CAEvE;AAED,wBAAgB,cAAc,CAC5B,MAAM,EAAE,WAAW,GAAG,SAAS,EAC/B,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,GACZ,IAAI,CAWN;AACD,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,UAAU,CAKvE;AACD,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAKjE;AACD,wBAAgB,
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/lib/utils.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/utils.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Buffer } from 'node:buffer';
|
|
2
|
-
import { createHmac,
|
|
2
|
+
import { createHmac, timingSafeEqual } from 'node:crypto';
|
|
3
3
|
import { setInterval as setIntervalPromise, setTimeout as setTimeoutPromise, } from 'node:timers/promises';
|
|
4
4
|
import { inspect } from 'node:util';
|
|
5
5
|
import { config, logDebug, logWarn } from './core.js';
|
|
@@ -39,9 +39,6 @@ export function timingSafeEqualUtf8(a, b) {
|
|
|
39
39
|
return false;
|
|
40
40
|
return timingSafeEqual(aBuf, bBuf);
|
|
41
41
|
}
|
|
42
|
-
export function sha256Hex(input) {
|
|
43
|
-
return oneShotHash('sha256', input, 'hex');
|
|
44
|
-
}
|
|
45
42
|
export function hmacSha256Hex(key, input) {
|
|
46
43
|
return createHmac('sha256', key).update(input).digest('hex');
|
|
47
44
|
}
|
|
@@ -112,38 +109,6 @@ export function isSystemError(error) {
|
|
|
112
109
|
const { code } = error;
|
|
113
110
|
return typeof code === 'string';
|
|
114
111
|
}
|
|
115
|
-
const MAX_DEPTH = 20;
|
|
116
|
-
const CIRCULAR_ERROR = 'stableStringify: Circular reference detected';
|
|
117
|
-
export function stableStringify(obj) {
|
|
118
|
-
const seen = new WeakSet();
|
|
119
|
-
const process = (value, depth) => {
|
|
120
|
-
if (typeof value !== 'object' || value === null)
|
|
121
|
-
return value;
|
|
122
|
-
if (depth > MAX_DEPTH) {
|
|
123
|
-
throw new Error(`stableStringify: Max depth (${MAX_DEPTH}) exceeded`);
|
|
124
|
-
}
|
|
125
|
-
if (seen.has(value)) {
|
|
126
|
-
throw new Error(CIRCULAR_ERROR);
|
|
127
|
-
}
|
|
128
|
-
seen.add(value);
|
|
129
|
-
try {
|
|
130
|
-
if (Array.isArray(value)) {
|
|
131
|
-
return value.map((item) => process(item, depth + 1));
|
|
132
|
-
}
|
|
133
|
-
const sorted = {};
|
|
134
|
-
if (!isObject(value))
|
|
135
|
-
return value;
|
|
136
|
-
for (const key of Object.keys(value).sort()) {
|
|
137
|
-
sorted[key] = process(value[key], depth + 1);
|
|
138
|
-
}
|
|
139
|
-
return sorted;
|
|
140
|
-
}
|
|
141
|
-
finally {
|
|
142
|
-
seen.delete(value);
|
|
143
|
-
}
|
|
144
|
-
};
|
|
145
|
-
return JSON.stringify(process(obj, 0));
|
|
146
|
-
}
|
|
147
112
|
const DROP_LOG_INTERVAL_MS = 10_000;
|
|
148
113
|
export function applyHttpServerTuning(server) {
|
|
149
114
|
const { headersTimeoutMs, requestTimeoutMs, keepAliveTimeoutMs, keepAliveTimeoutBufferMs, maxHeadersCount, maxConnections, } = config.server.http;
|
|
@@ -1,28 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type { ReadResourceResult } from '@modelcontextprotocol/sdk/types.js';
|
|
1
|
+
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
3
2
|
import { type IconInfo } from '../lib/utils.js';
|
|
4
|
-
type TemplateVariableValue = string | string[] | undefined;
|
|
5
|
-
interface CacheEntryMetaView {
|
|
6
|
-
scopeIds: string[];
|
|
7
|
-
}
|
|
8
|
-
export declare function isCacheEntryVisibleToScope(scopeId: string, meta: CacheEntryMetaView): boolean;
|
|
9
|
-
export declare function listCacheResourcesForScope(scopeId: string): {
|
|
10
|
-
resources: {
|
|
11
|
-
uri: string;
|
|
12
|
-
name: string;
|
|
13
|
-
title: string;
|
|
14
|
-
description: string;
|
|
15
|
-
mimeType: string;
|
|
16
|
-
annotations: {
|
|
17
|
-
audience: ['assistant'];
|
|
18
|
-
priority: number;
|
|
19
|
-
};
|
|
20
|
-
}[];
|
|
21
|
-
};
|
|
22
|
-
export declare function readCacheResourceForScope(uri: URL, variables: Record<string, TemplateVariableValue>, scopeId: string): ReadResourceResult;
|
|
23
3
|
export declare function registerInstructionResource(server: McpServer, instructions: string, iconInfo?: IconInfo): void;
|
|
24
|
-
export declare function registerCacheResourceTemplate(server: McpServer, iconInfo?: IconInfo): void;
|
|
25
4
|
export declare function buildServerInstructions(): string;
|
|
26
5
|
export declare function registerGetHelpPrompt(server: McpServer, instructions: string, iconInfo?: IconInfo): void;
|
|
27
|
-
export {};
|
|
28
6
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/resources/index.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/resources/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAOzE,OAAO,EAAsB,KAAK,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAIpE,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,SAAS,EACjB,YAAY,EAAE,MAAM,EACpB,QAAQ,CAAC,EAAE,QAAQ,GAClB,IAAI,CAwBN;AAED,wBAAgB,uBAAuB,IAAI,MAAM,CA8BhD;AAED,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,SAAS,EACjB,YAAY,EAAE,MAAM,EACpB,QAAQ,CAAC,EAAE,QAAQ,GAClB,IAAI,CAwBN"}
|
package/dist/resources/index.js
CHANGED
|
@@ -1,271 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { ErrorCode, McpError, SubscribeRequestSchema, UnsubscribeRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
|
|
3
|
-
import { get as getCacheEntry, getEntryMeta, keys as listCacheKeys, onCacheUpdate, parseCacheKey, toCacheScopeId, } from '../lib/cache.js';
|
|
4
|
-
import { config, logWarn, resolveMcpSessionIdByServer } from '../lib/core.js';
|
|
5
|
-
import { registerServerLifecycleCleanup } from '../lib/mcp-interop.js';
|
|
1
|
+
import { config } from '../lib/core.js';
|
|
6
2
|
import { buildOptionalIcons } from '../lib/utils.js';
|
|
7
|
-
import { isObject } from '../lib/utils.js';
|
|
8
|
-
import { parseCachedPayload, resolveCachedPayloadContent } from '../schemas.js';
|
|
9
3
|
import { FETCH_URL_TOOL_NAME } from '../tools/fetch-url.js';
|
|
10
|
-
const RESOURCE_NOT_FOUND_ERROR_CODE = -32002;
|
|
11
|
-
const CACHE_RESOURCE_TEMPLATE_URI = 'internal://cache/{namespace}/{hash}';
|
|
12
|
-
const CACHE_RESOURCE_PREFIX = 'internal://cache/';
|
|
13
|
-
const CACHE_NAMESPACE_PATTERN = /^[a-z0-9_-]{1,64}$/i;
|
|
14
|
-
const CACHE_HASH_PATTERN = /^[a-f0-9.]{8,64}$/i;
|
|
15
|
-
const MAX_COMPLETION_VALUES = 100;
|
|
16
|
-
function normalizeCompletionPrefix(value) {
|
|
17
|
-
return value.trim().toLowerCase();
|
|
18
|
-
}
|
|
19
|
-
function sortAndLimitValues(values) {
|
|
20
|
-
return [...values]
|
|
21
|
-
.sort((left, right) => left.localeCompare(right))
|
|
22
|
-
.slice(0, MAX_COMPLETION_VALUES);
|
|
23
|
-
}
|
|
24
|
-
function isValidCacheResourceParts(parts) {
|
|
25
|
-
return (CACHE_NAMESPACE_PATTERN.test(parts.namespace) &&
|
|
26
|
-
CACHE_HASH_PATTERN.test(parts.hash));
|
|
27
|
-
}
|
|
28
|
-
function decodeSegment(value) {
|
|
29
|
-
try {
|
|
30
|
-
return decodeURIComponent(value);
|
|
31
|
-
}
|
|
32
|
-
catch {
|
|
33
|
-
return value;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
function trimToValue(value) {
|
|
37
|
-
const trimmed = value.trim();
|
|
38
|
-
return trimmed.length > 0 ? trimmed : undefined;
|
|
39
|
-
}
|
|
40
|
-
function firstVariableValue(value) {
|
|
41
|
-
if (typeof value === 'string') {
|
|
42
|
-
return trimToValue(value);
|
|
43
|
-
}
|
|
44
|
-
if (Array.isArray(value)) {
|
|
45
|
-
const first = value[0];
|
|
46
|
-
if (typeof first !== 'string')
|
|
47
|
-
return undefined;
|
|
48
|
-
return trimToValue(first);
|
|
49
|
-
}
|
|
50
|
-
return undefined;
|
|
51
|
-
}
|
|
52
|
-
function validateCacheResourceParts(namespace, hash) {
|
|
53
|
-
const decoded = {
|
|
54
|
-
namespace: decodeSegment(namespace),
|
|
55
|
-
hash: decodeSegment(hash),
|
|
56
|
-
};
|
|
57
|
-
return isValidCacheResourceParts(decoded) ? decoded : null;
|
|
58
|
-
}
|
|
59
|
-
function parseCacheResourceFromVariables(variables) {
|
|
60
|
-
const namespace = firstVariableValue(variables['namespace']);
|
|
61
|
-
const hash = firstVariableValue(variables['hash']);
|
|
62
|
-
if (!namespace || !hash)
|
|
63
|
-
return null;
|
|
64
|
-
return validateCacheResourceParts(namespace, hash);
|
|
65
|
-
}
|
|
66
|
-
function parseCacheResourceFromUri(uri) {
|
|
67
|
-
if (!uri.href.startsWith(CACHE_RESOURCE_PREFIX))
|
|
68
|
-
return null;
|
|
69
|
-
const rawPath = uri.pathname.startsWith('/')
|
|
70
|
-
? uri.pathname.slice(1)
|
|
71
|
-
: uri.pathname;
|
|
72
|
-
const segments = rawPath.split('/');
|
|
73
|
-
if (segments.length !== 2)
|
|
74
|
-
return null;
|
|
75
|
-
const namespace = segments[0];
|
|
76
|
-
const hash = segments[1];
|
|
77
|
-
if (!namespace || !hash)
|
|
78
|
-
return null;
|
|
79
|
-
return validateCacheResourceParts(namespace, hash);
|
|
80
|
-
}
|
|
81
|
-
function toCacheResourceUri(parts) {
|
|
82
|
-
const namespace = encodeURIComponent(parts.namespace);
|
|
83
|
-
const hash = encodeURIComponent(parts.hash);
|
|
84
|
-
return `${CACHE_RESOURCE_PREFIX}${namespace}/${hash}`;
|
|
85
|
-
}
|
|
86
|
-
export function isCacheEntryVisibleToScope(scopeId, meta) {
|
|
87
|
-
return meta.scopeIds.includes(scopeId);
|
|
88
|
-
}
|
|
89
|
-
function getVisibleCacheEntries(scopeId) {
|
|
90
|
-
return listCacheKeys()
|
|
91
|
-
.map((key) => parseCacheKey(key))
|
|
92
|
-
.filter((parts) => parts !== null)
|
|
93
|
-
.map((parts) => ({ namespace: parts.namespace, hash: parts.urlHash }))
|
|
94
|
-
.filter((parts) => {
|
|
95
|
-
const meta = getEntryMeta(`${parts.namespace}:${parts.hash}`);
|
|
96
|
-
return meta ? isCacheEntryVisibleToScope(scopeId, meta) : false;
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
function completeCacheNamespaces(value, scopeId) {
|
|
100
|
-
const normalized = normalizeCompletionPrefix(value);
|
|
101
|
-
const namespaces = [
|
|
102
|
-
...new Set(getVisibleCacheEntries(scopeId).map((entry) => entry.namespace)),
|
|
103
|
-
].filter((ns) => ns.toLowerCase().startsWith(normalized));
|
|
104
|
-
return sortAndLimitValues(namespaces);
|
|
105
|
-
}
|
|
106
|
-
function completeCacheHashes(value, scopeId, context) {
|
|
107
|
-
const normalized = normalizeCompletionPrefix(value);
|
|
108
|
-
const namespace = context?.arguments?.['namespace']?.trim();
|
|
109
|
-
const hashes = getVisibleCacheEntries(scopeId)
|
|
110
|
-
.filter((entry) => namespace === undefined || entry.namespace === namespace)
|
|
111
|
-
.map((entry) => entry.hash)
|
|
112
|
-
.filter((h) => h.toLowerCase().startsWith(normalized));
|
|
113
|
-
return sortAndLimitValues(hashes);
|
|
114
|
-
}
|
|
115
|
-
function getServerCacheScopeId(server) {
|
|
116
|
-
return toCacheScopeId(resolveMcpSessionIdByServer(server));
|
|
117
|
-
}
|
|
118
|
-
export function listCacheResourcesForScope(scopeId) {
|
|
119
|
-
const resources = getVisibleCacheEntries(scopeId)
|
|
120
|
-
.map((parts) => {
|
|
121
|
-
const cacheParts = {
|
|
122
|
-
namespace: parts.namespace,
|
|
123
|
-
hash: parts.hash,
|
|
124
|
-
};
|
|
125
|
-
const cacheKey = `${parts.namespace}:${parts.hash}`;
|
|
126
|
-
const meta = getEntryMeta(cacheKey);
|
|
127
|
-
if (!meta)
|
|
128
|
-
return null; // expired between keys() and meta read — skip
|
|
129
|
-
return {
|
|
130
|
-
uri: toCacheResourceUri(cacheParts),
|
|
131
|
-
name: `${parts.namespace}:${parts.hash}`,
|
|
132
|
-
title: meta.title ?? 'Cached Markdown',
|
|
133
|
-
description: 'Cached markdown output generated by fetch-url',
|
|
134
|
-
mimeType: 'text/markdown',
|
|
135
|
-
annotations: {
|
|
136
|
-
audience: ['assistant'],
|
|
137
|
-
priority: 0.6,
|
|
138
|
-
...(meta.fetchedAt ? { lastModified: meta.fetchedAt } : {}),
|
|
139
|
-
},
|
|
140
|
-
};
|
|
141
|
-
})
|
|
142
|
-
.filter((r) => r !== null);
|
|
143
|
-
return { resources };
|
|
144
|
-
}
|
|
145
|
-
function normalizeSubscriptionUri(uri) {
|
|
146
|
-
const parsedUri = URL.parse(uri);
|
|
147
|
-
if (!parsedUri) {
|
|
148
|
-
throw new McpError(ErrorCode.InvalidParams, 'Invalid resource URI');
|
|
149
|
-
}
|
|
150
|
-
const cacheParts = parseCacheResourceFromUri(parsedUri);
|
|
151
|
-
if (cacheParts)
|
|
152
|
-
return toCacheResourceUri(cacheParts);
|
|
153
|
-
return parsedUri.href;
|
|
154
|
-
}
|
|
155
|
-
const cacheNotificationServers = new WeakSet();
|
|
156
|
-
function registerCacheResourceNotifications(server) {
|
|
157
|
-
if (cacheNotificationServers.has(server))
|
|
158
|
-
return;
|
|
159
|
-
cacheNotificationServers.add(server);
|
|
160
|
-
const subscribedResourceUris = new Set();
|
|
161
|
-
const setSubscription = (uri, subscribed) => {
|
|
162
|
-
const normalized = normalizeSubscriptionUri(uri);
|
|
163
|
-
if (subscribed) {
|
|
164
|
-
subscribedResourceUris.add(normalized);
|
|
165
|
-
}
|
|
166
|
-
else {
|
|
167
|
-
subscribedResourceUris.delete(normalized);
|
|
168
|
-
}
|
|
169
|
-
};
|
|
170
|
-
server.server.setRequestHandler(SubscribeRequestSchema, async (request) => {
|
|
171
|
-
setSubscription(request.params.uri, true);
|
|
172
|
-
return Promise.resolve({});
|
|
173
|
-
});
|
|
174
|
-
server.server.setRequestHandler(UnsubscribeRequestSchema, async (request) => {
|
|
175
|
-
setSubscription(request.params.uri, false);
|
|
176
|
-
return Promise.resolve({});
|
|
177
|
-
});
|
|
178
|
-
const unsubscribe = onCacheUpdate((event) => {
|
|
179
|
-
const scopeId = getServerCacheScopeId(server);
|
|
180
|
-
const changedUri = toCacheResourceUri({
|
|
181
|
-
namespace: event.namespace,
|
|
182
|
-
hash: event.urlHash,
|
|
183
|
-
});
|
|
184
|
-
const isVisibleToServer = event.scopeIds.includes(scopeId);
|
|
185
|
-
if (isVisibleToServer &&
|
|
186
|
-
server.isConnected() &&
|
|
187
|
-
subscribedResourceUris.has(changedUri)) {
|
|
188
|
-
void server.server
|
|
189
|
-
.sendResourceUpdated({ uri: changedUri })
|
|
190
|
-
.catch((error) => {
|
|
191
|
-
logWarn('Failed to send resource updated notification', {
|
|
192
|
-
uri: changedUri,
|
|
193
|
-
error,
|
|
194
|
-
});
|
|
195
|
-
});
|
|
196
|
-
}
|
|
197
|
-
if (!event.listChanged)
|
|
198
|
-
return;
|
|
199
|
-
if (!server.isConnected() || !isVisibleToServer)
|
|
200
|
-
return;
|
|
201
|
-
try {
|
|
202
|
-
server.sendResourceListChanged();
|
|
203
|
-
}
|
|
204
|
-
catch (error) {
|
|
205
|
-
logWarn('Failed to send resources list changed notification', { error });
|
|
206
|
-
}
|
|
207
|
-
});
|
|
208
|
-
let cleanedUp = false;
|
|
209
|
-
const cleanup = () => {
|
|
210
|
-
if (cleanedUp)
|
|
211
|
-
return;
|
|
212
|
-
cleanedUp = true;
|
|
213
|
-
unsubscribe();
|
|
214
|
-
};
|
|
215
|
-
registerServerLifecycleCleanup(server, cleanup);
|
|
216
|
-
}
|
|
217
|
-
function normalizeTemplateVariables(variables) {
|
|
218
|
-
if (!isObject(variables))
|
|
219
|
-
return {};
|
|
220
|
-
const normalized = {};
|
|
221
|
-
for (const [key, value] of Object.entries(variables)) {
|
|
222
|
-
if (typeof value === 'string' || value === undefined) {
|
|
223
|
-
normalized[key] = value;
|
|
224
|
-
continue;
|
|
225
|
-
}
|
|
226
|
-
if (Array.isArray(value)) {
|
|
227
|
-
normalized[key] = value.filter((item) => typeof item === 'string');
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
return normalized;
|
|
231
|
-
}
|
|
232
|
-
function resolveCacheResourceParts(uri, variables) {
|
|
233
|
-
const fromVariables = parseCacheResourceFromVariables(variables);
|
|
234
|
-
if (fromVariables)
|
|
235
|
-
return fromVariables;
|
|
236
|
-
const fromUri = parseCacheResourceFromUri(uri);
|
|
237
|
-
if (fromUri)
|
|
238
|
-
return fromUri;
|
|
239
|
-
throw new McpError(ErrorCode.InvalidParams, 'Invalid cache resource URI or template arguments');
|
|
240
|
-
}
|
|
241
|
-
export function readCacheResourceForScope(uri, variables, scopeId) {
|
|
242
|
-
const parts = resolveCacheResourceParts(uri, variables);
|
|
243
|
-
const cacheKey = `${parts.namespace}:${parts.hash}`;
|
|
244
|
-
const meta = getEntryMeta(cacheKey);
|
|
245
|
-
if (!meta || !isCacheEntryVisibleToScope(scopeId, meta)) {
|
|
246
|
-
throw new McpError(RESOURCE_NOT_FOUND_ERROR_CODE, 'Resource not found', {
|
|
247
|
-
uri: uri.href,
|
|
248
|
-
});
|
|
249
|
-
}
|
|
250
|
-
const entry = getCacheEntry(cacheKey);
|
|
251
|
-
if (!entry) {
|
|
252
|
-
throw new McpError(RESOURCE_NOT_FOUND_ERROR_CODE, 'Resource not found', {
|
|
253
|
-
uri: uri.href,
|
|
254
|
-
});
|
|
255
|
-
}
|
|
256
|
-
const payload = parseCachedPayload(entry.content);
|
|
257
|
-
const markdown = payload ? resolveCachedPayloadContent(payload) : null;
|
|
258
|
-
const text = markdown ?? entry.content;
|
|
259
|
-
return {
|
|
260
|
-
contents: [
|
|
261
|
-
{
|
|
262
|
-
uri: uri.href,
|
|
263
|
-
mimeType: 'text/markdown',
|
|
264
|
-
text,
|
|
265
|
-
},
|
|
266
|
-
],
|
|
267
|
-
};
|
|
268
|
-
}
|
|
269
4
|
export function registerInstructionResource(server, instructions, iconInfo) {
|
|
270
5
|
server.registerResource('fetch-url-mcp-instructions', 'internal://instructions', {
|
|
271
6
|
title: 'Server Instructions',
|
|
@@ -286,48 +21,22 @@ export function registerInstructionResource(server, instructions, iconInfo) {
|
|
|
286
21
|
],
|
|
287
22
|
}));
|
|
288
23
|
}
|
|
289
|
-
export function registerCacheResourceTemplate(server, iconInfo) {
|
|
290
|
-
const template = new ResourceTemplate(CACHE_RESOURCE_TEMPLATE_URI, {
|
|
291
|
-
list: () => listCacheResourcesForScope(getServerCacheScopeId(server)),
|
|
292
|
-
complete: {
|
|
293
|
-
namespace: (value) => completeCacheNamespaces(value, getServerCacheScopeId(server)),
|
|
294
|
-
hash: (value, context) => completeCacheHashes(value, getServerCacheScopeId(server), context),
|
|
295
|
-
},
|
|
296
|
-
});
|
|
297
|
-
server.registerResource('fetch-url-mcp-cache-entry', template, {
|
|
298
|
-
title: 'Cached Fetch Output',
|
|
299
|
-
description: 'Read cached markdown generated by previous fetch-url calls.',
|
|
300
|
-
mimeType: 'text/markdown',
|
|
301
|
-
annotations: {
|
|
302
|
-
audience: ['assistant'],
|
|
303
|
-
priority: 0.6,
|
|
304
|
-
},
|
|
305
|
-
...buildOptionalIcons(iconInfo),
|
|
306
|
-
}, (uri, variables) => readCacheResourceForScope(uri, normalizeTemplateVariables(variables), getServerCacheScopeId(server)));
|
|
307
|
-
registerCacheResourceNotifications(server);
|
|
308
|
-
}
|
|
309
24
|
export function buildServerInstructions() {
|
|
310
25
|
const maxHtmlSizeMb = config.constants.maxHtmlBytes / 1024 / 1024;
|
|
311
|
-
const cacheSizeMb = config.cache.maxSizeBytes / 1024 / 1024;
|
|
312
|
-
const cacheTtlHours = config.cache.ttl / 3600;
|
|
313
26
|
return `# Fetch public webpages and return clean, readable Markdown.
|
|
314
27
|
|
|
315
28
|
# Capabilities
|
|
316
29
|
- Tool: \`${FETCH_URL_TOOL_NAME}\` (fetch URL, return Markdown)
|
|
317
30
|
- Resource: \`internal://instructions\` (this document)
|
|
318
|
-
- Resource template: \`internal://cache/{namespace}/{hash}\` (cached Markdown)
|
|
319
31
|
- Prompt: \`get-help\` (returns these instructions)
|
|
320
|
-
- Completions: resource-template argument completion for cache entries
|
|
321
32
|
|
|
322
33
|
# Workflows
|
|
323
34
|
1. Standard: Call \`${FETCH_URL_TOOL_NAME}\` → read \`markdown\`. \`truncated: true\` means content was cut at server size limit.
|
|
324
|
-
2.
|
|
325
|
-
3. Async: \`task: { ttl: <ms> }\` in \`tools/call\` → poll \`tasks/get\` → \`tasks/result\`.
|
|
35
|
+
2. Async: \`task: { ttl: <ms> }\` in \`tools/call\` → poll \`tasks/get\` → \`tasks/result\`.
|
|
326
36
|
|
|
327
37
|
# Constraints
|
|
328
38
|
- Blocked URLs: localhost, private IPs (10.x, 172.16-31.x, 192.168.x), metadata (169.254.169.254), .local/.internal.
|
|
329
39
|
- Max HTML: ${maxHtmlSizeMb}MB. Max redirects: ${config.fetcher.maxRedirects}.
|
|
330
|
-
- Cache: ${config.cache.maxKeys} entries, ${cacheSizeMb}MB, ${cacheTtlHours}h TTL. Process-local, ephemeral.
|
|
331
40
|
- No JS rendering — client-side pages may be incomplete.
|
|
332
41
|
- Binary: not supported.
|
|
333
42
|
- Batch JSON-RPC (\`[{...}]\`): rejected with HTTP 400.
|
|
@@ -343,7 +52,7 @@ export function buildServerInstructions() {
|
|
|
343
52
|
- queue_full: worker pool busy. Wait and retry, or use task mode.`;
|
|
344
53
|
}
|
|
345
54
|
export function registerGetHelpPrompt(server, instructions, iconInfo) {
|
|
346
|
-
const description = 'Return Fetch URL server instructions: workflows,
|
|
55
|
+
const description = 'Return Fetch URL server instructions: workflows, task mode, and error handling.';
|
|
347
56
|
server.registerPrompt('get-help', {
|
|
348
57
|
title: 'Get Help',
|
|
349
58
|
description,
|
package/dist/schemas.d.ts
CHANGED
|
@@ -3,16 +3,8 @@ import type { ExtractedMetadata } from './transform/types.js';
|
|
|
3
3
|
export declare const extractedMetadataSchema: z.ZodType<ExtractedMetadata>;
|
|
4
4
|
export declare function normalizeExtractedMetadata(value: unknown): ExtractedMetadata | undefined;
|
|
5
5
|
export declare function normalizePageTitle(value: unknown): string | undefined;
|
|
6
|
-
export interface CachedPayload {
|
|
7
|
-
markdown: string;
|
|
8
|
-
title?: string | undefined;
|
|
9
|
-
metadata?: ExtractedMetadata | undefined;
|
|
10
|
-
truncated?: boolean | undefined;
|
|
11
|
-
}
|
|
12
|
-
export declare const cachedPayloadValueSchema: z.ZodType<CachedPayload>;
|
|
13
6
|
export declare const fetchUrlInputSchema: z.ZodObject<{
|
|
14
7
|
url: z.ZodURL;
|
|
15
|
-
forceRefresh: z.ZodOptional<z.ZodBoolean>;
|
|
16
8
|
}, z.core.$strict>;
|
|
17
9
|
export declare const fetchUrlOutputSchema: z.ZodObject<{
|
|
18
10
|
url: z.ZodURL;
|
|
@@ -22,14 +14,8 @@ export declare const fetchUrlOutputSchema: z.ZodObject<{
|
|
|
22
14
|
title: z.ZodOptional<z.ZodString>;
|
|
23
15
|
metadata: z.ZodOptional<z.ZodType<ExtractedMetadata, unknown, z.core.$ZodTypeInternals<ExtractedMetadata, unknown>>>;
|
|
24
16
|
markdown: z.ZodOptional<z.ZodString>;
|
|
25
|
-
fromCache: z.ZodOptional<z.ZodBoolean>;
|
|
26
17
|
fetchedAt: z.ZodOptional<z.ZodISODateTime>;
|
|
27
18
|
contentSize: z.ZodOptional<z.ZodNumber>;
|
|
28
19
|
truncated: z.ZodOptional<z.ZodBoolean>;
|
|
29
20
|
}, z.core.$strict>;
|
|
30
|
-
export declare function parseCachedPayload(raw: string): CachedPayload | null;
|
|
31
|
-
export declare function stringifyCachedPayload(payload: z.input<typeof cachedPayloadValueSchema>): string;
|
|
32
|
-
export declare function resolveCachedPayloadContent(payload: {
|
|
33
|
-
markdown?: string | null;
|
|
34
|
-
}): string | null;
|
|
35
21
|
//# sourceMappingURL=schemas.d.ts.map
|
package/dist/schemas.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../src/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAoD9D,eAAO,MAAM,uBAAuB,EAAE,CAAC,CAAC,OAAO,CAAC,iBAAiB,CAG9D,CAAC;AAgBJ,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,OAAO,GACb,iBAAiB,GAAG,SAAS,CAQ/B;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAErE;
|
|
1
|
+
{"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../src/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAoD9D,eAAO,MAAM,uBAAuB,EAAE,CAAC,CAAC,OAAO,CAAC,iBAAiB,CAG9D,CAAC;AAgBJ,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,OAAO,GACb,iBAAiB,GAAG,SAAS,CAQ/B;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAErE;AAED,eAAO,MAAM,mBAAmB;;kBAc/B,CAAC;AAEF,eAAO,MAAM,oBAAoB;;;;;;;;;;;kBAoC/B,CAAC"}
|