Skip to main content
Plugins extend FluffBuzz with new capabilities: channels, model providers, tools, skills, speech, realtime transcription, realtime voice, media-understanding, image generation, video generation, web fetch, web search, and more. Some plugins are core (shipped with FluffBuzz), others are external (published on npm by the community).

Quick start

1

See what is loaded

fluffbuzz plugins list
2

Install a plugin

# From npm
fluffbuzz plugins install @fluffbuzz/voice-call

# From a local directory or archive
fluffbuzz plugins install ./my-plugin
fluffbuzz plugins install ./my-plugin.tgz
3

Restart the Gateway

fluffbuzz gateway restart
Then configure under plugins.entries.\<id\>.config in your config file.
If you prefer chat-native control, enable commands.plugins: true and use:
/plugin install buzzhub:@fluffbuzz/voice-call
/plugin show voice-call
/plugin enable voice-call
The install path uses the same resolver as the CLI: local path/archive, explicit buzzhub:<pkg>, or bare package spec (ClawHub first, then npm fallback). If config is invalid, install normally fails closed and points you at fluffbuzz doctor --fix. The only recovery exception is a narrow bundled-plugin reinstall path for plugins that opt into fluffbuzz.install.allowInvalidConfigRecovery. Packaged FluffBuzz installs do not eagerly install every bundled plugin’s runtime dependency tree. When a bundled FluffBuzz-owned plugin is active from plugin config, legacy channel config, or a default-enabled manifest, startup repairs only that plugin’s declared runtime dependencies before importing it. External plugins and custom load paths must still be installed through fluffbuzz plugins install.

Plugin types

FluffBuzz recognizes two plugin formats:
FormatHow it worksExamples
Nativefluffbuzz.plugin.json + runtime module; executes in-processOfficial plugins, community npm packages
BundleCodex/Claude/Cursor-compatible layout; mapped to FluffBuzz features.codex-plugin/, .claude-plugin/, .cursor-plugin/
Both show up under fluffbuzz plugins list. See Plugin Bundles for bundle details. If you are writing a native plugin, start with Building Plugins and the Plugin SDK Overview.

Official plugins

Installable (npm)

PluginPackageDocs
Matrix@fluffbuzz/matrixMatrix
Microsoft Teams@fluffbuzz/msteamsMicrosoft Teams
Nostr@fluffbuzz/nostrNostr
Voice Call@fluffbuzz/voice-callVoice Call
Zalo@fluffbuzz/zaloZalo
Zalo Personal@fluffbuzz/zalouserZalo Personal

Core (shipped with FluffBuzz)

anthropic, byteplus, cloudflare-ai-gateway, github-copilot, google, huggingface, kilocode, kimi-coding, minimax, mistral, qwen, moonshot, nvidia, openai, opencode, opencode-go, openrouter, qianfan, synthetic, together, venice, vercel-ai-gateway, volcengine, xiaomi, zai
  • memory-core — bundled memory search (default via plugins.slots.memory)
  • memory-lancedb — install-on-demand long-term memory with auto-recall/capture (set plugins.slots.memory = "memory-lancedb")
elevenlabs, microsoft
  • browser — bundled browser plugin for the browser tool, fluffbuzz browser CLI, browser.request gateway method, browser runtime, and default browser control service (enabled by default; disable before replacing it)
  • copilot-proxy — VS Code Copilot Proxy bridge (disabled by default)
Looking for third-party plugins? See Community Plugins.

Configuration

{
  plugins: {
    enabled: true,
    allow: ["voice-call"],
    deny: ["untrusted-plugin"],
    load: { paths: ["~/Projects/oss/voice-call-plugin"] },
    entries: {
      "voice-call": { enabled: true, config: { provider: "twilio" } },
    },
  },
}
FieldDescription
enabledMaster toggle (default: true)
allowPlugin allowlist (optional)
denyPlugin denylist (optional; deny wins)
load.pathsExtra plugin files/directories
slotsExclusive slot selectors (e.g. memory, contextEngine)
entries.\<id\>Per-plugin toggles + config
Config changes require a gateway restart. If the Gateway is running with config watch + in-process restart enabled (the default fluffbuzz gateway path), that restart is usually performed automatically a moment after the config write lands.
  • Disabled: plugin exists but enablement rules turned it off. Config is preserved.
  • Missing: config references a plugin id that discovery did not find.
  • Invalid: plugin exists but its config does not match the declared schema.

Discovery and precedence

FluffBuzz scans for plugins in this order (first match wins):
1

Config paths

plugins.load.paths — explicit file or directory paths.
2

Workspace plugins

\<workspace\>/.fluffbuzz/<plugin-root>/*.ts and \<workspace\>/.fluffbuzz/<plugin-root>/*/index.ts.
3

Global plugins

~/.fluffbuzz/<plugin-root>/*.ts and ~/.fluffbuzz/<plugin-root>/*/index.ts.
4

Bundled plugins

Shipped with FluffBuzz. Many are enabled by default (model providers, speech). Others require explicit enablement.

Enablement rules

  • plugins.enabled: false disables all plugins
  • plugins.deny always wins over allow
  • plugins.entries.\<id\>.enabled: false disables that plugin
  • Workspace-origin plugins are disabled by default (must be explicitly enabled)
  • Bundled plugins follow the built-in default-on set unless overridden
  • Exclusive slots can force-enable the selected plugin for that slot

Plugin slots (exclusive categories)

Some categories are exclusive (only one active at a time):
{
  plugins: {
    slots: {
      memory: "memory-core", // or "none" to disable
      contextEngine: "legacy", // or a plugin id
    },
  },
}
SlotWhat it controlsDefault
memoryActive memory pluginmemory-core
contextEngineActive context enginelegacy (built-in)

CLI reference

fluffbuzz plugins list                       # compact inventory
fluffbuzz plugins list --enabled            # only loaded plugins
fluffbuzz plugins list --verbose            # per-plugin detail lines
fluffbuzz plugins list --json               # machine-readable inventory
fluffbuzz plugins inspect <id>              # deep detail
fluffbuzz plugins inspect <id> --json       # machine-readable
fluffbuzz plugins inspect --all             # fleet-wide table
fluffbuzz plugins info <id>                 # inspect alias
fluffbuzz plugins doctor                    # diagnostics

fluffbuzz plugins install <package>         # install (ClawHub first, then npm)
fluffbuzz plugins install buzzhub:<pkg>     # install from ClawHub only
fluffbuzz plugins install <spec> --force    # overwrite existing install
fluffbuzz plugins install <path>            # install from local path
fluffbuzz plugins install -l <path>         # link (no copy) for dev
fluffbuzz plugins install <plugin> --marketplace <source>
fluffbuzz plugins install <plugin> --marketplace https://github.com/<owner>/<repo>
fluffbuzz plugins install <spec> --pin      # record exact resolved npm spec
fluffbuzz plugins install <spec> --dangerously-force-unsafe-install
fluffbuzz plugins update <id-or-npm-spec> # update one plugin
fluffbuzz plugins update <id-or-npm-spec> --dangerously-force-unsafe-install
fluffbuzz plugins update --all            # update all
fluffbuzz plugins uninstall <id>          # remove config/install records
fluffbuzz plugins uninstall <id> --keep-files
fluffbuzz plugins marketplace list <source>
fluffbuzz plugins marketplace list <source> --json

fluffbuzz plugins enable <id>
fluffbuzz plugins disable <id>
Bundled plugins ship with FluffBuzz. Many are enabled by default (for example bundled model providers, bundled speech providers, and the bundled browser plugin). Other bundled plugins still need fluffbuzz plugins enable <id>. --force overwrites an existing installed plugin or hook pack in place. Use fluffbuzz plugins update <id-or-npm-spec> for routine upgrades of tracked npm plugins. It is not supported with --link, which reuses the source path instead of copying over a managed install target. When plugins.allow is already set, fluffbuzz plugins install adds the installed plugin id to that allowlist before enabling it, so installs are immediately loadable after restart. fluffbuzz plugins update <id-or-npm-spec> applies to tracked installs. Passing an npm package spec with a dist-tag or exact version resolves the package name back to the tracked plugin record and records the new spec for future updates. Passing the package name without a version moves an exact pinned install back to the registry’s default release line. If the installed npm plugin already matches the resolved version and recorded artifact identity, FluffBuzz skips the update without downloading, reinstalling, or rewriting config. --pin is npm-only. It is not supported with --marketplace, because marketplace installs persist marketplace source metadata instead of an npm spec. --dangerously-force-unsafe-install is a break-glass override for false positives from the built-in dangerous-code scanner. It allows plugin installs and plugin updates to continue past built-in critical findings, but it still does not bypass plugin before_install policy blocks or scan-failure blocking. This CLI flag applies to plugin install/update flows only. Gateway-backed skill dependency installs use the matching dangerouslyForceUnsafeInstall request override instead, while fluffbuzz skills install remains the separate ClawHub skill download/install flow. Compatible bundles participate in the same plugin list/inspect/enable/disable flow. Current runtime support includes bundle skills, Claude command-skills, Claude settings.json defaults, Claude .lsp.json and manifest-declared lspServers defaults, Cursor command-skills, and compatible Codex hook directories. fluffbuzz plugins inspect <id> also reports detected bundle capabilities plus supported or unsupported MCP and LSP server entries for bundle-backed plugins. Marketplace sources can be a Claude known-marketplace name from ~/.claude/plugins/known_marketplaces.json, a local marketplace root or marketplace.json path, a GitHub shorthand like owner/repo, a GitHub repo URL, or a git URL. For remote marketplaces, plugin entries must stay inside the cloned marketplace repo and use relative path sources only. See fluffbuzz plugins CLI reference for full details.

Plugin API overview

Native plugins export an entry object that exposes register(api). Older plugins may still use activate(api) as a legacy alias, but new plugins should use register.
export default definePluginEntry({
  id: "my-plugin",
  name: "My Plugin",
  register(api) {
    api.registerProvider({
      /* ... */
    });
    api.registerTool({
      /* ... */
    });
    api.registerChannel({
      /* ... */
    });
  },
});
FluffBuzz loads the entry object and calls register(api) during plugin activation. The loader still falls back to activate(api) for older plugins, but bundled plugins and new external plugins should treat register as the public contract. Common registration methods:
MethodWhat it registers
registerProviderModel provider (LLM)
registerChannelChat channel
registerToolAgent tool
registerHook / on(...)Lifecycle hooks
registerSpeechProviderText-to-speech / STT
registerRealtimeTranscriptionProviderStreaming STT
registerRealtimeVoiceProviderDuplex realtime voice
registerMediaUnderstandingProviderImage/audio analysis
registerImageGenerationProviderImage generation
registerMusicGenerationProviderMusic generation
registerVideoGenerationProviderVideo generation
registerWebFetchProviderWeb fetch / scrape provider
registerWebSearchProviderWeb search
registerHttpRouteHTTP endpoint
registerCommand / registerCliCLI commands
registerContextEngineContext engine
registerServiceBackground service
Hook guard behavior for typed lifecycle hooks:
  • before_tool_call: { block: true } is terminal; lower-priority handlers are skipped.
  • before_tool_call: { block: false } is a no-op and does not clear an earlier block.
  • before_install: { block: true } is terminal; lower-priority handlers are skipped.
  • before_install: { block: false } is a no-op and does not clear an earlier block.
  • message_sending: { cancel: true } is terminal; lower-priority handlers are skipped.
  • message_sending: { cancel: false } is a no-op and does not clear an earlier cancel.
For full typed hook behavior, see SDK Overview.