Skip to content

Marketplaces

Marketplaces are curated indexes of plugins hosted as GitHub repositories. Each marketplace contains a marketplace.json file that maps plugin names to source locations. APM resolves these entries to Git URLs, so plugins installed from marketplaces get the same version locking, security scanning, and governance as any other APM dependency.

A marketplace is a GitHub repository with a marketplace.json at its root. The file lists plugins with their source type and location:

{
"name": "Acme Plugins",
"plugins": [
{
"name": "code-review",
"description": "Automated code review agent",
"source": { "type": "github", "repo": "acme/code-review-plugin" }
},
{
"name": "style-guide",
"source": { "type": "url", "url": "https://github.com/acme/style-guide.git" }
},
{
"name": "eslint-rules",
"source": { "type": "git-subdir", "repo": "acme/monorepo", "subdir": "plugins/eslint-rules" }
},
{
"name": "local-tools",
"source": "./tools/local-plugin"
}
]
}

Both Copilot CLI and Claude Code marketplace.json formats are supported. Copilot CLI uses "repository" and "ref" fields; Claude Code uses "source" (string or object). APM normalizes entries from either format into its canonical dependency representation.

TypeDescriptionExample
githubGitHub owner/repo shorthandacme/code-review-plugin
urlFull HTTPS or SSH Git URLhttps://github.com/acme/style-guide.git
git-subdirSubdirectory within a Git repository (repo + subdir)acme/monorepo + plugins/eslint-rules
String sourceSubdirectory within the marketplace repository itself./tools/local-plugin

npm sources are not supported. Copilot CLI format uses "repository" and optional "ref" fields instead of "source".

Marketplaces can declare a metadata.pluginRoot field to specify the base directory for bare-name sources:

{
"metadata": { "pluginRoot": "./plugins" },
"plugins": [
{ "name": "my-tool", "source": "my-tool" }
]
}

With pluginRoot set to ./plugins, the source "my-tool" resolves to owner/repo/plugins/my-tool. Sources that already contain a path separator (e.g. ./custom/path) are not affected by pluginRoot.

Terminal window
apm marketplace add acme/plugin-marketplace

This registers the marketplace and fetches its marketplace.json. By default APM tracks the main branch.

Options:

  • --name/-n — Custom display name for the marketplace
  • --branch/-b — Branch to track (default: main)
Terminal window
# Register with a custom name on a specific branch
apm marketplace add acme/plugin-marketplace --name acme-plugins --branch release
Terminal window
apm marketplace list

Shows all registered marketplaces with their source repository and branch.

View all plugins available in a specific marketplace:

Terminal window
apm marketplace browse acme-plugins

Search plugins by name or description in a specific marketplace using QUERY@MARKETPLACE:

Terminal window
apm search "code review@skills"

Options:

  • --limit — Maximum results to return (default: 20)
Terminal window
apm search "linting@awesome-copilot" --limit 5

The @MARKETPLACE scope is required — this avoids name collisions when different marketplaces contain plugins with the same name. To see everything in a marketplace, use apm marketplace browse <name> instead.

Use the NAME@MARKETPLACE syntax to install a plugin from a specific marketplace:

Terminal window
apm install code-review@acme-plugins

APM resolves the plugin name against the marketplace index, fetches the underlying Git repository, and installs it as a standard APM dependency. The resolved source appears in apm.yml and apm.lock.yaml just like any direct dependency.

For full apm install options, see CLI Commands.

Marketplace-resolved plugins are tracked in apm.lock.yaml with full provenance:

apm_modules:
acme/code-review-plugin:
resolved: https://github.com/acme/code-review-plugin#main
commit: abc123def456789
discovered_via: acme-plugins
marketplace_plugin_name: code-review

The discovered_via field records which marketplace was used for discovery. marketplace_plugin_name stores the original plugin name from the index. The resolved URL and commit pin the exact version, so builds remain reproducible regardless of marketplace availability.

APM caches marketplace indexes locally with a 1-hour TTL. Within that window, commands like search and browse use the cached index. After expiry, APM fetches a fresh copy from the network. If the network request fails, APM falls back to the expired cache (stale-if-error) so commands still work offline.

Force a cache refresh:

Terminal window
# Refresh a specific marketplace
apm marketplace update acme-plugins
# Refresh all registered marketplaces
apm marketplace update

Remove a registered marketplace:

Terminal window
apm marketplace remove acme-plugins
# Skip confirmation prompt
apm marketplace remove acme-plugins --yes

Removing a marketplace does not uninstall plugins previously installed from it. Those plugins remain pinned in apm.lock.yaml to their resolved Git sources.