Marketplaces and updates
After reading this page you can publish a small catalog of plugins, add it to
Muse Code as a marketplace, install a plugin from it by name, and know what
muse plugins update and muse plugins remove do to a plugin that came from
a local path or from a marketplace. Every output below was produced by
Muse Code 1.3.0 against the weather plugin in an
empty plugin store. The plugin surface is part of the Developer Preview and
may change.
What a marketplace is
Section titled “What a marketplace is”A marketplace is a named catalog of plugin packages. You add it once with a
source; Muse Code reads the catalog, copies what it needs, and stores a
snapshot under your data directory. From then on
muse plugins list --available and muse plugins install <plugin>@<name>
read that snapshot and never touch the network. Refreshing is a separate,
explicit command.
There is no public catalog to browse yet. A marketplace is something you or your team publish, and the rest of this page shows how.
Sources you can add
Section titled “Sources you can add”muse plugins marketplace add <name> <source><name> follows the plugin id grammar: lowercase letters, digits, ., _
and -, starting with a letter or digit. A small set of names is reserved for
Muse Code’s own use; adding one fails with a message that the name is reserved
and cannot be added. Pick a name that describes your team or project.
The source is a marketplace.json file (package paths resolve relative to
it), a directory that holds a catalog, or a git repository given as a URL
(https://…/plugins.git, git@host:team/plugins.git, ssh://…,
file:///path/to/repo) or as the GitHub shorthand owner/repo. Any git
source may end in #ref to pin a branch, a tag or a commit, and clones time
out after 60 seconds. A path that exists on disk is treated as local unless
it ends in .git; anything else is treated as a git source.
The muse plugins command lists every accepted form
and the source kind each one records.
In a directory or a checkout, Muse Code looks for the catalog at three locations, in this order, and uses the first one it finds:
marketplace.json(the native format described below).agents/plugins/marketplace.json(a Codex catalog).claude-plugin/marketplace.json(a Claude Code catalog)
Codex and Claude Code catalogs are translated into the native shape when the snapshot is taken. Entries that point at other repositories are only materialized when the marketplace itself was added from git, and entry types Muse Code cannot fetch are skipped with a reason. Compatibility with other plugin formats says what happens to the packages themselves.
A directory with none of the three fails and names all of them:
muse plugins marketplace add empty ./empty-dirfailed to read plugin store `<empty-dir>/marketplace.json`: no marketplace catalog found; probed `marketplace.json`, `.agents/plugins/marketplace.json`, `.claude-plugin/marketplace.json`A native catalog
Section titled “A native catalog”This catalog publishes one plugin. The directory that holds it has the
weather plugin at plugins/weather, next to the catalog file:
team-marketplace/├── marketplace.json└── plugins/ └── weather/ ├── .muse-plugin/plugin.json ├── skills/forecast/SKILL.md ├── commands/forecast-brief.md └── hooks/log-tool-use.sh{ "schemaVersion": 1, "source": "local", "plugins": [ { "name": "weather", "version": "0.1.0", "install": { "transport": "local-path", "source": "plugins/weather" }, "integrity": { "digest": "sha256:bacc26ede05bf8aa08c888ddacf24540f757fb51f5248927df265bdcd41ea62c" }, "availability": { "status": "available" } } ]}| Field | Value |
|---|---|
schemaVersion |
The integer 1. |
source |
The string "local". |
plugins[].name |
The plugin id. It must equal the name in the package’s own manifest. |
plugins[].version |
A label shown in listings. Muse Code never compares versions. |
plugins[].install.transport |
The string "local-path"; it is the only transport a snapshot supports. |
plugins[].install.source |
The package directory, relative to the catalog file (an absolute path also works). |
plugins[].integrity.digest |
sha256: followed by 64 hex digits: the SHA-256 of the package tree. |
plugins[].availability.status |
available, deprecated or blocked. Only available entries install. |
To get the digest, install the package once from its directory with
muse plugins install <dir> --json and copy package_sha256; the digest
covers every file in the package except .git, .hg and .svn
directories, so it is the same on every machine that holds the same files.
An entry with a missing or malformed field is skipped with a warning, and a
catalog with no usable entry fails to add.
Adding the directory and reading the snapshot back:
muse plugins marketplace add team ./team-marketplacemuse plugins marketplace listmuse plugins list --availableteam plugins=1 source=<absolute path to team-marketplace>team plugins=1 source=<absolute path to team-marketplace>weather@team 0.1.0 status=available transport=local-pathWith --json, marketplace add reports the source kind, the counts and the
snapshot location:
{ "marketplace": { "name": "team", "source": { "kind": "local-dir", "path": "<absolute path to team-marketplace>" }, "plugin_count": 1, "skipped": [], "snapshot_path": "<data dir>/plugins/marketplaces/team/snapshot.json", "last_updated_at": "2026-09-17T04:27:36.045578Z", "fetched": true }}Adding the same directory from a git checkout instead (a file:// URL to a
repository that holds the same files) records source=file:///… and stores
the checkout with the snapshot; the rest of the flow is identical.
Installing from a marketplace
Section titled “Installing from a marketplace”muse plugins install weather@teaminstalled weather 0.1.0 marketplace=team enabled=true trust=user-local provenance=marketplace-user-added cache=<data dir>/plugins/cache/local/weather/bacc26ed…/packagewarning third-party plugin: hooks require review before activation; skills and commands are active without review while the plugin is enabledA target is read as <plugin>@<marketplace> when it contains @, does not
exist on disk, and does not look like a path. Before anything is copied,
Muse Code checks the entry in the snapshot:
| Check | On failure |
|---|---|
| The marketplace is configured | marketplace `nowhere` is not configured |
| The entry exists | plugin `nothing` is not available in marketplace `team` |
The entry’s status is available |
plugin `weather` in marketplace `team` is deprecated |
The package tree’s digest equals integrity.digest |
plugin `weather` in marketplace `team` failed integrity check |
| The package validates | The same diagnostics muse plugins validate would print |
The manifest name equals the catalog name |
marketplace plugin `weather-renamed` resolves to a bundle whose manifest id `weather` does not match |
The catalog version equals the manifest version |
A warning only; the install proceeds |
Each message in the table was produced by a real failed install; the
integrity one came from a catalog whose package had been edited after its
digest was recorded, and the name one from an entry called weather-renamed
that pointed at the weather package. The version check only warns. This is
the receipt from a catalog that said 0.2.0 for a package whose manifest says
0.1.0:
warning third-party plugin: hooks require review before activation; skills and commands are active without review while the plugin is enabled; marketplace plugin `weather` catalog version `0.2.0` differs from manifest version `0.1.0`The digest is the integrity mechanism; the version is a label. There is no
version comparison, no downgrade protection and no pinning beyond a git
#ref on the marketplace source and the digest in the snapshot.
After the checks the install is the same as a local one: the package is
copied into your cache, recorded as enabled with trust=user-local, its
skills and commands work at once, and its hooks, MCP servers, reminders and
agent definitions wait at review_needed until you approve them.
Trust, review and scopes covers that step.
Marketplace installs are always user scope; --scope project is refused for
them. The muse plugins command lists every
flag install accepts and the exact lines it prints.
Refreshing a marketplace
Section titled “Refreshing a marketplace”muse plugins marketplace update teamteam plugins=1 source=<absolute path to team-marketplace>update re-reads the source (for git, a fresh clone), builds a new snapshot
and swaps it in; a failed refresh keeps the previous snapshot. Installed
plugins are not touched by a marketplace refresh. For a marketplace added from
git, muse plugins update does not follow the new snapshot; to move an
installed plugin to what the refreshed catalog offers, remove it and install it
again from the marketplace (your approvals are forgotten and must be given
again). For a marketplace added from a local directory or file, the plugin’s
recorded source is your directory itself, so muse plugins update <plugin-id>
picks up changes without a refresh.
Updating an installed plugin
Section titled “Updating an installed plugin”muse plugins update weatherupdated weather sha256:b0cf4aec… trust=user-local previous=sha256:b0cf4aec…warning third-party plugin: hooks require review before activation; skills and commands are active without review while the plugin is enabledupdate <plugin-id> re-reads the plugin from the source recorded at install
and replaces the cached copy. It keeps the plugin’s enabled state and
provenance, prints the manifest digest before and after, and leaves the
previous record in place if anything fails.
| Installed from | What update re-reads |
|---|---|
| A local path | That directory, as it is now. This is the development loop: edit in place, run update. |
| A marketplace added from a local directory or file | The package directory the catalog points at, as it is now. Refreshing the marketplace is not needed to pick up a changed package. |
| A marketplace added from git | The checkout that was current when you installed. update never follows a refreshed snapshot; after a muse plugins marketplace update that checkout is superseded and deleted at the next marketplace change, and update then fails with plugin-source-unavailable. To move to what the refreshed catalog offers, run muse plugins remove <plugin-id>, then muse plugins install <plugin>@<name>, then approve its runtime capabilities again. |
If the recorded source is gone, update fails closed and tells you the way
out. This is a local install whose directory was deleted:
plugin `weather` source `<path>` is no longer available; run `muse plugins remove weather`, then reinstall the plugin from an available sourceWith --json the error code is plugin-source-unavailable. After a
marketplace update, plugins update for a plugin installed from a git
marketplace reports its source unavailable in the same way once the old
checkout is gone; remove the plugin and reinstall it with
muse plugins install <plugin>@<name>. For a marketplace added from git, the
copy a plugin was installed from lives with the snapshot, so
marketplace remove ends that plugin’s update path too; for a marketplace
added from a local directory or file, the recorded source is your directory
itself.
Removing
Section titled “Removing”muse plugins remove weather --delete-data --json{ "removed": "weather", "cache_path": "<data dir>/plugins/cache/local/weather/bacc26ed…/package", "data_path": "<data dir>/plugins/data/weather", "warning": null, "lockfile_path": "<data dir>/plugins/installed.json"}remove <plugin-id> deletes the installed record and the cached package and
forgets every review decision for the plugin. Without --delete-data the
plugin’s data directory (MUSE_PLUGIN_DATA_DIR, where a hook may have
written files) stays behind and a later reinstall finds it again; with the
flag it is deleted too and data_path names it. A cleanup problem is
reported in warning while the removal still succeeds.
muse plugins marketplace remove teamremoved teammarketplace remove <name> deletes the marketplace record and its snapshot.
Plugins you installed from it stay installed and keep working; only their
update path is gone, as described above.
Next steps
Section titled “Next steps”- Trust, review and scopes explains what to check before approving the hooks and MCP servers a marketplace plugin brings.
- The
muse pluginscommand lists everymarketplacesubcommand, thelist --availablecolumns and the--jsonshapes. - Compatibility with other plugin formats covers what Muse Code does with Codex and Claude Code catalogs and packages.
- Quickstart: your first plugin is the local-path loop that a marketplace later distributes.