@j0hanz/fetch-url-mcp 1.11.4 → 1.11.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/http/health.js +1 -1
- package/dist/http/native.d.ts.map +1 -1
- package/dist/http/native.js +2 -6
- package/dist/lib/cache.d.ts +48 -0
- package/dist/lib/cache.d.ts.map +1 -0
- package/dist/lib/cache.js +273 -0
- package/dist/lib/core.d.ts +1 -40
- package/dist/lib/core.d.ts.map +1 -1
- package/dist/lib/core.js +2 -233
- package/dist/lib/fetch-pipeline.d.ts.map +1 -1
- package/dist/lib/fetch-pipeline.js +5 -2
- package/dist/lib/http.d.ts.map +1 -1
- package/dist/lib/http.js +77 -112
- package/dist/lib/mcp-interop.d.ts +2 -2
- package/dist/lib/mcp-interop.js +2 -2
- package/dist/resources/index.d.ts +21 -0
- package/dist/resources/index.d.ts.map +1 -1
- package/dist/resources/index.js +47 -72
- package/dist/tasks/execution.d.ts.map +1 -1
- package/dist/tasks/execution.js +18 -3
- package/dist/tasks/handlers.d.ts.map +1 -1
- package/dist/tasks/handlers.js +3 -4
- package/dist/tasks/manager.js +3 -3
- package/dist/tasks/waiters.js +1 -1
- package/dist/tools/fetch-url.d.ts.map +1 -1
- package/dist/tools/fetch-url.js +3 -6
- package/dist/transform/transform.js +1 -2
- package/package.json +1 -1
- package/dist/lib/task-handlers.d.ts +0 -11
- package/dist/lib/task-handlers.d.ts.map +0 -1
- package/dist/lib/task-handlers.js +0 -151
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch-pipeline.d.ts","sourceRoot":"","sources":["../../src/lib/fetch-pipeline.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,KAAK,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"fetch-pipeline.d.ts","sourceRoot":"","sources":["../../src/lib/fetch-pipeline.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,7 +2,9 @@ import { z } from 'zod';
|
|
|
2
2
|
import { cachedPayloadValueSchema, extractedMetadataSchema, normalizeExtractedMetadata, normalizePageTitle, parseCachedPayload, stringifyCachedPayload, } from '../schemas.js';
|
|
3
3
|
import { transformBufferToMarkdown } from '../transform/transform.js';
|
|
4
4
|
import {} from '../transform/types.js';
|
|
5
|
-
import {
|
|
5
|
+
import { createCacheKey, get, isEnabled, set } from './cache.js';
|
|
6
|
+
import { toCacheScopeId } from './cache.js';
|
|
7
|
+
import { config, getSessionId, logDebug, logError, logWarn } from './core.js';
|
|
6
8
|
import { fetchNormalizedUrlBuffer, normalizeUrl, transformToRawUrl, } from './http.js';
|
|
7
9
|
import { getErrorMessage, isObject, withSignal } from './utils.js';
|
|
8
10
|
export { withSignal };
|
|
@@ -129,7 +131,7 @@ function logCacheMiss(reason, cacheNamespace, normalizedUrl, error) {
|
|
|
129
131
|
function attemptCacheRetrieval(cacheKey, deserialize, cacheNamespace, normalizedUrl) {
|
|
130
132
|
if (!cacheKey)
|
|
131
133
|
return null;
|
|
132
|
-
const cached = get(cacheKey);
|
|
134
|
+
const cached = get(cacheKey, { scopeId: toCacheScopeId(getSessionId()) });
|
|
133
135
|
if (!cached)
|
|
134
136
|
return null;
|
|
135
137
|
if (!deserialize) {
|
|
@@ -178,6 +180,7 @@ function persistCacheEntry(cacheKey, data, serialize, normalizedUrl, cacheNamesp
|
|
|
178
180
|
const title = typeof dataRecord?.title === 'string' ? dataRecord.title : undefined;
|
|
179
181
|
const metadata = {
|
|
180
182
|
url: normalizedUrl,
|
|
183
|
+
scopeIds: [toCacheScopeId(getSessionId())],
|
|
181
184
|
...(title === undefined ? {} : { title }),
|
|
182
185
|
};
|
|
183
186
|
try {
|
package/dist/lib/http.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/lib/http.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,WAAW,CAAC;AAQhD,OAAO,EAAE,KAAK,EAAmB,MAAM,QAAQ,CAAC;AAehD,OAAO,EAOL,KAAK,eAAe,EAGrB,MAAM,UAAU,CAAC;AAsElB,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,MAAM,EACX,KAAK,CAAC,EAAE,MAAM,EACd,YAAY,CAAC,EAAE,MAAM,EACrB,SAAS,SAAQ,GAChB,MAAM,CAIR;AAkBD,wBAAgB,cAAc,CAC5B,GAAG,EAAE,cAAc,EACnB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,GACX,IAAI,CA6CN;
|
|
1
|
+
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/lib/http.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,WAAW,CAAC;AAQhD,OAAO,EAAE,KAAK,EAAmB,MAAM,QAAQ,CAAC;AAehD,OAAO,EAOL,KAAK,eAAe,EAGrB,MAAM,UAAU,CAAC;AAsElB,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,MAAM,EACX,KAAK,CAAC,EAAE,MAAM,EACd,YAAY,CAAC,EAAE,MAAM,EACrB,SAAS,SAAQ,GAChB,MAAM,CAIR;AAkBD,wBAAgB,cAAc,CAC5B,GAAG,EAAE,cAAc,EACnB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,GACX,IAAI,CA6CN;AAkvCD,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;AA6ND,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/http.js
CHANGED
|
@@ -3,7 +3,7 @@ import { hash, randomUUID } from 'node:crypto';
|
|
|
3
3
|
import diagnosticsChannel from 'node:diagnostics_channel';
|
|
4
4
|
import {} from 'node:http';
|
|
5
5
|
import { posix as pathPosix } from 'node:path';
|
|
6
|
-
import { PassThrough, Readable
|
|
6
|
+
import { PassThrough, Readable } from 'node:stream';
|
|
7
7
|
import { finished, pipeline } from 'node:stream/promises';
|
|
8
8
|
import {} from 'node:stream/web';
|
|
9
9
|
import tls from 'node:tls';
|
|
@@ -671,13 +671,14 @@ function createUnsupportedContentEncodingError(url, encodingHeader) {
|
|
|
671
671
|
});
|
|
672
672
|
}
|
|
673
673
|
function createDecompressor(encoding) {
|
|
674
|
+
const options = { chunkSize: 64 * 1024 };
|
|
674
675
|
switch (encoding) {
|
|
675
676
|
case 'gzip':
|
|
676
|
-
return createGunzip();
|
|
677
|
+
return createGunzip(options);
|
|
677
678
|
case 'deflate':
|
|
678
|
-
return createInflate();
|
|
679
|
+
return createInflate(options);
|
|
679
680
|
case 'br':
|
|
680
|
-
return createBrotliDecompress();
|
|
681
|
+
return createBrotliDecompress(options);
|
|
681
682
|
}
|
|
682
683
|
}
|
|
683
684
|
function createPumpedStream(initialChunk, reader) {
|
|
@@ -800,86 +801,6 @@ async function decodeResponseIfNeeded(response, url, signal) {
|
|
|
800
801
|
// ═══════════════════════════════════════════════════════════════════
|
|
801
802
|
// RESPONSE READING
|
|
802
803
|
// ═══════════════════════════════════════════════════════════════════
|
|
803
|
-
function concatUint8Arrays(chunks, totalLength) {
|
|
804
|
-
const result = new Uint8Array(totalLength);
|
|
805
|
-
let offset = 0;
|
|
806
|
-
for (const chunk of chunks) {
|
|
807
|
-
result.set(chunk, offset);
|
|
808
|
-
offset += chunk.byteLength;
|
|
809
|
-
}
|
|
810
|
-
return result;
|
|
811
|
-
}
|
|
812
|
-
class BoundedBufferTransform extends Transform {
|
|
813
|
-
byteLimit;
|
|
814
|
-
captureChunks;
|
|
815
|
-
url;
|
|
816
|
-
declaredEncoding;
|
|
817
|
-
total = 0;
|
|
818
|
-
chunks = [];
|
|
819
|
-
effectiveEncoding;
|
|
820
|
-
encodingResolved = false;
|
|
821
|
-
firstChunk = true;
|
|
822
|
-
constructor(byteLimit, captureChunks, url, declaredEncoding) {
|
|
823
|
-
super();
|
|
824
|
-
this.byteLimit = byteLimit;
|
|
825
|
-
this.captureChunks = captureChunks;
|
|
826
|
-
this.url = url;
|
|
827
|
-
this.declaredEncoding = declaredEncoding;
|
|
828
|
-
this.effectiveEncoding = declaredEncoding ?? 'utf-8';
|
|
829
|
-
}
|
|
830
|
-
_transform(chunk, _encoding, callback) {
|
|
831
|
-
try {
|
|
832
|
-
const buf = chunk instanceof Uint8Array
|
|
833
|
-
? chunk
|
|
834
|
-
: new Uint8Array(chunk);
|
|
835
|
-
this.resolveChunkEncoding(buf);
|
|
836
|
-
const binaryError = this.detectBinaryContent(buf);
|
|
837
|
-
if (binaryError) {
|
|
838
|
-
callback(binaryError);
|
|
839
|
-
return;
|
|
840
|
-
}
|
|
841
|
-
this.enforceByteLimit(buf, callback);
|
|
842
|
-
}
|
|
843
|
-
catch (error) {
|
|
844
|
-
callback(toError(error));
|
|
845
|
-
}
|
|
846
|
-
}
|
|
847
|
-
resolveChunkEncoding(buf) {
|
|
848
|
-
if (this.encodingResolved)
|
|
849
|
-
return;
|
|
850
|
-
this.encodingResolved = true;
|
|
851
|
-
this.effectiveEncoding = resolveEncoding(this.declaredEncoding, buf);
|
|
852
|
-
}
|
|
853
|
-
detectBinaryContent(buf) {
|
|
854
|
-
const isFirst = this.firstChunk;
|
|
855
|
-
this.firstChunk = false;
|
|
856
|
-
if ((isFirst && hasBinarySignature(buf)) ||
|
|
857
|
-
(!isUnicodeWideEncoding(this.effectiveEncoding) &&
|
|
858
|
-
hasNullByte(buf, BINARY_NULL_CHECK_LIMIT))) {
|
|
859
|
-
return createBinaryContentError(this.url);
|
|
860
|
-
}
|
|
861
|
-
return null;
|
|
862
|
-
}
|
|
863
|
-
enforceByteLimit(buf, callback) {
|
|
864
|
-
const newTotal = this.total + buf.length;
|
|
865
|
-
if (newTotal > this.byteLimit) {
|
|
866
|
-
const remaining = this.byteLimit - this.total;
|
|
867
|
-
if (remaining > 0) {
|
|
868
|
-
const slice = buf.subarray(0, remaining);
|
|
869
|
-
this.total += remaining;
|
|
870
|
-
if (this.captureChunks)
|
|
871
|
-
this.chunks.push(slice);
|
|
872
|
-
this.push(slice);
|
|
873
|
-
}
|
|
874
|
-
callback(new MaxBytesError());
|
|
875
|
-
return;
|
|
876
|
-
}
|
|
877
|
-
this.total = newTotal;
|
|
878
|
-
if (this.captureChunks)
|
|
879
|
-
this.chunks.push(buf);
|
|
880
|
-
callback(null, buf);
|
|
881
|
-
}
|
|
882
|
-
}
|
|
883
804
|
function assertNonBinaryContent(buffer, encoding, url) {
|
|
884
805
|
if (isBinaryContent(buffer, encoding)) {
|
|
885
806
|
throw createBinaryContentError(url);
|
|
@@ -935,20 +856,53 @@ class ResponseTextReader {
|
|
|
935
856
|
const byteLimit = maxBytes <= 0 ? Number.POSITIVE_INFINITY : maxBytes;
|
|
936
857
|
const captureChunks = byteLimit !== Number.POSITIVE_INFINITY;
|
|
937
858
|
const source = Readable.fromWeb(toNodeReadableStream(stream, url, 'response:read-stream-buffer'));
|
|
938
|
-
const guard = new BoundedBufferTransform(byteLimit, captureChunks, url, encoding);
|
|
939
859
|
const chunks = [];
|
|
860
|
+
let total = 0;
|
|
861
|
+
let effectiveEncoding = encoding ?? 'utf-8';
|
|
862
|
+
let encodingResolved = false;
|
|
863
|
+
let firstChunk = true;
|
|
864
|
+
async function* guard(sourceIterable) {
|
|
865
|
+
for await (const chunk of sourceIterable) {
|
|
866
|
+
const buf = chunk instanceof Uint8Array
|
|
867
|
+
? chunk
|
|
868
|
+
: new Uint8Array(chunk);
|
|
869
|
+
if (!encodingResolved) {
|
|
870
|
+
encodingResolved = true;
|
|
871
|
+
effectiveEncoding = resolveEncoding(encoding, buf);
|
|
872
|
+
}
|
|
873
|
+
if ((firstChunk && hasBinarySignature(buf)) ||
|
|
874
|
+
(!isUnicodeWideEncoding(effectiveEncoding) &&
|
|
875
|
+
hasNullByte(buf, BINARY_NULL_CHECK_LIMIT))) {
|
|
876
|
+
throw createBinaryContentError(url);
|
|
877
|
+
}
|
|
878
|
+
firstChunk = false;
|
|
879
|
+
const newTotal = total + buf.length;
|
|
880
|
+
if (newTotal > byteLimit) {
|
|
881
|
+
const remaining = byteLimit - total;
|
|
882
|
+
if (remaining > 0) {
|
|
883
|
+
const slice = buf.subarray(0, remaining);
|
|
884
|
+
total += remaining;
|
|
885
|
+
yield slice;
|
|
886
|
+
}
|
|
887
|
+
throw new MaxBytesError();
|
|
888
|
+
}
|
|
889
|
+
total = newTotal;
|
|
890
|
+
yield buf;
|
|
891
|
+
}
|
|
892
|
+
}
|
|
940
893
|
try {
|
|
941
894
|
await pipeline(source, guard, async (iterable) => {
|
|
942
895
|
for await (const chunk of iterable) {
|
|
943
|
-
|
|
896
|
+
if (captureChunks)
|
|
897
|
+
chunks.push(chunk);
|
|
944
898
|
}
|
|
945
899
|
},
|
|
946
900
|
// Only pass `{ signal }` if signal exists to avoid type errors with exactOptionalPropertyTypes
|
|
947
901
|
...(signal ? [{ signal }] : []));
|
|
948
902
|
return {
|
|
949
|
-
buffer:
|
|
950
|
-
encoding:
|
|
951
|
-
size:
|
|
903
|
+
buffer: Buffer.concat(chunks, total),
|
|
904
|
+
encoding: effectiveEncoding,
|
|
905
|
+
size: total,
|
|
952
906
|
truncated: false,
|
|
953
907
|
};
|
|
954
908
|
}
|
|
@@ -960,9 +914,9 @@ class ResponseTextReader {
|
|
|
960
914
|
throw error;
|
|
961
915
|
if (error instanceof MaxBytesError) {
|
|
962
916
|
return {
|
|
963
|
-
buffer:
|
|
964
|
-
encoding:
|
|
965
|
-
size:
|
|
917
|
+
buffer: Buffer.concat(chunks, total),
|
|
918
|
+
encoding: effectiveEncoding,
|
|
919
|
+
size: total,
|
|
966
920
|
truncated: true,
|
|
967
921
|
};
|
|
968
922
|
}
|
|
@@ -1024,7 +978,7 @@ function toWebReadableStream(stream, url, stage) {
|
|
|
1024
978
|
assertReadableStreamLike(converted, url, stage);
|
|
1025
979
|
return converted;
|
|
1026
980
|
}
|
|
1027
|
-
const
|
|
981
|
+
const fetchChannels = diagnosticsChannel.tracingChannel('fetch-url-mcp.fetch');
|
|
1028
982
|
const SLOW_REQUEST_THRESHOLD_MS = 5000;
|
|
1029
983
|
class FetchTelemetry {
|
|
1030
984
|
logger;
|
|
@@ -1061,14 +1015,21 @@ class FetchTelemetry {
|
|
|
1061
1015
|
if (operationId)
|
|
1062
1016
|
ctx.operationId = operationId;
|
|
1063
1017
|
const fields = this.contextFields(ctx);
|
|
1064
|
-
|
|
1018
|
+
const event = {
|
|
1065
1019
|
v: 1,
|
|
1066
|
-
type: 'start',
|
|
1067
1020
|
requestId: ctx.requestId,
|
|
1068
1021
|
method: ctx.method,
|
|
1069
1022
|
url: ctx.url,
|
|
1070
1023
|
...fields,
|
|
1071
|
-
}
|
|
1024
|
+
};
|
|
1025
|
+
if (fetchChannels.hasSubscribers) {
|
|
1026
|
+
try {
|
|
1027
|
+
fetchChannels.start.publish(event);
|
|
1028
|
+
}
|
|
1029
|
+
catch {
|
|
1030
|
+
// Best-effort telemetry; never crash request path.
|
|
1031
|
+
}
|
|
1032
|
+
}
|
|
1072
1033
|
this.logger.debug('HTTP Request', {
|
|
1073
1034
|
requestId: ctx.requestId,
|
|
1074
1035
|
method: ctx.method,
|
|
@@ -1081,14 +1042,21 @@ class FetchTelemetry {
|
|
|
1081
1042
|
const duration = performance.now() - context.startTime;
|
|
1082
1043
|
const durationLabel = `${Math.round(duration)}ms`;
|
|
1083
1044
|
const fields = this.contextFields(context);
|
|
1084
|
-
|
|
1045
|
+
const event = {
|
|
1085
1046
|
v: 1,
|
|
1086
|
-
type: 'end',
|
|
1087
1047
|
requestId: context.requestId,
|
|
1088
1048
|
status: response.status,
|
|
1089
1049
|
duration,
|
|
1090
1050
|
...fields,
|
|
1091
|
-
}
|
|
1051
|
+
};
|
|
1052
|
+
if (fetchChannels.hasSubscribers) {
|
|
1053
|
+
try {
|
|
1054
|
+
fetchChannels.end.publish(event);
|
|
1055
|
+
}
|
|
1056
|
+
catch {
|
|
1057
|
+
// Best-effort telemetry; never crash request path.
|
|
1058
|
+
}
|
|
1059
|
+
}
|
|
1092
1060
|
const contentType = response.headers.get('content-type') ?? undefined;
|
|
1093
1061
|
const contentLengthHeader = response.headers.get('content-length');
|
|
1094
1062
|
const size = contentLengthHeader ??
|
|
@@ -1116,9 +1084,8 @@ class FetchTelemetry {
|
|
|
1116
1084
|
const err = toError(error);
|
|
1117
1085
|
const code = isSystemError(err) ? err.code : undefined;
|
|
1118
1086
|
const fields = this.contextFields(context);
|
|
1119
|
-
|
|
1087
|
+
const event = {
|
|
1120
1088
|
v: 1,
|
|
1121
|
-
type: 'error',
|
|
1122
1089
|
requestId: context.requestId,
|
|
1123
1090
|
url: context.url,
|
|
1124
1091
|
error: err.message,
|
|
@@ -1126,7 +1093,15 @@ class FetchTelemetry {
|
|
|
1126
1093
|
...(code !== undefined ? { code } : {}),
|
|
1127
1094
|
...(status !== undefined ? { status } : {}),
|
|
1128
1095
|
...fields,
|
|
1129
|
-
}
|
|
1096
|
+
};
|
|
1097
|
+
if (fetchChannels.hasSubscribers) {
|
|
1098
|
+
try {
|
|
1099
|
+
fetchChannels.error.publish(event);
|
|
1100
|
+
}
|
|
1101
|
+
catch {
|
|
1102
|
+
// Best-effort telemetry; never crash request path.
|
|
1103
|
+
}
|
|
1104
|
+
}
|
|
1130
1105
|
const logData = {
|
|
1131
1106
|
requestId: context.requestId,
|
|
1132
1107
|
url: context.url,
|
|
@@ -1141,16 +1116,6 @@ class FetchTelemetry {
|
|
|
1141
1116
|
}
|
|
1142
1117
|
this.logger.error('HTTP Request Error', logData);
|
|
1143
1118
|
}
|
|
1144
|
-
publish(event) {
|
|
1145
|
-
if (!fetchChannel.hasSubscribers)
|
|
1146
|
-
return;
|
|
1147
|
-
try {
|
|
1148
|
-
fetchChannel.publish(event);
|
|
1149
|
-
}
|
|
1150
|
-
catch {
|
|
1151
|
-
// Best-effort telemetry; never crash request path.
|
|
1152
|
-
}
|
|
1153
|
-
}
|
|
1154
1119
|
}
|
|
1155
1120
|
const defaultLogger = {
|
|
1156
1121
|
debug: logDebug,
|
|
@@ -67,14 +67,14 @@ export declare function registerServerLifecycleCleanup(server: McpServer, callba
|
|
|
67
67
|
/**
|
|
68
68
|
* Retrieves the SDK's internal request-handler map.
|
|
69
69
|
*
|
|
70
|
-
* Depends on SDK private API `_requestHandlers` (verified against ^1.
|
|
70
|
+
* Depends on SDK private API `_requestHandlers` (verified against ^1.28).
|
|
71
71
|
* If the SDK changes this internal, the sdk-compat-guard.test.ts tests will fail.
|
|
72
72
|
*/
|
|
73
73
|
export declare function getSdkCallToolHandler(server: McpServer): RequestHandlerFn | null;
|
|
74
74
|
/**
|
|
75
75
|
* Patches the SDK's internal capabilities to enable/disable task-mode tool calls.
|
|
76
76
|
*
|
|
77
|
-
* Depends on SDK private API `_capabilities.tasks.requests` (verified against ^1.
|
|
77
|
+
* Depends on SDK private API `_capabilities.tasks.requests` (verified against ^1.28).
|
|
78
78
|
* If the SDK changes this internal, the sdk-compat-guard.test.ts tests will fail.
|
|
79
79
|
*/
|
|
80
80
|
export declare function setTaskToolCallCapability(server: McpServer, enabled: boolean): void;
|
package/dist/lib/mcp-interop.js
CHANGED
|
@@ -176,7 +176,7 @@ export function registerServerLifecycleCleanup(server, callback) {
|
|
|
176
176
|
/**
|
|
177
177
|
* Retrieves the SDK's internal request-handler map.
|
|
178
178
|
*
|
|
179
|
-
* Depends on SDK private API `_requestHandlers` (verified against ^1.
|
|
179
|
+
* Depends on SDK private API `_requestHandlers` (verified against ^1.28).
|
|
180
180
|
* If the SDK changes this internal, the sdk-compat-guard.test.ts tests will fail.
|
|
181
181
|
*/
|
|
182
182
|
export function getSdkCallToolHandler(server) {
|
|
@@ -189,7 +189,7 @@ export function getSdkCallToolHandler(server) {
|
|
|
189
189
|
/**
|
|
190
190
|
* Patches the SDK's internal capabilities to enable/disable task-mode tool calls.
|
|
191
191
|
*
|
|
192
|
-
* Depends on SDK private API `_capabilities.tasks.requests` (verified against ^1.
|
|
192
|
+
* Depends on SDK private API `_capabilities.tasks.requests` (verified against ^1.28).
|
|
193
193
|
* If the SDK changes this internal, the sdk-compat-guard.test.ts tests will fail.
|
|
194
194
|
*/
|
|
195
195
|
export function setTaskToolCallCapability(server, enabled) {
|
|
@@ -1,7 +1,28 @@
|
|
|
1
1
|
import { type McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import type { ReadResourceResult } from '@modelcontextprotocol/sdk/types.js';
|
|
2
3
|
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;
|
|
3
23
|
export declare function registerInstructionResource(server: McpServer, instructions: string, iconInfo?: IconInfo): void;
|
|
4
24
|
export declare function registerCacheResourceTemplate(server: McpServer, iconInfo?: IconInfo): void;
|
|
5
25
|
export declare function buildServerInstructions(): string;
|
|
6
26
|
export declare function registerGetHelpPrompt(server: McpServer, instructions: string, iconInfo?: IconInfo): void;
|
|
27
|
+
export {};
|
|
7
28
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/resources/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,SAAS,EAEf,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/resources/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,SAAS,EAEf,MAAM,yCAAyC,CAAC;AACjD,OAAO,KAAK,EAEV,kBAAkB,EACnB,MAAM,oCAAoC,CAAC;AAkB5C,OAAO,EAAsB,KAAK,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAiBpE,KAAK,qBAAqB,GAAG,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC;AAQ3D,UAAU,kBAAkB;IAC1B,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAyFD,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,kBAAkB,GACvB,OAAO,CAET;AAuCD,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,MAAM,GAAG;IAC3D,SAAS,EAAE;QACT,GAAG,EAAE,MAAM,CAAC;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;QACd,WAAW,EAAE,MAAM,CAAC;QACpB,QAAQ,EAAE,MAAM,CAAC;QACjB,WAAW,EAAE;YAAE,QAAQ,EAAE,CAAC,WAAW,CAAC,CAAC;YAAC,QAAQ,EAAE,MAAM,CAAA;SAAE,CAAC;KAC5D,EAAE,CAAC;CACL,CA0BA;AA2HD,wBAAgB,yBAAyB,CACvC,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC,EAChD,OAAO,EAAE,MAAM,GACd,kBAAkB,CA8BpB;AAED,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,SAAS,EACjB,YAAY,EAAE,MAAM,EACpB,QAAQ,CAAC,EAAE,QAAQ,GAClB,IAAI,CAwBN;AAED,wBAAgB,6BAA6B,CAC3C,MAAM,EAAE,SAAS,EACjB,QAAQ,CAAC,EAAE,QAAQ,GAClB,IAAI,CAkCN;AAED,wBAAgB,uBAAuB,IAAI,MAAM,CAoChD;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,8 +1,7 @@
|
|
|
1
1
|
import { ResourceTemplate, } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
2
|
import { ErrorCode, McpError, SubscribeRequestSchema, UnsubscribeRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
|
|
3
|
-
import { get as getCacheEntry, getEntryMeta, keys as listCacheKeys, onCacheUpdate, parseCacheKey, } from '../lib/
|
|
4
|
-
import { logWarn } from '../lib/core.js';
|
|
5
|
-
import { config } from '../lib/core.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';
|
|
6
5
|
import { registerServerLifecycleCleanup } from '../lib/mcp-interop.js';
|
|
7
6
|
import { buildOptionalIcons } from '../lib/utils.js';
|
|
8
7
|
import { isObject } from '../lib/utils.js';
|
|
@@ -84,85 +83,52 @@ function toCacheResourceUri(parts) {
|
|
|
84
83
|
const hash = encodeURIComponent(parts.hash);
|
|
85
84
|
return `${CACHE_RESOURCE_PREFIX}${namespace}/${hash}`;
|
|
86
85
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
hashIndex = null;
|
|
90
|
-
invalidate() {
|
|
91
|
-
this.namespaces = null;
|
|
92
|
-
this.hashIndex = null;
|
|
93
|
-
}
|
|
94
|
-
getNamespaces() {
|
|
95
|
-
if (!this.namespaces) {
|
|
96
|
-
const seen = new Set();
|
|
97
|
-
for (const key of listCacheKeys()) {
|
|
98
|
-
const parsed = parseCacheKey(key);
|
|
99
|
-
if (parsed)
|
|
100
|
-
seen.add(parsed.namespace);
|
|
101
|
-
}
|
|
102
|
-
this.namespaces = [...seen].sort((a, b) => a.localeCompare(b));
|
|
103
|
-
}
|
|
104
|
-
return this.namespaces;
|
|
105
|
-
}
|
|
106
|
-
getHashes(namespace) {
|
|
107
|
-
if (!this.hashIndex) {
|
|
108
|
-
const index = new Map();
|
|
109
|
-
for (const key of listCacheKeys()) {
|
|
110
|
-
const parsed = parseCacheKey(key);
|
|
111
|
-
if (!parsed)
|
|
112
|
-
continue;
|
|
113
|
-
let set = index.get(parsed.namespace);
|
|
114
|
-
if (!set) {
|
|
115
|
-
set = new Set();
|
|
116
|
-
index.set(parsed.namespace, set);
|
|
117
|
-
}
|
|
118
|
-
set.add(parsed.urlHash);
|
|
119
|
-
}
|
|
120
|
-
this.hashIndex = new Map();
|
|
121
|
-
for (const [ns, set] of index) {
|
|
122
|
-
this.hashIndex.set(ns, [...set].sort((a, b) => a.localeCompare(b)));
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
if (namespace)
|
|
126
|
-
return this.hashIndex.get(namespace) ?? [];
|
|
127
|
-
const all = [];
|
|
128
|
-
for (const hashes of this.hashIndex.values()) {
|
|
129
|
-
all.push(...hashes);
|
|
130
|
-
}
|
|
131
|
-
return all.sort((a, b) => a.localeCompare(b));
|
|
132
|
-
}
|
|
86
|
+
export function isCacheEntryVisibleToScope(scopeId, meta) {
|
|
87
|
+
return meta.scopeIds.includes(scopeId);
|
|
133
88
|
}
|
|
134
|
-
|
|
135
|
-
|
|
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) {
|
|
136
100
|
const normalized = normalizeCompletionPrefix(value);
|
|
137
|
-
const namespaces =
|
|
138
|
-
.
|
|
139
|
-
|
|
101
|
+
const namespaces = [
|
|
102
|
+
...new Set(getVisibleCacheEntries(scopeId).map((entry) => entry.namespace)),
|
|
103
|
+
].filter((ns) => ns.toLowerCase().startsWith(normalized));
|
|
140
104
|
return sortAndLimitValues(namespaces);
|
|
141
105
|
}
|
|
142
|
-
function completeCacheHashes(value, context) {
|
|
106
|
+
function completeCacheHashes(value, scopeId, context) {
|
|
143
107
|
const normalized = normalizeCompletionPrefix(value);
|
|
144
108
|
const namespace = context?.arguments?.['namespace']?.trim();
|
|
145
|
-
const hashes =
|
|
146
|
-
.
|
|
109
|
+
const hashes = getVisibleCacheEntries(scopeId)
|
|
110
|
+
.filter((entry) => namespace === undefined || entry.namespace === namespace)
|
|
111
|
+
.map((entry) => entry.hash)
|
|
147
112
|
.filter((h) => h.toLowerCase().startsWith(normalized));
|
|
148
113
|
return sortAndLimitValues(hashes);
|
|
149
114
|
}
|
|
150
|
-
function
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
115
|
+
function getServerCacheScopeId(server) {
|
|
116
|
+
return toCacheScopeId(resolveMcpSessionIdByServer(server));
|
|
117
|
+
}
|
|
118
|
+
export function listCacheResourcesForScope(scopeId) {
|
|
119
|
+
const resources = getVisibleCacheEntries(scopeId)
|
|
154
120
|
.map((parts) => {
|
|
155
121
|
const cacheParts = {
|
|
156
122
|
namespace: parts.namespace,
|
|
157
|
-
hash: parts.
|
|
123
|
+
hash: parts.hash,
|
|
158
124
|
};
|
|
159
|
-
const cacheKey = `${parts.namespace}:${parts.
|
|
125
|
+
const cacheKey = `${parts.namespace}:${parts.hash}`;
|
|
160
126
|
const meta = getEntryMeta(cacheKey);
|
|
161
127
|
if (!meta)
|
|
162
128
|
return null; // expired between keys() and meta read — skip
|
|
163
129
|
return {
|
|
164
130
|
uri: toCacheResourceUri(cacheParts),
|
|
165
|
-
name: `${parts.namespace}:${parts.
|
|
131
|
+
name: `${parts.namespace}:${parts.hash}`,
|
|
166
132
|
title: meta.title ?? 'Cached Markdown',
|
|
167
133
|
description: 'Cached markdown output generated by fetch-url',
|
|
168
134
|
mimeType: 'text/markdown',
|
|
@@ -210,12 +176,15 @@ function registerCacheResourceNotifications(server) {
|
|
|
210
176
|
return Promise.resolve({});
|
|
211
177
|
});
|
|
212
178
|
const unsubscribe = onCacheUpdate((event) => {
|
|
213
|
-
|
|
179
|
+
const scopeId = getServerCacheScopeId(server);
|
|
214
180
|
const changedUri = toCacheResourceUri({
|
|
215
181
|
namespace: event.namespace,
|
|
216
182
|
hash: event.urlHash,
|
|
217
183
|
});
|
|
218
|
-
|
|
184
|
+
const isVisibleToServer = event.scopeIds.includes(scopeId);
|
|
185
|
+
if (isVisibleToServer &&
|
|
186
|
+
server.isConnected() &&
|
|
187
|
+
subscribedResourceUris.has(changedUri)) {
|
|
219
188
|
void server.server
|
|
220
189
|
.sendResourceUpdated({ uri: changedUri })
|
|
221
190
|
.catch((error) => {
|
|
@@ -227,7 +196,7 @@ function registerCacheResourceNotifications(server) {
|
|
|
227
196
|
}
|
|
228
197
|
if (!event.listChanged)
|
|
229
198
|
return;
|
|
230
|
-
if (!server.isConnected())
|
|
199
|
+
if (!server.isConnected() || !isVisibleToServer)
|
|
231
200
|
return;
|
|
232
201
|
try {
|
|
233
202
|
server.sendResourceListChanged();
|
|
@@ -269,9 +238,15 @@ function resolveCacheResourceParts(uri, variables) {
|
|
|
269
238
|
return fromUri;
|
|
270
239
|
throw new McpError(ErrorCode.InvalidParams, 'Invalid cache resource URI or template arguments');
|
|
271
240
|
}
|
|
272
|
-
function
|
|
241
|
+
export function readCacheResourceForScope(uri, variables, scopeId) {
|
|
273
242
|
const parts = resolveCacheResourceParts(uri, variables);
|
|
274
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
|
+
}
|
|
275
250
|
const entry = getCacheEntry(cacheKey);
|
|
276
251
|
if (!entry) {
|
|
277
252
|
throw new McpError(RESOURCE_NOT_FOUND_ERROR_CODE, 'Resource not found', {
|
|
@@ -313,10 +288,10 @@ export function registerInstructionResource(server, instructions, iconInfo) {
|
|
|
313
288
|
}
|
|
314
289
|
export function registerCacheResourceTemplate(server, iconInfo) {
|
|
315
290
|
const template = new ResourceTemplate(CACHE_RESOURCE_TEMPLATE_URI, {
|
|
316
|
-
list: () =>
|
|
291
|
+
list: () => listCacheResourcesForScope(getServerCacheScopeId(server)),
|
|
317
292
|
complete: {
|
|
318
|
-
namespace: (value) => completeCacheNamespaces(value),
|
|
319
|
-
hash: (value, context) => completeCacheHashes(value, context),
|
|
293
|
+
namespace: (value) => completeCacheNamespaces(value, getServerCacheScopeId(server)),
|
|
294
|
+
hash: (value, context) => completeCacheHashes(value, getServerCacheScopeId(server), context),
|
|
320
295
|
},
|
|
321
296
|
});
|
|
322
297
|
server.registerResource('fetch-url-mcp-cache-entry', template, {
|
|
@@ -328,7 +303,7 @@ export function registerCacheResourceTemplate(server, iconInfo) {
|
|
|
328
303
|
priority: 0.6,
|
|
329
304
|
},
|
|
330
305
|
...buildOptionalIcons(iconInfo),
|
|
331
|
-
}, (uri, variables) =>
|
|
306
|
+
}, (uri, variables) => readCacheResourceForScope(uri, normalizeTemplateVariables(variables), getServerCacheScopeId(server)));
|
|
332
307
|
registerCacheResourceNotifications(server);
|
|
333
308
|
}
|
|
334
309
|
export function buildServerInstructions() {
|
|
@@ -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;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,CAGvD;AAED,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,EAChB,aAAa,SAA4D,GACxE,MAAM,CAOR;AAED,wBAAgB,sBAAsB,IAAI,IAAI,CAE7C;AAMD,KAAK,WAAW,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC;AAC5C,KAAK,uBAAuB,GAAG,IAAI,CACjC,SAAS,EACP,QAAQ,GACR,QAAQ,GACR,eAAe,GACf,WAAW,GACX,eAAe,GACf,KAAK,GACL,cAAc,CACjB,CAAC;AAEF,wBAAgB,aAAa,CAAC,IAAI,EAAE,uBAAuB,GAAG,WAAW,CAUxE;AAED,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,SAAS,EACjB,IAAI,EAAE,SAAS,GACd,IAAI,CAeN;AAED,wBAAgB,iBAAiB,IAAI,KAAK,CAEzC;
|
|
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,CAGvD;AAED,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,EAChB,aAAa,SAA4D,GACxE,MAAM,CAOR;AAED,wBAAgB,sBAAsB,IAAI,IAAI,CAE7C;AAMD,KAAK,WAAW,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC;AAC5C,KAAK,uBAAuB,GAAG,IAAI,CACjC,SAAS,EACP,QAAQ,GACR,QAAQ,GACR,eAAe,GACf,WAAW,GACX,eAAe,GACf,KAAK,GACL,cAAc,CACjB,CAAC;AAEF,wBAAgB,aAAa,CAAC,IAAI,EAAE,uBAAuB,GAAG,WAAW,CAUxE;AAED,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,SAAS,EACjB,IAAI,EAAE,SAAS,GACd,IAAI,CAeN;AAED,wBAAgB,iBAAiB,IAAI,KAAK,CAEzC;AAmID,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,uBAAuB,EAChC,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,YAAY,CAAC,CA4CvB"}
|
package/dist/tasks/execution.js
CHANGED
|
@@ -83,18 +83,33 @@ function updateTaskAndEmitStatus(server, taskId, update) {
|
|
|
83
83
|
emitTaskStatusNotification(server, task);
|
|
84
84
|
}
|
|
85
85
|
function buildTaskFailureState(error) {
|
|
86
|
-
const
|
|
86
|
+
const mcpErrorMessage = error instanceof McpError
|
|
87
|
+
? (/^MCP error -?\d+:\s*(.*)$/s.exec(error.message)?.[1] ?? error.message)
|
|
88
|
+
: undefined;
|
|
89
|
+
const statusMessage = mcpErrorMessage ?? getErrorMessage(error);
|
|
90
|
+
const payload = { error: statusMessage };
|
|
87
91
|
if (error instanceof McpError) {
|
|
92
|
+
payload['code'] = error.code;
|
|
93
|
+
if (error.data !== undefined) {
|
|
94
|
+
payload['data'] = error.data;
|
|
95
|
+
}
|
|
88
96
|
return {
|
|
89
97
|
status: 'failed',
|
|
90
98
|
statusMessage,
|
|
91
|
-
|
|
99
|
+
result: {
|
|
100
|
+
content: [{ type: 'text', text: JSON.stringify(payload) }],
|
|
101
|
+
isError: true,
|
|
102
|
+
},
|
|
92
103
|
};
|
|
93
104
|
}
|
|
105
|
+
payload['code'] = ErrorCode.InternalError;
|
|
94
106
|
return {
|
|
95
107
|
status: 'failed',
|
|
96
108
|
statusMessage,
|
|
97
|
-
|
|
109
|
+
result: {
|
|
110
|
+
content: [{ type: 'text', text: JSON.stringify(payload) }],
|
|
111
|
+
isError: true,
|
|
112
|
+
},
|
|
98
113
|
};
|
|
99
114
|
}
|
|
100
115
|
function buildTaskCompletionUpdate(result, tool) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handlers.d.ts","sourceRoot":"","sources":["../../src/tasks/handlers.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAmCzE,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AA4D7E,UAAU,8BAA8B;IACtC,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED,UAAU,6BAA6B;IACrC,oBAAoB,EAAE,OAAO,CAAC;IAC9B,0BAA0B,EAAE,OAAO,CAAC;CACrC;AACD,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,SAAS,EACjB,OAAO,CAAC,EAAE,8BAA8B,GACvC,6BAA6B,
|
|
1
|
+
{"version":3,"file":"handlers.d.ts","sourceRoot":"","sources":["../../src/tasks/handlers.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAmCzE,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AA4D7E,UAAU,8BAA8B;IACtC,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED,UAAU,6BAA6B;IACrC,oBAAoB,EAAE,OAAO,CAAC;IAC9B,0BAA0B,EAAE,OAAO,CAAC;CACrC;AACD,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,SAAS,EACjB,OAAO,CAAC,EAAE,8BAA8B,GACvC,6BAA6B,CAyJ/B"}
|