@openfairygui/mcp 0.5.0-alpha.2 → 0.5.0-alpha.4

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/index.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_stdio = require("./stdio-D33c37mD.cjs");
2
+ const require_stdio = require("./stdio-BRrNOeUP.cjs");
3
3
  let _openfairygui_backend_docs = require("@openfairygui/backend/docs");
4
4
  exports.OPENFAIRYGUI_BACKEND_CAPABILITIES_RESOURCE_URI = require_stdio.OPENFAIRYGUI_BACKEND_CAPABILITIES_RESOURCE_URI;
5
5
  exports.OPENFAIRYGUI_BACKEND_PROMPT_DEFINITIONS = require_stdio.OPENFAIRYGUI_BACKEND_PROMPT_DEFINITIONS;
package/dist/index.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import { a as OPENFAIRYGUI_BACKEND_TOOL_NAMES, c as OPENFAIRYGUI_BACKEND_RESOURCE_TEMPLATES, d as getOpenFairyGuiOperationCatalog, f as getOpenFairyGuiOperationSchema, i as OPENFAIRYGUI_BACKEND_TOOL_DEFINITIONS, l as OPENFAIRYGUI_OPERATION_CATALOG_URI, m as OPENFAIRYGUI_BACKEND_PROMPT_NAMES, n as createOpenFairyGuiMcpServer, o as OPENFAIRYGUI_BACKEND_TOOL_PREFIX, p as OPENFAIRYGUI_BACKEND_PROMPT_DEFINITIONS, r as callOpenFairyGuiBackendTool, s as OPENFAIRYGUI_BACKEND_CAPABILITIES_RESOURCE_URI, t as connectOpenFairyGuiMcpStdio, u as OPENFAIRYGUI_OPERATION_SCHEMA_TEMPLATE } from "./stdio--4YykL4s.mjs";
1
+ import { a as OPENFAIRYGUI_BACKEND_TOOL_NAMES, c as OPENFAIRYGUI_BACKEND_RESOURCE_TEMPLATES, d as getOpenFairyGuiOperationCatalog, f as getOpenFairyGuiOperationSchema, i as OPENFAIRYGUI_BACKEND_TOOL_DEFINITIONS, l as OPENFAIRYGUI_OPERATION_CATALOG_URI, m as OPENFAIRYGUI_BACKEND_PROMPT_NAMES, n as createOpenFairyGuiMcpServer, o as OPENFAIRYGUI_BACKEND_TOOL_PREFIX, p as OPENFAIRYGUI_BACKEND_PROMPT_DEFINITIONS, r as callOpenFairyGuiBackendTool, s as OPENFAIRYGUI_BACKEND_CAPABILITIES_RESOURCE_URI, t as connectOpenFairyGuiMcpStdio, u as OPENFAIRYGUI_OPERATION_SCHEMA_TEMPLATE } from "./stdio-t-TXHfJJ.mjs";
2
2
  export { OPENFAIRYGUI_BACKEND_CAPABILITIES_RESOURCE_URI, OPENFAIRYGUI_BACKEND_PROMPT_DEFINITIONS, OPENFAIRYGUI_BACKEND_PROMPT_NAMES, OPENFAIRYGUI_BACKEND_RESOURCE_TEMPLATES, OPENFAIRYGUI_BACKEND_TOOL_DEFINITIONS, OPENFAIRYGUI_BACKEND_TOOL_NAMES, OPENFAIRYGUI_BACKEND_TOOL_PREFIX, OPENFAIRYGUI_OPERATION_CATALOG_URI, OPENFAIRYGUI_OPERATION_SCHEMA_TEMPLATE, callOpenFairyGuiBackendTool, connectOpenFairyGuiMcpStdio, createOpenFairyGuiMcpServer, getOpenFairyGuiOperationCatalog, getOpenFairyGuiOperationSchema };
@@ -501,16 +501,16 @@ const OPENFAIRYGUI_BACKEND_TOOL_METADATA = [
501
501
  //#region src/tool-definitions.ts
502
502
  const OPENFAIRYGUI_BACKEND_TOOL_PREFIX = "openfairygui_backend_";
503
503
  const OPENFAIRYGUI_BACKEND_TOOL_NAMES = OPENFAIRYGUI_BACKEND_TOOL_METADATA.map((entry) => entry.name);
504
- function isOpenFairyGuiMcpPayloadWithinBudget(root) {
504
+ function isOpenFairyGuiMcpPayloadWithinBudget(root, bytePaths = []) {
505
505
  const pending = [{
506
506
  value: root,
507
- depth: 0
507
+ path: []
508
508
  }];
509
- let nodes = 0;
509
+ let nodes = 0, binaryBytes = 0;
510
510
  while (pending.length > 0) {
511
- const { value, depth } = pending.pop();
511
+ const { value, path } = pending.pop();
512
512
  nodes += 1;
513
- if (nodes > 1e5 || depth > 32) return false;
513
+ if (nodes > 1e5 || path.length > 32) return false;
514
514
  if (value === null || typeof value === "boolean") continue;
515
515
  if (typeof value === "number") {
516
516
  if (!Number.isFinite(value)) return false;
@@ -521,23 +521,29 @@ function isOpenFairyGuiMcpPayloadWithinBudget(root) {
521
521
  continue;
522
522
  }
523
523
  if (value instanceof Uint8Array) {
524
- if (value.byteLength > 8 * 1024 * 1024) return false;
524
+ binaryBytes += value.byteLength;
525
+ if (binaryBytes > 8 * 1024 * 1024) return false;
525
526
  continue;
526
527
  }
527
528
  if (Array.isArray(value)) {
529
+ if (bytePaths.some((parts) => parts.length === path.length && parts.every((part, index) => part === "*" || part === path[index]))) {
530
+ binaryBytes += value.length;
531
+ if (binaryBytes > 8 * 1024 * 1024 || !value.every((byte) => Number.isInteger(byte) && byte >= 0 && byte <= 255)) return false;
532
+ continue;
533
+ }
528
534
  if (value.length > 1e4) return false;
529
- for (const child of value) pending.push({
535
+ for (const [index, child] of value.entries()) pending.push({
530
536
  value: child,
531
- depth: depth + 1
537
+ path: [...path, String(index)]
532
538
  });
533
539
  continue;
534
540
  }
535
541
  if (typeof value !== "object") return false;
536
542
  const entries = Object.entries(value);
537
543
  if (entries.length > 1e4 || entries.some(([key]) => key.length > 256)) return false;
538
- for (const [, child] of entries) pending.push({
544
+ for (const [key, child] of entries) pending.push({
539
545
  value: child,
540
- depth: depth + 1
546
+ path: [...path, key]
541
547
  });
542
548
  }
543
549
  return true;
@@ -586,11 +592,12 @@ function unhandledBackendFailure(startedAt) {
586
592
  };
587
593
  }
588
594
  async function callOpenFairyGuiBackendTool(runtime, name, input, policy) {
589
- if (!isOpenFairyGuiMcpPayloadWithinBudget(input)) throw new RangeError("MCP input exceeds the depth, node, key, string, or byte budget.");
590
595
  const definition = OPENFAIRYGUI_BACKEND_TOOL_DEFINITIONS.find((entry) => entry.name === name);
591
596
  if (!definition) throw new RangeError(`Unknown OpenFairyGUI backend MCP tool: ${name}`);
597
+ const bytePaths = CONTRACT_SNAPSHOT.tools[definition.backendMethod].bytePaths;
598
+ if (!isOpenFairyGuiMcpPayloadWithinBudget(input, bytePaths)) throw new RangeError("MCP input exceeds the depth, node, key, string, or byte budget.");
592
599
  const parsed = definition.inputSchema.parse(input);
593
- const decoded = decodeToolBytes(parsed, CONTRACT_SNAPSHOT.tools[definition.backendMethod].bytePaths);
600
+ const decoded = decodeToolBytes(parsed, bytePaths);
594
601
  const startedAt = Date.now();
595
602
  try {
596
603
  let hostFailure = await policy?.beforeCall(structuredClone(parsed));
@@ -622,7 +629,7 @@ async function callOpenFairyGuiBackendTool(runtime, name, input, policy) {
622
629
  //#region src/server.ts
623
630
  const require$1 = (0, node_module.createRequire)(require("url").pathToFileURL(__filename).href);
624
631
  function getInjectedPackageVersion() {
625
- const version = "0.5.0-alpha.2";
632
+ const version = "0.5.0-alpha.4";
626
633
  return typeof version === "string" && true ? version : null;
627
634
  }
628
635
  function readPackageVersion() {
@@ -478,16 +478,16 @@ const OPENFAIRYGUI_BACKEND_TOOL_METADATA = [
478
478
  //#region src/tool-definitions.ts
479
479
  const OPENFAIRYGUI_BACKEND_TOOL_PREFIX = "openfairygui_backend_";
480
480
  const OPENFAIRYGUI_BACKEND_TOOL_NAMES = OPENFAIRYGUI_BACKEND_TOOL_METADATA.map((entry) => entry.name);
481
- function isOpenFairyGuiMcpPayloadWithinBudget(root) {
481
+ function isOpenFairyGuiMcpPayloadWithinBudget(root, bytePaths = []) {
482
482
  const pending = [{
483
483
  value: root,
484
- depth: 0
484
+ path: []
485
485
  }];
486
- let nodes = 0;
486
+ let nodes = 0, binaryBytes = 0;
487
487
  while (pending.length > 0) {
488
- const { value, depth } = pending.pop();
488
+ const { value, path } = pending.pop();
489
489
  nodes += 1;
490
- if (nodes > 1e5 || depth > 32) return false;
490
+ if (nodes > 1e5 || path.length > 32) return false;
491
491
  if (value === null || typeof value === "boolean") continue;
492
492
  if (typeof value === "number") {
493
493
  if (!Number.isFinite(value)) return false;
@@ -498,23 +498,29 @@ function isOpenFairyGuiMcpPayloadWithinBudget(root) {
498
498
  continue;
499
499
  }
500
500
  if (value instanceof Uint8Array) {
501
- if (value.byteLength > 8 * 1024 * 1024) return false;
501
+ binaryBytes += value.byteLength;
502
+ if (binaryBytes > 8 * 1024 * 1024) return false;
502
503
  continue;
503
504
  }
504
505
  if (Array.isArray(value)) {
506
+ if (bytePaths.some((parts) => parts.length === path.length && parts.every((part, index) => part === "*" || part === path[index]))) {
507
+ binaryBytes += value.length;
508
+ if (binaryBytes > 8 * 1024 * 1024 || !value.every((byte) => Number.isInteger(byte) && byte >= 0 && byte <= 255)) return false;
509
+ continue;
510
+ }
505
511
  if (value.length > 1e4) return false;
506
- for (const child of value) pending.push({
512
+ for (const [index, child] of value.entries()) pending.push({
507
513
  value: child,
508
- depth: depth + 1
514
+ path: [...path, String(index)]
509
515
  });
510
516
  continue;
511
517
  }
512
518
  if (typeof value !== "object") return false;
513
519
  const entries = Object.entries(value);
514
520
  if (entries.length > 1e4 || entries.some(([key]) => key.length > 256)) return false;
515
- for (const [, child] of entries) pending.push({
521
+ for (const [key, child] of entries) pending.push({
516
522
  value: child,
517
- depth: depth + 1
523
+ path: [...path, key]
518
524
  });
519
525
  }
520
526
  return true;
@@ -563,11 +569,12 @@ function unhandledBackendFailure(startedAt) {
563
569
  };
564
570
  }
565
571
  async function callOpenFairyGuiBackendTool(runtime, name, input, policy) {
566
- if (!isOpenFairyGuiMcpPayloadWithinBudget(input)) throw new RangeError("MCP input exceeds the depth, node, key, string, or byte budget.");
567
572
  const definition = OPENFAIRYGUI_BACKEND_TOOL_DEFINITIONS.find((entry) => entry.name === name);
568
573
  if (!definition) throw new RangeError(`Unknown OpenFairyGUI backend MCP tool: ${name}`);
574
+ const bytePaths = CONTRACT_SNAPSHOT.tools[definition.backendMethod].bytePaths;
575
+ if (!isOpenFairyGuiMcpPayloadWithinBudget(input, bytePaths)) throw new RangeError("MCP input exceeds the depth, node, key, string, or byte budget.");
569
576
  const parsed = definition.inputSchema.parse(input);
570
- const decoded = decodeToolBytes(parsed, CONTRACT_SNAPSHOT.tools[definition.backendMethod].bytePaths);
577
+ const decoded = decodeToolBytes(parsed, bytePaths);
571
578
  const startedAt = Date.now();
572
579
  try {
573
580
  let hostFailure = await policy?.beforeCall(structuredClone(parsed));
@@ -599,7 +606,7 @@ async function callOpenFairyGuiBackendTool(runtime, name, input, policy) {
599
606
  //#region src/server.ts
600
607
  const require = createRequire(import.meta.url);
601
608
  function getInjectedPackageVersion() {
602
- const version = "0.5.0-alpha.2";
609
+ const version = "0.5.0-alpha.4";
603
610
  return typeof version === "string" && true ? version : null;
604
611
  }
605
612
  function readPackageVersion() {
package/dist/stdio.cjs CHANGED
@@ -1,3 +1,3 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_stdio = require("./stdio-D33c37mD.cjs");
2
+ const require_stdio = require("./stdio-BRrNOeUP.cjs");
3
3
  exports.connectOpenFairyGuiMcpStdio = require_stdio.connectOpenFairyGuiMcpStdio;
package/dist/stdio.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import { t as connectOpenFairyGuiMcpStdio } from "./stdio--4YykL4s.mjs";
1
+ import { t as connectOpenFairyGuiMcpStdio } from "./stdio-t-TXHfJJ.mjs";
2
2
  export { connectOpenFairyGuiMcpStdio };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openfairygui/mcp",
3
- "version": "0.5.0-alpha.2",
3
+ "version": "0.5.0-alpha.4",
4
4
  "description": "FairyGUI Headless Authoring SDK - MCP server adapter for the backend runtime.",
5
5
  "author": "OpenFairyGUI Contributors",
6
6
  "license": "MIT",
@@ -61,13 +61,13 @@
61
61
  "dependencies": {
62
62
  "@modelcontextprotocol/sdk": "^1.29.0",
63
63
  "zod": "^4.3.6",
64
- "@openfairygui/backend": "0.5.0-alpha.2"
64
+ "@openfairygui/backend": "0.5.0-alpha.4"
65
65
  },
66
66
  "devDependencies": {
67
67
  "ava": "^7.0.0",
68
68
  "tsx": "^4.0.0",
69
- "@openfairygui/test-utils": "0.3.0",
70
- "@openfairygui/core": "0.5.0-alpha.2"
69
+ "@openfairygui/core": "0.5.0-alpha.4",
70
+ "@openfairygui/test-utils": "0.3.0"
71
71
  },
72
72
  "ava": {
73
73
  "extensions": {
@@ -14,13 +14,13 @@ export interface OpenFairyGuiBackendToolDefinition extends BackendToolMetadata {
14
14
  outputSchema: z.ZodObject;
15
15
  }
16
16
 
17
- export function isOpenFairyGuiMcpPayloadWithinBudget(root: unknown): boolean {
18
- const pending: Array<{ value: unknown; depth: number }> = [{ value: root, depth: 0 }];
19
- let nodes = 0;
17
+ export function isOpenFairyGuiMcpPayloadWithinBudget(root: unknown, bytePaths: readonly string[][] = []): boolean {
18
+ const pending: Array<{ value: unknown; path: string[] }> = [{ value: root, path: [] }];
19
+ let nodes = 0, binaryBytes = 0;
20
20
  while (pending.length > 0) {
21
- const { value, depth } = pending.pop()!;
21
+ const { value, path } = pending.pop()!;
22
22
  nodes += 1;
23
- if (nodes > 100_000 || depth > 32) return false;
23
+ if (nodes > 100_000 || path.length > 32) return false;
24
24
  if (value === null || typeof value === 'boolean') continue;
25
25
  if (typeof value === 'number') {
26
26
  if (!Number.isFinite(value)) return false;
@@ -31,18 +31,24 @@ export function isOpenFairyGuiMcpPayloadWithinBudget(root: unknown): boolean {
31
31
  continue;
32
32
  }
33
33
  if (value instanceof Uint8Array) {
34
- if (value.byteLength > 8 * 1024 * 1024) return false;
34
+ binaryBytes += value.byteLength;
35
+ if (binaryBytes > 8 * 1024 * 1024) return false;
35
36
  continue;
36
37
  }
37
38
  if (Array.isArray(value)) {
39
+ if (bytePaths.some((parts) => parts.length === path.length && parts.every((part, index) => part === '*' || part === path[index]))) {
40
+ binaryBytes += value.length;
41
+ if (binaryBytes > 8 * 1024 * 1024 || !value.every((byte) => Number.isInteger(byte) && byte >= 0 && byte <= 255)) return false;
42
+ continue;
43
+ }
38
44
  if (value.length > 10_000) return false;
39
- for (const child of value) pending.push({ value: child, depth: depth + 1 });
45
+ for (const [index, child] of value.entries()) pending.push({ value: child, path: [...path, String(index)] });
40
46
  continue;
41
47
  }
42
48
  if (typeof value !== 'object') return false;
43
49
  const entries = Object.entries(value);
44
50
  if (entries.length > 10_000 || entries.some(([key]) => key.length > 256)) return false;
45
- for (const [, child] of entries) pending.push({ value: child, depth: depth + 1 });
51
+ for (const [key, child] of entries) pending.push({ value: child, path: [...path, key] });
46
52
  }
47
53
  return true;
48
54
  }
@@ -74,13 +74,14 @@ export async function callOpenFairyGuiBackendTool(
74
74
  input: Record<string, unknown>,
75
75
  policy?: OpenFairyGuiMcpToolPolicy,
76
76
  ): Promise<CallToolResult> {
77
- if (!isOpenFairyGuiMcpPayloadWithinBudget(input)) {
78
- throw new RangeError('MCP input exceeds the depth, node, key, string, or byte budget.');
79
- }
80
77
  const definition = OPENFAIRYGUI_BACKEND_TOOL_DEFINITIONS.find((entry) => entry.name === name);
81
78
  if (!definition) throw new RangeError(`Unknown OpenFairyGUI backend MCP tool: ${name}`);
79
+ const bytePaths = CONTRACT_SNAPSHOT.tools[definition.backendMethod].bytePaths;
80
+ if (!isOpenFairyGuiMcpPayloadWithinBudget(input, bytePaths)) {
81
+ throw new RangeError('MCP input exceeds the depth, node, key, string, or byte budget.');
82
+ }
82
83
  const parsed = definition.inputSchema.parse(input) as Record<string, unknown>;
83
- const decoded = decodeToolBytes(parsed, CONTRACT_SNAPSHOT.tools[definition.backendMethod].bytePaths);
84
+ const decoded = decodeToolBytes(parsed, bytePaths);
84
85
  const startedAt = Date.now();
85
86
  try {
86
87
  let hostFailure = await policy?.beforeCall(structuredClone(parsed));