@mcptrail/webmcp-testing
v0.1.0
Published
Test WebMCP tools without a flagged Chrome or a live model: a mock navigator.modelContext plus a driver to list, validate-args, invoke, and snapshot the toolset.
Maintainers
Readme
@mcptrail/webmcp-testing
Test your WebMCP tools without a flagged Chrome or a live model. It installs a mock navigator.modelContext, captures the tools your page registers, and gives you a driver to list, validate-args, invoke, and snapshot the toolset — so tools become plain unit tests.
Works with any runner (Vitest, Jest, Playwright, Node) in any DOM-ish environment.
Install
npm install -D @mcptrail/webmcp-testingUsage
import { installModelContext } from "@mcptrail/webmcp-testing";
test("book_hotel books a room", async () => {
const mcp = installModelContext(); // mocks navigator.modelContext
renderMyApp(); // your code calls navigator.modelContext.registerTool(...)
expect(mcp.has("book_hotel")).toBe(true);
const result = await mcp.call("book_hotel", { hotelId: "h1", guests: 2 });
expect(result).toContain("Confirmation");
expect(document.querySelector("#bookings")).toHaveTextContent("h1");
mcp.uninstall();
});Driver API
const mcp = installModelContext(options);
mcp.tools(); // ToolDescriptor[] (name, description, inputSchema, annotations, readOnly)
mcp.tool(name); // one descriptor
mcp.has(name); // boolean
await mcp.call(name, args); // run execute(args), await, return the result
mcp.validate(name, args); // { valid, errors[] } against the tool's inputSchema
mcp.assertValid(name, args); // throw if invalid
mcp.snapshot(); // { tools[], hash } — serializable + a stable hash for drift assertions
mcp.reset(); // clear the registry
mcp.uninstall(); // restore the previous modelContext
mcp.onRegister(cb); // (tool) => void
mcp.onCall(cb); // (name, args, result) => voidOptions
| Option | Default | Notes |
|--------|---------|-------|
| strict | false | call() validates args against the schema and rejects on error |
| target | navigator | object to receive .modelContext (created on globalThis if absent) |
| alsoDocument | true | also set document.modelContext |
Arg validation
validate / assertValid / strict check args against a common JSON-Schema subset — type, required, enum, minimum/maximum, minLength/maxLength, nested objects and arrays. Catches "the model sent the wrong shape" in a test instead of production.
import { validateArgs } from "@mcptrail/webmcp-testing";
validateArgs(schema, args); // { valid, errors: [{ path, message }] }Drift snapshots
snapshot() returns a sorted, serializable view of the toolset plus a stable hash — pair it with toMatchSnapshot(), or assert the hash is unchanged to catch an unexpected change to what your page exposes to agents.
Development
npm install
npm run typecheck
npm test # Vitest + jsdom
npm run build # tsup → dist (ESM + CJS + d.ts)License
MIT © Zied Guetari
