tiny-stdio-mcp-server 0.1.7 → 0.1.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/dist/schema.d.ts CHANGED
@@ -4,6 +4,7 @@ interface SchemaPropertyDef {
4
4
  type: SchemaPropertyType;
5
5
  description?: string;
6
6
  optional?: boolean;
7
+ [keyword: string]: unknown;
7
8
  }
8
9
  type SchemaDefinition = Record<string, SchemaPropertyDef>;
9
10
  type InferType<T extends SchemaPropertyType> = T extends "string" ? string : T extends "number" ? number : T extends "boolean" ? boolean : T extends "object" ? Record<string, unknown> : T extends "array" ? unknown[] : never;
package/dist/schema.js CHANGED
@@ -2,14 +2,17 @@ export function defineSchema(definition) {
2
2
  const properties = {};
3
3
  const required = [];
4
4
  for (const [key, prop] of Object.entries(definition)) {
5
+ const jsonSchemaProperty = {};
6
+ for (const [propertyKey, propertyValue] of Object.entries(prop)) {
7
+ if (propertyKey !== "optional") {
8
+ jsonSchemaProperty[propertyKey] = propertyValue;
9
+ }
10
+ }
5
11
  Object.defineProperty(properties, key, {
6
12
  enumerable: true,
7
13
  configurable: true,
8
14
  writable: true,
9
- value: {
10
- type: prop.type,
11
- ...(prop.description !== undefined && { description: prop.description }),
12
- },
15
+ value: jsonSchemaProperty,
13
16
  });
14
17
  if (!prop.optional) {
15
18
  required.push(key);
package/dist/server.js CHANGED
@@ -320,6 +320,7 @@ export function createServer(options) {
320
320
  };
321
321
  const server = {
322
322
  tool(name, description, inputSchema, handler, outputSchema) {
323
+ assertNonEmptyName(name, "Tool name required");
323
324
  if (outputSchema !== undefined) {
324
325
  assertSupportedOutputSchema(outputSchema);
325
326
  }
@@ -333,6 +334,7 @@ export function createServer(options) {
333
334
  return server;
334
335
  },
335
336
  registerTool(definition, handler) {
337
+ assertNonEmptyName(definition.name, "Tool name required");
336
338
  if (definition.outputSchema !== undefined) {
337
339
  assertSupportedOutputSchema(definition.outputSchema);
338
340
  }
@@ -343,6 +345,7 @@ export function createServer(options) {
343
345
  return server;
344
346
  },
345
347
  prompt(definition, handler) {
348
+ assertNonEmptyName(definition.name, "Prompt name required");
346
349
  prompts.set(definition.name, { ...definition, handler });
347
350
  return server;
348
351
  },
@@ -354,7 +357,7 @@ export function createServer(options) {
354
357
  return server;
355
358
  },
356
359
  resourceTemplate(definition, handler) {
357
- uriTemplateParser.parse(definition.uriTemplate);
360
+ assertReadableUriTemplate(definition.uriTemplate);
358
361
  new UriTemplate(definition.uriTemplate);
359
362
  resourceTemplates.set(definition.uriTemplate, { ...definition, handler });
360
363
  return server;
@@ -536,6 +539,20 @@ function isValidUri(uri) {
536
539
  return false;
537
540
  }
538
541
  }
542
+ function assertNonEmptyName(name, message) {
543
+ if (name.length === 0) {
544
+ throw new Error(message);
545
+ }
546
+ }
547
+ function assertReadableUriTemplate(uriTemplate) {
548
+ const parsed = uriTemplateParser.parse(uriTemplate);
549
+ const expanded = parsed.expand(new Proxy({}, {
550
+ get: (_target, property) => typeof property === "string" ? "value" : undefined,
551
+ }));
552
+ if (typeof expanded !== "string" || !isValidUri(expanded)) {
553
+ throw new Error(`Invalid resource URI template: ${uriTemplate}`);
554
+ }
555
+ }
539
556
  function toStringArguments(value) {
540
557
  if (value === undefined) {
541
558
  return {};
@@ -588,9 +605,13 @@ function normalizeToolResult(handlerResult, outputSchema) {
588
605
  throw new Error("Invalid tool result");
589
606
  }
590
607
  if (outputSchema === undefined) {
591
- return isCallToolResult(handlerResult)
608
+ const result = isCallToolResult(handlerResult)
592
609
  ? handlerResult
593
610
  : { content: toContentBlocks(handlerResult) };
611
+ if (!isCallToolResult(result)) {
612
+ throw new Error("Invalid tool result");
613
+ }
614
+ return result;
594
615
  }
595
616
  const structuredContent = isCallToolResult(handlerResult)
596
617
  ? handlerResult.structuredContent
@@ -695,7 +716,8 @@ function isGetPromptResult(value) {
695
716
  if (typeof value !== "object" || value === null || !hasOwnProperty(value, "messages")) {
696
717
  return false;
697
718
  }
698
- return Array.isArray(value.messages)
719
+ return (!hasOwnProperty(value, "description") || value.description === undefined || typeof value.description === "string")
720
+ && Array.isArray(value.messages)
699
721
  && value.messages.every((message) => typeof message === "object"
700
722
  && message !== null
701
723
  && hasOwnProperty(message, "role")
@@ -708,13 +730,7 @@ function isReadResourceResult(value) {
708
730
  return false;
709
731
  }
710
732
  return Array.isArray(value.contents)
711
- && value.contents.every((content) => typeof content === "object"
712
- && content !== null
713
- && hasOwnProperty(content, "uri")
714
- && typeof content.uri === "string"
715
- && isValidUri(content.uri)
716
- && ((hasOwnProperty(content, "text") && typeof content.text === "string")
717
- || (hasOwnProperty(content, "blob") && typeof content.blob === "string" && isBase64(content.blob))));
733
+ && value.contents.every(isResourceContents);
718
734
  }
719
735
  function hasContentArray(value) {
720
736
  return typeof value === "object" && value !== null && hasOwnProperty(value, "content")
@@ -725,6 +741,9 @@ function isContentItem(value) {
725
741
  return false;
726
742
  }
727
743
  const block = value;
744
+ if (!hasValidContentAnnotations(block)) {
745
+ return false;
746
+ }
728
747
  if (block.type === "text") {
729
748
  return hasOwnProperty(block, "text") && typeof block.text === "string";
730
749
  }
@@ -738,8 +757,13 @@ function isContentItem(value) {
738
757
  if (block.type === "resource_link") {
739
758
  return hasOwnProperty(block, "uri")
740
759
  && typeof block.uri === "string"
760
+ && isValidUri(block.uri)
741
761
  && hasOwnProperty(block, "name")
742
- && typeof block.name === "string";
762
+ && typeof block.name === "string"
763
+ && (!hasOwnProperty(block, "title") || block.title === undefined || typeof block.title === "string")
764
+ && (!hasOwnProperty(block, "description") || block.description === undefined || typeof block.description === "string")
765
+ && (!hasOwnProperty(block, "mimeType") || block.mimeType === undefined || typeof block.mimeType === "string")
766
+ && (!hasOwnProperty(block, "size") || block.size === undefined || typeof block.size === "number");
743
767
  }
744
768
  if (block.type !== "resource"
745
769
  || !hasOwnProperty(block, "resource")
@@ -747,12 +771,33 @@ function isContentItem(value) {
747
771
  || block.resource === null) {
748
772
  return false;
749
773
  }
750
- const resource = block.resource;
751
- return hasOwnProperty(resource, "uri")
752
- && typeof resource.uri === "string"
753
- && (!hasOwnProperty(resource, "mimeType") || typeof resource.mimeType === "string")
754
- && ((hasOwnProperty(resource, "text") && typeof resource.text === "string")
755
- || (hasOwnProperty(resource, "blob") && typeof resource.blob === "string" && isBase64(resource.blob)));
774
+ return isResourceContents(block.resource);
775
+ }
776
+ function isResourceContents(value) {
777
+ if (typeof value !== "object"
778
+ || value === null
779
+ || !hasOwnProperty(value, "uri")
780
+ || typeof value.uri !== "string"
781
+ || !isValidUri(value.uri)) {
782
+ return false;
783
+ }
784
+ if (hasOwnProperty(value, "mimeType") && value.mimeType !== undefined && typeof value.mimeType !== "string") {
785
+ return false;
786
+ }
787
+ return (hasOwnProperty(value, "text") && typeof value.text === "string")
788
+ || (hasOwnProperty(value, "blob") && typeof value.blob === "string" && isBase64(value.blob));
789
+ }
790
+ function hasValidContentAnnotations(value) {
791
+ if (!hasOwnProperty(value, "annotations") || value.annotations === undefined) {
792
+ return true;
793
+ }
794
+ if (!isJsonObject(value.annotations)) {
795
+ return false;
796
+ }
797
+ const { audience, priority, lastModified } = value.annotations;
798
+ return (audience === undefined || (Array.isArray(audience) && audience.every((item) => item === "user" || item === "assistant")))
799
+ && (priority === undefined || typeof priority === "number")
800
+ && (lastModified === undefined || typeof lastModified === "string");
756
801
  }
757
802
  function isBase64(value) {
758
803
  if (value.length === 0) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tiny-stdio-mcp-server",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
4
  "bugs": {
5
5
  "url": "https://github.com/poe-platform/poe-code/issues"
6
6
  },