@feniix/bridgekit
Advanced tools
+13
-0
@@ -7,2 +7,15 @@ # Changelog | ||
| ## [0.9.3] - Unreleased | ||
| ### Fixed | ||
| - `createMcpServer` construction errors now recognize top-level `$ref` / | ||
| `Type.Cyclic` / `Type.Recursive` schemas as a distinct rejection class with | ||
| `$ref`-specific guidance (inline the referenced shape or split recursive | ||
| shapes into multiple non-recursive tools), instead of falling through to | ||
| the misdirecting "wrap with `Type.Object`" recipe. New stable error code | ||
| `BRIDGEKIT_MCP_REF_PARAMETERS` for consumer branching. Existing | ||
| `BRIDGEKIT_MCP_NON_OBJECT_PARAMETERS` and `BRIDGEKIT_MCP_DUPLICATE_TOOL_NAME` | ||
| codes are unchanged. Resolves [#44](https://github.com/feniix/bridgekit/issues/44). | ||
| ## [0.9.2] - 2026-05-26 | ||
@@ -9,0 +22,0 @@ |
@@ -40,2 +40,8 @@ import { Server } from "@modelcontextprotocol/sdk/server/index.js"; | ||
| * not the composition itself. | ||
| * | ||
| * The `$ref` check is first because `Type.Cyclic` produces | ||
| * `{ $defs: {...}, $ref: "..." }` at the root; the `$ref` is the load-bearing | ||
| * structural signal regardless of what else is set, and the recipe for that | ||
| * shape (inline or split) is different from the generic `Type.Object(...)` | ||
| * wrap recipe. | ||
| */ | ||
@@ -46,2 +52,4 @@ function schemaTypeLabel(schema) { | ||
| const candidate = schema; | ||
| if (typeof candidate.$ref === "string") | ||
| return "$ref"; | ||
| if (typeof candidate.type === "string") | ||
@@ -88,2 +96,3 @@ return candidate.type; | ||
| const ERROR_CODE_NON_OBJECT_PARAMETERS = "BRIDGEKIT_MCP_NON_OBJECT_PARAMETERS"; | ||
| const ERROR_CODE_REF_PARAMETERS = "BRIDGEKIT_MCP_REF_PARAMETERS"; | ||
| const ERROR_CODE_DUPLICATE_TOOL_NAME = "BRIDGEKIT_MCP_DUPLICATE_TOOL_NAME"; | ||
@@ -99,2 +108,15 @@ function throwWithCode(message, code) { | ||
| const typeLabel = schemaTypeLabel(tool.parameters); | ||
| // Top-level $ref (TypeBox's `Type.Cyclic` lowering, or a bare `Type.Ref`) | ||
| // gets its own branch and code. The generic "wrap with Type.Object(...)" | ||
| // recipe is the wrong fix for a recursive schema — the user wants to | ||
| // express recursion, not wrap a primitive — so a $ref shape needs | ||
| // $ref-specific guidance (inline or split) before the generic branch | ||
| // can run. | ||
| if (typeLabel === "$ref") { | ||
| throwWithCode(`createMcpServer: tool "${tool.name}" has a top-level $ref schema (type="$ref"). ` + | ||
| "Top-level $ref / Type.Cyclic schemas are not currently supported by the MCP wire layer " + | ||
| "because tools/list ships inputSchema by value and the SDK client does not resolve $refs. " + | ||
| "Inline the referenced schema (wrap the target shape directly with Type.Object(...)) " + | ||
| "or split recursive shapes into multiple non-recursive tools.", ERROR_CODE_REF_PARAMETERS); | ||
| } | ||
| let message = `createMcpServer: tool "${tool.name}" has a non-object parameters schema (type="${typeLabel}"). ` + | ||
@@ -101,0 +123,0 @@ "MCP requires Type.Object(...) at the top level; use Type.Object({ value: Type.String() }) " + |
+1
-1
| { | ||
| "name": "@feniix/bridgekit", | ||
| "version": "0.9.2", | ||
| "version": "0.9.3", | ||
| "description": "BridgeKit defines TypeBox-backed tools once and adapts them to pi, MCP, and other hosts.", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
116889
1.87%1190
1.88%