tiny-stdio-mcp-server 0.1.15 → 0.1.16
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 +6 -2
- package/dist/server.js +135 -150
- package/dist/types.d.ts +1 -4
- package/dist/types.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -58,7 +58,7 @@ server.tool("search", "Search for things", schema, async ({ query, limit }) => {
|
|
|
58
58
|
});
|
|
59
59
|
```
|
|
60
60
|
|
|
61
|
-
For structured-data tools, pass a root-object output schema. The server advertises it as MCP `Tool.outputSchema`, validates
|
|
61
|
+
For structured-data tools, pass a root-object output schema. The server advertises it as MCP `Tool.outputSchema`, validates successful handler results, and returns them as `CallToolResult.structuredContent`. Plain object returns receive a JSON text backstop in `content[]` for older clients. Explicit `CallToolResult` values keep their handler-supplied content blocks; the JSON text backstop is added only when `content` is empty.
|
|
62
62
|
|
|
63
63
|
```ts
|
|
64
64
|
const input = defineSchema({
|
|
@@ -89,7 +89,11 @@ server.tool(
|
|
|
89
89
|
);
|
|
90
90
|
```
|
|
91
91
|
|
|
92
|
-
Output schemas must have `type: "object"` at the root
|
|
92
|
+
Output schemas must have `type: "object"` at the root because MCP structured content is an object. Otherwise, any schema accepted by Ajv is supported, including composition keywords, nullable type unions, and local `$defs`/`$ref` references. Input and output schemas compile synchronously during `.tool()` or `.registerTool()` registration, so malformed schemas throw immediately instead of failing on the first tool call.
|
|
93
|
+
|
|
94
|
+
Successful structured results must satisfy `outputSchema`. Validation failures use JSON-RPC `-32602` for inputs and `-32603` for outputs, with Ajv's formatted error text in the message and the raw Ajv error array in `error.data`. Explicit handler results with `isError: true` are passed through unchanged and are exempt from structured-content and output-schema validation.
|
|
95
|
+
|
|
96
|
+
Tools whose natural result is prose, images, audio, files, or other content blocks should omit `outputSchema` and keep returning content.
|
|
93
97
|
|
|
94
98
|
### `.listen()`
|
|
95
99
|
|
package/dist/server.js
CHANGED
|
@@ -47,7 +47,8 @@ export function createServer(options) {
|
|
|
47
47
|
? params.protocolVersion
|
|
48
48
|
: undefined;
|
|
49
49
|
const result = {
|
|
50
|
-
protocolVersion: requestedProtocol !== undefined &&
|
|
50
|
+
protocolVersion: requestedProtocol !== undefined &&
|
|
51
|
+
SUPPORTED_PROTOCOL_VERSIONS.has(requestedProtocol)
|
|
51
52
|
? requestedProtocol
|
|
52
53
|
: PROTOCOL_VERSION,
|
|
53
54
|
capabilities: {
|
|
@@ -95,6 +96,9 @@ export function createServer(options) {
|
|
|
95
96
|
for (const tool of tools.values()) {
|
|
96
97
|
const descriptor = { ...tool };
|
|
97
98
|
delete descriptor.handler;
|
|
99
|
+
delete descriptor.inputValidator;
|
|
100
|
+
delete descriptor
|
|
101
|
+
.outputValidator;
|
|
98
102
|
toolList.push({
|
|
99
103
|
...descriptor,
|
|
100
104
|
});
|
|
@@ -121,19 +125,25 @@ export function createServer(options) {
|
|
|
121
125
|
};
|
|
122
126
|
}
|
|
123
127
|
const toolArgs = (params?.arguments ?? {});
|
|
124
|
-
if (options.validateToolArguments !== false &&
|
|
128
|
+
if (options.validateToolArguments !== false &&
|
|
129
|
+
!tool.inputValidator(toolArgs)) {
|
|
130
|
+
const errors = tool.inputValidator.errors ?? [];
|
|
125
131
|
return {
|
|
126
132
|
error: {
|
|
127
133
|
code: JSON_RPC_ERROR_CODES.INVALID_PARAMS,
|
|
128
|
-
message:
|
|
134
|
+
message: `Invalid tool arguments: ${jsonSchemaValidator.errorsText(errors)}`,
|
|
135
|
+
data: errors,
|
|
129
136
|
},
|
|
130
137
|
};
|
|
131
138
|
}
|
|
132
139
|
try {
|
|
133
140
|
const handlerResult = await tool.handler(toolArgs);
|
|
134
141
|
const result = normalizeToolResult(handlerResult, tool.outputSchema);
|
|
135
|
-
if (
|
|
136
|
-
|
|
142
|
+
if (result.isError !== true &&
|
|
143
|
+
tool.outputValidator !== undefined &&
|
|
144
|
+
!tool.outputValidator(result.structuredContent)) {
|
|
145
|
+
const errors = tool.outputValidator.errors ?? [];
|
|
146
|
+
throw new ToolError(JSON_RPC_ERROR_CODES.INTERNAL_ERROR, `Invalid structured tool result: ${jsonSchemaValidator.errorsText(errors)}`, errors);
|
|
137
147
|
}
|
|
138
148
|
return { result };
|
|
139
149
|
}
|
|
@@ -220,7 +230,8 @@ export function createServer(options) {
|
|
|
220
230
|
return internalError(toErrorMessage(error));
|
|
221
231
|
}
|
|
222
232
|
}
|
|
223
|
-
if (method === "resources/subscribe" ||
|
|
233
|
+
if (method === "resources/subscribe" ||
|
|
234
|
+
method === "resources/unsubscribe") {
|
|
224
235
|
if (!supportResourceSubscriptions) {
|
|
225
236
|
return {
|
|
226
237
|
error: {
|
|
@@ -233,8 +244,8 @@ export function createServer(options) {
|
|
|
233
244
|
if (uri === undefined || !isValidUri(uri)) {
|
|
234
245
|
return invalidParams("Resource URI required");
|
|
235
246
|
}
|
|
236
|
-
if (method === "resources/subscribe"
|
|
237
|
-
|
|
247
|
+
if (method === "resources/subscribe" &&
|
|
248
|
+
findReadableResource(uri, resources, resourceTemplates) === undefined) {
|
|
238
249
|
return resourceNotFound(uri);
|
|
239
250
|
}
|
|
240
251
|
if (method === "resources/subscribe") {
|
|
@@ -336,26 +347,38 @@ export function createServer(options) {
|
|
|
336
347
|
const server = {
|
|
337
348
|
tool(name, description, inputSchema, handler, outputSchema) {
|
|
338
349
|
assertNonEmptyName(name, "Tool name required");
|
|
350
|
+
const inputValidator = jsonSchemaValidator.compile(inputSchema);
|
|
351
|
+
let outputValidator;
|
|
339
352
|
if (outputSchema !== undefined) {
|
|
340
|
-
|
|
353
|
+
assertObjectRootSchema(outputSchema, "outputSchema");
|
|
354
|
+
outputValidator = jsonSchemaValidator.compile(outputSchema);
|
|
341
355
|
}
|
|
342
356
|
tools.set(name, {
|
|
343
357
|
name,
|
|
344
358
|
description,
|
|
345
359
|
inputSchema: inputSchema,
|
|
346
|
-
...(outputSchema === undefined
|
|
360
|
+
...(outputSchema === undefined
|
|
361
|
+
? {}
|
|
362
|
+
: { outputSchema: outputSchema }),
|
|
347
363
|
handler: handler,
|
|
364
|
+
inputValidator,
|
|
365
|
+
...(outputValidator === undefined ? {} : { outputValidator }),
|
|
348
366
|
});
|
|
349
367
|
return server;
|
|
350
368
|
},
|
|
351
369
|
registerTool(definition, handler) {
|
|
352
370
|
assertNonEmptyName(definition.name, "Tool name required");
|
|
371
|
+
const inputValidator = jsonSchemaValidator.compile(definition.inputSchema);
|
|
372
|
+
let outputValidator;
|
|
353
373
|
if (definition.outputSchema !== undefined) {
|
|
354
|
-
|
|
374
|
+
assertObjectRootSchema(definition.outputSchema, "outputSchema");
|
|
375
|
+
outputValidator = jsonSchemaValidator.compile(definition.outputSchema);
|
|
355
376
|
}
|
|
356
377
|
tools.set(definition.name, {
|
|
357
378
|
...definition,
|
|
358
379
|
handler: handler,
|
|
380
|
+
inputValidator,
|
|
381
|
+
...(outputValidator === undefined ? {} : { outputValidator }),
|
|
359
382
|
});
|
|
360
383
|
return server;
|
|
361
384
|
},
|
|
@@ -396,17 +419,20 @@ export function createServer(options) {
|
|
|
396
419
|
return resourceTemplates.delete(uriTemplate);
|
|
397
420
|
},
|
|
398
421
|
async notifyToolsChanged() {
|
|
399
|
-
if (supportNotifications &&
|
|
422
|
+
if (supportNotifications &&
|
|
423
|
+
[...messageLifecycles].some((lifecycle) => lifecycle.notificationReady)) {
|
|
400
424
|
await broadcastNotification("notifications/tools/list_changed");
|
|
401
425
|
}
|
|
402
426
|
},
|
|
403
427
|
async notifyPromptsChanged() {
|
|
404
|
-
if (supportNotifications &&
|
|
428
|
+
if (supportNotifications &&
|
|
429
|
+
[...messageLifecycles].some((lifecycle) => lifecycle.notificationReady)) {
|
|
405
430
|
await broadcastNotification("notifications/prompts/list_changed");
|
|
406
431
|
}
|
|
407
432
|
},
|
|
408
433
|
async notifyResourcesChanged() {
|
|
409
|
-
if (supportNotifications &&
|
|
434
|
+
if (supportNotifications &&
|
|
435
|
+
[...messageLifecycles].some((lifecycle) => lifecycle.notificationReady)) {
|
|
410
436
|
await broadcastNotification("notifications/resources/list_changed");
|
|
411
437
|
}
|
|
412
438
|
},
|
|
@@ -617,14 +643,14 @@ function isCallToolResult(value) {
|
|
|
617
643
|
if (!hasContentArray(value) || !value.content.every(isContentItem)) {
|
|
618
644
|
return false;
|
|
619
645
|
}
|
|
620
|
-
if (hasOwnProperty(value, "structuredContent")
|
|
621
|
-
|
|
622
|
-
|
|
646
|
+
if (hasOwnProperty(value, "structuredContent") &&
|
|
647
|
+
value.structuredContent !== undefined &&
|
|
648
|
+
!isJsonObject(value.structuredContent)) {
|
|
623
649
|
return false;
|
|
624
650
|
}
|
|
625
|
-
return !(hasOwnProperty(value, "isError")
|
|
626
|
-
|
|
627
|
-
|
|
651
|
+
return !(hasOwnProperty(value, "isError") &&
|
|
652
|
+
value.isError !== undefined &&
|
|
653
|
+
typeof value.isError !== "boolean");
|
|
628
654
|
}
|
|
629
655
|
function normalizeToolResult(handlerResult, outputSchema) {
|
|
630
656
|
if (hasContentArray(handlerResult) && !isCallToolResult(handlerResult)) {
|
|
@@ -639,131 +665,71 @@ function normalizeToolResult(handlerResult, outputSchema) {
|
|
|
639
665
|
}
|
|
640
666
|
return result;
|
|
641
667
|
}
|
|
642
|
-
|
|
643
|
-
|
|
668
|
+
if (isCallToolResult(handlerResult) && handlerResult.isError === true) {
|
|
669
|
+
return handlerResult;
|
|
670
|
+
}
|
|
671
|
+
const callToolResult = isCallToolResult(handlerResult)
|
|
672
|
+
? handlerResult
|
|
673
|
+
: undefined;
|
|
674
|
+
const structuredContent = callToolResult
|
|
675
|
+
? callToolResult.structuredContent
|
|
644
676
|
: handlerResult;
|
|
645
677
|
if (!isJsonObject(structuredContent)) {
|
|
646
678
|
throw new ToolError(JSON_RPC_ERROR_CODES.INTERNAL_ERROR, "Structured tool result must be an object");
|
|
647
679
|
}
|
|
648
680
|
return {
|
|
649
|
-
content:
|
|
650
|
-
|
|
651
|
-
|
|
681
|
+
content: callToolResult !== undefined && callToolResult.content.length > 0
|
|
682
|
+
? callToolResult.content
|
|
683
|
+
: [{ type: "text", text: JSON.stringify(structuredContent) }],
|
|
684
|
+
...(callToolResult?.isError !== undefined
|
|
685
|
+
? { isError: callToolResult.isError }
|
|
652
686
|
: {}),
|
|
653
687
|
structuredContent,
|
|
654
688
|
};
|
|
655
689
|
}
|
|
656
|
-
function assertSupportedOutputSchema(schema) {
|
|
657
|
-
assertObjectRootSchema(schema, "outputSchema");
|
|
658
|
-
assertSupportedJsonSchema(schema, "outputSchema");
|
|
659
|
-
}
|
|
660
690
|
function assertObjectRootSchema(schema, path) {
|
|
661
691
|
if (schema.type !== "object") {
|
|
662
692
|
throw new Error(`${path} root type must be "object"`);
|
|
663
693
|
}
|
|
664
694
|
}
|
|
665
|
-
function assertSupportedJsonSchema(schema, path) {
|
|
666
|
-
for (const keyword of ["anyOf", "allOf", "not", "if", "then", "else", "contains", "prefixItems"]) {
|
|
667
|
-
if (schema[keyword] !== undefined) {
|
|
668
|
-
throw new Error(`${path} uses unsupported keyword "${keyword}"`);
|
|
669
|
-
}
|
|
670
|
-
}
|
|
671
|
-
const type = schema.type;
|
|
672
|
-
if (Array.isArray(type)) {
|
|
673
|
-
const supported = new Set(["string", "number", "integer", "boolean", "object", "array", "null"]);
|
|
674
|
-
for (const item of type) {
|
|
675
|
-
if (!supported.has(item)) {
|
|
676
|
-
throw new Error(`${path} uses unsupported type "${item}"`);
|
|
677
|
-
}
|
|
678
|
-
}
|
|
679
|
-
}
|
|
680
|
-
else if (type !== undefined &&
|
|
681
|
-
type !== "string" &&
|
|
682
|
-
type !== "number" &&
|
|
683
|
-
type !== "integer" &&
|
|
684
|
-
type !== "boolean" &&
|
|
685
|
-
type !== "object" &&
|
|
686
|
-
type !== "array") {
|
|
687
|
-
throw new Error(`${path} uses unsupported type "${type}"`);
|
|
688
|
-
}
|
|
689
|
-
if (isJsonObject(schema.properties)) {
|
|
690
|
-
for (const [key, child] of Object.entries(schema.properties)) {
|
|
691
|
-
if (isJsonObject(child)) {
|
|
692
|
-
assertSupportedJsonSchema(child, `${path}.properties.${key}`);
|
|
693
|
-
}
|
|
694
|
-
else {
|
|
695
|
-
throw new Error(`${path}.properties.${key} must be an object schema`);
|
|
696
|
-
}
|
|
697
|
-
}
|
|
698
|
-
}
|
|
699
|
-
else if (schema.properties !== undefined) {
|
|
700
|
-
throw new Error(`${path}.properties must be an object`);
|
|
701
|
-
}
|
|
702
|
-
const additionalProperties = schema.additionalProperties;
|
|
703
|
-
if (typeof additionalProperties === "object" && additionalProperties !== null) {
|
|
704
|
-
if (Array.isArray(additionalProperties)) {
|
|
705
|
-
throw new Error(`${path}.additionalProperties must be an object schema or boolean`);
|
|
706
|
-
}
|
|
707
|
-
assertSupportedJsonSchema(additionalProperties, `${path}.additionalProperties`);
|
|
708
|
-
}
|
|
709
|
-
else if (additionalProperties !== undefined
|
|
710
|
-
&& typeof additionalProperties !== "boolean") {
|
|
711
|
-
throw new Error(`${path}.additionalProperties must be an object schema or boolean`);
|
|
712
|
-
}
|
|
713
|
-
const items = schema.items;
|
|
714
|
-
if (Array.isArray(items)) {
|
|
715
|
-
throw new Error(`${path}.items uses unsupported tuple array schemas`);
|
|
716
|
-
}
|
|
717
|
-
if (typeof items === "object" && items !== null && !Array.isArray(items)) {
|
|
718
|
-
assertSupportedJsonSchema(items, `${path}.items`);
|
|
719
|
-
}
|
|
720
|
-
else if (items !== undefined && typeof items !== "boolean") {
|
|
721
|
-
throw new Error(`${path}.items must be an object schema or boolean`);
|
|
722
|
-
}
|
|
723
|
-
const oneOf = schema.oneOf;
|
|
724
|
-
if (Array.isArray(oneOf)) {
|
|
725
|
-
for (const [index, child] of oneOf.entries()) {
|
|
726
|
-
if (typeof child === "object" && child !== null && !Array.isArray(child)) {
|
|
727
|
-
assertSupportedJsonSchema(child, `${path}.oneOf[${index}]`);
|
|
728
|
-
}
|
|
729
|
-
else {
|
|
730
|
-
throw new Error(`${path}.oneOf[${index}] must be an object schema`);
|
|
731
|
-
}
|
|
732
|
-
}
|
|
733
|
-
}
|
|
734
|
-
else if (oneOf !== undefined) {
|
|
735
|
-
throw new Error(`${path}.oneOf must be an array`);
|
|
736
|
-
}
|
|
737
|
-
}
|
|
738
695
|
function isJsonObject(value) {
|
|
739
696
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
740
697
|
}
|
|
741
698
|
function isGetPromptResult(value) {
|
|
742
|
-
if (typeof value !== "object" ||
|
|
699
|
+
if (typeof value !== "object" ||
|
|
700
|
+
value === null ||
|
|
701
|
+
!hasOwnProperty(value, "messages")) {
|
|
743
702
|
return false;
|
|
744
703
|
}
|
|
745
|
-
return (!hasOwnProperty(value, "description") ||
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
704
|
+
return ((!hasOwnProperty(value, "description") ||
|
|
705
|
+
value.description === undefined ||
|
|
706
|
+
typeof value.description === "string") &&
|
|
707
|
+
Array.isArray(value.messages) &&
|
|
708
|
+
value.messages.every((message) => typeof message === "object" &&
|
|
709
|
+
message !== null &&
|
|
710
|
+
hasOwnProperty(message, "role") &&
|
|
711
|
+
(message.role === "user" || message.role === "assistant") &&
|
|
712
|
+
hasOwnProperty(message, "content") &&
|
|
713
|
+
isPromptContentItem(message.content)));
|
|
753
714
|
}
|
|
754
715
|
function isReadResourceResult(value) {
|
|
755
|
-
if (typeof value !== "object" ||
|
|
716
|
+
if (typeof value !== "object" ||
|
|
717
|
+
value === null ||
|
|
718
|
+
!hasOwnProperty(value, "contents")) {
|
|
756
719
|
return false;
|
|
757
720
|
}
|
|
758
|
-
return Array.isArray(value.contents)
|
|
759
|
-
&& value.contents.every(isResourceContents);
|
|
721
|
+
return (Array.isArray(value.contents) && value.contents.every(isResourceContents));
|
|
760
722
|
}
|
|
761
723
|
function hasContentArray(value) {
|
|
762
|
-
return typeof value === "object" &&
|
|
763
|
-
&&
|
|
724
|
+
return (typeof value === "object" &&
|
|
725
|
+
value !== null &&
|
|
726
|
+
hasOwnProperty(value, "content") &&
|
|
727
|
+
Array.isArray(value.content));
|
|
764
728
|
}
|
|
765
729
|
function isContentItem(value) {
|
|
766
|
-
if (typeof value !== "object" ||
|
|
730
|
+
if (typeof value !== "object" ||
|
|
731
|
+
value === null ||
|
|
732
|
+
!hasOwnProperty(value, "type")) {
|
|
767
733
|
return false;
|
|
768
734
|
}
|
|
769
735
|
const block = value;
|
|
@@ -774,56 +740,71 @@ function isContentItem(value) {
|
|
|
774
740
|
return hasOwnProperty(block, "text") && typeof block.text === "string";
|
|
775
741
|
}
|
|
776
742
|
if (block.type === "image" || block.type === "audio") {
|
|
777
|
-
return hasOwnProperty(block, "data")
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
743
|
+
return (hasOwnProperty(block, "data") &&
|
|
744
|
+
typeof block.data === "string" &&
|
|
745
|
+
isBase64(block.data) &&
|
|
746
|
+
hasOwnProperty(block, "mimeType") &&
|
|
747
|
+
typeof block.mimeType === "string");
|
|
782
748
|
}
|
|
783
749
|
if (block.type === "resource_link") {
|
|
784
|
-
return hasOwnProperty(block, "uri")
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
750
|
+
return (hasOwnProperty(block, "uri") &&
|
|
751
|
+
typeof block.uri === "string" &&
|
|
752
|
+
isValidUri(block.uri) &&
|
|
753
|
+
hasOwnProperty(block, "name") &&
|
|
754
|
+
typeof block.name === "string" &&
|
|
755
|
+
(!hasOwnProperty(block, "title") ||
|
|
756
|
+
block.title === undefined ||
|
|
757
|
+
typeof block.title === "string") &&
|
|
758
|
+
(!hasOwnProperty(block, "description") ||
|
|
759
|
+
block.description === undefined ||
|
|
760
|
+
typeof block.description === "string") &&
|
|
761
|
+
(!hasOwnProperty(block, "mimeType") ||
|
|
762
|
+
block.mimeType === undefined ||
|
|
763
|
+
typeof block.mimeType === "string") &&
|
|
764
|
+
(!hasOwnProperty(block, "size") ||
|
|
765
|
+
block.size === undefined ||
|
|
766
|
+
typeof block.size === "number"));
|
|
767
|
+
}
|
|
768
|
+
if (block.type !== "resource" ||
|
|
769
|
+
!hasOwnProperty(block, "resource") ||
|
|
770
|
+
typeof block.resource !== "object" ||
|
|
771
|
+
block.resource === null) {
|
|
798
772
|
return false;
|
|
799
773
|
}
|
|
800
774
|
return isResourceContents(block.resource);
|
|
801
775
|
}
|
|
802
776
|
function isResourceContents(value) {
|
|
803
|
-
if (typeof value !== "object"
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
777
|
+
if (typeof value !== "object" ||
|
|
778
|
+
value === null ||
|
|
779
|
+
!hasOwnProperty(value, "uri") ||
|
|
780
|
+
typeof value.uri !== "string" ||
|
|
781
|
+
!isValidUri(value.uri)) {
|
|
808
782
|
return false;
|
|
809
783
|
}
|
|
810
|
-
if (hasOwnProperty(value, "mimeType") &&
|
|
784
|
+
if (hasOwnProperty(value, "mimeType") &&
|
|
785
|
+
value.mimeType !== undefined &&
|
|
786
|
+
typeof value.mimeType !== "string") {
|
|
811
787
|
return false;
|
|
812
788
|
}
|
|
813
|
-
return (hasOwnProperty(value, "text") && typeof value.text === "string")
|
|
814
|
-
|
|
789
|
+
return ((hasOwnProperty(value, "text") && typeof value.text === "string") ||
|
|
790
|
+
(hasOwnProperty(value, "blob") &&
|
|
791
|
+
typeof value.blob === "string" &&
|
|
792
|
+
isBase64(value.blob)));
|
|
815
793
|
}
|
|
816
794
|
function hasValidContentAnnotations(value) {
|
|
817
|
-
if (!hasOwnProperty(value, "annotations") ||
|
|
795
|
+
if (!hasOwnProperty(value, "annotations") ||
|
|
796
|
+
value.annotations === undefined) {
|
|
818
797
|
return true;
|
|
819
798
|
}
|
|
820
799
|
if (!isJsonObject(value.annotations)) {
|
|
821
800
|
return false;
|
|
822
801
|
}
|
|
823
802
|
const { audience, priority, lastModified } = value.annotations;
|
|
824
|
-
return (audience === undefined ||
|
|
825
|
-
|
|
826
|
-
|
|
803
|
+
return ((audience === undefined ||
|
|
804
|
+
(Array.isArray(audience) &&
|
|
805
|
+
audience.every((item) => item === "user" || item === "assistant"))) &&
|
|
806
|
+
(priority === undefined || typeof priority === "number") &&
|
|
807
|
+
(lastModified === undefined || typeof lastModified === "string"));
|
|
827
808
|
}
|
|
828
809
|
function isBase64(value) {
|
|
829
810
|
if (value.length === 0) {
|
|
@@ -836,7 +817,8 @@ function isBase64(value) {
|
|
|
836
817
|
const paddingStart = value.indexOf("=");
|
|
837
818
|
const encoded = paddingStart === -1 ? value : value.slice(0, paddingStart);
|
|
838
819
|
const padding = paddingStart === -1 ? "" : value.slice(paddingStart);
|
|
839
|
-
if (padding.length > 2 ||
|
|
820
|
+
if (padding.length > 2 ||
|
|
821
|
+
[...padding].some((character) => character !== "=")) {
|
|
840
822
|
return false;
|
|
841
823
|
}
|
|
842
824
|
if ([...encoded].some((character) => !alphabet.includes(character))) {
|
|
@@ -848,7 +830,10 @@ function isPromptContentItem(value) {
|
|
|
848
830
|
if (!isContentItem(value)) {
|
|
849
831
|
return false;
|
|
850
832
|
}
|
|
851
|
-
return !(typeof value === "object" &&
|
|
833
|
+
return !(typeof value === "object" &&
|
|
834
|
+
value !== null &&
|
|
835
|
+
hasOwnProperty(value, "type") &&
|
|
836
|
+
value.type === "resource_link");
|
|
852
837
|
}
|
|
853
838
|
function hasOwnProperty(value, name) {
|
|
854
839
|
return Object.prototype.hasOwnProperty.call(value, name);
|
package/dist/types.d.ts
CHANGED
|
@@ -164,10 +164,7 @@ export interface ResourceTemplateDefinition extends ResourceTemplate {
|
|
|
164
164
|
}
|
|
165
165
|
export interface HandleResult {
|
|
166
166
|
result?: unknown;
|
|
167
|
-
error?:
|
|
168
|
-
code: number;
|
|
169
|
-
message: string;
|
|
170
|
-
};
|
|
167
|
+
error?: JSONRPCError;
|
|
171
168
|
}
|
|
172
169
|
export type PromptContentItem = {
|
|
173
170
|
type: "text";
|
package/dist/types.js
CHANGED