Usage
facets.json and installs them into every connected adapter. There is no separate install step afterwards.
Specifiers are validated before anything touches disk. If the project has no adapter, a terminal gets the picker and a non-interactive run fails pointing at facet adapter add. From there the run is an ordinary install, so it reports the same outcomes and can meet the same collision and MCP approval screens.
A facet whose only asset is an MCP server is valid: it configures servers and writes no files. A facet that composes other facets with a non-empty facets array is rejected.
Examples
Flags
boolean
Show detailed step output on stderr. Declaration contents never appear here. See where declarations appear.
boolean
Approve the MCP configuration this run would write, without prompting.
Exit codes
Nothing is written unless the run had already started writing, in which case it is rolled back.
Details
Source grammar
Registry names
Git and GitHub sources
git must be on your PATH.
Local paths
~ is not expanded by the CLI. Let your shell expand it, and remember the result still has to sit inside the project tree.
Forms that are rejected
Re-adding a facet
Re-adding pins one facet to a version you name. To move every declared facet to newer releases, usefacet update instead.
- Same source: a no-op, reported as
unchangedorrepaired. If you aliased or omitted one of its contributions since, it reportsupdated. - Different version: updates the entry and counts under
N updated. Per-facet version transitions are printed byfacet update. - Bare re-add: resolves the newest release and pins it, even over an existing wildcard.
- Explicit
@latestor wildcard: re-resolves to the newest match and keeps floating.
--frozen-lockfile that same stale override is blocking drift instead.
What gets written per specifier shape is defined by the manifest write policy. A successful non-frozen add also stamps "manifestVersion": 0.2.
Troubleshooting
a source specifier was rejected
a source specifier was rejected
Cause: the specifier does not match the source grammar. Every specifier is parsed before any network or disk work, so the run stops with the project untouched.Fix: the error names the offending specifier and the accepted forms. See forms that are rejected for the common substitutions.
git is not installed
git is not installed
Cause: a git or GitHub source is cloned locally, and
git was not found on your PATH.Fix: install git, or add the facet from the registry or a local path instead.a git source needs authentication
a git source needs authentication
Cause: the repository is private, or the clone prompted for credentials.Fix: configure git authentication for the repository, or use a public one. Interactive credential prompts are not supported during a clone.
a git ref could not be checked out
a git ref could not be checked out
Cause: the branch, tag, or commit named after
# does not exist in the cloned repository.Fix: correct the ref, or drop it to use the default branch.a local path resolved outside the project
a local path resolved outside the project
Cause: a local source must resolve inside the project tree, so a facet cannot be installed from an arbitrary location on your machine.Fix: move or copy the facet into the project, then add it by a path inside the tree.
the facet declares composition
the facet declares composition
Cause: the source declares a non-empty
facets array. Composition is reserved in the manifest format and is not installable yet.Fix: ask the publisher for a release that ships its own assets directly. There is no flag to install it as-is.a git or local source failed to build
a git or local source failed to build
Cause: the clone or directory resolved, but its
facet.json did not load, its name disagreed with what you asked for, or the build failed.Fix: run facet build --verify inside that source to see the validation errors, then fix and re-add.