Skip to main content
Create Droid plugins to package skills, commands, hooks, and MCP configuration into shareable bundles for teams and projects.

Quick start

1

Create the plugin directory

mkdir -p my-plugin/.factory-plugin
2

Create the manifest

Create my-plugin/.factory-plugin/plugin.json:
{
  "name": "my-plugin",
  "description": "A helpful plugin description",
  "version": "1.0.0"
}
3

Add a command

Create my-plugin/commands/hello.md:
---
description: Greet the user with a friendly message
---

Greet the user warmly and ask how you can help them today.
4

Test your plugin

Install from local directory to test:
droid plugin marketplace add ./my-plugin
droid plugin install my-plugin@my-plugin
Then run /hello to test.

Plugin manifest

The manifest file at .factory-plugin/plugin.json defines your plugin’s metadata:
{
  "name": "my-plugin",
  "description": "What this plugin does",
  "version": "1.0.0",
  "author": {
    "name": "Your Name",
    "email": "you@example.com"
  },
  "homepage": "https://github.com/you/my-plugin",
  "repository": "https://github.com/you/my-plugin",
  "license": "MIT"
}

Required fields

FieldDescription
nameUnique identifier. Lowercase letters, digits, hyphens.
descriptionShort description shown in plugin manager.
versionSemantic version (e.g., 1.0.0).

Optional fields

FieldDescription
authorObject with name and optional email.
homepageURL for plugin documentation.
repositoryGit repository URL.
licenseLicense identifier (e.g., MIT, Apache-2.0).

Adding skills

Skills are model-invoked capabilities. Create them in the skills/ directory:
my-plugin/
└── skills/
    └── code-review/
        └── SKILL.md

Skill format

---
name: code-review
description: Reviews code for best practices and potential issues. Use when reviewing code, checking PRs, or analyzing code quality.
---

When reviewing code, check for:
1. Code organization and structure
2. Error handling
3. Security concerns
4. Test coverage

Provide specific, actionable feedback with line references.

Skill frontmatter

FieldRequiredDescription
nameYesUnique identifier for the skill
descriptionYesWhen to use this skill (helps model decide when to invoke)
disable-model-invocationNoSet true to make it user-only
allowed-toolsNoRestrict which tools the skill can use

Adding commands

Commands are user-invoked via slash syntax. Create them in the commands/ directory:
my-plugin/
└── commands/
    └── review-pr.md

Command format

---
description: Review the current PR for issues
disable-model-invocation: true
---

# Review PR Command

Review the current pull request. Check for:
1. Code correctness and logic errors
2. Test coverage
3. Documentation updates
4. Breaking changes

If the user provides arguments: $ARGUMENTS

Use them to focus on specific areas of the review.
A command at commands/review-pr.md becomes /review-pr.

Command arguments

Use $ARGUMENTS to capture user input:
---
description: Greet a user by name
---

Greet the user named "$ARGUMENTS" warmly.
Usage: /greet Alice

Adding agents

Define specialized subagents in the droids/ directory:
my-plugin/
└── droids/
    └── security-reviewer.md

Agent format

---
name: security-reviewer
description: Reviews code for security vulnerabilities
model: inherit
tools: ["Read", "Grep", "Glob"]
---

You are a security expert. Review the code for:

1. Injection vulnerabilities (SQL, command, XSS)
2. Authentication/authorization issues
3. Sensitive data exposure
4. Insecure cryptography
5. Security misconfigurations

Report findings with severity levels and remediation steps.
See Custom Droids for full agent configuration options.

Adding hooks

Define lifecycle hooks in hooks/hooks.json:
my-plugin/
└── hooks/
    ├── hooks.json
    └── format-check.sh

Hook configuration

{
  "PostToolUse": [
    {
      "matcher": "Create|Edit|ApplyPatch",
      "hooks": [
        {
          "type": "command",
          "command": "${DROID_PLUGIN_ROOT}/hooks/format-check.sh",
          "timeout": 30
        }
      ]
    }
  ]
}

Environment variables

VariableDescription
${DROID_PLUGIN_ROOT}Absolute path to your plugin directory
${CLAUDE_PLUGIN_ROOT}Alias for ${DROID_PLUGIN_ROOT} (Claude Code compatibility)
Plugin hooks cannot be imported via /hooks import. They only function within installed plugins where the plugin root path can be resolved.

Adding MCP servers

Configure MCP servers in mcp.json at the plugin root:
{
  "mcpServers": {
    "my-api": {
      "command": "npx",
      "args": ["-y", "@example/mcp-server"],
      "env": {
        "API_KEY": "${MY_API_KEY}"
      }
    }
  }
}

Testing plugins

Local testing

Install from a local directory to test during development:
droid plugin marketplace add ./my-plugin
droid plugin install my-plugin@my-plugin

Validation checklist

Before sharing your plugin:
  • Manifest has required fields (name, description, version)
  • All skills have name and description in frontmatter
  • Commands work with and without arguments
  • No hardcoded paths or machine-specific config
  • README documents all commands and features

Distributing plugins

Creating a marketplace

A marketplace is a Git repository with a manifest listing available plugins:
my-marketplace/
├── .factory-plugin/
│   └── marketplace.json
├── plugin-one/
│   └── .factory-plugin/
│       └── plugin.json
└── plugin-two/
    └── .factory-plugin/
        └── plugin.json

Marketplace manifest

Create .factory-plugin/marketplace.json:
{
  "name": "my-marketplace",
  "description": "A collection of useful plugins",
  "owner": {
    "name": "Your Name"
  },
  "plugins": [
    {
      "name": "plugin-one",
      "description": "Description of plugin one",
      "source": "./plugin-one"
    },
    {
      "name": "plugin-two",
      "description": "Description of plugin two",
      "source": "./plugin-two"
    }
  ]
}
FieldRequiredDescription
nameYesMarketplace identifier
descriptionNoShown when browsing marketplaces
ownerNoContact information
plugins[].nameYesPlugin identifier
plugins[].sourceYesWhere to fetch the plugin from. A relative path string or a source object. See Plugin sources.
plugins[].descriptionNoShown in plugin browser
plugins[].categoryNoFor organizing plugins

Plugin sources

Each plugin entry’s source field tells Droid where to fetch the plugin from. The default form, a relative path string like "./plugin-one", points at a directory inside the marketplace repository. For plugins that live elsewhere, use a source object.
Source typeFieldsUse when
Relative path"./path/to/plugin"Plugin lives inside the marketplace repository.
githubrepo, ref?, sha?Plugin is hosted in its own GitHub repository.
urlurl, ref?, sha?Plugin is hosted on a non-GitHub git host (GitLab, Bitbucket, self-hosted).
git-subdirurl, path, ref?, sha?Plugin lives inside a subdirectory of a larger git repository, such as a monorepo.
npmpackage, version?, registry?Plugin is published as an npm package.

npm packages

Distribute plugins as npm packages when you already ship to a private registry (Artifactory, CodeArtifact, GitHub Packages, Verdaccio, and so on) and want to reuse that channel for your Droid plugins. Public packages on the npm registry work the same way.
{
  "name": "pr-triage",
  "source": {
    "source": "npm",
    "package": "@your-org/droid-pr-triage"
  }
}
Pin to a specific version or range:
{
  "name": "pr-triage",
  "source": {
    "source": "npm",
    "package": "@your-org/droid-pr-triage",
    "version": "2.4.0"
  }
}
Install from a private registry:
{
  "name": "pr-triage",
  "source": {
    "source": "npm",
    "package": "@your-org/droid-pr-triage",
    "version": "^2.0.0",
    "registry": "https://npm.your-org.example"
  }
}
FieldRequiredDescription
packageYesnpm package name. Scoped packages (@scope/name) are supported.
versionNonpm version, range, or dist-tag (for example 2.4.0, ^2.0.0, latest). Defaults to latest.
registryNoCustom registry URL. Defaults to the system npm registry. The setting is scoped to the install run and never written to your global ~/.npmrc.
Layout requirements. The published package root must contain a plugin manifest. Both the native Droid layout (.factory-plugin/plugin.json, droids/, mcp.json) and the Claude Code layout (.claude-plugin/plugin.json, agents/, .mcp.json) are accepted. Claude Code layouts are translated into Droid form when the package is copied into the plugin cache. A typical published package looks like this:
@your-org/droid-pr-triage/
├── .factory-plugin/
│   └── plugin.json
├── package.json
├── skills/
│   └── classify/
│       └── SKILL.md
├── droids/
│   └── triage-reviewer.md
└── README.md
Set the files field in package.json so only the plugin payload ships:
{
  "name": "@your-org/droid-pr-triage",
  "version": "2.4.0",
  "files": [
    ".factory-plugin",
    "skills",
    "droids",
    "mcp.json",
    "hooks",
    "README.md"
  ]
}
Hardening. Droid runs npm install in a per-plugin scratch directory with --ignore-scripts, --no-save, --no-audit, and --no-fund. Lifecycle scripts (postinstall, preinstall, and so on) are not executed, and your global npm configuration is not consulted or mutated.
npm: is not a valid marketplace source. Droid only accepts npm as a per-plugin source inside a marketplace’s marketplace.json. To ship a single npm-published plugin to your team without standing up a full marketplace repo, publish a thin wrapper marketplace (see below).
Wrapper marketplace for a single npm plugin
To distribute one npm-published plugin without a dedicated marketplace repo, commit a small marketplace.json to any folder. The folder name becomes the marketplace name.
your-org-plugins/
└── .factory-plugin/
    └── marketplace.json
{
  "name": "your-org-plugins",
  "owner": { "name": "Your Org Platform Team" },
  "plugins": [
    {
      "name": "pr-triage",
      "description": "Triage and label new pull requests for the on-call rotation",
      "source": {
        "source": "npm",
        "package": "@your-org/droid-pr-triage",
        "version": "^2.0.0"
      }
    }
  ]
}
Teammates add it like any other local marketplace:
droid plugin marketplace add ./your-org-plugins
droid plugin install pr-triage@your-org-plugins

Version management

Use semantic versioning in your plugin manifest for documentation purposes:
  • Major (1.0.0 → 2.0.0): Breaking changes
  • Minor (1.0.0 → 1.1.0): New features, backward compatible
  • Patch (1.0.0 → 1.0.1): Bug fixes
Droid tracks plugin versions by Git commit hash, not semantic version. By default, updating a plugin fetches the latest commit from the marketplace. To pin a plugin to a specific version, pin the marketplace it lives in by setting ref (branch or tag) or sha (full commit SHA) on the marketplace source — see Pinning a marketplace to a ref or commit.

Claude Code compatibility

Droid is fully compatible with Claude Code plugins. If you find a Claude Code plugin, you can install it directly and Droid will automatically translate the format.

Best practices

Design plugins around a single purpose or workflow. Prefer several small plugins over one monolithic plugin that does everything.
Include a README with:
  • What the plugin does
  • Installation instructions
  • All available commands and their usage
  • Configuration options
  • Examples
Follow semver conventions so users know when updates might break their workflows.
Ensure your plugin works on macOS, Linux, and Windows if applicable. Use portable shell commands and avoid platform-specific paths.
Scripts should fail gracefully without blocking the user. Log errors but don’t crash sessions.
Don’t collect telemetry or send data without explicit consent. Document any network requests your plugin makes.

Example: Complete plugin

Here’s a complete example of a code review plugin:
code-review-plugin/
├── .factory-plugin/
│   └── plugin.json
├── commands/
│   └── review.md
├── skills/
│   └── review-patterns/
│       └── SKILL.md
├── droids/
│   └── reviewer.md
└── README.md
.factory-plugin/plugin.json:
{
  "name": "code-review",
  "description": "Automated code review with multiple specialized reviewers",
  "version": "1.0.0",
  "author": { "name": "Your Team" }
}
commands/review.md:
---
description: Run comprehensive code review on staged changes
---

Review the staged git changes using the review-patterns skill.
Focus on: $ARGUMENTS

If no focus area specified, perform a general review.
skills/review-patterns/SKILL.md:
---
name: review-patterns
description: Use when reviewing code to check for common issues and best practices.
---

Check code for:
- Logic errors and edge cases
- Error handling completeness
- Security vulnerabilities
- Performance concerns
- Test coverage gaps
droids/reviewer.md:
---
name: reviewer
description: Specialized code reviewer subagent
model: inherit
tools: read-only
---

You are a senior code reviewer. Analyze the provided code and report:

Summary: <one-line assessment>
Issues:
- <severity> <description>
Suggestions:
- <improvement>

Next steps

Plugins overview

Learn about installing and managing plugins.

Skills

Deep dive into creating powerful skills.

Custom commands

Create user-invoked slash commands.

Custom Droids

Create specialized subagents for your plugins.