Plugins
Install a package of skills, commands, sub-agent types and integrations from one source string.
A plugin is a package of agent capabilities. A skill is one set of instructions. A plugin can contain many components together: skills, commands, sub-agent types, MCP servers, hooks, LLM providers and executables. Thus you install a full set of capabilities from one location and turn it on for your agents.
dashsquad plugins use the Claude Code plugin layout. Thus a plugin for Claude Code also works in dashsquad.
Quick start
All these steps occur in Desktop → Settings → Plugins.
Install a plugin
In the Install Plugin form, type a Source. A source is a git repository (git:owner/repo), a download URL, or a folder on the HQ computer (/path/to/plugin). Then click Install. If Name (optional) is empty, the name comes from the plugin manifest or from the source. Refer to Install a plugin for the three source forms.
Find it in the list
The plugin shows with a status badge (Loaded, Disabled or Error) and a row of contribution tags. The tags show what the plugin adds, for example skills, commands, agents, mcp, hooks, providers or bin. A new plugin is enabled but not trusted. Its skills and commands work immediately. Its code components wait until you trust the plugin.
Enable or disable it
Use the Enable or Disable button to turn the Markdown components (skills, commands and sub-agent types) on or off. A new plugin is already enabled. When you disable a plugin, the HQ also removes its trust. When you enable a plugin that has code components, the Trust Plugin dialog opens at once.
Trust it (only if it contains code)
If the plugin contains code or credential components (MCP servers, hooks, bin/ executables or LLM providers), click Trust. Read the list of components that will run, then confirm. A plugin with only Markdown components does not need trust. Refer to Security model.
Use it
Agents can load the skills and commands. Agents can start the sub-agent types. Trusted MCP servers and hooks connect automatically. Trusted providers show on the AI Providers page, where you add a key. Refer to How to use each component.
The other sections of this page give the details for each step. If you prefer files, you can also put a plugin folder in the plugins folder of the HQ (~/.dash/gateway/plugins/) and edit config.json. Refer to Where plugins live, Configuration → Plugins and the complete example.
Where plugins live
Installed plugins are in the managed plugins folder of the HQ:
~/.dash/gateway/plugins/
├── config.json # the state of each plugin (enabled, trusted, source, installed)
└── <plugin-name>/ # one folder for each plugin (its skills, commands and other components)This is the location for a standalone HQ. For an HQ that Desktop starts, ~/.dash/gateway on this page means ~/.dashsquad/<hq id>. If you run the HQ with --data-dir <path>, the plugins go into <path>/plugins/. Refer to Data folders.
Usually you do not change this folder yourself. The Plugins page in Desktop and the Management API manage it for you. But you can put a plugin into it manually or look at config.json.
Built-in plugins
dashsquad includes some plugins:
| Plugin | Contents |
|---|---|
dash-assistant, dash-comms, dash-creative, dash-dev, dash-meta | The built-in skill library. Refer to Skills. |
dash-core-providers (AI providers in Desktop) | The provider catalogs for Anthropic, OpenAI, Google, Moonshot (Kimi) and OpenRouter. |
Built-in plugins show the badge Built-in and have no Remove button. To stop a built-in skill plugin, disable it. You cannot disable, untrust or remove the AI providers plugin, because the HQ refuses these changes. Desktop shows no Disable, Revoke trust or Remove button for it. The HQ installs, enables and trusts dash-core-providers again each time it starts.
The Management API refuses an install with the name of a built-in plugin. If you put a plugin with that name into the plugins folder manually, your plugin replaces the built-in plugin. The built-in plugin then shows an error.
Plugin contents
A plugin is a folder with an optional .claude-plugin/plugin.json manifest and one or more of these components:
| Component | What it adds | Loads when the plugin is |
|---|---|---|
skills/ | Skills (SKILL.md files) | Enabled |
commands/ | Commands, with the name <plugin>:<command> | Enabled |
agents/ | Sub-agent types that an agent can start | Enabled |
.mcp.json | MCP servers (more tools) | Enabled and trusted |
hooks/hooks.json | Shell commands that run at specific events in a turn | Enabled and trusted |
providers/ | LLM provider catalogs that add models | Enabled and trusted |
bin/ | Executables that the HQ adds to its PATH | Enabled and trusted |
The first three components are Markdown. They give only instructions, so they load when the plugin is enabled. The last four components run code or contain credentials. They do nothing until you trust the plugin. Refer to Security model.
The .claude-plugin/plugin.json manifest is optional. It can set name, displayName, description, version, author, homepage, repository, license and keywords. It can also give different paths for skills, commands, agents and providers. If there is no manifest, the name comes from the source or from the folder name. The name must be kebab-case.
If you know skills, a plugin is the next step. You do not install skills one at a time. You install a package that also contains commands, sub-agent types and integrations.
Install a plugin
You install a plugin from a source. In Desktop, go to Settings → Plugins, fill in the Install Plugin form and click Install. For scripts, use the Management API: POST /plugins/install.
The installer gets the plugin, scans it and puts it into the managed plugins folder of the HQ at ~/.dash/gateway/plugins/<name>. Then the HQ loads it again. You do not need to restart, but bin/ executables need an HQ restart. Refer to MCP servers, hooks and executables.
The source string has one of three forms:
| Source form | Example | Meaning |
|---|---|---|
| Git | git:owner/repo[/subpath][@ref] | A GitHub repository, with an optional subfolder and an optional ref |
| URL | https://example.com/my-plugin.tar.gz | A direct link to a .tar.gz archive. http:// also works. |
| Local | /path/to/plugin or /path/to/plugin.tar.gz | A folder or an archive on the HQ computer. A path can start with ~/. |
The installer stops a download after 30 seconds. An archive can have a maximum size of 50 MiB.
Example of an install from git:
POST /plugins/install
{ "source": "git:acme/dash-plugins/research@v1.2.0" }If the install is successful, the response gives the name, the location on the disk and the source of the plugin. It also gives the version, the description and the result of the scan. The plugin is enabled but not trusted. Its skills and commands work immediately. Its code components wait until you trust the plugin.
To use a different name, give name. If the manifest has a name, the manifest name is used.
Pin a version
For git sources, add @ref to pin the plugin to a branch, a tag or a commit:
git:acme/dash-plugins/research@main # a branch (it changes over time)
git:acme/dash-plugins/research@v1.2.0 # a tag
git:acme/dash-plugins/research@9f2c1ab… # a full commit SHA (recommended)A full commit SHA is the safest choice, because those bytes cannot change. A branch such as @main always installs the latest version. This is easy, but a later install can bring in different code.
Manage plugins in Desktop
On the Settings → Plugins page in Desktop, you install, examine, enable, trust and remove plugins. You do not have to edit a configuration file. Most changes apply immediately, because the HQ loads the plugins again.
Install Plugin form. The Source field accepts all install sources. Refer to Install a plugin. The Name (optional) field gives a different install name, but a manifest name has priority. Click Install to get, scan and load the plugin. If the scan finds the plugin suspicious, the page shows Warning: scan verdict is "suspicious".
The plugin list. Each installed plugin shows on a card with its name, its version, a status badge and its contributions:
| Status badge | Meaning |
|---|---|
| Built-in | The plugin comes with dashsquad. |
| Loaded | The plugin is enabled and its components loaded with no error. |
| Disabled | The plugin is installed but turned off. It adds nothing. |
| Error | The plugin did not load. The card shows the error message. |
Below the badge, the Contributions: tags show the component types of the plugin. A green tag is active: that component runs. A gray tag with a line through it is not active. For example, a code component of a plugin that is not trusted shows this way until you trust the plugin. An enabled plugin with code components that is not trusted also shows the text Not trusted. Its code components do not run until you trust it.
Controls on each card:
- Enable or Disable: turns the Markdown components (skills, commands and sub-agent types) on or off. Disable also removes the trust of the plugin. If you enable a plugin that has code components, the Trust Plugin dialog opens at once.
- Trust or Revoke Trust: shows only when the plugin is enabled. Trust opens a confirmation (refer to the next section). Revoke Trust stops the code components of the plugin.
- Remove: deletes the plugin folder from your computer, after you confirm in the Remove Plugin? dialog. Built-in plugins do not have this button.
The trust confirmation
When you click Trust, the Trust Plugin dialog opens before code runs. It shows the warning This code will run on your machine. It then lists the code component types that will start when you trust the plugin: bin, hooks, mcp or providers. Click Trust Plugin to confirm, or Cancel to keep the plugin not trusted.
The same dialog opens when you click Enable on a plugin that has code components, because Disable removed the trust. If you click Cancel, the plugin stays enabled but not trusted. Its skills, commands and sub-agent types load. Its code components wait. To trust the plugin later, click Trust on its card.
The Trust Plugin button is not available until the plugin is enabled. Enable the plugin first, then trust it. Trust is a separate action that only you can do. Refer to Security model.
Security model
When you install a plugin, you bring the instructions of a different person, and possibly their code, onto your HQ. dashsquad does not trust a new plugin. It uses these protections:
-
Not trusted at install. A new plugin is
enabledbut nottrusted. Its Markdown components (skills, commands and sub-agent types) load. Its code components do nothing: MCP servers, hooks,bin/executables and provider catalogs wait until you trust the plugin. The install alone cannot run code from the plugin on your HQ. -
Trust is a separate action. You mark a plugin as
trustedafter you examine it. An install or the plugin itself cannot do this for you. Trust only plugins whose code you read and that you agree to run in the HQ process. If you disable a plugin, the HQ removes its trust. After you enable the plugin again, you must confirm trust again. -
A heuristic scan. Before the HQ installs a plugin, it scans these parts:
- The manifest and the code (
bin/,hooks/hooks.json,.mcp.json,providers/), for dangerous patterns. Examples are a download sent into a shell, destructive deletes, prompt injection, secret exfiltration and private keys. - The Markdown in
skills/,commands/andagents/, for prompt injection.
The HQ refuses a plugin that the scan finds dangerous: the install fails, and nothing goes onto the disk. If the scan itself fails, the install also fails. A file that the scan cannot read or parse does not stop the install. Suspicious signals do not stop the install. Examples are environment variable reads, base64 decode operations, or prototype-pollution keys in
hooks.json,.mcp.jsonor provider files. Examine the plugin before you trust it. - The manifest and the code (
-
Path traversal (zip slip) protection. The installer refuses an archive entry whose path goes outside the plugin folder. The path can use
../, an absolute path or a symbolic link. Then the full install fails. A dangerous archive cannot write files outside its own plugin folder. The installer also refuses an archive that contains a hard link, a device file or a FIFO. Then the full install fails witharchive member type not allowed.
Examine a plugin before you trust it. This is important for a plugin from a source that you do not control. When you trust a plugin, its hooks, MCP servers, bin/ executables and provider catalogs run in the HQ with the permissions of the HQ.
Provider credentials
Some plugins contain LLM provider catalogs (providers/*.json) that add AI providers. Examples are a model service in your company, a regional endpoint or a service that is compatible with OpenAI. When you trust a plugin with a catalog, its providers show automatically on the Settings → AI Providers page in Desktop (AI Providers). They show together with the built-in providers: Anthropic, OpenAI, Google, Moonshot (Kimi) and OpenRouter.
You add a key as for a built-in provider. Open AI Providers, select the provider of the plugin and paste your key. Each provider needs its own API key.
More than one key. A provider can have more than one key, for example default and backup, so a second key is ready. The HQ keeps the keys in the same encrypted credential store as the keys of the built-in providers, with these names:
<provider-id>-api-key:<key-name>For example, a provider with the ID myprov keeps its first key as myprov-api-key:default and a second key as myprov-api-key:backup.
The providers of a plugin show only if the plugin is trusted. If the plugin is not trusted, its providers are not on the AI Providers page, and you cannot add a key for them. The same trust gate stops MCP servers, hooks and bin/ executables. Refer to Security model.
A plugin cannot replace a built-in provider. The built-in IDs are anthropic, openai, google, moonshotai and openrouter. If a plugin uses one of these IDs for a provider, the HQ ignores that provider. This is also true for a trusted plugin.
How to use each component
When a plugin is loaded (and trusted, if necessary), its components are available in different locations:
| Component | How you use it | Needs trust? |
|---|---|---|
| Skills | They go into the skill index of the agent. The agent loads one with load_skill when it needs it. | No |
| Commands | The agent can load a command as the skill <plugin>:<command>. In Telegram and WhatsApp, type /<plugin>:<command>. | No |
| Sub-agent types | An agent starts one with the agent tool, with the type <plugin>:<agent>. | No |
| MCP servers | They connect automatically. Their tools become available to the agent. | Yes |
| Hooks | They run automatically at events in a turn. | Yes |
| LLM providers | They show in the model list of the agent after you trust the plugin and add a key. | Yes |
Executables (bin/) | The HQ adds them to the start of its PATH when it starts. Commands, hooks and the shell tools of the agent can then run them by name. | Yes |
Skills
The skills/<name>/SKILL.md files of a plugin go into the skill index of the agent: the short list of skills in its system prompt. The agent loads the full instructions of a skill with load_skill when it needs them. Refer to Skills for the format.
Commands and sub-agent types
The commands/<name>.md file of a plugin becomes a command with the name <plugin>:<command>. For example, a plugin with the name research and the file commands/triage.md gives research:triage. The agent can load the command as a skill. In Telegram and WhatsApp, a user can type /research:triage.
The agents/<name>.md file of a plugin (Claude Code sub-agent format) becomes a sub-agent type with the name <plugin>:<agent>. An agent starts it with the agent tool. A sub-agent type is not a command, and the agent cannot load it as a skill.
Commands and sub-agent types are Markdown, so they work when the plugin is enabled. They do not need trust. The plugin name is part of their name, so they cannot have the same name as other components.
Plugin sub-agents run in their own context, not in the main session. The HQ applies their tools and model frontmatter. A sub-agent never gets a tool or an MCP server that its parent does not have. Refer to Configuration → Plugin sub-agent types.
MCP servers, hooks and executables
These are trusted code components. You do not start them with a command. They connect automatically:
- MCP servers (
.mcp.json) connect to the HQ. Their tools become part of the tools of the agent. If one server does not start, the HQ writes it to the log and continues without it. - Hooks (
hooks/hooks.json) run automatically at events in a turn. The events arePreToolUse,PostToolUse,UserPromptSubmit,SessionStart,Stop,SubagentStartandSubagentStop. Refer to Hooks. - Executables (
bin/) go to the start of thePATHof the HQ. Thus they have priority over the system programs with the same name when a command, a hook or a shell tool runs them.
To stop a PreToolUse or PostToolUse command, select Cancel response in Chat. The command stops, and later hooks for that tool do not start. If you stop a PreToolUse hook, the tool does not run.
Restart the HQ after you trust, revoke the trust of, or remove a plugin with bin/ executables. The HQ changes its PATH only when it starts.
LLM providers
The providers/*.json catalogs of a trusted plugin add models. After you trust the plugin and add a key (refer to Provider credentials), the models show in the model list of the agent as <id>/<model-id>. You select them as you select the models of the built-in providers.
Select plugins for each agent
By default, each agent sees all loaded plugins. You can limit an agent to some plugins:
Open the configuration of the agent
In Desktop, click Manage next to Agents, open the agent and click the Configuration tab.
Open the Plugins card
Expand the Plugins card. If you selected no plugins, it shows All plugins (default). The agent then sees all loaded plugins.
Select the plugins for this agent
Use Add plugin... to select from the loaded plugins. Each plugin that you add shows as a chip. To remove a chip, click its × button. When you select one or more plugins, the agent sees only those plugins. To go back to all plugins, remove all the chips.
The selection for each agent controls only what the agent sees. It does not trust a plugin. Trust applies to the full HQ. If a plugin is not trusted, its code does not run, also when you select it for an agent. A trusted plugin stays trusted for all agents. The list shows only loaded plugins.
Select AI providers for each agent
The Configuration tab of each agent also has a Providers card. By default it shows All providers (default): the agent can use models from all available AI providers.
Add one or more providers to limit the agent to those providers. The model list of the agent then shows only the models of those providers. If the current model of the agent comes from a provider that you removed, the model stays in the list with the text (not allowed). Select a different model. If an agent tries to use a provider that is not permitted, it gives an error, not a response. To go back to all providers, remove all the chips.
Use this setting when an agent must use only one vendor. For example, you can keep an agent for customers on Anthropic models only, whatever other providers the HQ has.
Config flags
Each plugin has an entry in ~/.dash/gateway/plugins/config.json with its state. You can see these fields:
| Flag | Meaning |
|---|---|
enabled | The skills, commands and sub-agent types of the plugin load. The install sets it to true. |
trusted | The code components of the plugin (MCP, hooks, bin/ and providers) can run. It is off by default. Set it only after you examine the plugin. |
source | The source of the install. |
installed | true if the Management API installed the plugin into ~/.dash/gateway/plugins/<name>. If it is true, a removal also deletes the folder. |
An entry can also have a path, to load a plugin from a different folder. Refer to Configuration → Plugins for the full file format.
A complete example plugin
You can copy this small plugin and install it from a local folder. It contains a skill, a command, and an optional LLM provider and hook.
Folder structure:
my-plugin/
├── .claude-plugin/
│ └── plugin.json
├── skills/
│ └── summarize/
│ └── SKILL.md
├── commands/
│ └── triage.md
├── providers/ (optional — needs trust)
│ └── myprov.json
└── hooks/ (optional — needs trust)
└── hooks.json.claude-plugin/plugin.json: the manifest. The name must be kebab-case. The other fields are metadata.
{
"name": "my-plugin",
"displayName": "My Plugin",
"description": "A summarize skill and a triage command",
"version": "1.0.0"
}skills/summarize/SKILL.md: a skill. It is Markdown, so it loads when the plugin is enabled.
---
name: summarize
description: Summarize any text concisely
---
Summarize the provided text in three sentences or fewer.commands/triage.md: a command with the name my-plugin:triage. The optional frontmatter (name, description) can change the command name and add a description.
---
description: Triage an incoming support ticket
---
Read the ticket below and assign a priority (P1–P4) with a one-line reason.providers/myprov.json (optional: a credential component, so it works only when the plugin is trusted). The credentialPrefix must be <id>-api-key, and models must contain one or more models.
{
"id": "myprov",
"label": "My Provider",
"credentialPrefix": "myprov-api-key",
"baseUrl": "https://api.myprov.example/v1",
"api": "openai-completions",
"models": [
{ "id": "my-fast", "name": "My Fast", "contextWindow": 128000, "maxTokens": 8192 },
{
"id": "my-reasoning",
"name": "My Reasoning",
"api": "openai-responses",
"contextWindow": 128000,
"maxTokens": 16384,
"reasoning": true,
"thinkingLevelMap": { "off": null, "minimal": null, "xhigh": "max" }
}
]
}Each model can set api to use a different API format from the provider. In this example, my-fast uses Chat Completions and my-reasoning uses Responses. Select the format that your provider supports for that model.
For models that can think before they answer, set reasoning: true and give the limits in thinkingLevelMap:
reasoning: truetells the HQ that the model can think. It does not make thinking mandatory."off": nullmakes thinking mandatory. The HQ then selects the lowest available thinking level automatically.nullremoves a level from the supported levels. The example also removesminimal, so its lowest level islow.- A string connects a dashsquad level to the value of the provider. The example connects
xhightomax.
Use the keys off, minimal, low, medium, high and xhigh. If you do not give a key, the defaults of the provider adapter apply. xhigh is available only if you map it. Refer to the API documentation of the provider for the values that it accepts. Refer to Extended thinking for the default behavior of the HQ.
hooks/hooks.json (optional: it also needs trust). It uses the Claude Code hooks format. Put the events in a top-level hooks object. If there is no hooks object, the HQ finds no hooks. ${CLAUDE_PLUGIN_ROOT} is the folder of the plugin.
{
"hooks": {
"PreToolUse": [
{
"matcher": "bash",
"hooks": [
{ "type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/scripts/guard.sh" }
]
}
]
}
}Install it. On the Settings → Plugins page in Desktop, type the folder path in the Source field, for example /Users/you/plugins/my-plugin. Then click Install.
The plugin is enabled but not trusted. The summarize skill and the my-plugin:triage command work immediately. To turn on the provider and the hook, click Trust and confirm. Then add a key for the provider on the Settings → AI Providers page. The myprov/my-fast model is then available for all agents.
What the errors mean
If an install fails, the response code tells you the cause:
| Code | Meaning | What to do |
|---|---|---|
400 | The source is empty. | Give a source. |
404 | The HQ cannot find the source: a missing repository or an incorrect URL. | Make sure that the source string is correct and that the plugin exists. |
409 | A plugin with that name is already installed, or the name is the name of a built-in plugin. | Remove the plugin first, or install with a different name. |
422 | The plugin is not valid, damaged or dangerous: an incorrect manifest, a damaged archive, a zip slip archive, a dangerous result from the scan, or a scan that failed. | Examine the source. Usually you must not install this plugin as it is. |
If the install is successful but the HQ cannot load the plugins again, the response is 200 with a note and an error.
Not yet supported
These capabilities are not available:
- Signature checks. The HQ scans each install with heuristics, but it does not do a cryptographic check of a publisher signature.
- npm and registry sources. You can install plugins only from git, URL and local sources. There is no
npm:source. - Marketplaces. You cannot install a plugin by name from a marketplace catalog. Install it from its source.