Skip to content
Back to skills

Install

ASecurity

Use when the user wants to make a tool, CLI, binary, package, GUI app, Claude Code plugin, or MCP server persistently available — in the dotfiles (user/global), the current project, or ephemerally. Triggers: install, add, set up, wire up, configure, pin a version of, make available. Routes by scope: user → chezmoi dotfiles; project → current repo. Prefers mise for dev tools.

  • 9 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 6, 2026
toolsgobashnodegitapibackend

Works with

  • claude code
  • cli
  • api
  • mcp

Security analysis

A100/100

Scanned October 6, 2026

npx -y skills add ivy/dotfiles --skill install --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Install?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Install
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/ivy-install/badge)](https://www.skillsdirectory.com/skills/ivy-install)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: install
description: "Use when the user wants to make a tool, CLI, binary, package, GUI app, Claude Code plugin, or MCP server persistently available — in the dotfiles (user/global), the current project, or ephemerally. Triggers: install, add, set up, wire up, configure, pin a version of, make available. Routes by scope: user → chezmoi dotfiles; project → current repo. Prefers mise for dev tools."
argument-hint: "<tool[@version]> | <plugin@marketplace> | <url> | <mcp-name> [--scope user|project|local]"
allowed-tools:
  - AskUserQuestion
  - Read
  - Glob
  - Grep
  - Bash(pwd:*)
  - Bash(realpath:*)
  - Bash(git rev-parse:*)
  - Bash(chezmoi source-path:*)
  - Bash(chezmoi diff:*)
  - Bash(chezmoi data:*)
  - Bash(mise search:*)
  - Bash(mise registry:*)
  - Bash(mise ls-remote:*)
  - Bash(mise ls:*)
  - Bash(mise use --dry-run:*)
  - Bash(mise which:*)
  - Bash(which:*)
  - Bash(command -v:*)
  - Bash(gh release view:*)
  - Bash(npm view:*)
  - Bash(pip index:*)
  - Bash(claude plugin marketplace list:*)
  - Bash(claude plugin list:*)
  - Bash(claude mcp list:*)
  - Bash(claude mcp get:*)
  - Bash(mise use:*)
  - Bash(claude plugin install:*)
  - Bash(claude plugin marketplace add:*)
  - Bash(claude mcp add:*)
  - Bash(chezmoi apply:*)
  - Bash(chezmoi status:*)
  - Edit(home/dot_config/mise/config.toml)
  - Edit(home/.chezmoidata/packages.yaml)
  - Edit(home/.chezmoidata/claude-extensions.yaml)
  - Skill(commit)
---

# Install

**Autonomy:** model-invocable · acts autonomously — manifest edits, installs, and `chezmoi apply` are local and reversible · delegates the commit to `/commit`

One door for adding anything to this environment. Figure out **what** is being
installed and at **which scope**, then route to the right source of truth.

## Arguments

```
$ARGUMENTS
```

## Scope is the source of truth

Scope decides *which repo and file* the change lands in — not just a flag.

| Scope | Source of truth | How it is realized | Reproducible via |
|-------|-----------------|--------------------|------------------|
| **user** (default for general-purpose tools) | the **dotfiles repo** (`chezmoi source-path`), editable from any cwd | edit source manifest → `chezmoi apply` | dotfiles |
| **project** | the **current repo** (`.mise.toml`, `.mcp.json`, `.claude/settings.json`) | run the tool's CLI in-place | the project repo |
| **local** | machine + project local | `--scope local` / untracked | nothing (ephemeral) |

### The reach-in invariant (do not violate)

For **user** scope, **edit the chezmoi source and `chezmoi apply`** — never run a
tool's native `--global` / `--scope user` command from a foreign cwd. Those write
the *live* file out-of-band from chezmoi, which chezmoi then fights on the next
apply. Reaching in means: resolve `chezmoi source-path`, edit the source manifest
there, then apply. This works from anywhere — you do not need to `cd` into dotfiles.

## Step 1 — Classify type and scope

**Type** (check in order):

1. **Claude Code plugin** — argument looks like `name@marketplace`, or the user says
   "plugin". → *Plugins* below.
2. **MCP server** — the user says "MCP server" / "MCP", or gives a server URL or a
   stdio command to wire up. → *MCP servers* below.
3. **Tool / CLI** — a binary/dev tool. → *Tools* below (mise).
4. **GUI app / system utility** — → *Homebrew* below.

**Scope:**

- Explicit `--scope user|project|local`, or `--global`/`-g` → user. Honor it.
- Otherwise infer: inside a non-dotfiles project repo with (or wanting) a local
  manifest → **project**; everything else → **user**.
- When ambiguous and it matters, ask with `AskUserQuestion`.
- **If cwd *is* the dotfiles repo,** `chezmoi source-path` returns it — editing there
  is still correct, and you still run a full `chezmoi apply` afterward (the apply
  installs the tool; the file edit alone does not).

Resolve the dotfiles source once when acting at user scope:

```bash
src="$(chezmoi source-path)"   # e.g. ~/.local/share/chezmoi/home
```

## Step 2 — Route

### Tools (mise — preferred for all dev tools)

1. Identify & discover: `mise search <tool>`, `mise registry <tool>`,
   `mise ls-remote <tool>` for versions. Pin an exact version (no `latest`).
2. **user scope** → edit `${src}/dot_config/mise/config.toml` under `[tools]`
   (correct backend prefix, exact version, existing comment grouping), then:
   ```bash
   chezmoi apply        # NO target arg — a targeted apply skips
                        # run_onchange_00-install-mise-tools and the tool won't install
   ```
3. **project scope** → in the cwd repo: `mise use <tool>@<version>` (creates/updates
   `.mise.toml`); `mise use --pin` for an exact pin.
4. Verify: `mise which <tool>` and `<tool> --version`.

If `mise search` and `mise registry` find nothing:
1. Try the universal backends — `mise use ubi:<owner>/<repo>` or `aqua:<owner>/<repo>`.
2. Else, if it's a GUI app or a system utility, route to Homebrew (below).
3. Else ask with `AskUserQuestion` before acting.

Never silently fall back to `brew`/`apt`/`npm`/`pipx` — the guard hook blocks those;
tell the user what was tried and the options.

### Homebrew (GUI apps, non-versioned system utilities) — user scope

Edit `${src}/.chezmoidata/packages.yaml` (`packages.darwin.casks` for GUI apps,
`packages.darwin.brews` for CLIs mise can't provide), alphabetical, then
`chezmoi apply`.

### Claude Code plugins

First ensure the marketplace is known (`claude plugin marketplace list --json`).

- **user scope** → edit `${src}/.chezmoidata/claude-extensions.yaml`: add the
  marketplace under `marketplaces` (if not built-in) and the plugin to `plugins`
  as `name@marketplace`. **Public OSS only** in the committed file — anything
  employer-internal/private goes in machine-local `[data.claudeExtensionsExtra]`
  in `~/.config/chezmoi/chezmoi.toml`. Then `chezmoi apply` (the
  `sync-claude-extensions` reconciler installs it).
- **project scope** → in the cwd repo:
  ```bash
  claude plugin marketplace add <owner/repo> --scope project   # if not already known
  claude plugin install <name>@<marketplace> --scope project   # writes .claude/settings.json
  ```

### MCP servers

**Secret check first** (before composing any command): if `$ARGUMENTS` or the
conversation contains a literal token, key, or password, do NOT put it in a command
or a committed file. Tell the user it will be referenced via 1Password or kept in
machine-local `[data.claudeExtensionsExtra]`, then take the safe path below.

The forms, so you never have to re-derive them:

```bash
# HTTP (most remote servers):
claude mcp add --scope <scope> --transport http <name> <url>
# HTTP with an auth header:
claude mcp add --scope <scope> --transport http <name> <url> --header "Authorization: Bearer <token>"
# stdio (local subprocess):
claude mcp add --scope <scope> [--env KEY=val ...] <name> -- <command> [args...]
```

- **user scope** → add an entry to `mcpServers` in
  `${src}/.chezmoidata/claude-extensions.yaml` (shape:
  `{name, transport: http|sse|stdio, url|command, args?, env?, headers?}`), then
  `chezmoi apply`. **Never commit secrets** — for a bearer token/API key, keep the
  whole entry in machine-local `[data.claudeExtensionsExtra]`, or reference 1Password.
- **project scope** → `claude mcp add --scope project ...`, which writes `.mcp.json`
  in the cwd repo (committed, shared with the team). The `.mcp.json` shape:
  ```json
  { "mcpServers": { "<name>": { "type": "http", "url": "https://..." } } }
  ```
- **local scope** → `claude mcp add --scope local ...` (this repo, not shared).

Verify with `claude mcp get <name>` / `claude mcp list`.

## Step 3 — Verify & hand off

- Show `chezmoi diff` (user scope) — only the intended manifest should change.
- For tools/plugins at user scope, run a **full** `chezmoi apply`. If it is
  interrupted, run it again before declaring success — a half-done apply leaves the
  live files behind the source you just edited.
- Verify the result (`mise which <tool>`, `claude plugin list`, `claude mcp get`).
- Commit with `/commit` (one logical change). For a user-scope change made from a
  foreign cwd, the edit landed in the dotfiles repo — `chezmoi cd` first (or commit
  from the dotfiles root), since `/commit` acts on the current repo.

## Examples

```
/install ripgrep                      → mise tool, user scope → dotfiles config.toml
/install node@22 --scope project      → mise tool in this repo's .mise.toml
/install ci-cd-tools@pickled-claude-plugins
                                      → plugin, user scope → claude-extensions.yaml
/install linear@claude-plugins-official --scope project
                                      → plugin in this repo's .claude/settings.json
/install --scope project an MCP server for the sentry API at https://mcp.sentry.dev/mcp
                                      → claude mcp add -s project -t http sentry https://mcp.sentry.dev/mcp → .mcp.json
/install --global jq                  → reach-in: edit $(chezmoi source-path)/dot_config/mise/config.toml → full chezmoi apply (works from any cwd)
/install an MCP server with token sk-abc123
                                      → secret detected → do NOT commit; use 1Password / machine-local extras
```

## Reference

- Tools/packages & backends: `docs/package-management.md`, and `/mise` for deep
  mise context (backends, lockfiles, github-first policy).
- Plugins, MCP servers, scope routing, the reconciler, and the guard hook:
  `docs/claude-code.md` and `docs/adrs/006-declarative-claude-code-extensions.md`.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…