@feniix/bridgekit
Advanced tools
+18
-0
@@ -7,2 +7,20 @@ # Changelog | ||
| ## [0.9.5] - Unreleased | ||
| ### Documentation | ||
| - README restructured to quickstart-first ordering: a copy-pasteable | ||
| three-file working example (`tools.ts`, `mcp-server.ts`, | ||
| `pi-extension.ts`) now lands above the fold; runtime requirements, | ||
| the import map, best practices, packaging, and the coding-agent | ||
| section all move below. Content preserved; no new entrypoints, no | ||
| API changes, no behavioral effects. Resolves | ||
| [#19](https://github.com/feniix/bridgekit/issues/19). | ||
| - `docs/packaging-invariants.md` adds a cross-reference under | ||
| `inv-mcp-sdk-major` pointing at `toInputSchema`'s JSDoc in | ||
| `src/adapters/mcp.ts` as the canonical record of the SDK-v1 | ||
| `inputSchema.type` Zod-validation quirk that the `allOf` → | ||
| `type: "object"` synthesis addresses. Resolves | ||
| [#45](https://github.com/feniix/bridgekit/issues/45). | ||
| ## [0.9.4] - 2026-05-27 | ||
@@ -9,0 +27,0 @@ |
+1
-1
| { | ||
| "name": "@feniix/bridgekit", | ||
| "version": "0.9.4", | ||
| "version": "0.9.5", | ||
| "description": "BridgeKit defines TypeBox-backed tools once and adapts them to pi, MCP, and other hosts.", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
+94
-53
@@ -5,18 +5,72 @@ # BridgeKit | ||
| ## Runtime support | ||
| ## Quickstart | ||
| This package is ESM-only and supports Node.js 22.19.0 or newer. Published modules are import-passive and marked as side-effect free; tools are registered or servers are started only when the exported adapter functions are called. | ||
| ```ts | ||
| // src/tools.ts | ||
| import { Type } from "typebox"; | ||
| import { definePortableTool } from "@feniix/bridgekit"; | ||
| ## For coding agents | ||
| export const echoTool = definePortableTool({ | ||
| name: "echo", | ||
| title: "Echo", | ||
| description: "Echo text back to the caller.", | ||
| parameters: Type.Object({ text: Type.String() }), | ||
| execute(args, ctx) { | ||
| return { | ||
| text: args.text, | ||
| structuredContent: { text: args.text, host: ctx.host }, | ||
| }; | ||
| }, | ||
| hostExtras: { | ||
| pi: { pendingMessage: "Echoing..." }, | ||
| mcp: { annotations: { readOnlyHint: true } }, | ||
| }, | ||
| }); | ||
| Read these files in order: | ||
| export function createTools() { | ||
| return [echoTool]; | ||
| } | ||
| ``` | ||
| 1. `README.md` — public API, contracts, and best practices. | ||
| 2. `llms.txt` — compact agent-facing usage rules and anti-patterns. | ||
| 3. `examples/README.md` — copyable layouts for shared tools, pi extensions, MCP stdio servers, and custom hosts. | ||
| 4. Published declarations such as `dist/src/index.d.ts`, `dist/src/pi.d.ts`, and `dist/src/mcp.d.ts` — canonical installed-package type contracts. In a source checkout, the matching `src/` files contain the same implementation context. | ||
| ```ts | ||
| // src/mcp-server.ts | ||
| import { runMcpStdioServer } from "@feniix/bridgekit/mcp"; | ||
| import { createTools } from "./tools.js"; | ||
| ## Entrypoints | ||
| await runMcpStdioServer({ | ||
| name: "my-tools", | ||
| version: "0.1.0", | ||
| tools: createTools(), | ||
| }); | ||
| ``` | ||
| ```ts | ||
| // src/pi-extension.ts | ||
| import { registerPiTools } from "@feniix/bridgekit/pi"; | ||
| import { createTools } from "./tools.js"; | ||
| export default function extension(pi: Parameters<typeof registerPiTools>[0]) { | ||
| registerPiTools(pi, createTools()); | ||
| } | ||
| ``` | ||
| ## Install | ||
| ```bash | ||
| npm install @feniix/bridgekit typebox | ||
| ``` | ||
| This package is ESM-only and supports Node.js 22.19.0 or newer. Published modules are import-passive and marked as side-effect free; tools are registered or servers are started only when the exported adapter functions are called. | ||
| ## Why | ||
| - Define a tool once; ship it to pi and MCP (and custom hosts) without per-host forks. | ||
| - Host-neutral tool files: no pi or MCP SDK imports in the tool definition itself. | ||
| - TypeBox schemas pass through to MCP `inputSchema` directly — no JSON Schema conversion step. | ||
| - Import-passive, `sideEffects: false`, three-entrypoint split (`.`, `./pi`, `./mcp`) so pi-only consumers do not pull the MCP SDK and vice versa. | ||
| - Conformance-tested public surface: a packed-install smoke test enforces the runtime export set, deep-import rejection, and type-level strictness against the installed declarations. | ||
| ## API reference | ||
| ```ts | ||
| import { | ||
@@ -44,44 +98,5 @@ definePortableTool, | ||
| ## Core tools | ||
| ### pi adapter | ||
| Define tools once in host-neutral files: | ||
| ```ts | ||
| import { Type } from "typebox"; | ||
| import { definePortableTool } from "@feniix/bridgekit"; | ||
| export const echoTool = definePortableTool({ | ||
| name: "echo", | ||
| title: "Echo", | ||
| description: "Echo text.", | ||
| parameters: Type.Object({ text: Type.String() }), | ||
| execute(args, ctx) { | ||
| return { | ||
| text: args.text, | ||
| structuredContent: { text: args.text, host: ctx.host }, | ||
| }; | ||
| }, | ||
| }); | ||
| export function createTools() { | ||
| return [echoTool]; | ||
| } | ||
| ``` | ||
| Tool definition best practices: | ||
| - Keep tool files host-neutral: no pi imports, no MCP SDK imports. | ||
| - Use TypeBox `Type.Object(...)` schemas so MCP can expose input schemas directly. | ||
| - Return `text` for model-visible output and `structuredContent` for machine-readable data. | ||
| - Use `isError: true` for expected/domain failures that should be represented as tool output. | ||
| - Throw only for unexpected programmer, adapter, or runtime failures. | ||
| - Respect `ctx.signal` in long-running tools. | ||
| - Use `ctx.progress?.(...)` for incremental updates. | ||
| - Keep modules import-passive; do not register tools or start servers at import time. | ||
| - For stateful tools, export a `createTools()` factory instead of a module-level singleton so each host runtime gets isolated state. | ||
| - TypeBox validation happens before `execute`; use a permissive schema plus domain validation if you need custom guidance for structurally invalid input. | ||
| ## pi adapter | ||
| ```ts | ||
| import { registerPiTools } from "@feniix/bridgekit/pi"; | ||
@@ -146,3 +161,3 @@ import { createTools } from "./tools.js"; | ||
| ### Per-host metadata via `hostExtras` | ||
| #### Per-host metadata via `hostExtras` | ||
@@ -180,3 +195,3 @@ `PortableTool.hostExtras` is an optional namespace for host-specific fields that should travel with the tool definition rather than a parallel sidecar map. The pi adapter reads `hostExtras.pi`; the MCP adapter reads `hostExtras.mcp`; each adapter ignores keys it does not recognise. Tools that omit `hostExtras` see no behavior change. | ||
| ## MCP adapter | ||
| ### MCP adapter | ||
@@ -224,3 +239,3 @@ ```ts | ||
| ## Custom host typing | ||
| ### Custom host typing | ||
@@ -260,4 +275,21 @@ Default portable tools accept the built-in host union: | ||
| ## Package and release checklist | ||
| ## Best practices | ||
| Tool definition best practices: | ||
| - Keep tool files host-neutral: no pi imports, no MCP SDK imports. | ||
| - Use TypeBox `Type.Object(...)` schemas so MCP can expose input schemas directly. | ||
| - Return `text` for model-visible output and `structuredContent` for machine-readable data. | ||
| - Use `isError: true` for expected/domain failures that should be represented as tool output. | ||
| - Throw only for unexpected programmer, adapter, or runtime failures. | ||
| - Respect `ctx.signal` in long-running tools. | ||
| - Use `ctx.progress?.(...)` for incremental updates. | ||
| - Keep modules import-passive; do not register tools or start servers at import time. | ||
| - For stateful tools, export a `createTools()` factory instead of a module-level singleton so each host runtime gets isolated state. | ||
| - TypeBox validation happens before `execute`; use a permissive schema plus domain validation if you need custom guidance for structurally invalid input. | ||
| ## Packaging | ||
| Package and release checklist: | ||
| - Publish compiled JavaScript plus generated `.d.ts` declarations for runtime entrypoints. | ||
@@ -276,1 +308,10 @@ - Keep `exports`, `main`, and `types` aligned with built files. | ||
| See `examples/README.md` for complete copyable examples. | ||
| ## For coding agents | ||
| Read these files in order: | ||
| 1. `README.md` — public API, contracts, and best practices. | ||
| 2. `llms.txt` — compact agent-facing usage rules and anti-patterns. | ||
| 3. `examples/README.md` — copyable layouts for shared tools, pi extensions, MCP stdio servers, and custom hosts. | ||
| 4. Published declarations such as `dist/src/index.d.ts`, `dist/src/pi.d.ts`, and `dist/src/mcp.d.ts` — canonical installed-package type contracts. In a source checkout, the matching `src/` files contain the same implementation context. |
119937
1.79%311
15.19%