Skip to main content

Function: createToolGate()

createToolGate(__namedParameters?): ToolGate

Defined in: toolGate.ts:202

Factory for a gate: a function that wraps a Tool so every call passes the same authentication and authorization pipeline before its handler runs. The gated tool is an ordinary Tool, so it registers directly or joins a catalog like any other.

Every gated call:

  1. Resolves the caller identity (default: getIdentity()). Returns an isError result when the identity is absent (unauthenticated request).
  2. When enforceScope is true (default), checks requiredScope — returns an isError result when the scope is absent, consistent with how MCP surfaces authorization errors.
  3. Runs global gates then the tool's gates in order; a throwing gate rejects the call. Every gate receives the full ToolCallContext.
  4. Merges buildContext output into the handler args.
  5. Calls onError on handler throw before rethrowing.
  6. With i18n, renders a LocalizedError from a gate or the handler as an isError result in the caller's locale instead of rethrowing it.

Parameters​

ParameterType
__namedParametersCreateToolGateOptions

Returns​

ToolGate

Example​

const gate = createToolGate({
resolveIdentity: () => {
const jwt = getIdentity<{ sub: string; scopes: string[] }>();
return { userId: jwt!.sub, scopes: jwt!.scopes };
},
});

registerTools({
server,
tools: [
gate({
requiredScope: 'campaigns:write',
// arg-conditional gate: active vs. inactive have different restrictions
gates: [
({ args }) =>
args.isActive
? subscriptionGate(['mustNotExceedMaxActive', 'mustHaveBudget'])
: subscriptionGate(['mustIncludeService']),
],
tool: defineTool({
name: 'activate-campaign',
description: 'Activate or deactivate a campaign.',
inputSchema: z.object({ isActive: z.boolean() }),
method: ({ userId, isActive }) => toggleCampaign(userId, isActive),
}),
}),
],
});