> ## Documentation Index
> Fetch the complete documentation index at: https://praison.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# plugins add

> Install a plugin package from the CLI and verify it registered

One command installs a plugin package and tells you exactly which plugins registered — or exits non-zero if nothing did.

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph LR
    Cmd["🖥️ praisonai plugins add pkg"] --> Install["📦 pip / uv install"]
    Install --> Discover["🔍 discover_entry_points"]
    Discover --> Diff{"🆕 New plugins?"}
    Diff -->|yes| Table["✅ Registered table"]
    Diff -->|no| Fail["🛑 exit 1"]

    classDef input fill:#6366F1,stroke:#7C90A0,color:#fff
    classDef process fill:#F59E0B,stroke:#7C90A0,color:#fff
    classDef output fill:#10B981,stroke:#7C90A0,color:#fff
    classDef error fill:#8B0000,stroke:#7C90A0,color:#fff

    class Cmd input
    class Install,Discover,Diff process
    class Table output
    class Fail error
```

Previously a package could `pip install` cleanly yet register nothing — a silent failure. `plugins add` turns that into a surfaced non-zero exit.

## Quick Start

**1. Install a plugin**

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
praisonai plugins add praisonai-my-plugin
```

> [!NOTE]
>
> `praisonai-my-plugin` is a placeholder — replace it with a real pip requirement spec.

**2. Upgrade an installed plugin**

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
praisonai plugins add praisonai-my-plugin --upgrade
```

**3. Verify without installing**

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
praisonai plugins add praisonai-my-plugin --dry-run
```

`--dry-run` skips installation and reports whether anything **new** would register from what's already installed.

> [!TIP]
>
> After installing, run `praisonai plugins reload` to pick the plugin up in the current process without a restart — see [Plugins CLI → reload](https://praison.ai/docs/cli/plugins.md#reload-plugins).

***

## How It Works

The command snapshots registered plugins, installs, refreshes discovery, then reports the diff.

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
sequenceDiagram
    participant User
    participant CLI as plugins add
    participant Installer as pip / uv
    participant Manager as PluginManager

    User->>CLI: praisonai plugins add pkg
    CLI->>Manager: snapshot registered names (before)
    alt not --dry-run
        CLI->>Installer: install pkg
        Installer-->>CLI: exit code
    end
    CLI->>Manager: discover_entry_points()
    Manager-->>CLI: registered names (after)
    CLI->>User: table of new plugins OR exit 1
```

| Step | What happens |
| - | - |
| **Snapshot** | Records current entry-point plugin names via `get_plugin_manager().list_plugins()` |
| **Install** | Skipped on `--dry-run`; otherwise runs the resolved installer command |
| **Refresh** | `get_plugin_manager().discover_entry_points()` scans the `praisonai.plugins` group |
| **Diff** | `sorted(after − before)` — new names become table rows |

> [!NOTE]
>
> **Built-in names can't be taken over.** PraisonAI's registries subclass the base `PluginRegistry`, so since [PR #4176](https://github.com/MervinPraison/PraisonAI/pull/4176) an entry point whose name (case-insensitive) matches a shipped built-in is skipped during discovery — it never appears in the "Registered" diff, and a `DEBUG` line notes the collision. Ship your plugin under a distinct name, or override deliberately with a runtime `register(...)` call. See [Plugin Precedence](https://praison.ai/docs/features/plugin-precedence.md).

***

## Options

| Argument / flag | Type | Default | Description |
| - | - | - | - |
| `package` | positional `str` | *(required)* | pip requirement spec — anything `pip install` / `uv pip install` accepts (name, `name==1.2.3`, VCS URL, path, extras) |
| `--dry-run` | flag | `False` | Skip installation; run discovery only. Exits non-zero if nothing new is discovered |
| `--upgrade`, `-U` | flag | `False` | Append `--upgrade` so an already-installed package is upgraded |
| `--global` | flag | `False` | Install into the ambient/system environment instead of the CLI interpreter |

***

## How the Installer Is Chosen

The command pins installation to the interpreter running the CLI so the package lands where discovery will look — not in a nearby `.venv` that `uv` might auto-discover.

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph TB
    Q{"uv on PATH?"} -->|yes| G1{"--global?"}
    Q -->|no| G2{"--global?"}
    G1 -->|yes| A["uv pip install --system"]
    G1 -->|no| B["uv pip install --python &lt;sys.executable&gt;"]
    G2 -->|yes| C["pip install"]
    G2 -->|no| D["&lt;python&gt; -m pip install"]

    classDef decision fill:#6366F1,stroke:#7C90A0,color:#fff
    classDef result fill:#10B981,stroke:#7C90A0,color:#fff
    class Q,G1,G2 decision
    class A,B,C,D result
```

`--upgrade` appends `--upgrade` to whichever command runs, then the package spec.

***

## Exit Codes

| Situation | Exit code |
| - | - |
| At least one new plugin registered | `0` |
| Installer command returned non-zero | `1` |
| Install succeeded but nothing new discovered | `1` |
| `--dry-run` and nothing new discovered | `1` |
| `praisonaiagents` not importable at all | `1` |

***

## Output Shape

A successful run prints a Rich table titled `Registered N plugin(s) from <package>`:

```text theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
        Registered 1 plugin from praisonai-my-plugin
┏━━━━━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Plugin        ┃ Type      ┃ Hooks                  ┃
┡━━━━━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━┩
│ my_plugin     │ plugin    │ before_tool,after_tool │
└───────────────┴───────────┴────────────────────────┘
```

On `--dry-run` the title verb is `Discovered` instead of `Registered`.

***

## Common Patterns

> [tab] Default (pin to CLI interpreter)
>
> ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
> praisonai plugins add praisonai-my-plugin
> ```
>
> When `uv` is present, the package is pinned to the CLI interpreter so discovery finds it — not a nearby `.venv`.

> [tab] Global install
>
> ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
> praisonai plugins add praisonai-my-plugin --global
> ```
>
> Installs into the ambient/system environment (`uv pip install --system`, or plain `pip install`).

> [tab] CI verification
>
> ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
> praisonai plugins add praisonai-my-plugin --dry-run
> ```
>
> Fails the job (exit 1) if the package no longer registers after another change — a cheap regression guard.

***

## Best Practices

> [accordion] Use --dry-run in CI to catch silent breakage
>
> A package can install cleanly yet register nothing. `--dry-run` exits non-zero when discovery finds nothing new, turning a silent failure into a failed check.

> [accordion] Prefer the default over --global
>
> The default pins to the CLI interpreter so the plugin is discoverable by the same process. Reach for `--global` only when you deliberately want the system environment.

> [accordion] Pin versions for reproducible installs
>
> Pass a full spec like `praisonai-my-plugin==1.2.3` so the installed version is deterministic across machines.

> [accordion] Inspect after installing
>
> Run `praisonai plugins list` to see everything registered, not just what this command added.

***

## Related

> [card] [Plugins](https://praison.ai/docs/features/plugins.md)
>
> Write, load, and configure plugins

> [card] [Message-Lifecycle Plugins](https://praison.ai/docs/features/plugins.md#message-lifecycle-plugins)
>
> Override `before_message`, `after_message`, `message_sent`, and `message_undelivered`

> [card] [Plugins CLI](https://praison.ai/docs/cli/plugins.md)
>
> List, enable, disable, reload, and diagnose plugins

> [card] [tools add](https://praison.ai/docs/features/tools-add.md)
>
> Install a tool package and verify its tools

> [card] [Tool Source Registry](https://praison.ai/docs/features/tool-source-registry.md)
>
> Plug third-party tool sources via entry points

> [card] [Tool Resolver](https://praison.ai/docs/features/tool-resolver.md)
>
> Single source of truth for loading tools


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.