name: authoring-marketplaces description: Use when creating a new omp marketplace. Covers marketplace.json schema, source types, install commands, and publishing.
Authoring Marketplaces
A marketplace is a Git repository (or local directory) that contains a catalog file at .claude-plugin/marketplace.json. Anyone can author one. Users add it with /marketplace add owner/repo and then install individual plugins from it.
Minimum viable marketplace
my-marketplace/
.claude-plugin/
marketplace.json
plugins/
my-plugin/
package.json
index.ts
{
"name": "my-marketplace",
"owner": { "name": "Your Name" },
"plugins": [
{
"name": "my-plugin",
"description": "What it does",
"source": "./plugins/my-plugin"
}
]
}
Push to GitHub. Users install with:
/marketplace add your-github-username/my-marketplace
/marketplace install my-plugin@my-marketplace
marketplace.json schema
The catalog file must live at .claude-plugin/marketplace.json in the repository root.
Top-level fields
| Field | Required | Description |
|---|---|---|
name |
yes | Marketplace name. Lowercase alphanumeric, hyphens, dots. Must start and end with alphanumeric. Max 64 chars. |
owner |
yes | Object with at minimum owner.name (string) |
owner.name |
yes | Marketplace owner name |
owner.email |
no | Owner contact email |
plugins |
yes | Array of plugin entries (see below) |
metadata.description |
no | Short description of the marketplace |
metadata.version |
no | Catalog metadata version string |
metadata.pluginRoot |
no | String prepended to all relative plugin source paths |
| extra top-level fields | no | Preserved by the parser but not used by marketplace install/runtime logic |
Plugin entry fields
| Field | Required | Description |
|---|---|---|
name |
yes | Plugin name (same naming rules as marketplace name) |
source |
yes | Where to find the plugin — string or object (see source types below) |
description |
no | Short plugin description |
version |
no | Version string |
author |
no | { name, email? } |
homepage |
no | URL |
category |
no | e.g. development, productivity, security |
tags / keywords |
no | Arrays of string tags/keywords |
repository |
no | Repository URL |
license |
no | License string |
strict |
no | Boolean plugin metadata flag |
commands, agents, hooks, mcpServers, lspServers |
no | Capability metadata used by plugin tooling and selectors |
Full catalog example
{
"$schema": "https://anthropic.com/claude-code/marketplace.schema.json",
"name": "acme-plugins",
"owner": {
"name": "Acme Corp",
"email": "plugins@acme.example"
},
"metadata": {
"description": "Official Acme plugins for oh-my-pi"
},
"plugins": [
{
"name": "acme-linter",
"description": "Enforce Acme coding standards",
"category": "development",
"source": "./plugins/linter"
},
{
"name": "acme-deploy",
"description": "One-command deploy to Acme cloud",
"category": "devops",
"source": {
"source": "github",
"repo": "acme-corp/omp-deploy-plugin",
"ref": "main"
}
}
]
}
Plugin source types
1. Relative path string
Points to a subdirectory inside the marketplace repository itself. Must start with ./.
"source": "./plugins/my-plugin"
The path is resolved relative to the marketplace repository root. Path traversal outside the repo root is rejected.
Use metadata.pluginRoot to avoid repeating a common prefix:
{
"metadata": { "pluginRoot": "./plugins" },
"plugins": [
{ "name": "plugin-a", "source": "./plugin-a" },
{ "name": "plugin-b", "source": "./plugin-b" }
]
}
2. Git URL
A full Git repository URL. Optionally pin to a branch/tag (ref) or exact commit (sha):
"source": {
"source": "url",
"url": "https://github.com/org/my-plugin.git",
"ref": "main",
"sha": "a1b2c3d4..."
}
3. GitHub shorthand
Shorthand for GitHub repositories. Functionally equivalent to a Git URL but more concise:
"source": {
"source": "github",
"repo": "org/my-plugin",
"ref": "v2.1.0",
"sha": "a1b2c3d4..."
}
4. Git subdirectory (monorepo)
For plugins living inside a subdirectory of a larger repository. url accepts a full HTTPS URL or a GitHub owner/repo shorthand:
"source": {
"source": "git-subdir",
"url": "https://github.com/org/monorepo.git",
"path": "packages/my-plugin",
"ref": "main",
"sha": "a1b2c3d4..."
}
The path must resolve inside the cloned repository — directory escape is rejected.
5. NPM package
Declares the plugin as an npm package. version is optional:
"source": {
"source": "npm",
"package": "@acme/omp-plugin",
"version": "1.2.0"
}
Note: npm plugin sources are declared in the schema but installation support is not yet fully implemented. Use Git-based sources for plugins that need to work today.
Plugin structure
Each plugin directory (regardless of source type) should contain:
my-plugin/
package.json ← required: declares omp.extensions entry points
src/
main.ts ← extension factory
README.md ← recommended: description + usage
Minimum package.json:
{
"name": "my-plugin",
"omp": {
"extensions": ["./src/main.ts"]
}
}
Install command
/marketplace install name@marketplace-name
/marketplace install --force name@marketplace-name # reinstall
/marketplace install --scope project name@marketplace # project-scoped
CLI equivalent:
omp plugin marketplace add owner/repo
omp plugin install name@marketplace-name
Scope behavior:
- user (default) — installed in
~/.omp/plugins/installed_plugins.json, available in all projects - project — installed in
<project>/.omp/plugins/installed_plugins.json, available only in that project
Project-scoped installs shadow user-scoped installs of the same plugin name.
Naming rules
Marketplace names and plugin names must:
- Contain only lowercase letters, digits, hyphens (
-), and dots (.) - Start and end with a lowercase letter or digit
- Be at most 64 characters
Plugin IDs (name@marketplace) must be at most 128 characters total.
Valid: my-plugin, code-review, acme.tools, ai-v2
Invalid: -bad-start, bad-end-, .dot-start, Under_score, HAS_CAPS
Publishing workflow
- Create
marketplace.jsonat.claude-plugin/marketplace.jsonin a new Git repo. - Add plugin entries pointing to subdirectories (or external sources).
- Push to GitHub.
- Share the
owner/repostring. Users add it with/marketplace add owner/repo. - When you update the catalog, users run
/marketplace update your-marketplace-nameto pull the latest.
To test locally before publishing:
/marketplace add ./path/to/my-marketplace
Local path sources also accept ~/ and absolute paths.
Further reading
docs/marketplace.md— marketplace system internals, on-disk layout, command referencedocs/skills/authoring-extensions.md— how to author the extension modules inside pluginsdocs/skills/examples/mini-marketplace/— minimal working marketplace example