Chapter 16
Chapter 16 — Plugins
A plugin is a bundle of skills + legacy commands + agent definitions + MCP servers, managed as one thing — install once, get everything.
Plugins are the long-form answer to: “I want to hand a teammate (or another machine) a folder with our team’s agent extensions, and have them just work.”
Manifest
Every plugin has a manifest at its root, looked up in this order:
.thclaws-plugin/plugin.json(thClaws-native, preferred).claude-plugin/plugin.json(Claude Code compat fallback)
Shape:
{
"name": "agentic-press-deploy",
"version": "1.0.0",
"description": "Deploy apps to Agentic Press Hosting",
"author": "Agentic Press",
"skills": ["skills"],
"commands": ["commands"],
"agents": ["agents"],
"mcpServers": {
"deploy-hub": {
"transport": "http",
"url": "https://mcp.example.com"
}
}
}
All paths are relative to the manifest root. Each contribution:
| Field | Points to | Each entry is |
|---|---|---|
skills |
Directories of <name>/SKILL.md subdirs |
A skill-catalog directory (ch 12) |
commands |
Directories of *.md prompt templates |
A commands directory (ch 10) |
agents |
Directories of *.md agent defs |
An agent-catalog directory (ch 15) |
mcpServers |
JSON map of server configs | Same shape as mcp.json (ch 14) |
Directory layout of an installed plugin
Installed plugins live under:
| Scope | Install root | Registry file |
|---|---|---|
| Project | .thclaws/plugins/<name>/ |
.thclaws/plugins.json |
| User | ~/.config/thclaws/plugins/<name>/ |
~/.config/thclaws/plugins.json |
The registry is a JSON array tracking name, source URL, install path, version, and enabled flag.
Marketplace
Plugins are one of the four types in the unified thClaws marketplace
(skills · MCP · plugins · subagents — see
Chapter 12). In the GUI, /marketplace opens a
browser modal with a Plugins tab; the text commands below work
everywhere.
/plugin marketplace browses the curated catalog at
thClaws/marketplace, same
shape as the skill marketplace. Three discovery commands plus a
name-based install:
❯ /plugin marketplace
plugin marketplace (baseline 2026-04-29, 1 plugin(s))
── workflow ──
productivity — Task management, workplace memory, visual dashboard
install with: /plugin install <name> | detail: /plugin info <name>
❯ /plugin info productivity
license: Apache-2.0 (open)
homepage: https://github.com/thClaws/marketplace/tree/main/plugins/productivity
install with: /plugin install productivity (resolves to https://github.com/thClaws/marketplace.git#main:plugins/productivity)
❯ /plugin install productivity
plugin 'productivity' installed (project, 1 skill dir(s)) → .thclaws/plugins/productivity
skills callable in this session — no restart needed
Use /plugin show <name> for an INSTALLED plugin’s detail (path,
contributions, scope) — the marketplace’s /plugin info is for
catalog entries before install.
Install (custom URL)
For plugins not in the marketplace:
❯ /plugin install https://github.com/agentic-press/deploy-plugin.git
plugin 'agentic-press-deploy' installed (project) → .thclaws/plugins/agentic-press-deploy
Skills refreshed and callable this session.
1 plugin-contributed MCP server(s) still need a restart to spawn — or use /mcp add to register them now.
The <git-url>#<branch>:<subpath> extension also works for plugins
(same as skills) — useful when the upstream repo bundles many plugins
under a plugins/ directory:
❯ /plugin install https://github.com/anthropics/knowledge-work-plugins.git#main:productivity
Plugin-contributed skills activate immediately in the current
session — the SkillTool’s live store is refreshed and the new skill
shows in the system prompt’s # Available skills section. Plugin-
contributed MCP servers still require either /mcp add (to
live-register) or a restart, because the auto-spawn path would need
to diff against already-running servers. Commands and agent
definitions live in directories that are re-scanned on next use, so
they’re live too.
From a .zip:
❯ /plugin install --user https://example.com/plugins/deploy-v1.zip
Scope selection:
- default (no flag) → project install (
.thclaws/plugins/) --user→ user global (~/.config/thclaws/plugins/)--project→ the default, spelled out; useful in a script that shouldn’t inherit a habit
Reinstalling over an existing plugin
Installing a plugin that is already registered is refused, so an upgrade can’t half-overwrite a working install:
❯ /plugin install https://github.com/agentic-press/deploy-plugin.git
plugin 'agentic-press-deploy' already installed at .thclaws/plugins/agentic-press-deploy
— run /plugin remove first, or reinstall with --force
--force (or -f) replaces the directory in place. Use it to pull a
newer version of the same plugin; use /plugin remove first if you’d
rather start from nothing.
An install whose directory is present but has no registry entry —
a lost plugins.json write, a workspace sync that deleted it — is a
different case: it’s adopted automatically without --force, because
/plugin remove is registry-keyed and could never have cleaned it up.
List / show / enable / disable / remove
❯ /plugins
agentic-press-deploy v1.0.0 (enabled) → .thclaws/plugins/agentic-press-deploy
source: https://github.com/agentic-press/deploy-plugin.git
big-noisy-plugin v0.2.3 (disabled) → .thclaws/plugins/big-noisy-plugin
❯ /plugin show agentic-press-deploy
agentic-press-deploy v1.0.0 (enabled)
path: .thclaws/plugins/agentic-press-deploy
source: https://github.com/agentic-press/deploy-plugin.git
description: Deploy apps to Agentic Press Hosting
author: Agentic Press
skill dirs: skills
command dirs: commands
agent dirs: agents
mcp servers: deploy-hub
❯ /plugin disable big-noisy-plugin
plugin 'big-noisy-plugin' disabled (restart to drop its contributions)
❯ /plugin enable big-noisy-plugin
plugin 'big-noisy-plugin' enabled (restart to pick up its contributions)
❯ /plugin remove big-noisy-plugin
plugin 'big-noisy-plugin' removed (restart to drop active tools)
Disable ≠ remove: files stay on disk, only the enabled flag flips.
/plugin remove also answers to /plugin rm and /plugin uninstall,
and /plugins to /plugin list or /plugin ls.
/plugin gc — clear out broken registry entries
The registry can end up pointing at plugins that are no longer usable —
you deleted the directory by hand, a git clean took it, or the
plugin.json inside it stopped parsing. Those entries linger and show
up in /plugins as if they were installed.
❯ /plugin gc
removed zombie entries:
- big-noisy-plugin (project)
- old-deploy (user)
If there is nothing to clean it says no zombie entries — registry is
clean and leaves everything alone.
It drops any entry whose directory is missing or whose manifest no
longer parses, across both the project and user registries. It never
deletes a working plugin, so it is safe to run whenever /plugins
lists something that is not really there.
What a plugin contributes
On next start, thClaws’s discovery walks both the standard dirs and each enabled plugin’s declared contribution dirs:
- Skills from the plugin appear alongside project-local ones.
- Commands the same.
- Agents (the
agentsarray) merge additively into the agent-def catalogue — a plugin agent can’t shadow a user’s or project’s existing agent with the same name. Useful for shipping a team of specialist agents (e.g.reviewer,tester,architect) as one install. - MCP servers in the manifest are merged into
config.mcp_servers— project-levelmcp.jsonentries always win on name clash.
On collision the rule is consistent everywhere: your stuff beats plugin stuff. Skills, commands, agents, and MCP servers you define project- or user-locally always override a plugin’s contribution with the same name, so installing a plugin can’t silently change a convention you’ve already committed.
Writing a plugin
Minimal example — a skill, a command, and an agent def:
my-plugin/
├── .thclaws-plugin/
│ └── plugin.json
├── skills/
│ └── hello/
│ └── SKILL.md
├── commands/
│ └── greet.md
└── agents/
└── reviewer.md
{
"name": "my-plugin",
"version": "0.1.0",
"description": "Say hello in style + a reviewer agent",
"skills": ["skills"],
"commands": ["commands"],
"agents": ["agents"]
}
Example agents/reviewer.md:
---
name: reviewer
description: Read-only code review focused on naming + security
model: claude-haiku-4-5
tools: Read, Glob, Grep
permissionMode: auto
---
You are a code reviewer. Read the files you're pointed at. Flag
naming inconsistencies, missing tests, and security-sensitive
patterns. Don't propose fixes unless asked.
Zip it up:
cd my-plugin
zip -r ../my-plugin.zip .thclaws-plugin skills commands agents
Host the zip anywhere reachable over HTTPS (your CDN, S3, GitHub
Releases) and share the URL. Or push to a git repo — /plugin install
<git-url> works identically.
Compared to skills + /mcp add
You can get equivalent functionality by installing each piece separately. Plugins are about atomicity: one install, one uninstall, one version to pin. Ship one for your team; everyone gets the same set.
Deferred features
Not yet supported but on the roadmap:
- Hook merging — manifest
hooksblock applied to the runtime hooks config (ch 13). - Marketplace —
/plugin search,/plugin browse.
For now, do these by hand via separate files.