Skills Field Notes

Claude Code skills: 3 ways to install

One command installs 15 Claude Code skills in 9.4 seconds. The twelve failures I hit, in order.

Tested 2026-10-19 Windows 11, Node 24.15.0, skills 1.7.2, Claude Code 2.1.278 Every error text below is copy-pasted from a real run

Scope: what I ran, and what I did not

Everything on this page was run on one Windows 11 machine on 2026-10-19, inside a scratch directory that was not a git repository. Nothing is reconstructed from memory. Three things are explicitly not first-hand:

  • The /skills menu inside a live session. A headless session on this machine dies before it starts: see failure 12.
  • The “skill is installed but a new session does not see it” symptom. Same reason. The reload behaviour below comes from the official docs, not from my terminal.
  • Two Windows-only failures reported in GitHub issues, marked as such near the end. I did not reproduce them here.

And the first install did fail, so the rest of this page is not a happy path with a footnote. My git http.proxy pointed at 127.0.0.1:7890, where nothing was listening. Failure 1 is that exact run. Once git pointed at the live listener, the same command went through.

Three ways in. Pick one.

The installer (npx skills add, npm package skills, repo vercel-labs/skills) is the only one that also feeds other agents. The other two exist because it needs git and npm to work, and half the support threads in this space are people whose git cannot reach GitHub.

Way in Command Lands in What I saw
Cross-agent installer npx skills add owner/repo project .claude/skills/name/ exit 0, 9.4 s, 15 skills
By hand copy SKILL.md into place project or user ~/.claude/skills/ paths verified on disk
Plugin marketplace claude plugin install name@market ~/.claude/plugins/cache/... exit 0, 13.6 s + 1.5 s

Method 1: npx skills add (9.4 s, 15 skills)

The package is skills, version 1.7.2 on 2026-10-19, and it ships two bin names, skills and add-skill. It knows 80 agent names — I counted them out of its own error message in failure 7 — including claude-code, cursor, codex, windsurf and gemini-cli.

  1. Check the proxy before you check the installer. git config --global --get http.proxy. If it prints a local port, confirm something is listening on it. This one step prevents failure 1, the single most common reason an install appears blocked.
  2. Preview the repo. npx -y skills add obra/superpowers --list prints each skill name and description and stops. On my machine: exit 0, 22.8 s, and a closing hint to install a subset with --skill. It is slower than the install itself, because it still clones the repo.
  3. Install with every prompt answered. npx -y skills add obra/superpowers -y --agent claude-code. Without -y and --agent it refuses outside a terminal: failure 4.
  4. Read the directory, not the summary. The run ends with Done! and a line reminding you that skills execute with the agent's full permissions. It also writes skills-lock.json, which records each skill's skillPath and the sha256 of its SKILL.md.
install · exit 0 · 9.4 s
o  Source: https://github.com/obra/superpowers.git
o  Repository cloned
o  Found 15 skills
•  Installing all 15 skills
o  Installed 15 skills ---------------------------------+
     brainstorming (copied)
       -> .\.claude\skills\brainstorming
     ... fourteen more, same shape
—  Done!  Review skills before use; they run with full agent permissions.

Per-skill receipt lines trimmed; everything else is verbatim. Four runs on this machine took 8.6 s, 9.4 s, 9.6 s and 10.0 s; a separate run on the same machine the same day took 12.4 s. The 15 skills weigh 426.1 KB.

It does not need a git repo to install into a project: my directory had a package.json and no .git, and skills list still reports scope: project. Add -g for user-level, --agent '*' for every detected agent, --copy to physically copy files instead of linking them.

What fifteen skills actually look like on disk

Fifteen real directories, not symlinks, 426.1 KB total. Individual SKILL.md files run from 2.9 KB to 32.6 KB. Some bundle scripts: brainstorming ships scripts/server.cjs, start-server.sh and an HTML template. That is the part the one-line summary hides — Done! Review skills before use is the CLI telling you it just put executable code on your disk.

Method 2: put the folder in the right place

Your agent does not install skills through a registry; it reads directories. These are the paths from the official docs, and I confirmed the first two on disk.

Level Path Loads for
Project project/.claude/skills/name/SKILL.md sessions started in that repo
User ~/.claude/skills/name/SKILL.md every project on this machine
Subdirectory subdir/.claude/skills/name/SKILL.md sessions started inside that subdirectory
Plugin plugin/skills/name/SKILL.md invoked as /plugin-name:skill-name
Enterprise .claude/skills/name/SKILL.md in the managed settings directory every machine the org deploys to

On this machine, ~/.claude/skills/ holds about fifteen directories such as cloudflare, wrangler and web-perf, each a folder with one SKILL.md. There is also a separate ~/.agents/skills/: that is the installer's own convention directory, not the one Claude Code reads by default. Copying into the wrong one is a silent no-op.

Same-name precedence, per the docs: enterprise beats user, user beats project. Two names are reserved and will not load: synced (case-insensitive) and anything under the anthropic-skills namespace. On Windows the “name contains <” rule is unreachable, because < is not a legal filename character.

The advantage of manual install: no lock file, no settings entry, deleting the directory is the uninstall. The cost: you own the version.

Method 3: the plugin marketplace

Documented as two slash commands inside a session, /plugin marketplace add anthropics/claude-plugins-official then /plugin install skill-creator@claude-plugins-official. The same two steps exist as CLI verbs, which is what I ran:

claude plugin marketplace add anthropics/claude-plugins-official --scope project
claude plugin install skill-creator@claude-plugins-official --scope project -y
marketplace + plugin · 13.6 s + 1.5 s
[ok] Successfully added marketplace: claude-plugins-official (declared in project settings)
[ok] Successfully installed plugin: skill-creator@claude-plugins-official (scope: project)

Installed plugins:
  > skill-creator@claude-plugins-official
    Version: ea10b213686c
    Scope: project
    Status: [ok] enabled

Marketplace add took 13.6 s, the plugin install 1.5 s. The CLI prints those three lines with a square-root glyph; the substitution note at the head of the failure list covers why they read [ok] here.

The files do not land in your project. The project .claude/settings.json gets two entries, enabledPlugins and extraKnownMarketplaces, and the skill itself lives at ~/.claude/plugins/cache/claude-plugins-official/skill-creator/ea10b213686c/skills/skill-creator/SKILL.md. So “the plugin is installed and my project has no skill files” is correct behaviour, not a bug. Plugin skills also keep their namespaced name, which is why they never fight a project skill for the short name.

Verify the skill is actually installed

Four checks, cheapest first. The first three are things I ran; the fourth is documented, not reproduced.

  1. The installer's own ledger. npx -y skills list --json. Fields: name, path, scope, agents, source. This proves the installer believes it installed something. It does not prove the file is readable.
  2. The disk. .claude/skills/name/SKILL.md exists, is a real directory, and is not a broken link. This is where a “listed but not loadable” install surfaces.
  3. Claude Code's own validator. claude plugin validate .claude/skills printed Validation passed with exit 0 for my fifteen skills. Read failure 11 before you trust it.
  4. Inside a session. /skills lists what loaded, grouped by source. No restart is normally needed: the docs say the skills directories are watched and changes apply live. If the top-level skills directory did not exist when the session started, run /reload-skills once. Plugin skills need /reload-plugins.

Avoid skills list -g as a smoke test. On this machine it took 77.8 s (exit 0) with roughly a hundred global skill directories present. Issue #1389 reports 20–25 s on a similarly crowded Windows box, so the order of magnitude is not mine alone.

Twelve failures, in the order you hit them

One substitution, stated up front

The CLI paints some lines with a check mark, a square-root sign or a cross glyph, and this site's style rules reject all three. Where you see [ok] or a bare x in the blocks below, the real output had one of those glyphs. Every other character — words, paths, punctuation, exit codes, timings — is copied as printed.

1. Clone dies with “via 127.0.0.1”

Symptom. Cloning spins, then fails in about five seconds (exit 1, 5.0 s on the first run):

exit 1 · 5.0 s
x  Failed to clone repository
|  Failed to clone https://github.com/obra/superpowers.git: Cloning into 'C:\Users\...\Temp\skills-0cSW6M'...
|  fatal: unable to access 'https://github.com/obra/superpowers.git/':
|  Failed to connect to github.com port 443 via 127.0.0.1 after 2055 ms: Could not connect to server
—  Installation failed

Root cause. git config --global http.proxy pointed at http://127.0.0.1:7890. Nothing was listening on 7890 — the proxy client on this machine listens on 7897. The phrase via 127.0.0.1 is the tell: the request never left the box, so no amount of retrying or VPN switching will help.

Fix. git config --global --unset http.proxy, or point it at the port that is actually open. Verify with git ls-remote https://github.com/obra/superpowers.git before rerunning the installer. If you only want this for one command, inject it for the child process instead of editing the global config.

2. Direct connection: “Recv failure: Connection was reset”

Symptom. A different error with the same shape. With no proxy in the way the clone ends in Recv failure: Connection was reset after roughly 23 seconds (measured on the same machine in a separate run, 23.2 s; the line x Failed to clone repository and the closing Installation failed are identical).

Root cause. The TCP connection to GitHub is being reset in transit. This is a network-path problem, not an installer defect and not a bad repo name.

Fix. Use a proxy that actually works, or a mirror. Do not reinstall in a loop and do not start dissecting the npm package: the command never reached the repository. The distinction matters, because failure 1 is a config you can fix in one line and this one is the network you happen to be on.

3. The installer can exit 0 and install nothing

Symptom. This is the one worth remembering. Make .claude a regular file instead of a directory — one stray redirect is enough — and the installer fails every single skill, then reports success anyway. Exit code: 0, after 9.2 s.

exit 0 · 9.2 s · nothing installed
x  Failed to install 15
|    x brainstorming -> Claude Code: ENOTDIR: not a directory, mkdir '...\err-path2\.claude'
|    x diagnosing-superpowers -> Claude Code: ENOTDIR: not a directory, mkdir '...\.claude'
     ... thirteen more, identical
—  Done!  Review skills before use; they run with full agent permissions.

Root cause. Per-skill failures are collected into a summary, but the process still ends on the success path. No skills-lock.json was written, and the directory contained nothing but my placeholder file. The summary line Failed to install 15 is the only trace.

Fix. Never gate CI on this exit code. Assert the artefact: skills list --json plus a check that .claude/skills/name/SKILL.md exists. If you see ENOTDIR, confirm .claude is a directory.

4. Outside a terminal it refuses to install

Symptom. In a script, a CI job, or any wrapper without a TTY, the clone succeeds and then it gives up (exit 1, 8.6 s):

exit 1 · 8.6 s
■  Select skills to install
|  Cancelled
—  Installation cancelled
Interactive prompt required but stdin is not a TTY. Nothing was installed.
Use --agent <name> (or --agent '*') and -y to run non-interactively.

Root cause. The default flow asks which agent and which skills. With no TTY it cannot draw the picker, and it chooses to install nothing rather than guess.

Fix. Pass -y --agent claude-code, plus --skill a b or --all. This is the only form that belongs in a Dockerfile or a CI step.

5. A wrong repo name reports “Authentication failed”

Symptom. Typo the repo and you do not get a 404 (exit 1, 11.7 s):

exit 1 · 11.7 s
Authentication failed for https://github.com/obra/superpowers-does-not-exist.git.
  - For private repos, ensure you have access
  - Retry with SSH: npx skills add git@github.com:obra/superpowers-does-not-exist.git
  - Check access with: gh auth status -h github.com or ssh -T git@github.com

Root cause. Over HTTPS, “private repo” and “repo does not exist” are the same 401. The CLI folds both into one message and then offers credential advice.

Fix. Open the repo URL in a browser first. Do not spend time on SSH keys for a name you misspelled. Both halves matter: owner/repo, not just the repo.

6. A bare name is treated as a git path

Symptom. skills add superpowers (exit 1, 2.7 s):

exit 1 · 2.7 s
o  Source: superpowers
x  Failed to clone superpowers: fatal: repository 'superpowers' does not exist

Root cause. That argument accepts a package id or a URL; a single word is handed straight to git. Interactively it would have offered you a picker, but non-interactively there is no fallback.

Fix. Write owner/repo or paste the GitHub URL. To search by keyword use npx skills find some-keyword.

7. Wrong agent name: it knows 80, not yours

Symptom. --agent foo-agent fails after the clone (exit 1, 8.6 s) and prints the whole valid list. It is exactly 80 names:

exit 1 · 8.6 s
x  Invalid agents: foo-agent
•  Valid agents: aider-desk, amp, antigravity, ..., claude-code, openclaw, cline,
   ..., codex, ..., cursor, ..., gemini-cli, github-copilot, ..., trae,
   ..., windsurf, zed, ... (80 total)

Root cause. A whitelist, matched literally. The display name “Claude Code” is not accepted; the id claude-code is.

Fix. Use claude-code, or --agent '*' to hit every agent it detects. Re-check with skills ls -a claude-code.

8. Wrong skill name gives you a list, not a diagnosis

Symptom. --skill no-such-skill exits 1 after 8.3 s and prints Available skills: followed by the list. It does not say which name was wrong or which one you probably meant.

Root cause. Name filtering runs after discovery, and the failure path is a generic “unknown selection”.

Fix. Run --list first and copy the name exactly. Skill names are directory names, so case and hyphens matter.

9. skills update finishes the work, then crashes on exit

Symptom. The update succeeds and the process still exits non-zero (10.3 s):

exit -1073740791 · 10.3 s
Checking for skill updates...
Updating for: Claude Code
Checking 15 skill(s)...
[ok] All project skills are up to date
Assertion failed: !(handle->flags & UV_HANDLE_CLOSING), file src\win\async.c, line 76

Root cause. Issue #2461: the CLI fires a telemetry request before exiting, then calls process.exit() before the socket teardown finishes. On Windows that trips a libuv assertion. Exit code -1073740791 (0xC0000409). The issue reports async.c: line 94 on Node 24.19.0; this machine runs Node 24.15.0 and reports line 76. Same mechanism, different line number. The command worked — only the exit status is corrupted.

Fix. Read the output, not the status. In a pipeline, keep skills update out of the gate, or pin a version without the bug. Note that skills add and skills list exited 0 cleanly in every run I did; only update reproduced this.

10. Wrong marketplace or plugin name in the plugin path

Symptom. Two different mistakes, two different amounts of help (both exit 1):

exit 1 · both cases
Failed to install plugin "skill-creator@no-such-marketplace":
  Plugin "skill-creator" not found in marketplace "no-such-marketplace".
  Your local copy may be out of date - try `claude plugin marketplace update no-such-marketplace`.

Failed to install plugin "no-such-plugin@claude-plugins-official":
  Plugin "no-such-plugin" not found in marketplace "claude-plugins-official"

Root cause. “Marketplace missing” and “plugin missing inside a marketplace” collapse into one message, and the suggested fix only applies to the second.

Fix. claude plugin marketplace list first — mine started as No marketplaces configured. Add the marketplace, then check the plugin name. Only run marketplace update when the marketplace exists and its catalogue is stale.

11. validate passes on a broken SKILL.md

Symptom. I wrote a deliberately broken frontmatter (description: [unclosed) and claude plugin validate .claude/skills still printed Validation passed with exit 0. With the whole frontmatter block removed it printed one warning and still exited 0:

exit 0 · broken frontmatter
frontmatter: No frontmatter block found. Add YAML frontmatter between ---
delimiters at the top of the file to set description and other metadata.

Root cause. Per the docs, when the YAML between the delimiters fails to parse the skill body still loads with empty metadata. /name keeps working, but Claude has no description to match on, so automatic invocation silently never fires. The validator checks structure, not meaning.

Fix. Start a session with claude --debug to see the parse error. Write description in the words a user would actually type, front-load the keywords (each entry's combined text is capped at 1536 characters), and add disable-model-invocation: true if you want manual-only.

12. A headless session dies before it can list anything

Symptom. claude -p "reply with one word: ok" exits 1 in 3.0 s with a model error, not a skill error:

exit 1 · 3.0 s
[claude-code:unrecognized_model] {"model":"deepseek-v4-pro[1m]","query_source":"sdk"}
There's an issue with the selected model. It may not exist or you may not have
access to it. Run --model to pick a different model.

Root cause. This machine's Claude Code is configured with a model id the CLI cannot resolve in headless mode. It is an environment problem, unrelated to skills.

Fix. Point the session at a valid model. This is also the honest reason the /skills menu is described from docs on this page rather than screenshotted from my terminal.

Failures from issues I could not reproduce

Marked as second-hand on purpose. Both are Windows-specific and both deserve a line here, but neither happened to me.

No git on the machine. from issue npx skills add fails with Failed to clone ...: Error: spawn git ENOENT. Per issue #1010, only three owners (vercel, vercel-labs, heygen-com) take a git-free download path; every other repo needs git installed. Fix: install Git for Windows, or use one of those owners.

Node installed under a path with spaces. from issue Issues #1457 and #941 report skills update printing Failed to update ... for every skill when Node lives in C:\Program Files\nodejs, because the update path spawns a child process through a shell without quoting the executable. My Node is at E:\Program Files\nodejs — also a space — and 1.7.2 did not reproduce it: I hit failure 9 instead. Treat it as version-dependent.

When not to use the installer

  • npm works but git does not. The installer ends in git clone. Download the repo as a zip and copy one folder into .claude/skills/; you skip failures 1, 2, 5 and 6 entirely and leave no lock file behind.
  • You want one skill out of a big repo. Fifteen skills means fifteen descriptions in context on every turn. Per the docs, when the listing exceeds its budget the descriptions get truncated starting with the skills you call least — and at install time it has no idea which those are.
  • You are gating CI. Failure 3 exits 0 on total failure; failure 9 exits non-zero on success. Assert artefacts, not status codes.
  • You only need the files to exist. Then the manual path is strictly less stateful: no lock file, no settings entry, and rm -rf is a complete uninstall.

The short version

Run the installer with -y --agent claude-code after checking that git's proxy points at a live port. Expect 8.6 to 12.4 seconds for fifteen skills. Then verify with skills list --json, the presence of .claude/skills/name/SKILL.md, and claude plugin validate .claude/skills — remembering that the validator passes broken YAML, and that the installer's exit code is not evidence either way.

The scratch directory still holds the fifteen installed skills, plus three folders I created on purpose to test the blind spots (broken-yaml, no-frontmatter, synced). The Chinese edition of this page carries the same numbers: install guide (Chinese).