@mcptrail/webmcp-kit
v0.1.0
Published
Type-safe defineTool for WebMCP: infer execute() arg types from a JSON Schema, with optional runtime validation. Zero deps.
Downloads
58
Maintainers
Readme
@mcptrail/webmcp-kit
Author WebMCP tools with full type safety and zero dependencies. defineTool infers your execute handler's argument type straight from its JSON Schema at the type level — required vs. optional props, primitive types, and even enum literal unions — so the compiler catches a wrong shape before an agent ever calls it. Opt into runtime validation with a single flag.
Install
npm install @mcptrail/webmcp-kitUsage
import { defineTool, toolset, registerTools } from "@mcptrail/webmcp-kit";
const searchHotels = defineTool({
name: "search_hotels",
description: "Search available hotels",
inputSchema: {
type: "object",
properties: {
city: { type: "string" },
guests: { type: "integer", minimum: 1 },
cabin: { type: "string", enum: ["economy", "business"] },
},
required: ["city"],
},
readOnly: true,
validate: true, // execute() checks args at runtime and throws on a bad shape
execute: (args) => {
// args is typed as { city: string; guests?: number; cabin?: "economy" | "business" }
return `Searching ${args.city} for ${args.guests ?? 1} guest(s)`;
},
});
// Register the whole set into navigator.modelContext (a no-op off-page).
registerTools(toolset(searchHotels));The headline: args above is inferred as { city: string; guests?: number; cabin?: "economy" | "business" } — no manual type annotation, no code generation.
API
| Export | Signature | Notes |
|--------|-----------|-------|
| defineTool | defineTool(spec) => WebMcpTool | Infers execute(args) from spec.inputSchema. validate: true wraps execute with a runtime guard; readOnly sets annotations.readOnlyHint |
| toolset | toolset(...tools) => WebMcpTool[] | Collect tools into an array |
| registerTools | registerTools(tools, target?) => void | Register each into (target ?? navigator).modelContext.registerTool when present |
| validateArgs | validateArgs(schema, args) => { valid, errors } | Common JSON-Schema subset: type, required, enum, minimum/maximum, minLength/maxLength, nested objects and arrays |
| InferArgs<S> | type | The type-level schema → args mapping, exported for your own helpers |
Type inference rules
For an { type: "object", properties, required } schema, each property maps by its type — string → string, number/integer → number, boolean → boolean, array → unknown[], object → Record<string, unknown>. A statically-known enum of string literals becomes a union of those literals. Keys in required are required; the rest are optional. Non-object schemas infer as unknown.
Development
npm install
npm run typecheck
npm test # Vitest + jsdom
npm run build # tsup → dist (ESM + CJS + d.ts)License
MIT © Zied Guetari
