Basic Plugin
A simple plugin uses the@Plugin decorator:
Using Plugins
Attach plugins at app scope:Dynamic Plugin with Options
For plugins that need runtime configuration, extendDynamicPlugin:
Type-Safe Options with Zod
For complex options with defaults, use Zod schemas with two types:my-plugin.types.ts
my-plugin.plugin.ts
Adding Hooks
Plugins can intercept flow stages using hooks. Usethis.get(Token) to access providers:
Contributing Skills
Plugins can contribute skills that teach AI how to perform workflows using the plugin’s tools:searchSkills results alongside app-level skills and can be loaded with loadSkill.
Available Hooks
ToolHook (tools:call-tool)
Intercept tool execution flow:| Stage | Phase | Description |
|---|---|---|
parseInput | pre | Parse and validate request |
findTool | pre | Locate the requested tool |
createToolCallContext | pre | Create execution context |
acquireQuota | pre | Rate limiting |
acquireSemaphore | pre | Concurrency control |
validateInput | execute | Validate tool input against schema |
execute | execute | Run the tool |
validateOutput | execute | Validate tool output |
releaseSemaphore | finalize | Release concurrency |
releaseQuota | finalize | Release rate limit |
finalize | finalize | Format and return response |
ListToolsHook (tools:list-tools)
Intercept tool listing flow:| Stage | Phase | Description |
|---|---|---|
parseInput | pre | Parse request |
findTools | execute | Collect available tools |
resolveConflicts | execute | Handle name conflicts |
parseTools | post | Format tool descriptors |
Hook Timing
.Will(stage)- runs before the stage.Did(stage)- runs after the stage
DynamicPlugin API
| Type Parameter | Description |
|---|---|
TOptions | Resolved options type (after defaults). Use internally. |
TInput | Input options type (for init()). Defaults to TOptions. |
The
init() method accepts your plugin’s input options type and returns a provider
configuration that the framework uses internally. You don’t need to import or reference
the return type—just pass the result directly to the plugins array.Extending Tool Metadata
Plugins can extend the global tool metadata interface:Plugin Scope
By default, plugins operate at the app scope - their hooks only fire for requests to that specific app. For cross-app functionality, you can use server scope.App Scope (Default)
Hooks fire only for requests to the app where the plugin is registered:Server Scope
Hooks fire at the gateway level for all apps in the server:When to Use Each Scope
| Use Case | Scope | Example |
|---|---|---|
| App-specific caching | app | Cache responses for one app only |
| Per-app rate limiting | app | Different limits per app |
| Global audit logging | server | Log all tool calls across apps |
| Cross-app orchestration | server | Access tools from multiple apps |
| Authentication gateway | server | Validate tokens before any app |
Accessing Other Apps (Server Scope)
Server-scoped plugins can access other apps viascope.apps: