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, optionalagents/,references/,.claude/commands/,.gemini/commands/, multi-tool rules at root. Oneinstall <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
agentsmesh install <source> [flags]agentsmesh install --syncFlags
| Flag | Description |
|---|---|
<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. |
--extends | Record as an extends entry instead of a materialized pack. |
--sync | Reinstall missing packs from .agentsmesh/installs.yaml. |
--all | Install 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-run | Preview what would be installed without writing. |
--global | Install into ~/.agentsmesh/ and regenerate user-level outputs. |
--force | Non-interactive mode: include all resources, skip prompts (implied by --json). |
--accept-hooks | Trust hooks.yaml from a non-local source. Stripped by default — hook commands run as shell on tool events. |
--accept-permissions | Trust permissions.yaml from a non-local source. Stripped by default — grants allowlist tool capabilities. |
--accept-mcp | Trust mcp.json from a non-local source. Stripped by default — MCP launch specs spawn child processes. |
--accept-elevated | Convenience for --accept-hooks --accept-permissions --accept-mcp together. |
--json | Machine-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 see | Flag that resolves it | Why |
|---|---|---|
Repo uses a non-canonical collection dir name (e.g. rules-mdc/ instead of rules/) | --path rules-mdc --as rules | FLAT_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 agents | Native 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 | --all | Bypasses 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/ parent | Separate 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
| Code | Meaning |
|---|---|
0 | Success (or --dry-run preview shown). |
1 | Validation failure (missing source, non-TTY without --force/--dry-run, source not found, lock contention, parse-time failure with no installable resources remaining). |
130 | User aborted at a prompt (bulk select, broken-link, abort sentinel). |
Source formats
| Format | Example |
|---|---|
| GitHub shorthand | github:org/repo@v1.0.0 |
| GitHub (no version) | github:org/repo |
| GitLab shorthand | gitlab:group/repo@main |
| Git SSH | git+ssh://git@github.com/org/repo#main |
| Git HTTPS | git+https://github.com/org/repo#v2.0.0 |
| Local path | local:../shared-config |
Examples
Auto-discover and install
agentsmesh install github:org/shared-rules@v2.0.0AgentsMesh clones the repo, classifies the source, and imports everything into .agentsmesh/.
Install a community skill pack in one command
agentsmesh install github:addyosmani/agent-skillsThe 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]| Response | Effect |
|---|---|
y / Y | Install the entity. |
n / N / Enter | Skip the entity (exit 0, nothing installed). |
| anything else | Abort 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]| Response | Effect |
|---|---|
a | Accept every entity across every kind. |
n | Decline everything (exit 0, nothing installed). |
s | Drill into Tier 2 per kind. |
| anything else / blank | Abort (exit 130). |
Tier 2 — per-kind, fires once per non-empty kind under s:
Install all 23 skills? [y/n/c]| Response | Effect |
|---|---|
y | Take every entity of this kind, continue to the next kind. |
n | Skip every entity of this kind, continue to the next kind. |
c | Drill into Tier 3 (cherry-pick by name). |
| anything else | Abort (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]| Response | Effect |
|---|---|
y | Include this entity. |
n / Enter | Skip this entity, continue to the next. |
a | Accept this entity and every remaining entity of this kind. |
q | Skip this entity and every remaining entity of this kind (move to the next kind’s Tier 2). |
| anything else | Abort (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). -
--forceor 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
--allto 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)| Response | Effect |
|---|---|
y / yes | Include the colliding entity. At generate time, your canonical entry still wins on basename collision — see Merge behavior. |
| anything else | Drop 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.
6. Broken-link prompt (skill packs)
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| Response | Effect |
|---|---|
i | Copy resolvable files into the entity’s supportingFiles, rewrite the body link to ./references/<x>.md. Unresolvables stay as-is with warnings. |
l | Preserve every link string verbatim and warn at generate time. |
a | Abort 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 default | Notes |
|---|---|---|
| Single-entity confirm | accept (install the entity) | Matches Tier 1 a. |
| Bulk-select Tier 1 | a (accept all) | Same for --json. |
| Bulk-select Tier 2 / 3 | not reached (Tier 1 short-circuits to a) | — |
| Multiple flat collections | errors with the collection list | Re-run with --as or --path. No silent default. |
| Marketplace fan-out | errors with the sub-pack list | Re-run with --all or --path. --all accepts every sub-pack. |
| Conflict (already in merged) | accept colliding entity | Merge-time precedence resolves it. |
| Broken-link | l (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 see | What it means | Recovery |
|---|---|---|
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.mdcboth normalize todocker.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.jsonentries 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-validationflag; bad frontmatter is fixed in the source so downstreamgeneratestays predictable.
Install from a subdirectory
agentsmesh install github:org/repo --path skills --as skillsOnly installs from the skills/ subdirectory, treating contents as skills.
Cherry-pick with a custom name
agentsmesh install github:org/repo --as agents --name team-agentsRecord as an extends entry (linked, not materialized)
agentsmesh install github:org/base-config --extendsagentsmesh install github:org/commands --path workflows --as commands --extendsInstead 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
agentsmesh install --syncReads .agentsmesh/installs.yaml and reinstalls any packs that are missing from .agentsmesh/packs/. Add this to your project postinstall script.
Install into global mode
agentsmesh install --global github:org/shared-rulesagentsmesh install --global --syncIn global mode, install state lives in ~/.agentsmesh/installs.yaml and packs are materialized in ~/.agentsmesh/packs/.
Preview before committing
agentsmesh install github:org/repo --dry-runNon-interactive (CI/scripts)
agentsmesh install github:org/repo --forceIncludes all resources, skips all prompts.
JSON output
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;pathis forward-slash relative to scope root.skipped[]—{ kind, name, reason }per resource that the user (or--forcedefaults) 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:
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: agentsPer-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.