createCallTracker
Creates a counter for a tool's calls, so its unregistration can wait for them.
Creates a counter for a tool’s calls, so its unregistration can wait for them. Pair it with deferRelease and pass it as calls to registerWebTool; the registry and useWebTool already do, so you reach for it only when you register tools yourself.
Import
import { createCallTracker } from "@webmcp-agents/core";
import type { CallTracker } from "@webmcp-agents/core";
Example
Count the calls of one registration, and ask whether it is safe to unregister it. deferRelease does the waiting for you.
import {
createCallTracker,
defineWebTool,
registerWebTool,
} from "@webmcp-agents/core";
const tool = defineWebTool({
id: "get_time",
description: "Read the time.",
readOnly: true,
execute: () => new Date().toISOString(),
});
// registerWebTool counts each call of the tool on this tracker.
const calls = createCallTracker();
export const unregister = registerWebTool(tool, { calls });
// You can count your own work on it too.
export async function refresh(load: () => Promise<void>) {
await calls.track(load);
}
// While a call runs, and for 500 ms after the last one settled.
export const canUnregister = () => !calls.busy();
Options
None: createCallTracker() takes no arguments.
Returns
A CallTracker:
| Name | Type | Description |
|---|---|---|
track(call) |
<T>(call: () => T | Promise<T>) => Promise<T> |
Run one call and count it until it settles. Resolves or rejects with the call’s own outcome. |
busy() |
() => boolean |
true while a call runs, and for RESPONSE_GRACE_MS (500 ms) after the last one settled. |
Notes
- The grace after the last call gives the browser time to deliver the answer before the tool changes.
busyis a plain function and can be passed asisBusywithout binding.- A rejected call still counts as settled: the counter drops in a
finally. - Each tool needs its own tracker: it counts calls, not which tool they were for.
See also
- Tools across your app, where tools turn on and off
deferReleaseregisterWebToolcreateToolRegistry