Skip to content

Plugins

APM treats plugins and packages as the same artifact. Every APM package is plugin-compatible by default: apm pack writes a plugin.json at the root of the bundle so any plugin host (Claude Code and other Claude-plugin-compatible runtimes) can load it natively.

The only authoring decision is whether you also keep an apm.yml:

  • With apm.yml (recommended). You get dependency management, lockfile pinning, security scanning, devDependencies, and multi-runtime deploy during development. apm pack still emits a plugin-compatible bundle for non-APM consumers. This is what apm init --plugin produces.
  • From an existing plugin.json. APM consumes it natively - apm install owner/repo works against any plugin repo without migration. Metadata is synthesized from plugin.json. Add an apm.yml later if you want APM tooling during development.

For why apm.yml adds value on top of plugin.json, see Anatomy — Why not just ship a plugin.json?.

Terminal window
apm init my-plugin --plugin # apm.yml + plugin.json
apm install --dev owner/helpers # dev-only dependency (excluded from pack)
apm install owner/core-rules # production dependency
apm pack # plugin-compatible bundle by default

The packed directory contains no APM-specific files. See Pack & Distribute — Plugin format for the output mapping and Without APM: what you give up for the consumer-side trade-off.

Plugins are packages that contain:

  • Skills - Reusable agent personas and expertise
  • Agents - AI agent definitions
  • Commands - Executable prompts and workflows
  • Instructions - Context and guidelines

APM automatically detects plugins with plugin.json manifests and synthesizes apm.yml from the metadata, treating them identically to other APM packages.

Install plugins using the standard apm install command:

Terminal window
# Install a plugin from GitHub
apm install owner/repo/plugin-name
# Or add to apm.yml
dependencies:
apm:
- anthropics/claude-code-plugins/commit-commands#v1.2.0

When you run apm install owner/repo/plugin-name:

  1. Clone - APM clones the repository to apm_modules/
  2. Detect - It searches for plugin.json in priority order:
    1. plugin.json (root)
    2. .github/plugin/plugin.json (GitHub Copilot format)
    3. .claude-plugin/plugin.json (Claude format)
    4. .cursor-plugin/plugin.json (Cursor format)
  3. Map Artifacts - Plugin primitives from the repository root are mapped into .apm/:
    • agents/.apm/agents/
    • skills/.apm/skills/
    • commands/.apm/prompts/
    • *.md command files are normalized to *.prompt.md for prompt/command integration
  4. Synthesize - apm.yml is automatically generated from plugin metadata
  5. Integrate - The plugin is now a standard dependency with:
    • Version pinning via apm.lock.yaml
    • Transitive dependency resolution
    • Conflict detection
    • Everything else APM packages support

This unified approach means no special commands needed — plugins work exactly like any other APM package.

A plugin repository contains a plugin.json manifest and primitives at the repository root.

APM supports multiple plugin manifest locations to accommodate different platforms:

plugin-repo/
├── .github/
│ └── plugin/
│ └── plugin.json # GitHub Copilot location
├── agents/
│ └── agent-name.agent.md
├── skills/
│ └── skill-name/
│ └── SKILL.md
└── commands/
└── command-1.md
└── command-2.md
plugin-repo/
├── .claude-plugin/
│ └── plugin.json # Claude location
├── agents/
│ └── agent-name.agent.md
├── skills/
│ └── skill-name/
│ └── SKILL.md
└── commands/
└── command-1.md
└── command-2.md
plugin-repo/
├── plugin.json # Root location (checked first)
├── agents/
│ └── agent-name.agent.md
├── skills/
│ └── skill-name/
│ └── SKILL.md
└── commands/
└── command-1.md
└── command-2.md
plugin-repo/
├── .cursor-plugin/
│ └── plugin.json # Cursor location
├── agents/
│ └── agent-name.md
├── skills/
│ └── skill-name/
│ └── SKILL.md
└── rules/
└── my-rule.mdc

Priority Order: APM checks for plugin.json in these locations:

  1. plugin.json (root)
  2. .github/plugin/plugin.json
  3. .claude-plugin/plugin.json
  4. .cursor-plugin/plugin.json

Note: Primitives (agents, skills, commands, instructions) are always located at the repository root, regardless of where plugin.json is located.

Only name is required. version and description are optional metadata:

{
"name": "Plugin Display Name",
"version": "1.0.0",
"description": "What this plugin does"
}

Optional fields:

{
"name": "My Plugin",
"version": "1.0.0",
"description": "A plugin for APM",
"author": "Author Name",
"license": "MIT",
"repository": "owner/repo",
"homepage": "https://example.com",
"tags": ["ai", "coding"],
"dependencies": [
"another-plugin-id"
]
}

By default APM looks for agents/, skills/, commands/, and hooks/ directories at the plugin root. You can override these with custom paths using strings or arrays:

{
"name": "my-plugin",
"agents": ["./agents/planner.md", "./agents/coder.md"],
"skills": ["./skills/analysis", "./skills/review"],
"commands": "my-commands/",
"hooks": "hooks.json"
}
  • String — single directory or file path
  • Array — list of directories or individual files
  • For skills, directories are preserved as named subdirectories (e.g., ./skills/analysis/.apm/skills/analysis/SKILL.md)
  • For agents, directory contents are flattened into .apm/agents/ (agents are flat files, not named directories)
  • hooks also accepts an inline object: "hooks": {"hooks": {"PreToolUse": [...]}}

When a package ships hooks for multiple tools, use target-specific filenames so each tool receives only its own hooks:

Filename patternDeployed to
*-copilot-hooks.jsonGitHub Copilot only
*-cursor-hooks.jsonCursor only
*-claude-hooks.jsonClaude Code only
*-codex-hooks.jsonCodex CLI only
*-gemini-hooks.jsonGemini CLI only
Any other name (e.g. hooks.json, telemetry-hooks.json)All targets

Example directory tree for a multi-target hook package:

my-hooks-pkg/
hooks/
hooks.json # deployed to all targets
copilot-hooks.json # Copilot only
cursor-hooks.json # Cursor only
claude-hooks.json # Claude Code only

Plugins can ship MCP servers that are automatically deployed through APM’s MCP pipeline. Define servers using mcpServers in plugin.json:

{
"name": "my-plugin",
"mcpServers": {
"my-server": {
"command": "npx",
"args": ["-y", "my-mcp-server"]
},
"my-api": {
"url": "https://api.example.com/mcp"
}
}
}

mcpServers supports three forms:

  • Object — inline server definitions (as above)
  • String — path to a JSON file containing mcpServers
  • Array — list of JSON file paths (merged, last-wins on name conflicts)

When mcpServers is absent, APM auto-discovers .mcp.json at the plugin root (then .github/.mcp.json as fallback), matching Claude Code’s auto-discovery behavior.

Servers with command are configured as stdio transport; servers with url use http (or the type field if it specifies sse or streamable-http). All plugin-defined MCP servers are treated as self-defined (registry: false).

Trust model: Self-defined MCP servers from direct dependencies (depth=1) are auto-trusted. Transitive dependencies require --trust-transitive-mcp. See dependencies.md for details.

Terminal window
# Install a specific plugin
apm install anthropics/claude-code-plugins/commit-commands
# With version
apm install anthropics/claude-code-plugins/commit-commands#v1.2.0
dependencies:
apm:
- anthropics/claude-code-plugins/commit-commands#v1.2.0
- anthropics/claude-code-plugins/refactor-tools#v2.0
- mycompany/internal-standards#main

Then sync and install:

Terminal window
apm install

Plugins support all standard APM versioning:

dependencies:
apm:
# Latest version
- owner/repo/plugin
# Latest from branch
- owner/repo/plugin#main
# Specific tag
- owner/repo/plugin#v1.2.0
# Specific commit
- owner/repo/plugin#abc123

Run apm install to download and lock versions in apm.lock.yaml.

  • GitHub - owner/repo or owner/repo/plugin-path
  • GitHub - GitHub URLs or SSH references
  • Azure DevOps - dev.azure.com/org/project/repo

Plugin versions are automatically tracked in apm.lock.yaml:

apm_modules:
anthropics/claude-code-plugins/commit-commands:
resolved: https://github.com/anthropics/claude-code-plugins/commit-commands#v1.2.0
commit: abc123def456789

This ensures reproducible installs across environments.

APM automatically detects:

  • Duplicate plugins from different sources
  • Version conflicts between dependencies
  • Missing transitive dependencies

Run with --verbose to see dependency resolution details:

Terminal window
apm install --verbose

Plugins are automatically compiled during apm compile:

Terminal window
apm compile

This:

  • Generates AGENTS.md from plugin agents
  • Integrates skills into the runtime
  • Includes prompt primitives

Use the authoring workflow to develop plugins with APM’s full tooling and export them as standalone plugin directories. See Pack & Distribute — Plugin format for the output mapping and structure.

Plugins can be found through:

  • Marketplaces — curated marketplace.json indexes browsable with apm marketplace browse and searchable with apm search QUERY@MARKETPLACE. See the Marketplaces guide for setup.
  • GitHub repositories (search for repos with plugin.json)
  • Organization-specific plugin repositories

Install by name from a registered marketplace:

Terminal window
apm install code-review@acme-plugins

APM resolves marketplace entries to Git URLs, so marketplace-installed plugins get full version locking, security scanning, and governance. See Marketplaces for details.

For direct installs, use the standard apm install owner/repo/plugin-name command.

If APM doesn’t recognize your plugin:

  1. Check plugin.json exists in one of the checked locations:
    • plugin.json (root)
    • .github/plugin/plugin.json (GitHub Copilot format)
    • .claude-plugin/plugin.json (Claude format)
    • .cursor-plugin/plugin.json (Cursor format)
  2. Verify JSON is valid: cat plugin.json | jq .
  3. Ensure name field is present (only required field)
  4. Verify primitives are at the repository root (agents/, skills/, commands/)

See the concepts.md guide on dependency resolution.

See integration-testing.md for enterprise setup.