Skip to content

agentsmesh install

Install rules, commands, agents, or skills from remote repositories or local paths. Installed packs are tracked in .agentsmesh/installs.yaml and merged into canonical config during generation.

A multi-signal classifier auto-detects three source shapes at install time:

  • Anthropic-style skill packs — root skills/<kebab>/SKILL.md, optional agents/, references/, .claude/commands/, .gemini/commands/, multi-tool rules at root. One install <url> imports the whole pack as a bulk set.
  • Canonical agentsmesh repos — anything carrying .agentsmesh/ at the root. Imports verbatim via the canonical loader.
  • Tool-native repos.claude/, .cursor/, .codex/, etc. layouts. Native importer dispatches per target, identical to pre-skill-pack behavior.

--target <id> and --as <kind> are explicit overrides that skip the classifier; existing scripts keep working unchanged. .agentsmesh/.install.lock serialises concurrent install/uninstall runs.

Usage

Terminal window
agentsmesh install <source> [flags]
agentsmesh install --sync

Flags

FlagDescription
<source>GitHub/GitLab URL, git URL, SSH URL, or local path.
--path <dir>Subdirectory within the source repo to install from.
--target <id>Hint for native format auto-discovery (e.g., claude-code).
--as <kind>Manual install type: rules, commands, agents, or skills.
--name <id>Override the generated install entry name.
--extendsRecord as an extends entry instead of a materialized pack.
--syncReinstall missing packs from .agentsmesh/installs.yaml.
--allInstall every sub-pack from a marketplace source (.claude-plugin/marketplace.json) or every flat collection in a multi-collection layout. Skips the picker prompt.
--dry-runPreview what would be installed without writing.
--globalInstall into ~/.agentsmesh/ and regenerate user-level outputs.
--forceNon-interactive mode: include all resources, skip prompts (implied by --json).
--accept-hooksTrust hooks.yaml from a non-local source. Stripped by default — hook commands run as shell on tool events.
--accept-permissionsTrust permissions.yaml from a non-local source. Stripped by default — grants allowlist tool capabilities.
--accept-mcpTrust mcp.json from a non-local source. Stripped by default — MCP launch specs spawn child processes.
--accept-elevatedConvenience for --accept-hooks --accept-permissions --accept-mcp together.
--jsonMachine-readable JSON envelope on stdout. Implies --force. Validation errors land in the envelope, not stderr.

Elevated artifacts (hooks, permissions, mcp)

hooks.yaml, permissions.yaml, and mcp.json control your agent’s tool settings at generate time — shell hooks, granted allowlist permissions, and MCP server launch specs. A third-party pack shipping any of these gets local code execution on your machine the next time the matching event fires.

For any non-local source (github:, gitlab:, git+...) AgentsMesh strips these three artifacts by default and warns you. To accept them, re-run with the matching --accept-* flag (or --accept-elevated for all three). Local sources (a directory on disk) are trusted as-is — you already control those bytes.

Your consent is recorded in installs.yaml (accepted_elevated). install --sync and refresh re-apply it automatically, so a post-clone replay keeps the artifacts you accepted without you re-passing the --accept-* flags.

Additional hardening: git transports are allowlisted (https/ssh by default; git+http:// needs AGENTSMESH_ALLOW_INSECURE_GIT=1, git+file:// needs AGENTSMESH_ALLOW_LOCAL_GIT=1, all others refused) and the check runs before any git ls-remote/clone, so the install path cannot be steered to an internal host or arbitrary local repo. Canonical entity traversal (rules, commands, agents, and skill supporting files) does not follow symlinks, and credentials are redacted from all error output. See Fetch hardening for the full list.

When to reach for each flag

Auto-classification handles the common shapes — Anthropic skill pack, canonical agentsmesh, tool-native — without any flag. Reach for these only when the classifier refuses a source, picks the wrong shape, or asks you to disambiguate.

Symptom you seeFlag that resolves itWhy
Repo uses a non-canonical collection dir name (e.g. rules-mdc/ instead of rules/)--path rules-mdc --as rulesFLAT_COLLECTION_DIRS only matches the canonical names; --path narrows the discovery root and --as declares the kind.
Root CLAUDE.md (or other root marker) shadows nested content the auto-detector ignores (e.g. categories/<group>/<agent>.md)--path categories --as agentsNative auto-detect sees the root marker and stops; --path re-roots discovery on the nested tree.
Source is a .claude-plugin/marketplace.json and you want every sub-pack--allBypasses the picker and fans out one install per sub-pack. For a single sub-pack, prefer --path plugins/<name>.
Source is ambiguous between two or more flat collections at root--as <kind> (optionally with --path <subdir>)Picks one kind and skips the picker prompt.
Auto-detection picks the wrong native tool format for an embedded .<tool>/ layout--target <id>Locks the native importer; useful for shared-root markers like AGENTS.md that several targets could own.
Repo has agents/ + commands/ + skills/ at root with no .agentsmesh/ parentSeparate calls, one per kind: --as commands --path commands, then --as agents --path agents, …Multi-collection canonical layouts intentionally require explicit intent today — see Troubleshooting.

Exit codes

CodeMeaning
0Success (or --dry-run preview shown).
1Validation failure (missing source, non-TTY without --force/--dry-run, source not found, lock contention, parse-time failure with no installable resources remaining).
130User aborted at a prompt (bulk select, broken-link, abort sentinel).

Source formats

FormatExample
GitHub shorthandgithub:org/repo@v1.0.0
GitHub (no version)github:org/repo
GitLab shorthandgitlab:group/repo@main
Git SSHgit+ssh://git@github.com/org/repo#main
Git HTTPSgit+https://github.com/org/repo#v2.0.0
Local pathlocal:../shared-config

Examples

Auto-discover and install

Terminal window
agentsmesh install github:org/shared-rules@v2.0.0

AgentsMesh clones the repo, classifies the source, and imports everything into .agentsmesh/.

Install a community skill pack in one command

Terminal window
agentsmesh install github:addyosmani/agent-skills

The classifier sees skills/<kebab>/SKILL.md, agents/, references/, multi-tool rules, and per-target command dirs (.claude/commands/, .gemini/commands/); it imports all skills, agents, root rule, and the merged command set in one shot. Per-entity prompts surface only when the source contains relative links that cross the imported subtree.

Interactive prompts

What you see at the prompt depends on the source’s shape. AgentsMesh detects the shape during discovery and picks the simplest prompt that fits — never asks more than it needs to. Every prompt has a deterministic non-interactive default (see the bypass table below) so --force, --json, --dry-run, and non-TTY runs never block.

1. Single-entity confirm

When discovery turns up exactly one installable entity across all four kinds, you get a one-line yes/no:

Found in source-name:
- 1 skill
Install skill "interview-me"? [y/N]
ResponseEffect
y / YInstall the entity.
n / N / EnterSkip the entity (exit 0, nothing installed).
anything elseAbort the run (exit 130).

2. Multi-entity bulk-select (skill packs)

When the classifier picks anthropic-skill-pack and the count is ≥ 2, you get a three-tier flow. Each tier only fires if the previous one routed there:

Tier 1 — top-level choice across all kinds:

Found in agent-skills:
- 23 skills
- 3 agents
- 7 commands
- 1 root rule
Install [a]ll, [n]one, or [s]elect per type? [a/n/s]
ResponseEffect
aAccept every entity across every kind.
nDecline everything (exit 0, nothing installed).
sDrill into Tier 2 per kind.
anything else / blankAbort (exit 130).

Tier 2 — per-kind, fires once per non-empty kind under s:

Install all 23 skills? [y/n/c]
ResponseEffect
yTake every entity of this kind, continue to the next kind.
nSkip every entity of this kind, continue to the next kind.
cDrill into Tier 3 (cherry-pick by name).
anything elseAbort (exit 130).

Tier 3 — per-entity, fires once per entity inside the kind you entered under c:

Install skill "interview-me"? [y/N/a/q]
ResponseEffect
yInclude this entity.
n / EnterSkip this entity, continue to the next.
aAccept this entity and every remaining entity of this kind.
qSkip this entity and every remaining entity of this kind (move to the next kind’s Tier 2).
anything elseAbort (exit 130).

3. Multiple flat collections

When the source root holds two or more flat collections — e.g. agents/ + commands/ + rules/ side-by-side — AgentsMesh can’t infer a single intent. Pass --as <kind> to pick one kind, or --path <subdir> to scope to one folder. Without those flags, the run errors out with the collection list so you can re-run with the right flag:

Ambiguous source with 3 resource collections. Pass --as <kind> to select, or --path <subpath>:
- agents (agents, .md)
- commands (commands, .md)
- rules (rules, .md)

A single flat collection auto-picks silently — no prompt — and the inferred --as/--target are recorded in installs.yaml.

4. Marketplace fan-out

When the source is a marketplace (.claude-plugin/marketplace.json or a parent dir holding two or more sub-packs), AgentsMesh fans out one install per sub-pack:

  • TTY, no --all — every sub-pack installs silently (no per-sub-pack prompt; each sub-install runs under --force).

  • --force or non-TTY — the run errors out with the sub-pack list so you can choose:

    Marketplace source with 4 sub-packs. Pass --all to install all, or use --path <subpath>:
    - plugins/code-review (skills)
    - plugins/security (skills, rules)
    - plugins/testing (commands)
    - plugins/release (commands, agents)

    Re-run with --all to fan-out, or --path plugins/<one> to install a single sub-pack.

5. Conflict with existing canonical entities

If a pack would add a rule / command / agent / skill whose name already exists in your merged canonical config (the union of .agentsmesh/, prior packs, and any extends:), AgentsMesh asks per collision before writing:

Skill "code-reviewer" already exists in merged config. Add extend anyway? (y/n)
ResponseEffect
y / yesInclude the colliding entity. At generate time, your canonical entry still wins on basename collision — see Merge behavior.
anything elseDrop the colliding entity from this install. The rest of the pack still installs.

Under --force, --dry-run, --json, or non-TTY, every colliding entity is kept (treated as y); merge-time precedence handles the collision.

When a skill or agent body references files outside its own subtree (e.g. ../references/orchestration-patterns.md from a skills/<x>/SKILL.md), AgentsMesh classifies each link and prompts per-entity:

Entity "code-reviewer" (agent) has 2 broken links:
- ../references/orchestration-patterns.md (resolvable-outside)
- ../references/missing.md (unresolvable)
Action: [i]nclude resolvable as supporting files / [l]eave with warnings / [a]bort install
ResponseEffect
iCopy resolvable files into the entity’s supportingFiles, rewrite the body link to ./references/<x>.md. Unresolvables stay as-is with warnings.
lPreserve every link string verbatim and warn at generate time.
aAbort the run (exit 130).

Non-interactive defaults

When --force, --json (implies --force), --dry-run, or non-TTY runs hit a prompt, AgentsMesh applies the documented default below without asking. This makes CI runs deterministic.

Prompt--force / non-TTY defaultNotes
Single-entity confirmaccept (install the entity)Matches Tier 1 a.
Bulk-select Tier 1a (accept all)Same for --json.
Bulk-select Tier 2 / 3not reached (Tier 1 short-circuits to a)
Multiple flat collectionserrors with the collection listRe-run with --as or --path. No silent default.
Marketplace fan-outerrors with the sub-pack listRe-run with --all or --path. --all accepts every sub-pack.
Conflict (already in merged)accept colliding entityMerge-time precedence resolves it.
Broken-linkl (leave with warnings)Preserves the link string; warns at generate.

--dry-run runs the prompts the same way as the bypass column but never writes anything; the planned changes appear in the renderer/JSON output.

Troubleshooting

Every install error surfaces a recovery flag in its own text — you should never need to leave the terminal to find the next step. The mapping below is the same one the CLI prints, written out so you can scan it without re-running the command.

Error you seeWhat it meansRecovery
Ambiguous source with N resource collections. Pass --as <kind> to select, or --path <subpath>:Two or more canonical-named flat collections sit at the source root (e.g. agents/ + commands/ + rules/) with no .agentsmesh/ parent. The picker won’t guess.Run one install per kind: --as <kind> --path <kind>. Combine the kinds you want and re-run as needed.
Marketplace source with N sub-packs. Pass --all to install all, or use --path <subpath>:Source is a .claude-plugin/marketplace.json (or a parent dir with two-plus sub-packs) hit under --force or non-TTY, so the silent TTY fan-out can’t apply.Re-run with --all (fan out every sub-pack) or --path plugins/<name> (install one).
No installable files found under <path> for manual install.--as <kind> was passed but the directory holds no .md / .mdc files matching the kind.Try a different --path to point at the directory holding the markdown files, or drop --as so the classifier can re-evaluate the layout.
No installable native resources found under "<path>" for target "<id>".--target + --path were combined but the resulting subtree carries no native artifacts the target recognizes.Re-run with --path <dir> and without --target to let auto-detect run on the narrowed tree, or use --as <kind> to install the directory as a flat collection.
No installable resources after skipping invalid files (N): ...Every .md under the chosen scope had invalid YAML frontmatter (e.g. unquoted scalars containing colons or [...] flow-sequences). Lenient parsing skipped each one with a per-file reason; nothing remained.Fix the frontmatter at the source (quote the offending strings), or narrow --path to a subdirectory that excludes the bad files.
No installable resources at <cache path>The classifier ran clean but found no rules / commands / agents / skills / SKILL.md / marketplace.json anywhere under the source. Usually means the repo is a README-only “awesome list” or a CLI tool repo, not a content pack.Verify the repo actually carries installable content. If it does live under a non-standard path, point at it with --path <dir>; if it’s a single flat collection, add --as <kind>.

Limitations that no flag recovers

  • Filename collisions after normalization (e.g. docker.md + docker.mdc both normalize to docker.md) — the manual-install scope refuses the write so neither file silently overwrites the other. Resolution requires renaming one file at the source.
  • .claude-plugin/marketplace.json entries that point at external URLs instead of local paths — the parser only resolves local-path plugin sources today. Install each linked repo directly.
  • Repos where every detected entity has invalid YAML — there is intentionally no --skip-validation flag; bad frontmatter is fixed in the source so downstream generate stays predictable.

Install from a subdirectory

Terminal window
agentsmesh install github:org/repo --path skills --as skills

Only installs from the skills/ subdirectory, treating contents as skills.

Cherry-pick with a custom name

Terminal window
agentsmesh install github:org/repo --as agents --name team-agents

Record as an extends entry (linked, not materialized)

Terminal window
agentsmesh install github:org/base-config --extends
agentsmesh install github:org/commands --path workflows --as commands --extends

Instead of copying files, records the source in agentsmesh.yaml’s extends field. Config is resolved at generate time from cache. When you combine --extends with --as, the forced kind is saved as extends[].as, so flat markdown folders keep loading as the intended resource type on every future generate.

Reinstall after a fresh clone

Terminal window
agentsmesh install --sync

Reads .agentsmesh/installs.yaml and reinstalls any packs that are missing from .agentsmesh/packs/. Add this to your project postinstall script.

Install into global mode

Terminal window
agentsmesh install --global github:org/shared-rules
agentsmesh install --global --sync

In global mode, install state lives in ~/.agentsmesh/installs.yaml and packs are materialized in ~/.agentsmesh/packs/.

Preview before committing

Terminal window
agentsmesh install github:org/repo --dry-run

Non-interactive (CI/scripts)

Terminal window
agentsmesh install github:org/repo --force

Includes all resources, skips all prompts.

JSON output

Terminal window
agentsmesh install github:addyosmani/agent-skills --json
{
"success": true,
"command": "install",
"data": {
"source": "github:addyosmani/agent-skills",
"mode": "install",
"installed": [
{ "kind": "skills", "name": "lint", "path": ".agentsmesh/skills/lint/SKILL.md" }
],
"skipped": [],
"dryRun": false,
"brokenResources": [
{
"path": "skills/draft/SKILL.md",
"kind": "frontmatter",
"reason": "Nested mappings are not allowed in compact mappings"
}
]
}
}

Field reference:

  • mode"install" or "sync" (matches the documented contract).
  • installed[]{ kind, name, path } per resource that landed; path is forward-slash relative to scope root.
  • skipped[]{ kind, name, reason } per resource that the user (or --force defaults) chose not to include.
  • brokenResources[] — only present when the install pipeline skipped one or more files whose YAML frontmatter could not be parsed. Each entry carries the source path, the failure category, and the underlying parser message. The renderer also surfaces a footer warning when this is non-empty.

Pack storage

Installed packs are stored in .agentsmesh/packs/{name}/ and tracked in .agentsmesh/installs.yaml:

.agentsmesh/installs.yaml
packs:
- name: shared-rules
source: github:org/shared-rules@v2.0.0
installed: 2026-03-01T10:00:00Z
- name: team-agents
source: github:org/repo
path: agents
as: agents

Per-install integrity manifest

Every install writes .agentsmesh-install-manifest.json next to the pack with the install-time name, source, installed_at, classifier verdict (source_type), and a files map of relative-path → sha256:<hex>. agentsmesh uninstall reuses this manifest to detect locally-modified files and prompts before deleting them. Legacy packs without a manifest auto-migrate at uninstall time (current contents become the baseline) and surface a one-line warning.

Concurrent-install lock

.agentsmesh/.install.lock (mirrored from .generate.lock) is acquired at the top of any install or uninstall run. Concurrent invocations on the same project fail fast with a clear lock-holder error rather than racing on filesystem writes. --sync replay holds the same lock across all recursive installs.

Merge behavior

Installed packs merge with your canonical config during agentsmesh generate. If a pack defines a rule with the same name as your canonical rule, the canonical rule takes precedence.