Skip to main content
Hooks allow you to intercept and modify tool execution at specific lifecycle stages. Use hooks to add cross-cutting concerns like validation, logging, auditing, rate limiting, and data transformation without modifying individual tools.

Core Concepts

Flows

Named execution pipelines with defined stages (e.g., tools:call-tool, http:request)

Hook Types

Will (before), Did (after), Around (wrap), Stage (one more step of the stage)

Priority

Within a stage, a lower priority runs first, for Will, Did and Stage hooks alike

Context

The running flow, typed FlowCtxOf<'flow-name'>: its typed state, logger and provider lookup

Hook Types

Runs before a stage executes. Use for:
  • Input validation
  • Pre-processing
  • Short-circuiting execution
  • Setting up context

Available Flows

FrontMCP provides pre-defined hooks for common flows. Each flow has its own stages; a hook names one of them:
Hiding a tool from tools/list does not stop a client that knows its name from calling it; gate the call in tools:call-tool too.
You can also create custom flows using FlowHooksOf('custom-flow-name') for application-specific pipelines.

Complete Examples

Example 1: Request Validation & Auditing

Example 2: Error Handling & Retries

An Around hook sees a failing stage as a rejected next(), and can call next() again to retry it. A Did hook runs only after its stage succeeded, so failures are logged here.

Example 3: Data Transformation Pipeline


Priority System

Priority sets the order within a stage: a lower priority runs first, for Will, Did and Stage hooks alike. Hooks with the same priority run in the order they were registered.
To run a Will hook before everything else, give it a very low priority (the observability plugin uses -1000). To run a Did hook after everything else, give it a very high one (1000).

Flow Context

A hook receives the running flow, typed FlowCtxOf<'flow-name'>. It has:
  • state - The flow’s state, typed per flow (tool, toolContext, input, authInfo, resultMeta, … for tools:call-tool)
  • rawInput - The input the flow was started with
  • logger - Logger instance for this flow
  • get(token) - Resolves a provider
  • respond(output) / fail(error) - End the flow with an output or an error
The state accepts only the keys the flow declares. The flow has no error or metrics member: a Did hook runs only after its stage succeeded, so observe failures from an Around hook. See Hook Context for details.
randomUUID comes from @frontmcp/utils.

Hook Registry API

For advanced use cases, you can programmatically access hooks using the Hook Registry API. This is useful when building custom flow orchestration or when you need to dynamically query which hooks are registered.

Accessing the Hook Registry

The registry is the scope’s hooks. A hook reaches the scope by resolving the ScopeEntry token; inside a tool, resource or prompt it is this.scope.

Registry Methods

Retrieves the plugin and provider hooks registered for a specific flow.

Example: Owner-Scoped Hook Filtering

The Hook Registry API is an advanced feature primarily intended for framework developers and complex plugin authors. Most users should use the decorator-based approach (@ToolHook, @HttpHook, etc.) instead.

Best Practices

Package related hooks into plugins to reuse across multiple apps:
  • Validation: Low priority (1-20)
  • Transformation: Medium priority (40-60)
  • Logging/Metrics (Did hooks): High priority (90-100)
Lower priorities run first, so validation runs before transformation, and late Did hooks capture everything.
Throw an MCP error class: a public error such as InvalidInputError reaches the client with its message and code. A plain Error becomes a generic server error, and in production the client sees only its error id.
The flow state accepts only the keys the flow declares, and a plugin serves every call, so this is shared. Keep per-call data in a local variable of an Around hook, or in a WeakMap keyed on ctx when separate hooks share it:
Hooks run for every tool execution. Keep them fast:
  • Use caching for expensive operations
  • Delegate heavy work to background jobs
  • Consider async/non-blocking operations

Plugin Documentation

Learn more about FrontMCP plugins

Tool Documentation

Understand tool lifecycle and execution

Cache Plugin

See hooks in action with the Cache Plugin