Skip to main content

Creating Plugins

Build custom plugins to extend FrontMCP with cross-cutting capabilities like caching, authorization, logging, and more.
Nx users: Scaffold with nx g @frontmcp/nx:plugin my-plugin --project my-app. See Plugin Generator.

Plugin Architecture

FrontMCP plugins use the @Plugin decorator and typically extend DynamicPlugin. They can:
  1. Register providers — Services available to the plugin and exported to the host app
  2. Contribute tools, resources, and skills — Add capabilities when the plugin is attached
  3. Intercept flows via hooks — Run code before/after specific stages using @ToolHook and @ListToolsHook
  4. Accept configuration — Via init() for runtime customization
  5. Extend metadata — Add custom fields to tool metadata

Basic Plugin

Registering a Plugin

Attach plugins at the app level:

Adding Hooks

Plugins intercept flow stages using @ToolHook and @ListToolsHook decorators:

Hook Timing

  • .Will(stage) — runs before the stage
  • .Did(stage) — runs after the stage

Priority

Lower numbers run first:

Dynamic Providers

For plugins that create providers based on configuration:

Options named like plugin metadata, and option-derived tools

init(options) spreads your options into the plugin’s metadata, so an option whose name matches a list-valued metadata key (tools, resources, prompts, skills, adapters, plugins, exports) used to be read as that list. RememberPlugin.init({ tools: { enabled: true } }) crashed at startup for that reason. A value that is not an array under one of those keys is now an option and is left out of the metadata; an array still contributes, as before. A plugin that registers tools only when an option asks for it declares static dynamicTools(options), the counterpart of dynamicProviders. Its tools are added to the ones from @Plugin({ tools }) and from an array tools option:
dynamicTools runs for init(options); init({ inject, useFactory }) takes its tools from the @Plugin metadata, since the options are not known until the factory runs.

Extending Tool Metadata

Plugins can add custom fields to tool metadata via global type augmentation:
Tools can then use this metadata:
When a field asks your plugin to protect the entry (a gate, not an optimization like cache), declare it with enforcesMetadata on the plugin class whose hooks enforce it:
A server where an entry declares requireMfa and no hook of such a plugin reaches it (in tools/call for tools and agents, resources/read for resources, prompts/get for prompts, skills:filter for skills) refuses to start with UnenforcedMetadataError. The key is known as soon as the plugin class is loaded. FrontMCP’s own approval and featureFlag fields are checked even when their plugin is never loaded.

Contributing Tools and Skills

Plugins can contribute tools and skills via the @Plugin decorator:

Publishing Plugins

package.json

Next Steps

Plugin Guide

Full plugin API reference with hooks, scopes, and DynamicPlugin details

Create a Plugin

Step-by-step tutorial building a real-world plugin

Cache Plugin

Study the built-in cache plugin implementation

Community

Share your plugin with the community