Plugins
Plugins extend Open Astra at runtime — adding custom tools, API routes, event handlers, and agent configurations without modifying the core codebase. Plugins are auto-discovered from the plugins/core/ directory at startup and participate in the full gateway lifecycle.
Plugin lifecycle
text
Gateway startup:
1. discoverPlugins("plugins/core/")
→ Scan directory for subdirectories
→ Each must have index.js or index.ts
→ Dynamic import, validate name + init fields
2. initPlugins(plugins, context)
→ Call plugin.init(ctx) on each
→ Emit "plugin.loaded" or "plugin.error" event
3. startPlugins(plugins)
→ Call plugin.start() on each (after HTTP server is ready)
Gateway shutdown:
4. stopPlugins(plugins)
→ Call plugin.stop() in reverse order (LIFO)Reverse shutdown. Plugins are stopped in reverse order (last loaded, first stopped). This ensures plugins that depend on earlier-loaded plugins are cleaned up before their dependencies.
GatewayPlugin interface
typescript
interface GatewayPlugin {
name: string // unique identifier
version: string // semver string
init(ctx: PluginContext): Promise<void> | void
start?(): Promise<void> | void // called after HTTP is ready
stop?(): Promise<void> | void // called on graceful shutdown
}Plugin context
The PluginContext is injected into every plugin's init() call, providing access to the core gateway systems.
typescript
interface PluginContext {
app: Express // the Express app — mount routes, middleware
resolveClient: (config) => InferenceClient // get an inference client
getEventBus: () => EventBus // subscribe to / emit events
registerTool: (tool) => void // add tools to the registry
registerAgentConfig: (id, config) => void // register new agents
logger: { info, error } // scoped logger
}| Capability | Method | Use case |
|---|---|---|
| Custom routes | ctx.app | Mount REST endpoints, webhooks, or middleware |
| Custom tools | ctx.registerTool() | Add tools agents can call |
| Custom agents | ctx.registerAgentConfig() | Register new agent configurations |
| Event handling | ctx.getEventBus() | React to agent completions, tool calls, memory writes, etc. |
| Inference | ctx.resolveClient() | Make inference calls from plugin code |
Discovery
Plugins are auto-discovered from subdirectories of plugins/core/. Each subdirectory must contain an index.js or index.ts entry point.
text
plugins/
└── core/
├── my-plugin/
│ └── index.ts ← discovered automatically
├── analytics/
│ └── index.ts
└── custom-channel/
└── index.tsHot reload
In development mode, the gateway watches the plugins/core/ directory for changes. When a plugin file changes, it's re-imported with a 1000ms debounce. Syntax errors cause the reload to roll back — the previous version continues running.
Plugin events
| Event | When |
|---|---|
plugin.loaded | Plugin successfully initialized |
plugin.error | Plugin failed to initialize (logged, other plugins continue) |
Next steps
- Creating a Plugin — step-by-step guide to building your first plugin
- Creating a Tool — tool registration reference
- Event System — all available events to subscribe to