Plugin System Overview

Learn how the CloudCLI UI plugin system works — architecture, capabilities, and what you can build.

Plugin System Overview

The plugin system lets you add custom functionality to CloudCLI UI. A plugin is a small project you install from a Git repository. Once installed, it shows up as a new tab in the app and can do things like scan your project files, call external APIs, or display custom dashboards.

Where Plugins Appear

Plugins show up in two places:

  1. The tab bar — Each enabled plugin adds a tab next to the built-in tabs (Chat, Shell, Files, Git, Tasks). Click it to open the plugin.
  2. Settings → Plugins — Where you install, enable/disable, update, and uninstall plugins.

Plugin tabs sit at the same level as the built-in tabs. When you click a plugin tab, it takes over the main content area just like Chat or Files would.

What Plugins Can Do

Frontend (runs in the browser)

  • Render any UI inside their tab — plain HTML, styled components, charts, dashboards, forms, anything you can build with vanilla JavaScript and the DOM
  • Know which project is selected — receive the project name and filesystem path
  • Know which session is active — receive the session ID and title
  • Adapt to the theme — know whether dark or light mode is active and update in real time when it changes
  • Load assets — serve CSS, images, fonts, and other files from their plugin directory

Backend (optional Node.js server)

  • Access the filesystem — read files, scan directories, watch for changes
  • Call external APIs — use secret API keys that are injected securely into each request
  • Run computations — process data, run analysis, generate reports
  • Use npm packages — dependencies are installed automatically from your package.json
  • Keep state in memory — cache results between requests since the server stays running

What Plugins Cannot Do

Plugins are scoped to their own tab. They cannot:

  • Modify the Chat, Shell, Files, Git, or Tasks tabs — plugins don't have access to the built-in UI
  • Send messages to Claude — there is no API to interact with the chat or agent
  • Appear in the sidebar, toolbar, or status bar — plugins can only live in the tab area
  • Access other plugins — each plugin is independent, with no inter-plugin communication
  • Read the user's auth tokens or session cookies — authentication is handled by the host and never exposed
  • Intercept or modify requests — plugins can't act as middleware on other features

How It Works

A plugin is an ES module — a JavaScript file that exports a mount function. When you open the plugin tab, the host calls mount(container, api) with:

  • A DOM element (container) you render your UI into
  • An API object (api) with three things:
    • api.context — the current theme, project, and session
    • api.onContextChange(callback) — get notified when any of those change
    • api.rpc(method, path, body?) — call your backend server through the host's proxy

When the tab closes, unmount(container) is called so you can clean up.

┌─────────────────────────────────────────────────┐
│  CloudCLI UI (Browser)                          │
│                                                 │
│  ┌─────┬───────┬───────┬─────┬────────────────┐ │
│  │ Chat│ Shell │ Files │ Git │ YOUR PLUGIN ◄──┼─┤
│  └─────┴───────┴───────┴─────┴────────────────┘ │
│  ┌───────────────────────────────────────────┐   │
│  │  Your plugin's tab content                │   │
│  │  ┌──────────────────────────────────────┐ │   │
│  │  │  mount(container, api)               │ │   │
│  │  │       │                              │ │   │
│  │  │       │ api.rpc('GET', '/data')      │ │   │
│  │  │       ▼                              │ │   │
│  │  │  ┌─────────────────────────────┐     │ │   │
│  │  │  │ Host proxy (adds auth +     │     │ │   │
│  │  │  │ secrets, forwards to server)│     │ │   │
│  │  │  └──────────────┬──────────────┘     │ │   │
│  │  └─────────────────┼────────────────────┘ │   │
│  └────────────────────┼──────────────────────┘   │
└───────────────────────┼──────────────────────────┘
                        │
┌───────────────────────┼──────────────────────────┐
│  Your plugin server   │  (Node.js subprocess)    │
│  127.0.0.1:<port> ◄───┘                          │
│  • Receives secrets as x-plugin-secret-* headers │
│  • Full filesystem + network access              │
└──────────────────────────────────────────────────┘

Plugin Directory Structure

Plugins live in ~/.claude-code-ui/plugins/. Each plugin is a folder:

~/.claude-code-ui/plugins/
└── my-plugin/
    ├── manifest.json      # Required — tells the host about your plugin
    ├── index.js           # Required — your frontend code
    ├── server.js          # Optional — your backend server
    ├── package.json       # Optional — npm dependencies for your server
    └── ...                # Any other files (CSS, images, etc.)

Installing a Plugin

  1. Go to Settings → Plugins
  2. Paste a Git URL (e.g. https://github.com/user/my-plugin.git)
  3. Click Install

The host clones the repo, validates the manifest, installs dependencies, starts the server (if any), and your tab appears. That's it.

Managing Plugins

From Settings → Plugins you can:

  • Enable/disable — toggle the switch to show or hide the plugin tab
  • Update — click the refresh button to pull the latest code from Git
  • Uninstall — click the trash icon (requires confirmation) to remove completely

Plugin state is saved in ~/.claude-code-ui/plugins.json and persists across restarts.

What's in This Guide

PageWhat You'll Learn
Getting StartedBuild a working plugin step by step
Manifest ReferenceEvery field in manifest.json explained
Frontend APIThe api object — context, events, and RPC calls
Backend ServersRunning a server subprocess, secrets, and lifecycle
Security ModelHow plugins are isolated and secured
Example: Project StatsWalkthrough of the built-in example plugin

Last updated March 6, 2026