comfyui-mcp 0.50.41 → 0.50.42

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.
@@ -5149,6 +5149,33 @@ export const __panelAskTestHooks = {
5149
5149
  isReplyTimeoutError,
5150
5150
  askFingerprint,
5151
5151
  };
5152
+ /**
5153
+ * #754 — an unrecognized argument key was silently DROPPED, not rejected. Measured:
5154
+ * a real call and one with an extra `utterly_bogus_param` key returned byte-identical
5155
+ * replies. Zod's default `z.object()` is "strip" mode: unknown keys vanish before the
5156
+ * handler ever sees them, so a caller with a misspelled or hallucinated field name gets
5157
+ * no signal that anything was wrong — the call just quietly does less than asked.
5158
+ *
5159
+ * `.strict()` turns that into a validation error the caller can see and correct,
5160
+ * which is the whole value for an LLM caller: a loud, specific failure ("Unrecognized
5161
+ * key: X") is something a model can read and fix on the next attempt; a silent no-op
5162
+ * is not distinguishable from "it worked but had no effect".
5163
+ *
5164
+ * BOTH transports' registration functions accept this directly in place of the raw
5165
+ * shape (verified against each SDK's actual runtime behavior, not assumed from the
5166
+ * TypeScript types — see the cast note at the Anthropic SDK call site):
5167
+ * - `@modelcontextprotocol/sdk`'s `registerTool({ inputSchema })` types `inputSchema`
5168
+ * as `AnySchema | ZodRawShapeCompat`, so a full ZodObject is accepted as-is by the
5169
+ * TYPE, and at runtime `normalizeObjectSchema` detects an already-built schema
5170
+ * (it carries `_def`/`_zod`) and passes it through unwrapped rather than
5171
+ * re-wrapping it — so the `.strict()` marker survives into validation.
5172
+ * - The Anthropic Agent SDK's `tool()` stores whatever is passed as `inputSchema`
5173
+ * verbatim; a `.safeParse()` probe against the returned tool definition confirmed
5174
+ * an unrecognized key is rejected with `Unrecognized key: "..."`.
5175
+ */
5176
+ function strictPanelSchema(shape) {
5177
+ return z.object(shape).strict();
5178
+ }
5152
5179
  const PANEL_EDIT_NODE_FIELDS = ["pos", "size", "title", "preset", "color", "bgcolor", "shape", "collapsed", "pinned", "mode"];
5153
5180
  const NODE_COLOR_HEX = /^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/;
5154
5181
  /** Cross-field rules that a flat ZodRawShape cannot express. Keep these at the
@@ -8681,7 +8708,17 @@ export function buildPanelToolDefs() {
8681
8708
  export function createPanelMcpServer(bridge, tabId, workflowTargets) {
8682
8709
  const ctx = makePanelToolCtx(bridge, tabId, workflowTargets);
8683
8710
  const defs = buildPanelToolDefs();
8684
- const tools = defs.map((d) => tool(d.name, d.description, d.schema, (args) => d.handler(args, ctx)));
8711
+ const tools = defs.map((d) => tool(d.name, d.description,
8712
+ // #754 — strict() so an unrecognized arg key is a loud validation error,
8713
+ // not a silent drop. tool()'s TS signature requires a bare ZodRawShape
8714
+ // (`Schema extends AnyZodRawShape`), which a strict ZodObject instance does
8715
+ // NOT structurally satisfy (it has methods like `.parse`, not just field
8716
+ // schemas) — but at RUNTIME the SDK stores whatever is passed as
8717
+ // `inputSchema` verbatim (confirmed by constructing a tool this way and
8718
+ // calling `.safeParse` on the returned definition: unknown keys are
8719
+ // rejected). The cast documents that the type is being widened past what
8720
+ // TS can express here, not past what the SDK actually accepts.
8721
+ strictPanelSchema(d.schema), (args) => d.handler(args, ctx)));
8685
8722
  const server = createSdkMcpServer({
8686
8723
  name: "comfyui-panel",
8687
8724
  version: "1.0.0",
@@ -8705,9 +8742,12 @@ export function registerPanelTools(server, ctx) {
8705
8742
  for (const d of buildPanelToolDefs()) {
8706
8743
  server.registerTool(d.name, {
8707
8744
  description: d.description,
8708
- // The MCP SDK accepts a zod raw shape as inputSchema (same shape the
8709
- // Anthropic SDK tool() takes), so the shared schema drops straight in.
8710
- inputSchema: d.schema,
8745
+ // #754 strict() so an unrecognized arg key is a loud validation error,
8746
+ // not silently stripped. The MCP SDK types `inputSchema` as a full zod
8747
+ // schema OR a raw shape (`AnySchema | ZodRawShapeCompat`), so passing the
8748
+ // already-built ZodObject needs no cast here — unlike the Anthropic SDK
8749
+ // call site, which types inputSchema as a bare raw shape only.
8750
+ inputSchema: strictPanelSchema(d.schema),
8711
8751
  }, (async (args) => {
8712
8752
  const res = await d.handler(args ?? {}, ctx);
8713
8753
  // ToolResult is already the MCP CallToolResult shape (content[] + isError).