Scopes
A scope groups tools. Its path prefixes the names of the tools registered into it, it can hide all of them at once, and disposing it removes all of them (spec §5).
ts
const challenges = tm.scope('challenges')
const create = challenges.scope('create', { when: false }) // hidden until shown
tm.register({ name: 'fill', description: '…', input, run }, { scope: create }) // full name: challenges.create.fill
create.setWhen(true) // the tools appear in manifest() and become callable
challenges.dispose() // removes challenges.* including challenges.create.*- Nesting is only through
scope.scope(name);tm.scopecreates root-level scopes. when: falsehides a scope's tools (and its descendants') frommanifest()andcall(); a call getsrefusedunknown_tool. Use it for tabs, dialogs and steps that are not on screen.- Transparent scopes (
{ transparent: true }) group tools forwhenand disposal without adding a name segment, so tools keep the names they were given (server-declared tools use this). - Disposal unregisters the scope's tools and drops their pending confirmations. Registering into a disposed scope is
scope_disposed. - Queues. Calls run serially per scope in arrival order; separate scopes run in parallel (D22). A tool that ignores its aborted signal is abandoned after
abortGraceMs(default 5000) and its queue slot released. - Deadline without a caller signal. A run with no caller
signal(atm.callwithout one, the run aconfirmPendingapproval starts, anundorestorer) is aborted aftercallTimeoutMs(default 120000) and then abandoned after the grace period withcancelledsignal, so a hung tool cannot hold its scope queue forever. A caller that passes asignalowns the deadline instead. The deadline is paused while an inlinectx.confirmis open (that wait is bounded byconfirmExpiryMs) and resumes with the time that was left, so the operator's answer time never counts against the run.
In React, <ToolScope name="create" when={open}> creates a scope for its subtree; hooks inside it register into it (see React).
API: Scope, ScopeOptions.