apm install
Synopsis
Section titled “Synopsis”apm install [PACKAGE_REF...] [OPTIONS]Description
Section titled “Description”apm install resolves the dependencies declared in apm.yml, downloads them (with transitive resolution and a content-addressed cache), runs the built-in security scan, and deploys the resulting primitives plus the project’s own .apm/ content into every harness target it detects. It writes apm.lock.yaml so the next install on any machine reproduces the same files.
With no arguments it installs everything from apm.yml. With one or more PACKAGE_REF arguments it adds those packages to apm.yml (creating one if needed) and installs only what was added. apm install --mcp NAME is the dedicated path for adding an MCP server entry.
PACKAGE_REF accepts: shorthand (owner/repo), HTTPS or SSH Git URLs, FQDN shorthand (host/owner/repo), local paths (./path, /abs/path, ~/path), packed bundles (./bundle.zip, ./bundle.tar.gz), and marketplace refs (NAME@MARKETPLACE[#ref]).
Options
Section titled “Options”Common
Section titled “Common”| Flag | Default | Description |
|---|---|---|
--update | off | Re-resolve dependencies to the latest version or Git ref allowed by apm.yml and rewrite apm.lock.yaml. Mutually exclusive with --frozen. Prefer the dedicated apm update command for the consent-gated workflow. |
--frozen | off | Lockfile-only install: refuse to resolve anything new and fail if apm.yml and apm.lock.yaml have drifted. Mirrors npm ci. Mutually exclusive with --update. |
--dry-run | off | Print the install plan without deployment writes. If a positional package bootstraps a project, the new apm.yml and any explicit --target selection are kept for the next run. |
--force | off | Overwrite locally-authored files on collision and bypass the security scan’s critical-finding block. Does not suppress general install errors (any reported error still exits 1, matching npm / pip / cargo). Does not refresh remote refs — use apm update for that. Use only after independent verification. |
--verbose, -v | off | Show per-file paths and full error context in the diagnostic summary. |
--dev | off | Add new packages to devDependencies. Dev deps install locally but are excluded from apm pack output. |
Deploy location
Section titled “Deploy location”| Flag | Default | Description |
|---|---|---|
--root DIR | $PWD | Redirect every write — apm_modules/, apm.lock.yaml, .gitignore, and integrated harness files — under DIR, while apm.yml, .apm/, and local-path dependencies still resolve from the current working directory. Mirrors pip install --target / npm install --prefix. DIR is created if missing (except under --dry-run, which refuses to create it). Not valid with --global (user scope), which exits 2. |
Target selection
Section titled “Target selection”| Flag | Default | Description |
|---|---|---|
--target, -t VALUE | auto-detect | Force deployment targets. Comma-separated for multiple (-t claude,cursor). Values: copilot, claude, cursor, opencode, codex, gemini, antigravity, windsurf, kiro, intellij, vscode, agent-skills, all; experimental copilot-cowork and copilot-app are also accepted when enabled. IntelliJ-specific integration is MCP-only and writes JetBrains Copilot’s user-scope MCP config; package file primitives use the Copilot profile. all excludes agent-skills, antigravity, and intellij; combine them explicitly to add them, for example all,intellij. Explicit MCP target lists are exact: intellij,claude writes only those two client configs. Highest precedence in the chain --target > apm.yml targets: > apm config set target ... > auto-detect. With nothing to detect, install exits 2 with a teaching message. |
--runtime VALUE | unset | Legacy alias for --target (single value only). Still accepted; prefer --target. |
--exclude VALUE | unset | Skip a single runtime that auto-detect or targets: would otherwise enable. |
--only apm|mcp | both | Install only APM packages or only MCP servers. |
-g, --global | off | Install to user scope (~/.apm/) instead of the current project. MCP servers deploy only to global-capable runtimes, such as Copilot CLI, Claude Code, Codex CLI, Gemini CLI, Antigravity CLI, Kiro, Windsurf, and JetBrains Copilot. |
--legacy-skill-paths | off | Deploy skills to per-client paths (.cursor/skills/, .github/skills/, …) instead of the converged .agents/skills/. Env: APM_LEGACY_SKILL_PATHS=1. |
Policy and trust
Section titled “Policy and trust”| Flag | Default | Description |
|---|---|---|
--no-policy | off | Skip org policy enforcement for this invocation. Loudly logged. Does not bypass apm audit --ci. Env: APM_POLICY_DISABLE=1. |
--audit <off|warn|block> | (config/policy) | Run a content audit over the files this install deploys. warn records findings in the summary; block halts the install on critical findings. Overrides your audit-on-install config but cannot relax an org policy floor. Requires the external-scanners experimental flag. |
--no-audit | off | Disable the install-time audit for this invocation (equivalent to --audit off). Cannot relax an org policy block floor. |
--trust-transitive-mcp | off | Trust self-defined MCP servers shipped by transitive packages without re-declaring them in your apm.yml. |
--allow-insecure | off | Permit direct http:// (non-TLS) dependencies. |
--allow-insecure-host HOSTNAME | unset | Permit transitive http:// dependencies from HOSTNAME. Repeatable. |
Cache and network
Section titled “Cache and network”| Flag | Default | Description |
|---|---|---|
--parallel-downloads N | 4 | Max concurrent package downloads. 0 disables parallelism. |
--refresh | off | Bypass the persistent cache and re-fetch every dependency from upstream. |
--ssh | off | Prefer SSH transport for shorthand (owner/repo) deps. Mutually exclusive with --https. |
--https | off | Prefer HTTPS transport for shorthand deps. Mutually exclusive with --ssh. |
--allow-protocol-fallback | off | Restore the legacy permissive HTTPS<->SSH fallback chain. Env: APM_ALLOW_PROTOCOL_FALLBACK=1. |
Transport env vars: APM_GIT_PROTOCOL (ssh or https) sets the default initial transport for shorthand deps; APM_ALLOW_PROTOCOL_FALLBACK=1 mirrors --allow-protocol-fallback.
Skill subset
Section titled “Skill subset”| Flag | Default | Description |
|---|---|---|
--skill NAME | all | Install only named skills from a dependency that exposes selectable skills. Repeatable. For plugin manifests, NAME may be the skill name or manifest path, such as skills/productivity/grill-me. A CLI name that matches no declared skill is an install error; the diagnostic lists the available names. If a previously persisted skills: pin later matches no available source skill, install stays successful but warns with the package, requested names, and available names instead of silently doing nothing. The selection is persisted to apm.yml and apm.lock.yaml only after a successful CLI match. --skill is additive across separate installs: a later apm install <bundle> --skill X adds X to the existing pin (union) rather than replacing it — previously deployed skills are never silently removed. Use --skill '*' to reset to the full bundle; to drop a single skill, edit the skills: list in apm.yml and re-run apm install. |
--as ALIAS | bundle id | Override the log/display label for a local-bundle install. Only valid with a single local-bundle PACKAGE_REF. |
Skill-filter outcomes
Section titled “Skill-filter outcomes”An invalid name passed directly with --skill is an
install error. A previously persisted skills: selection that no longer
matches an available source skill is a warning instead: install succeeds and
lists the package, declared request names, and available names. Edit skills:
in apm.yml, then run apm install again.
MCP server entry (use only with --mcp)
Section titled “MCP server entry (use only with --mcp)”| Flag | Default | Description |
|---|---|---|
--mcp NAME | unset | Add an MCP server entry to apm.yml and install it. Pair with the flags below or pass an executable after --. |
--transport stdio|http|sse|streamable-http | inferred | Inferred from --url or the post--- argv when omitted. |
--url URL | unset | Endpoint for http, sse, or streamable-http transports. Scheme must be http or https. |
--env KEY=VALUE | unset | Environment variable for stdio MCP servers. Repeatable. |
--header KEY=VALUE | unset | HTTP header for remote MCP servers. Repeatable. Requires --url. |
--mcp-version VER | unset | Pin a registry MCP entry to a specific version. |
--registry URL | https://api.mcp.github.com | Custom MCP registry URL for resolving --mcp NAME. Persisted to apm.yml. Overrides MCP_REGISTRY_URL. Not valid with --url or a stdio command. |
Behavior
Section titled “Behavior”- Auto-bootstrap.
apm install <pkg>with noapm.ymlcreates a minimal one. Bareapm installwith noapm.ymlexits with a hint to runapm initorapm install <org/repo>. - Target persistence on bootstrap. When
--targetmaps to recognized manifest targets, those target(s) are persisted to the new manifest’stargets:field so a later bareapm updateredeploys to the same targets without re-specifying--target. - Diff-aware. Packages whose ref or version changed in
apm.ymlare re-downloaded automatically;--updateis only needed to pull a newer ref under a floating constraint. MCP servers with matching config are skipped (already configured); changed config is re-applied (updated). - Lockfile replay. For unchanged Git dependencies, install reuses the locked commit for the whole resolved graph, including transitive packages. Upstream changes to a transitive package’s
apm.ymlare picked up only when you regenerate the graph, for example withapm updateorapm lock --update. See the lockfile specification for the replay contract. - Semver ranges on git deps.
ref:accepts semver ranges (^1.2.0,~1.4,>=2.0 <3,1.5.x) for git-source deps. APM runsgit ls-remoteagainst the dep, picks the highest tag matching the range, and pins the resolved tag plus commit SHA, version, and original constraint inapm.lock.yaml. Subsequent installs replay the lockfile without network; use--update(or change the manifest constraint) to re-resolve. See manage dependencies for the supported syntax. - No-op nudge. When the lockfile is already satisfied and nothing needs deploying, install prints
[i] Run 'apm update' to check for newer versions.so you know the silent success was not a missed refresh. - Frozen mode. With
--frozen, install resolves only what is inapm.lock.yaml. A direct dependency missing from the lockfile, or a missing lockfile entirely, exits1. Orphan lockfile entries (locked but no longer inapm.yml) are tolerated; local-path deps are skipped. This is a structural check, not a content check — runapm audit --cifor hash verification. - Local
.apm/deployment. After dependencies are integrated, primitives in the project’s own.apm/directory are deployed to the same targets. Local files win on collision. Skipped at--globaland with--only mcp. - User-scope root context hint. Compilation stays explicit. After
apm install -g, targets with native user-scope instruction files pick up global instructions during install. Targets whose user-scope instruction surface is a root context file requireapm compile --global; install prints a one-line[i]hint and writes no root context file. - Project-scope root context hint. After
apm install, targets that require post-install instruction compilation print a one-line[i]hint when dependency instructions requireapm compile. The hint names only the root context files that compile will update. - Stale-file cleanup. Files a still-present package previously deployed but no longer produces are removed from the workspace, gated by per-file content hashes recorded in the lockfile (user-edited files are kept with a warning).
- Enterprise marketplace gate. When installing from a
*.ghe.commarketplace, bare cross-reporepo:fields (e.g.repo: owner/repo) are refused before any network request runs, preventing dependency-confusion attacks. Host-qualify the field to proceed:repo: corp.ghe.com/owner/repofor an enterprise dep, orrepo: github.com/owner/repofor a declared cross-host dep. - Security scan. Source files are scanned for hidden Unicode and other tag-character / bidi-override patterns before deployment. Critical findings block the package; the install exits
1. Use--forceto deploy anyway, or runapm audit --stripfirst to remediate. - Diagnostic summary. Output is grouped at the end (collisions, replacements, warnings, errors) instead of inline. Use
--verboseto expand individual file paths. - Declared plugin components. Every path explicitly listed under a recognized plugin manifest’s
agents,skills,commands, orhooksfield must resolve inside that plugin root. A missing or escaping path fails before deployment and lockfile commit; remove the declaration or add the component, then reinstall. Omitted fields and empty lists remain valid. - Default registry routing. When a default registry is configured (project
registries.defaultinapm.ymlorregistry.<name>.default truein~/.apm/config.json), unscopedowner/repo#refshorthand deps passed toapm installroute to the registry instead of GitHub. A#<version>selector is required; omitting it exits1. The selector may be a semver range (^1.0.0), an exact version (1.2.3), or a non-semver label (main,stable,v1.4.2) — the registry exact-matches non-semver selectors against its published version list. GitHub probe is skipped for these deps; use thegit:URL form inapm.ymlto force the GitHub path (e.g.,- git: https://github.com/owner/repo.git).
Examples
Section titled “Examples”Install everything from apm.yml
Section titled “Install everything from apm.yml”apm installInstall (and add) a specific package
Section titled “Install (and add) a specific package”apm install microsoft/apm-sample-packageapm install https://gitlab.com/acme/coding-standards.gitapm install code-review@acme-plugins#v2.0.0Install only an MCP server
Section titled “Install only an MCP server”# Stdio server via post-`--` argvapm install --mcp filesystem -- npx -y @modelcontextprotocol/server-filesystem /workspace
# Registry entryapm install --mcp io.github.github/github-mcp-server
# Remote HTTP serverapm install --mcp my-api --url https://mcp.example.com --header "Authorization=Bearer ${API_TOKEN}"Pick targets explicitly
Section titled “Pick targets explicitly”apm install --target claude,cursorapm install --target all,agent-skillsapm install --exclude codexInstall in CI (no interactive prompts, no policy escape)
Section titled “Install in CI (no interactive prompts, no policy escape)”# Fail fast on any drift; never bypass policy in CI.apm install --parallel-downloads 8For a CI workflow that also gates on apm audit --ci, see Enforce in CI.
Preview without writing
Section titled “Preview without writing”apm install --dry-runapm install microsoft/apm-sample-package --dry-runRedirect writes to a scratch directory
Section titled “Redirect writes to a scratch directory”# Resolve apm.yml + local deps from this directory, but write# apm_modules/, apm.lock.yaml, and harness files under /tmp/apm-out.apm install --root /tmp/apm-out --target copilot
# The source tree stays clean; the deploy root holds every artifact.ls /tmp/apm-out # apm_modules/ apm.lock.yaml .github/ .gitignoreInstall a local bundle produced by apm pack
Section titled “Install a local bundle produced by apm pack”apm install ./build/my-bundleapm install ./my-bundle.zip --as custom-nameapm install ./my-bundle --target opencodeInstall only a subset of skills from a bundle
Section titled “Install only a subset of skills from a bundle”apm install owner/skill-bundle --skill reviewapm install owner/skill-bundle --skill refactor # adds refactor; review is kept (union)apm install owner/skill-bundle --skill '*' # reset to all skillsExit codes
Section titled “Exit codes”| Code | Meaning |
|---|---|
0 | Success. All requested dependencies and local content deployed. |
1 | Install failure: security scan blocked a critical finding, auth error, manifest write error, dependency resolution error, --frozen with a missing lockfile or a direct dependency absent from apm.lock.yaml, any reported install error (the diagnostic summary closes with Installation failed with N error(s)), or unhandled exception. --force does not suppress general install errors. The diagnostic summary names the cause. |
2 | Usage error: no deployment target detectable (no --target, no target(s): in apm.yml, no default target configured via apm config set target <value>, and no harness signal in the project), --ssh and --https both passed, --frozen and --update both passed, --root combined with --global, or a Click flag conflict. |
--forceis dual-purpose. It overwrites locally-authored files on collision and disables the critical-finding block from the built-in security scan. It does not suppress general install errors — any error reported in the diagnostic summary still exits1(matchesnpm/pip/cargo). It does not refresh remote refs — for routine ref updates, runapm update. To remediate findings, preferapm audit --strip. See Drift and secure by default.- Target contraction is reconciled. A narrowed
targets:inapm.ymlis reconciled on the next non-dry-run install: deployed files, lockfile ownership, and merge-hook config/sidecar entries for the dropped target are cleaned up, even when no dependency itself changed. See Hooks and commands for what the merge-hook config/sidecar files are.apm lockonly refreshes the lockfile and does not trigger this reconciliation. - Claude target prompt rewrite. When deploying to
.claude/commands/, prompt files with aninput:front-matter key are rewritten to Claude’sarguments:shape and${input:name}placeholders become$name. Argument names must match^[A-Za-z][\w-]{0,63}$; rejected names are dropped with a warning. - MCP env-var passthrough. Copilot CLI and Kiro translate
${env:VAR}and<VAR>to${VAR}in their MCP configs. Kiro writes.kiro/settings/mcp.jsonand~/.kiro/settings/mcp.jsonwith0o600permissions. JetBrains Copilot preserves env references as${env:VAR}ingithub-copilot/intellij/mcp.json. Plaintext secrets are never written to disk for these runtime-resolved targets; legacy targets resolve placeholders at install time.
Install from a private registry (experimental)
Section titled “Install from a private registry (experimental)”Enable the feature, configure the registry (in apm.yml and/or ~/.apm/config.json), and run install normally. APM resolves registry-sourced deps alongside git deps:
apm experimental enable registries
# Option A: apm.yml has a registries: block and registry-routed depsapm install
# Option B: workstation config only (no registries: block in apm.yml)apm config set registry.corp-main.url https://artifactory.corp.example.com/apmapm config set registry.corp-main.token eyJ...apm config set registry.corp-main.default trueapm install
# In CI: use env var for the token, never commit itAPM_REGISTRY_TOKEN_CORP_MAIN=eyJ... apm install --frozenSee Registries for the full setup guide.
Related
Section titled “Related”apm update— refresh dependencies inapm.ymlto their latest matching versions or refs, with a consent gate.apm self-update— upgrade theapmCLI binary itself.apm prune— remove orphaned packages and stale files.- Registries — end-to-end guide for registry-sourced dependencies.
apm audit— explicit security reporting and remediation after install.apm targets— print which harnesses APM detects in the current directory.- Install packages (consumer guide) — task-oriented walkthrough.
- Manifest schema — field reference for
apm.yml. - Lockfile spec — field reference for
apm.lock.yaml.