@orkestrel/mcp 0.0.31 → 0.0.32
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/src/core/index.cjs +55 -60
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.js +56 -61
- package/dist/src/core/index.js.map +1 -1
- package/dist/src/server/index.cjs +1 -1
- package/dist/src/server/index.cjs.map +1 -1
- package/dist/src/server/index.js +2 -2
- package/dist/src/server/index.js.map +1 -1
- package/package.json +15 -15
package/dist/src/core/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { arrayOf, attempt, cloneJSONRecord, cloneJSONValue, isArray, isBoolean, isFiniteNumber, isInteger, isJSONValue, isNumber, isRecord, isString, isUndefined, objectOf, parseJSON, sanitizeBudget } from "@orkestrel/contract";
|
|
1
|
+
import { arrayOf, attempt, cloneJSONRecord, cloneJSONValue, isArray, isBoolean, isError, isFiniteNumber, isInstance, isInteger, isJSONValue, isNumber, isObject, isRecord, isString, isUndefined, objectOf, parseJSON, sanitizeBudget } from "@orkestrel/contract";
|
|
2
2
|
import { decodeBase64, decodeUTF8, encodeBase64, encodeHex } from "@orkestrel/codec";
|
|
3
3
|
import { createSSEParser } from "@orkestrel/sse";
|
|
4
4
|
import { Emitter } from "@orkestrel/emitter";
|
|
@@ -325,11 +325,7 @@ var MCPError = class extends Error {
|
|
|
325
325
|
* ```
|
|
326
326
|
*/
|
|
327
327
|
function isMCPError(value) {
|
|
328
|
-
|
|
329
|
-
return value instanceof MCPError;
|
|
330
|
-
} catch {
|
|
331
|
-
return false;
|
|
332
|
-
}
|
|
328
|
+
return isInstance(value, MCPError);
|
|
333
329
|
}
|
|
334
330
|
//#endregion
|
|
335
331
|
//#region src/core/cloners.ts
|
|
@@ -580,7 +576,7 @@ function parseMCPInputState(value) {
|
|
|
580
576
|
const name = parsed["name"];
|
|
581
577
|
const digest = parsed["digest"];
|
|
582
578
|
const state = parsed["state"];
|
|
583
|
-
if (!isString(principal) || principal.length === 0 || !
|
|
579
|
+
if (!isString(principal) || principal.length === 0 || !isFiniteNumber(expiry)) return;
|
|
584
580
|
if (!isJSONRPCId(id)) return void 0;
|
|
585
581
|
if (!isString(version) || !isString(method) || !isString(name)) return void 0;
|
|
586
582
|
if (!isString(digest) || !isUndefined(state) && !isJSONValue(state)) return void 0;
|
|
@@ -743,9 +739,9 @@ function serializeJSON(value, limits) {
|
|
|
743
739
|
const limit = limits.bytes;
|
|
744
740
|
const depth = limits.depth;
|
|
745
741
|
const breadth = limits.keys;
|
|
746
|
-
if (!
|
|
747
|
-
if (!
|
|
748
|
-
if (breadth !== void 0 && (!
|
|
742
|
+
if (!isInteger(limit) || limit < 0) return void 0;
|
|
743
|
+
if (!isInteger(depth) || depth < 0) return void 0;
|
|
744
|
+
if (breadth !== void 0 && (!isInteger(breadth) || breadth < 0)) return void 0;
|
|
749
745
|
let bytes = 0;
|
|
750
746
|
let keys = 0;
|
|
751
747
|
const chunks = [];
|
|
@@ -859,7 +855,7 @@ function serializeJSON(value, limits) {
|
|
|
859
855
|
continue;
|
|
860
856
|
}
|
|
861
857
|
if (isNumber(entry)) {
|
|
862
|
-
if (!
|
|
858
|
+
if (!isFiniteNumber(entry)) return void 0;
|
|
863
859
|
const text = JSON.stringify(entry);
|
|
864
860
|
if (!isString(text)) return void 0;
|
|
865
861
|
bytes += text.length;
|
|
@@ -875,10 +871,10 @@ function serializeJSON(value, limits) {
|
|
|
875
871
|
});
|
|
876
872
|
continue;
|
|
877
873
|
}
|
|
878
|
-
if (
|
|
879
|
-
if (
|
|
874
|
+
if (!isObject(entry) || ancestors.has(entry)) return void 0;
|
|
875
|
+
if (isArray(entry)) {
|
|
880
876
|
const lengthDescriptor = Reflect.getOwnPropertyDescriptor(entry, "length");
|
|
881
|
-
if (lengthDescriptor === void 0 || !Object.hasOwn(lengthDescriptor, "value") || !isNumber(lengthDescriptor.value) || !
|
|
877
|
+
if (lengthDescriptor === void 0 || !Object.hasOwn(lengthDescriptor, "value") || !isNumber(lengthDescriptor.value) || !isInteger(lengthDescriptor.value) || lengthDescriptor.value < 0 || lengthDescriptor.value > 4294967295 || lengthDescriptor.enumerable === true || lengthDescriptor.configurable === true) return void 0;
|
|
882
878
|
const length = lengthDescriptor.value;
|
|
883
879
|
keys += length;
|
|
884
880
|
bytes += 2 + (length === 0 ? 0 : length - 1);
|
|
@@ -895,7 +891,7 @@ function serializeJSON(value, limits) {
|
|
|
895
891
|
continue;
|
|
896
892
|
}
|
|
897
893
|
const index = Number(name);
|
|
898
|
-
if (!
|
|
894
|
+
if (!isInteger(index) || index < 0 || index >= length || String(index) !== name) return void 0;
|
|
899
895
|
}
|
|
900
896
|
if (!foundLength) return void 0;
|
|
901
897
|
const values = [];
|
|
@@ -1116,10 +1112,9 @@ function buildCallOutcome(name, result) {
|
|
|
1116
1112
|
if (isRecord(result) && result["isError"] === true) throw new Error(text.length > 0 ? text : `MCP tool '${name}' failed`);
|
|
1117
1113
|
let value;
|
|
1118
1114
|
if (isRecord(result) && Object.hasOwn(result, "structuredContent")) value = result["structuredContent"];
|
|
1119
|
-
else if (text.length > 0)
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
value = text;
|
|
1115
|
+
else if (text.length > 0) {
|
|
1116
|
+
const parsed = parseJSON(text);
|
|
1117
|
+
value = parsed === void 0 ? text : parsed;
|
|
1123
1118
|
}
|
|
1124
1119
|
return Object.freeze({
|
|
1125
1120
|
resultType: "complete",
|
|
@@ -1135,7 +1130,7 @@ function buildCallOutcome(name, result) {
|
|
|
1135
1130
|
*/
|
|
1136
1131
|
function buildToolCall(request, args) {
|
|
1137
1132
|
const name = request.params?.["name"];
|
|
1138
|
-
if (
|
|
1133
|
+
if (!isString(name)) return void 0;
|
|
1139
1134
|
const rawArguments = request.params?.["arguments"];
|
|
1140
1135
|
return {
|
|
1141
1136
|
id: String(request.id),
|
|
@@ -1320,7 +1315,7 @@ function modernResultToLegacy(result) {
|
|
|
1320
1315
|
const projected = {};
|
|
1321
1316
|
for (const [key, value] of Object.entries(result)) {
|
|
1322
1317
|
if (key === "resultType" || key === "ttlMs" || key === "cacheScope") continue;
|
|
1323
|
-
if (key === "content" &&
|
|
1318
|
+
if (key === "content" && isArray(value)) {
|
|
1324
1319
|
projected[key] = value.map((entry) => isRecord(entry) && entry["type"] === "text" && isString(entry["text"]) ? {
|
|
1325
1320
|
type: "text",
|
|
1326
1321
|
text: entry["text"]
|
|
@@ -1433,7 +1428,7 @@ function matchesSubscriptionNotification(notification, filter) {
|
|
|
1433
1428
|
if (notification.method === "notifications/resources/list_changed") return filter.resourcesListChanged === true;
|
|
1434
1429
|
if (notification.method === "notifications/resources/updated") {
|
|
1435
1430
|
const uri = notification.params?.["uri"];
|
|
1436
|
-
return
|
|
1431
|
+
return isString(uri) && filter.resourceSubscriptions?.includes(uri) === true;
|
|
1437
1432
|
}
|
|
1438
1433
|
if (notification.method === "notifications/tasks") return isMCPTaskNotification(notification) && filter.taskIds?.includes(notification.params.taskId) === true;
|
|
1439
1434
|
return false;
|
|
@@ -2147,7 +2142,7 @@ function bindServer(server, transport) {
|
|
|
2147
2142
|
try {
|
|
2148
2143
|
const answer = await server.handle(message, { signal: request.signal });
|
|
2149
2144
|
if (answer === void 0) return;
|
|
2150
|
-
if (
|
|
2145
|
+
if (isString(answer)) {
|
|
2151
2146
|
if (!request.signal.aborted) await transport.send(answer);
|
|
2152
2147
|
} else if (request.signal.aborted) await answer[Symbol.asyncDispose]();
|
|
2153
2148
|
else await sendStream(answer, transport);
|
|
@@ -2548,7 +2543,7 @@ function isMCPAnnotations(value) {
|
|
|
2548
2543
|
const audience = annotations["audience"];
|
|
2549
2544
|
const priority = annotations["priority"];
|
|
2550
2545
|
const lastModified = annotations["lastModified"];
|
|
2551
|
-
if (!isUndefined(audience) && (!
|
|
2546
|
+
if (!isUndefined(audience) && (!isArray(audience) || !audience.every((role) => role === "user" || role === "assistant"))) return false;
|
|
2552
2547
|
if (!isUndefined(priority) && (!isFiniteNumber(priority) || priority < 0 || priority > 1)) return false;
|
|
2553
2548
|
return isUndefined(lastModified) || isString(lastModified);
|
|
2554
2549
|
} catch {
|
|
@@ -2570,7 +2565,7 @@ function isMCPIcon(value) {
|
|
|
2570
2565
|
const mimeType = icon["mimeType"];
|
|
2571
2566
|
const sizes = icon["sizes"];
|
|
2572
2567
|
const theme = icon["theme"];
|
|
2573
|
-
return (isUndefined(mimeType) || isString(mimeType)) && (isUndefined(sizes) ||
|
|
2568
|
+
return (isUndefined(mimeType) || isString(mimeType)) && (isUndefined(sizes) || isArray(sizes) && sizes.every((size) => isString(size))) && (isUndefined(theme) || theme === "light" || theme === "dark");
|
|
2574
2569
|
} catch {
|
|
2575
2570
|
return false;
|
|
2576
2571
|
}
|
|
@@ -2586,7 +2581,7 @@ function isMCPIdentity(value) {
|
|
|
2586
2581
|
const description = identity["description"];
|
|
2587
2582
|
const website = identity["websiteUrl"];
|
|
2588
2583
|
const icons = identity["icons"];
|
|
2589
|
-
return (isUndefined(title) || isString(title)) && (isUndefined(description) || isString(description)) && (isUndefined(website) || isAbsoluteURI(website)) && (isUndefined(icons) ||
|
|
2584
|
+
return (isUndefined(title) || isString(title)) && (isUndefined(description) || isString(description)) && (isUndefined(website) || isAbsoluteURI(website)) && (isUndefined(icons) || isArray(icons) && icons.every((icon) => isMCPIcon(icon)));
|
|
2590
2585
|
} catch {
|
|
2591
2586
|
return false;
|
|
2592
2587
|
}
|
|
@@ -2697,7 +2692,7 @@ function isMCPResource(value) {
|
|
|
2697
2692
|
const resource = owned.value;
|
|
2698
2693
|
const icons = resource["icons"];
|
|
2699
2694
|
const size = resource["size"];
|
|
2700
|
-
return isAbsoluteURI(resource["uri"]) && isString(resource["name"]) && (isUndefined(resource["title"]) || isString(resource["title"])) && (isUndefined(resource["description"]) || isString(resource["description"])) && (isUndefined(resource["mimeType"]) || isString(resource["mimeType"])) && (isUndefined(resource["annotations"]) || isMCPAnnotations(resource["annotations"])) && (isUndefined(size) || isInteger(size) && size >= 0) && (isUndefined(icons) ||
|
|
2695
|
+
return isAbsoluteURI(resource["uri"]) && isString(resource["name"]) && (isUndefined(resource["title"]) || isString(resource["title"])) && (isUndefined(resource["description"]) || isString(resource["description"])) && (isUndefined(resource["mimeType"]) || isString(resource["mimeType"])) && (isUndefined(resource["annotations"]) || isMCPAnnotations(resource["annotations"])) && (isUndefined(size) || isInteger(size) && size >= 0) && (isUndefined(icons) || isArray(icons) && icons.every((icon) => isMCPIcon(icon))) && (isUndefined(resource["_meta"]) || isMCPMetaObject(resource["_meta"]));
|
|
2701
2696
|
} catch {
|
|
2702
2697
|
return false;
|
|
2703
2698
|
}
|
|
@@ -2740,7 +2735,7 @@ function isMCPResourceTemplate(value) {
|
|
|
2740
2735
|
try {
|
|
2741
2736
|
const template = owned.value;
|
|
2742
2737
|
const icons = template["icons"];
|
|
2743
|
-
return isString(template["uriTemplate"]) && template["uriTemplate"].length > 0 && isString(template["name"]) && (isUndefined(template["title"]) || isString(template["title"])) && (isUndefined(template["description"]) || isString(template["description"])) && (isUndefined(template["mimeType"]) || isString(template["mimeType"])) && (isUndefined(template["annotations"]) || isMCPAnnotations(template["annotations"])) && (isUndefined(icons) ||
|
|
2738
|
+
return isString(template["uriTemplate"]) && template["uriTemplate"].length > 0 && isString(template["name"]) && (isUndefined(template["title"]) || isString(template["title"])) && (isUndefined(template["description"]) || isString(template["description"])) && (isUndefined(template["mimeType"]) || isString(template["mimeType"])) && (isUndefined(template["annotations"]) || isMCPAnnotations(template["annotations"])) && (isUndefined(icons) || isArray(icons) && icons.every((icon) => isMCPIcon(icon))) && (isUndefined(template["_meta"]) || isMCPMetaObject(template["_meta"]));
|
|
2744
2739
|
} catch {
|
|
2745
2740
|
return false;
|
|
2746
2741
|
}
|
|
@@ -2780,7 +2775,7 @@ function isMCPResourcePage(value) {
|
|
|
2780
2775
|
if (!owned.success) return false;
|
|
2781
2776
|
const resources = owned.value["resources"];
|
|
2782
2777
|
const cursor = owned.value["nextCursor"];
|
|
2783
|
-
return
|
|
2778
|
+
return isArray(resources) && resources.every((resource) => isMCPResource(resource)) && (isUndefined(cursor) || isString(cursor));
|
|
2784
2779
|
}
|
|
2785
2780
|
/**
|
|
2786
2781
|
* Determines whether a value is one consumer-owned resource-template page.
|
|
@@ -2793,7 +2788,7 @@ function isMCPResourceTemplatePage(value) {
|
|
|
2793
2788
|
if (!owned.success) return false;
|
|
2794
2789
|
const templates = owned.value["resourceTemplates"];
|
|
2795
2790
|
const cursor = owned.value["nextCursor"];
|
|
2796
|
-
return
|
|
2791
|
+
return isArray(templates) && templates.every((template) => isMCPResourceTemplate(template)) && (isUndefined(cursor) || isString(cursor));
|
|
2797
2792
|
}
|
|
2798
2793
|
/**
|
|
2799
2794
|
* Determines whether a value is a string-valued MCP argument record.
|
|
@@ -2829,7 +2824,7 @@ function isMCPPrompt(value) {
|
|
|
2829
2824
|
const prompt = owned.value;
|
|
2830
2825
|
const argumentsValue = prompt["arguments"];
|
|
2831
2826
|
const icons = prompt["icons"];
|
|
2832
|
-
return isString(prompt["name"]) && (isUndefined(prompt["title"]) || isString(prompt["title"])) && (isUndefined(prompt["description"]) || isString(prompt["description"])) && (isUndefined(argumentsValue) ||
|
|
2827
|
+
return isString(prompt["name"]) && (isUndefined(prompt["title"]) || isString(prompt["title"])) && (isUndefined(prompt["description"]) || isString(prompt["description"])) && (isUndefined(argumentsValue) || isArray(argumentsValue) && argumentsValue.every((argument) => isMCPPromptArgument(argument))) && (isUndefined(icons) || isArray(icons) && icons.every((icon) => isMCPIcon(icon))) && (isUndefined(prompt["_meta"]) || isMCPMetaObject(prompt["_meta"]));
|
|
2833
2828
|
}
|
|
2834
2829
|
/**
|
|
2835
2830
|
* Determines whether a value is one prompt message with existing rich content.
|
|
@@ -2852,7 +2847,7 @@ function isMCPPromptPage(value) {
|
|
|
2852
2847
|
if (!owned.success) return false;
|
|
2853
2848
|
const prompts = owned.value["prompts"];
|
|
2854
2849
|
const cursor = owned.value["nextCursor"];
|
|
2855
|
-
return
|
|
2850
|
+
return isArray(prompts) && prompts.every((prompt) => isMCPPrompt(prompt)) && (isUndefined(cursor) || isString(cursor));
|
|
2856
2851
|
}
|
|
2857
2852
|
/**
|
|
2858
2853
|
* Determines whether a value is one complete `prompts/get` result.
|
|
@@ -2865,7 +2860,7 @@ function isMCPPromptGetResult(value) {
|
|
|
2865
2860
|
if (!owned.success) return false;
|
|
2866
2861
|
const result = owned.value;
|
|
2867
2862
|
const messages = result["messages"];
|
|
2868
|
-
return result["resultType"] === "complete" && (isUndefined(result["description"]) || isString(result["description"])) &&
|
|
2863
|
+
return result["resultType"] === "complete" && (isUndefined(result["description"]) || isString(result["description"])) && isArray(messages) && messages.every((message) => isMCPPromptMessage(message)) && (isUndefined(result["_meta"]) || isMCPResultMetaObject(result["_meta"]));
|
|
2869
2864
|
}
|
|
2870
2865
|
/**
|
|
2871
2866
|
* Determines whether a value is a prompt or resource-template completion reference.
|
|
@@ -2910,7 +2905,7 @@ function isMCPCompletion(value) {
|
|
|
2910
2905
|
const completion = owned.value;
|
|
2911
2906
|
const values = completion["values"];
|
|
2912
2907
|
const total = completion["total"];
|
|
2913
|
-
return
|
|
2908
|
+
return isArray(values) && values.every((candidate) => isString(candidate)) && (isUndefined(total) || isInteger(total) && total >= 0) && (isUndefined(completion["hasMore"]) || isBoolean(completion["hasMore"]));
|
|
2914
2909
|
}
|
|
2915
2910
|
/**
|
|
2916
2911
|
* Determines whether a value is one complete, capped `completion/complete` result.
|
|
@@ -2948,7 +2943,7 @@ function isMCPContent(value) {
|
|
|
2948
2943
|
case "resource_link": {
|
|
2949
2944
|
const icons = content["icons"];
|
|
2950
2945
|
const size = content["size"];
|
|
2951
|
-
return isString(content["name"]) && isAbsoluteURI(content["uri"]) && (isUndefined(content["title"]) || isString(content["title"])) && (isUndefined(content["description"]) || isString(content["description"])) && (isUndefined(content["mimeType"]) || isString(content["mimeType"])) && (isUndefined(icons) ||
|
|
2946
|
+
return isString(content["name"]) && isAbsoluteURI(content["uri"]) && (isUndefined(content["title"]) || isString(content["title"])) && (isUndefined(content["description"]) || isString(content["description"])) && (isUndefined(content["mimeType"]) || isString(content["mimeType"])) && (isUndefined(icons) || isArray(icons) && icons.every((icon) => isMCPIcon(icon))) && (isUndefined(size) || isInteger(size) && size >= 0);
|
|
2952
2947
|
}
|
|
2953
2948
|
default: return false;
|
|
2954
2949
|
}
|
|
@@ -3022,7 +3017,7 @@ function isMCPCallResult(value) {
|
|
|
3022
3017
|
const content = result["content"];
|
|
3023
3018
|
const error = result["isError"];
|
|
3024
3019
|
const metadata = result["_meta"];
|
|
3025
|
-
return
|
|
3020
|
+
return isArray(content) && content.every((entry) => isMCPContent(entry)) && (isUndefined(error) || isBoolean(error)) && (isUndefined(metadata) || isMCPResultMetaObject(metadata));
|
|
3026
3021
|
} catch {
|
|
3027
3022
|
return false;
|
|
3028
3023
|
}
|
|
@@ -3211,7 +3206,7 @@ function isMCPTaskNotification(value) {
|
|
|
3211
3206
|
* ```
|
|
3212
3207
|
*/
|
|
3213
3208
|
function isBoundedString(value, bytes) {
|
|
3214
|
-
if (!isString(value) || !
|
|
3209
|
+
if (!isString(value) || !isInteger(bytes) || bytes < 0) return false;
|
|
3215
3210
|
let measured = 0;
|
|
3216
3211
|
for (let index = 0; index < value.length; index += 1) {
|
|
3217
3212
|
const code = value.charCodeAt(index);
|
|
@@ -3396,21 +3391,21 @@ function isMCPElicitFieldSchema(value) {
|
|
|
3396
3391
|
const names = schema["enumNames"];
|
|
3397
3392
|
const titled = schema["oneOf"];
|
|
3398
3393
|
if (!isUndefined(minimum) && (!isInteger(minimum) || minimum < 0) || !isUndefined(maximum) && (!isInteger(maximum) || maximum < 0) || !isUndefined(fallback) && !isString(fallback) || !isUndefined(format) && format !== "uri" && format !== "email" && format !== "date" && format !== "date-time") return false;
|
|
3399
|
-
if (!isUndefined(choices) && (!
|
|
3400
|
-
if (!isUndefined(names) && (isUndefined(choices) || !
|
|
3401
|
-
return !(!isUndefined(titled) && (!
|
|
3394
|
+
if (!isUndefined(choices) && (!isArray(choices) || !choices.every(isString))) return false;
|
|
3395
|
+
if (!isUndefined(names) && (isUndefined(choices) || !isArray(names) || !names.every(isString))) return false;
|
|
3396
|
+
return !(!isUndefined(titled) && (!isArray(titled) || !titled.every((choice) => isJSONObject(choice) && isString(choice["const"]) && isString(choice["title"]))));
|
|
3402
3397
|
}
|
|
3403
3398
|
if (schema["type"] !== "array") return false;
|
|
3404
3399
|
const minimum = schema["minItems"];
|
|
3405
3400
|
const maximum = schema["maxItems"];
|
|
3406
3401
|
const items = schema["items"];
|
|
3407
|
-
if (!isUndefined(minimum) && (!isInteger(minimum) || minimum < 0) || !isUndefined(maximum) && (!isInteger(maximum) || maximum < 0) || !isUndefined(fallback) && (!
|
|
3402
|
+
if (!isUndefined(minimum) && (!isInteger(minimum) || minimum < 0) || !isUndefined(maximum) && (!isInteger(maximum) || maximum < 0) || !isUndefined(fallback) && (!isArray(fallback) || !fallback.every((item) => isString(item))) || !isJSONObject(items)) return false;
|
|
3408
3403
|
const itemType = items["type"];
|
|
3409
3404
|
const choices = items["enum"];
|
|
3410
3405
|
const titled = items["anyOf"];
|
|
3411
3406
|
if (!isUndefined(itemType) && itemType !== "string") return false;
|
|
3412
|
-
if (!isUndefined(choices) && (!
|
|
3413
|
-
if (!isUndefined(titled) && (!
|
|
3407
|
+
if (!isUndefined(choices) && (!isArray(choices) || !choices.every(isString))) return false;
|
|
3408
|
+
if (!isUndefined(titled) && (!isArray(titled) || !titled.every((choice) => isJSONObject(choice) && isString(choice["const"]) && isString(choice["title"])))) return false;
|
|
3414
3409
|
return itemType === "string" && !isUndefined(choices) || !isUndefined(titled);
|
|
3415
3410
|
} catch {
|
|
3416
3411
|
return false;
|
|
@@ -3445,7 +3440,7 @@ function isMCPElicitSchema(value) {
|
|
|
3445
3440
|
const dialect = schema["$schema"];
|
|
3446
3441
|
if (!isUndefined(dialect) && !isString(dialect)) return false;
|
|
3447
3442
|
const required = schema["required"];
|
|
3448
|
-
return (isUndefined(required) ||
|
|
3443
|
+
return (isUndefined(required) || isArray(required) && required.every((name) => isString(name))) && Object.values(properties).every((property) => isMCPElicitFieldSchema(property));
|
|
3449
3444
|
} catch {
|
|
3450
3445
|
return false;
|
|
3451
3446
|
}
|
|
@@ -3588,7 +3583,7 @@ function isMCPElicitResult(value) {
|
|
|
3588
3583
|
if (action !== "accept") return isUndefined(content);
|
|
3589
3584
|
if (isUndefined(content)) return true;
|
|
3590
3585
|
if (!isJSONObject(content)) return false;
|
|
3591
|
-
return Object.values(content).every((item) => isString(item) || isFiniteNumber(item) || isBoolean(item) ||
|
|
3586
|
+
return Object.values(content).every((item) => isString(item) || isFiniteNumber(item) || isBoolean(item) || isArray(item) && item.every((entry) => isString(entry)));
|
|
3592
3587
|
} catch {
|
|
3593
3588
|
return false;
|
|
3594
3589
|
}
|
|
@@ -3643,11 +3638,11 @@ function isElicitContent(value, schema) {
|
|
|
3643
3638
|
const properties = declared.value["properties"];
|
|
3644
3639
|
const required = declared.value["required"];
|
|
3645
3640
|
if (!isJSONObject(properties)) return false;
|
|
3646
|
-
if (
|
|
3641
|
+
if (isArray(required)) {
|
|
3647
3642
|
for (const name of required) if (!isString(name) || !Object.hasOwn(content, name)) return false;
|
|
3648
3643
|
}
|
|
3649
3644
|
for (const [name, item] of Object.entries(content)) {
|
|
3650
|
-
if (!isString(item) && !isFiniteNumber(item) && !isBoolean(item) && !(
|
|
3645
|
+
if (!isString(item) && !isFiniteNumber(item) && !isBoolean(item) && !(isArray(item) && item.every((entry) => isString(entry)))) return false;
|
|
3651
3646
|
if (!Object.hasOwn(properties, name)) continue;
|
|
3652
3647
|
const field = properties[name];
|
|
3653
3648
|
if (!isJSONObject(field)) return false;
|
|
@@ -3660,7 +3655,7 @@ function isElicitContent(value, schema) {
|
|
|
3660
3655
|
const minimum = field["minimum"];
|
|
3661
3656
|
const maximum = field["maximum"];
|
|
3662
3657
|
if (!isFiniteNumber(item)) return false;
|
|
3663
|
-
if (declaredType === "integer" && !
|
|
3658
|
+
if (declaredType === "integer" && !isInteger(item)) return false;
|
|
3664
3659
|
if (isFiniteNumber(minimum) && item < minimum) return false;
|
|
3665
3660
|
if (isFiniteNumber(maximum) && item > maximum) return false;
|
|
3666
3661
|
continue;
|
|
@@ -3672,8 +3667,8 @@ function isElicitContent(value, schema) {
|
|
|
3672
3667
|
const maximum = field["maxLength"];
|
|
3673
3668
|
const format = field["format"];
|
|
3674
3669
|
if (!isString(item)) return false;
|
|
3675
|
-
if (
|
|
3676
|
-
if (
|
|
3670
|
+
if (isArray(choices) && !choices.includes(item)) return false;
|
|
3671
|
+
if (isArray(titled) && !titled.some((choice) => isJSONObject(choice) && choice["const"] === item)) return false;
|
|
3677
3672
|
const length = Array.from(item).length;
|
|
3678
3673
|
if (isInteger(minimum) && length < minimum) return false;
|
|
3679
3674
|
if (isInteger(maximum) && length > maximum) return false;
|
|
@@ -3686,14 +3681,14 @@ function isElicitContent(value, schema) {
|
|
|
3686
3681
|
const items = field["items"];
|
|
3687
3682
|
const minimum = field["minItems"];
|
|
3688
3683
|
const maximum = field["maxItems"];
|
|
3689
|
-
if (!
|
|
3684
|
+
if (!isArray(item) || !item.every((entry) => isString(entry))) return false;
|
|
3690
3685
|
if (isInteger(minimum) && item.length < minimum) return false;
|
|
3691
3686
|
if (isInteger(maximum) && item.length > maximum) return false;
|
|
3692
3687
|
if (!isJSONObject(items)) return false;
|
|
3693
3688
|
const choices = items["enum"];
|
|
3694
3689
|
const titled = items["anyOf"];
|
|
3695
|
-
if (
|
|
3696
|
-
if (
|
|
3690
|
+
if (isArray(choices) && !item.every((entry) => choices.includes(entry))) return false;
|
|
3691
|
+
if (isArray(titled) && !item.every((entry) => titled.some((choice) => isJSONObject(choice) && choice["const"] === entry))) return false;
|
|
3697
3692
|
}
|
|
3698
3693
|
return true;
|
|
3699
3694
|
} catch {
|
|
@@ -3754,7 +3749,7 @@ function isMCPRootResult(value) {
|
|
|
3754
3749
|
const result = owned.value;
|
|
3755
3750
|
const roots = result["roots"];
|
|
3756
3751
|
const metadata = result["_meta"];
|
|
3757
|
-
if (!
|
|
3752
|
+
if (!isArray(roots) || !roots.every((root) => isMCPRoot(root))) return false;
|
|
3758
3753
|
return isUndefined(metadata) || isMCPMetaObject(metadata);
|
|
3759
3754
|
} catch {
|
|
3760
3755
|
return false;
|
|
@@ -3792,7 +3787,7 @@ function isMCPSampleContent(value) {
|
|
|
3792
3787
|
if (block["type"] === "tool_result") {
|
|
3793
3788
|
const carried = block["content"];
|
|
3794
3789
|
const failed = block["isError"];
|
|
3795
|
-
if (!
|
|
3790
|
+
if (!isArray(carried) || !carried.every((entry) => isMCPContent(entry))) return false;
|
|
3796
3791
|
if (!isUndefined(failed) && !isBoolean(failed)) return false;
|
|
3797
3792
|
return isString(block["toolUseId"]);
|
|
3798
3793
|
}
|
|
@@ -3841,7 +3836,7 @@ function isMCPSampleResult(value) {
|
|
|
3841
3836
|
const metadata = result["_meta"];
|
|
3842
3837
|
if (role !== "user" && role !== "assistant") return false;
|
|
3843
3838
|
if (!isString(result["model"])) return false;
|
|
3844
|
-
if (!(
|
|
3839
|
+
if (!(isArray(content) ? content : [content]).every((block) => isMCPSampleContent(block))) return false;
|
|
3845
3840
|
if (!isUndefined(reason) && !isString(reason)) return false;
|
|
3846
3841
|
return isUndefined(metadata) || isMCPMetaObject(metadata);
|
|
3847
3842
|
} catch {
|
|
@@ -5254,7 +5249,7 @@ var MCPServer = class {
|
|
|
5254
5249
|
const input = captured[0];
|
|
5255
5250
|
return this.#forward(input, request);
|
|
5256
5251
|
}
|
|
5257
|
-
if (!
|
|
5252
|
+
if (!isArray(captured[0]) || !captured[0].every((entry) => isMCPResourceContents(entry))) return buildJSONRPCError(request.id, JSONRPC_INTERNAL_ERROR, "Server resource manager returned invalid or oversized contents");
|
|
5258
5253
|
const result = buildModernResult({ contents: captured[0] }, this.#options.identity, this.#options.cache?.ttl ?? 6e4, this.#options.cache?.scope);
|
|
5259
5254
|
return buildJSONRPCResult(request.id, result);
|
|
5260
5255
|
}
|
|
@@ -5337,7 +5332,7 @@ var MCPServer = class {
|
|
|
5337
5332
|
const generated = await manager.complete(params, options);
|
|
5338
5333
|
if (generated === void 0) return buildJSONRPCError(request.id, JSONRPC_INVALID_PARAMS, "Completion reference not found");
|
|
5339
5334
|
const candidate = generated;
|
|
5340
|
-
if (!isRecord(candidate) || !
|
|
5335
|
+
if (!isRecord(candidate) || !isArray(candidate["values"])) return buildJSONRPCError(request.id, JSONRPC_INTERNAL_ERROR, "Server completion manager returned invalid or oversized candidates");
|
|
5341
5336
|
const values = candidate["values"];
|
|
5342
5337
|
const truncated = values.length > 100;
|
|
5343
5338
|
const captured = snapshotJSON({
|
|
@@ -5370,7 +5365,7 @@ var MCPServer = class {
|
|
|
5370
5365
|
if (deferred !== void 0) return deferred;
|
|
5371
5366
|
const token = params?.["_meta"];
|
|
5372
5367
|
const progressToken = isRecord(token) ? token["progressToken"] : void 0;
|
|
5373
|
-
if (this.#options.execution !== void 0 && (isString(progressToken) ||
|
|
5368
|
+
if (this.#options.execution !== void 0 && (isString(progressToken) || isInteger(progressToken))) return this.#progress(request, call, progressToken, options);
|
|
5374
5369
|
const result = await this.#execute(request, call, options);
|
|
5375
5370
|
return "jsonrpc" in result ? result : buildJSONRPCResult(id, result);
|
|
5376
5371
|
}
|
|
@@ -5583,7 +5578,7 @@ var MCPServer = class {
|
|
|
5583
5578
|
bytes: this.#limits.message,
|
|
5584
5579
|
depth: this.#limits.depth
|
|
5585
5580
|
});
|
|
5586
|
-
if (configured === void 0 || context === void 0 || !isString(principal) || principal.length === 0 || !
|
|
5581
|
+
if (configured === void 0 || context === void 0 || !isString(principal) || principal.length === 0 || !isFiniteNumber(configured.ttl) || configured.ttl <= 0) return buildJSONRPCError(id, JSONRPC_INVALID_PARAMS, "Invalid params: input policy returned an invalid round or continuation context");
|
|
5587
5582
|
if (previous !== void 0 && previous <= Date.now()) return buildJSONRPCError(id, JSONRPC_INVALID_PARAMS, "Invalid params: request state could not be verified for this retry");
|
|
5588
5583
|
const expiry = Date.now() + configured.ttl;
|
|
5589
5584
|
const protectedState = {
|
|
@@ -6221,7 +6216,7 @@ var MCPClient = class {
|
|
|
6221
6216
|
...report === void 0 ? {} : { progress: report }
|
|
6222
6217
|
});
|
|
6223
6218
|
this.#transport.send(request).catch((error) => {
|
|
6224
|
-
this.#settle(id, error
|
|
6219
|
+
this.#settle(id, isError(error) ? error : new Error(String(error)), true);
|
|
6225
6220
|
});
|
|
6226
6221
|
});
|
|
6227
6222
|
}
|