Plugin Architecture
A FrontMCP plugin can:- Register providers - Services available to the plugin and optionally exported to the host app
- Contribute tools - Add tools that become available when the plugin is attached
- Intercept flows via hooks - Run code before/after specific stages (caching, validation, logging)
- Accept configuration - Via
init()for runtime customization - Extend metadata - Add custom fields to tool metadata for plugin-specific behavior
Step 1: Create the Plugin Structure
Step 2: Define Types
Start by defining your plugin’s options and any metadata extensions.site-authorization.types.ts
Step 3: Create the Plugin Class
Simple Plugin (No Required Options)
For plugins that work without configuration:site-authorization.plugin.ts
Usage
Step 4: Add Dynamic Providers
For plugins that need to create providers based on configuration:cache.plugin.ts
Step 5: Type-Safe Options with Zod
For plugins with complex options and defaults, use Zod:my-plugin.types.ts
my-plugin.plugin.ts
Step 6: Using Factory Pattern
For async initialization or injecting other providers:Step 7: Export the Plugin
index.ts
Hook Reference
Available Hooks
| Hook | Flow | Stages |
|---|---|---|
ToolHook | tools:call-tool | parseInput, findTool, createToolCallContext, acquireQuota, acquireSemaphore, validateInput, execute, validateOutput, releaseSemaphore, releaseQuota, finalize |
ListToolsHook | tools:list-tools | parseInput, findTools, resolveConflicts, parseTools |
Hook Timing
Priority
Lower numbers run first. Common conventions:| Priority | Use Case |
|---|---|
| 100-500 | Critical security checks |
| 500-900 | Authorization, validation |
| 900-1000 | Standard plugin behavior |
| 1000+ | Logging, metrics |
FlowCtxOf State
Access flow state in hooks:Error Handling in Hooks
Hooks should handle errors gracefully, especially in non-critical paths:- Authorization hooks - Throw errors to block execution
- Caching/logging hooks - Catch errors and continue gracefully
- Cleanup hooks (Did) - Always wrap in try/catch to avoid breaking the response
Best Practices
- Use descriptive names - Plugin name should be lowercase with hyphens
- Provider naming - Use
plugin-name:provider-nameformat - Default options - Always provide sensible defaults
- Guard hooks early - Check for required state before processing
- Don’t throw in cleanup - Wrap finalize hooks in try/catch
- Document metadata extensions - If extending
ExtendFrontMcpToolMetadata - Export types - Export options types for consumers
- Type-safe authInfo access - Use helper methods to safely extract user data
Complete Example
See the built-in plugins for complete examples:- CachePlugin - Caching with Redis/memory, hooks, dynamic providers
- CodeCallPlugin - Complex plugin with tools, multiple providers, Zod validation
- SiteAuthorizationPlugin - Simple authorization plugin with hooks

