Benefits of Plugins
Extension Glossary
What is a Plugin?
A plugin is anAgentPlugin — an object that implements the SDK’s extension interface. It can register tools, hook into agent lifecycle events, and provide configuration defaults.
hooks object, not directly on the extension. The available lifecycle hooks are beforeRun, afterRun, beforeModel, afterModel, beforeTool, afterTool, and onEvent.
Next Steps
Register withClineCore:
File-Based Plugins
ClineCore supports plugin module paths via pluginPaths in session config:
AgentPlugin.
How Plugins Run
By default each plugin runs in its own worker thread, one per session, inside the host’s runtime. Module-level state is never shared between sessions, no separatenode or bun process is started (plugins work in the compiled CLI, the hub, and the desktop app without a runtime on PATH), and a plugin can use the host runtime’s globals, such as Bun under the Bun-built hub.
A worker contains its plugin’s failures:
- A plugin stuck in a loop is stopped at its timeout; the next call starts a fresh worker.
- An uncaught error, an unhandled rejection, or
process.exit()ends only that plugin’s worker. The plugin is markedfailedand turned off, like any other fatal plugin error, and the hub and other plugins keep running. - Plugin
console.logand stdout output are discarded, so they cannot corrupt--jsonoutput or a JSON-RPC stream. Usectx.logger.
process.cwd() reports the session’s directory, but relative file paths resolve against the host’s, so use ctx.cwd. Workers share the host’s memory limit, environment snapshot, and native addons: this is crash isolation, not a security boundary.
Plugin code never runs on the host’s main thread. One other mode is available as an opt-in through CLINE_PLUGIN_MODE (or mode on resolveAndLoadAgentPlugins):
sandbox: the previous per-session subprocess sandbox. A compiled Cline CLI uses its embedded Bun runtime; other hosts neednodeorbunonPATHwhen the host isn’tnodeorbunitself, and this mode does not apply the per-session plugin policy or report plugin status.
@cline/core should ship dist/plugin-runtime beside its bundle, or point CLINE_PLUGIN_RUNTIME_DIR at that directory. It includes the bootstrap and SDK package exports used by plugins. Compiled CLI binaries read this artifact directly from their embedded read-only filesystem, without installing SDK packages into each plugin directory. Hosts without a bootstrap fail closed with PluginBootstrapMissingError; plugin code never falls back to the host’s main thread.
Plugins are bound to a session when it starts. Adding, editing, or reloading a plugin affects only sessions started afterwards; running sessions keep the plugins and code they started with. Every new session imports the plugin fresh, so any change is picked up; cline hub plugins --reload <plugin> re-checks it and clears a failed status.
Choosing Plugins per Session
Pass aplugins policy when you start a session. It’s shaped like toolPolicies: "*" sets the default, and named entries override it for one plugin. Plugins are enabled unless a policy turns them off.
toolPolicies. The policy applies in worker mode; the opt-in sandbox mode loads every discovered plugin.
Setup and Call Context
setup(api, ctx) receives the session’s context:
When a session ends, the host runs your
onDispose callbacks. Plugins share the host process, so stop everything you start for a session there: timers, child processes, sockets, listeners on shared emitters.
cwd and emitEvent in their call context (execute(input, context)). globalThis.__clinePluginHost.emitEvent still works for plugins written for the sandbox; it routes to the session whose hook or tool is running.
Plugin Status and Errors
The host wraps every plugin call and records what goes wrong, so a broken plugin never just loses its tools silently.
Five failures in a row turn a
degraded plugin failed. An import failure, or five failed calls in a row, turns the plugin off for every session using it until it is reloaded or its source changes. A successful reload does not interrupt running sessions: they keep the copy they started with, and new sessions get the new code. A reload whose import fails turns the plugin off for running sessions too, and they are told why. In the hub, a stray exception or unhandled rejection whose stack points into a plugin marks that plugin failed instead of stopping the hub.
Each plugin has a status of loading, ready, degraded, failed, or disabled. Its last error records the phase (discover, import, setup, hook:<name>, tool:<name>, command:<name>, or uncaught), the message, the stack, the plugin path, and a timestamp. The status also counts errors and timeouts.
To read status:
StartSessionResult.pluginIssueslists the plugins the session asked for but doesn’t have.- Plugins that fail later in the session (
setup()and hooks run on the first turn) are reported to that session as a status notice event, with the issue inmetadata.pluginIssue. - Hub clients can send
plugins.status(orplugins.list) for every plugin’s status, last error, and the sessions using it.plugins.reloadwith{ plugin: "<name or path>" }re-imports one plugin without restarting the hub. The hub broadcasts aplugin.status_changedevent when a status changes.
Installing Plugins via CLI
Plugins can also be installed from file URLs, npm, git, or local paths usingcline plugin install. See Plugins for install commands, the manifest format, and directory layout.
Hooks
Plugin hooks are functions in the plugin’shooks object. Each one receives a context with the current runtime snapshot (agent id, conversation id, iteration, messages, usage), and some can return a result that changes what happens next.
To block dangerous tool calls, return
{ skip: true, reason } from beforeTool, or require approval with { policy: { autoApprove: false } }.
When a hook fails
Each plugin hook call has a 3-second timeout. If a hook throws, rejects, or times out, the session’shookErrorMode decides what happens:
A hook that keeps failing marks its plugin
degraded, then failed after five failures in a row. See Plugin Status and Errors.
Build a Plugin
For a step-by-step plugin tutorial, see Writing Plugins.SDK Examples
The SDK repository includes ready-to-run plugin examples underexamples/plugins/, including tool registration, lifecycle metrics, notifications, custom compaction, policy guards, web search, background jobs, TypeScript LSP tools, and multi-agent teams.
See Plugin Examples for the full list and usage commands.