Skip to content

Repository files navigation

@mcptrail/use-model-tool

CI License: MIT

React hooks that bind WebMCP tool registration to component lifecycle. A tool is registered when its component mounts and unregistered when it unmounts — so the AI agent only ever sees the tools for what's currently on screen.

No context provider, no global tool registry to keep in sync with your UI. Register a tool where it makes sense, and React's lifecycle keeps the agent's view honest.

Install

npm install @mcptrail/use-model-tool

react (^18.2.0 || ^19.0.0) is a peer dependency.

Usage

import { useModelTool } from "@mcptrail/use-model-tool";

function CheckoutPanel({ cartId }: { cartId: string }) {
  useModelTool({
    name: "apply_coupon",
    description: "Apply a discount coupon to the current cart",
    inputSchema: {
      type: "object",
      properties: { code: { type: "string" } },
      required: ["code"],
    },
    execute: async (args) => {
      const { code } = args as { code: string };
      return applyCoupon(cartId, code);
    },
  });

  return <div>/* ...checkout UI... */</div>;
}

When CheckoutPanel is mounted, the agent can call apply_coupon. Navigate away and the tool is gone — the agent can no longer call it.

Register several tools from one component with useModelTools:

import { useModelTools } from "@mcptrail/use-model-tool";

function TableTools({ rows }: { rows: Row[] }) {
  useModelTools([
    { name: "sort_table", description: "Sort the visible table", execute: sort },
    { name: "filter_table", description: "Filter the visible table", execute: filter },
  ]);

  return <Table rows={rows} />;
}

API

useModelTool(tool, deps?)

Registers a single tool on mount and unregisters it on unmount. Pass deps to re-register when they change (defaults to [] — register once).

useModelTools(tools, deps?)

Registers every tool on mount and cleans them all up on unmount. Pass deps to re-register the set when they change (defaults to []).

registerModelTool(tool, target?): () => void

The pure, framework-free core the hooks are built on. Resolves the ambient modelContext (prefers target, then navigator, then document), calls registerTool(tool), and returns a cleanup fn:

  • if registerTool returned a disposer, cleanup calls its .unregister();
  • else if the modelContext exposes unregisterTool(name), cleanup calls that;
  • else cleanup is a no-op.

If no modelContext is available, registerModelTool is a no-op and returns a no-op cleanup — safe to call during SSR or in non-WebMCP browsers.

WebMcpTool

interface WebMcpTool {
  name: string;
  description?: string;
  inputSchema?: JSONSchema;
  annotations?: { readOnlyHint?: boolean; [k: string]: unknown };
  execute: (args: unknown) => unknown;
}

Development

npm install
npm run typecheck
npm test          # Vitest + jsdom
npm run build     # tsup → dist (ESM + CJS + d.ts)

License

MIT © Zied Guetari

About

React hooks that register/unregister WebMCP tools with component lifecycle — the agent only sees tools for what's currently on screen.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages