Installing an agent skill feels like installing a note. It is closer to installing a package: a SKILL.md that steers your agent, plus scripts that can run on your machine with your credentials. NVIDIA’s SkillSpector, now past 20,000 GitHub stars, is a static scanner built to look inside a skill before you let it in.
This guide covers what it is, its four-step pipeline, the commands as documented, a CI gate and, just as important, where it stops. The one-line version: skillspector scan ./my-skill/. A scan is a filter, not a verdict.
1. What Is SkillSpector?
SkillSpector is a security scanner for AI agent skills: the folders of instructions and scripts that tools like Claude Code, Codex CLI or Gemini CLI load on demand. You point it at a skill (a directory, a single SKILL.md, a zip or a Git URL) and it reports vulnerabilities, malicious patterns and a 0–100 risk score with an install recommendation. The project is published by NVIDIA under Apache-2.0 and written in Python.
~20.2k
Stars
GitHub API, Oct 14, 2026
Apache-2.0
License
Open source
v2.12.0
Latest release
Sep 23, 2026
Python 3.12+
Stack
CLI + optional MCP server
Read from the GitHub API and the README on 2026-10-14. Stars move daily; the repo was created in March 2026.
The README says it is part of NVIDIA’s Verified Skills pipeline, which scans, evaluates and signs agent skills before publication. That context matters: it was designed as a gate for a publisher’s catalog, and it doubles as a pre-install check for anyone consuming skills.
Why scan skills at all?
The README cites an academic study, “Agent Skills in the Wild” (Liu et al., 2026, arXiv 2601.10338). The researchers collected 42,447 skills, analyzed 31,132 and used their own scanner, not SkillSpector, for the numbers below. Read them as a signal about the ecosystem, not as a measurement of this tool.
26.1%
of analyzed skills had at least one vulnerability
5.2%
showed high-severity patterns pointing to likely malicious intent
2.12x
more likely to be vulnerable when the skill bundles executable scripts
2. How It Works: Four Steps From Input to Verdict
The README describes a two-stage detection pipeline wrapped by an intake step and a scoring step. Nothing in it executes the skill: the trust model states plainly that it never runs what it scans.
1. Intake and inventory
You hand it a directory, a single file, a zip or a Git URL. SkillSpector builds an inventory of the files it can analyze (instructions, scripts, manifests, dependency files). Since v2.12.0 it also accepts selected GitHub subdirectory links and GitHub or GitLab file links.
2. Stage 1: deterministic static analysis
Fast pattern matching across 11 static analyzers, plus Python AST checks, YARA signatures and taint tracking from sources such as credentials to sinks such as network output. Repeatable, no API key needed. Dependency names and versions are checked against OSV.dev.
3. Stage 2: optional LLM semantic review
A model compares what a skill claims with what its code does, which helps with description-behavior mismatches and vague triggers. Every deterministic finding stays in the report whether the model confirms it, disputes it or ignores it; confirmed findings can gain an explanation and higher confidence, never lower.
4. Score, verdict and report
Findings are weighted (CRITICAL 50, HIGH 25, MEDIUM 10, LOW 5 points, with a 1.3x multiplier for executable scripts) into a 0–100 score, a severity and an install recommendation. Reports come as terminal, JSON, Markdown or SARIF 2.1.0.
Score-to-verdict mapping (README)
0–20
LOW
SAFE
21–50
MEDIUM
CAUTION
51–80
HIGH
DO_NOT_INSTALL
81–100
CRITICAL
DO_NOT_INSTALL
Mind the wording: SAFE means nothing scored high enough, not that the skill is proven safe. Section 8 comes back to this.
3. What It Checks: 17 Categories of Skill Risk
This is the README’s own taxonomy. Each category has numbered rule IDs (P1, E2, SC4, AST1, TT3…) that show up in reports and baselines, so you can talk about a finding precisely.
Prompt Injection
P1–P5, P9Instruction override, hidden instructions, exfiltration commands, behavior manipulation, harmful content, whitespace padding.
Anti-Refusal
AR1–AR3Text that tells the agent to stop refusing, drop disclaimers or treat safety policy as void.
Data Exfiltration
E1–E4External transmission, environment-variable harvesting, file-system enumeration, context leakage.
Privilege Escalation
PE1–PE3Excessive permissions, sudo or root execution, credential access.
Supply Chain
SC1–SC10Unpinned or known-vulnerable dependencies, remote script fetching, obfuscated code, typosquatting, shipped bytecode, concealed executables, dependency source redirection.
Excessive Agency
EA1–EA5Unrestricted tool access, autonomous decisions, scope creep, unbounded resources, external model or provider selection.
Output Handling
OH1–OH3Unvalidated output injection, cross-context output, unbounded output.
System Prompt Leakage
P6–P8Direct leakage, indirect extraction and tool-based exfiltration of system prompts.
Memory Poisoning
MP1–MP3Persistent context injection, context-window stuffing, memory manipulation.
Tool Misuse
TM1–TM3Parameter abuse, chaining abuse and unsafe defaults such as disabled TLS verification.
Rogue Agent
RA1–RA2Self-modification at runtime and session persistence such as cron jobs or startup hooks.
Trigger Abuse
TR1–TR3Overly broad triggers, shadowing built-in commands or other skills, keyword baiting.
Behavioral AST
AST1–AST9Dangerous Python calls found by syntax-tree analysis: exec, eval, dynamic import, subprocess, os.system, compile, getattr sinks.
Taint Tracking
TT1–TT5Data flowing from credentials, files or external input into network output or code execution.
YARA Signatures
YR1–YR4Malware, webshell, cryptominer and exploit-tool signatures.
MCP Least Privilege
LP1–LP4Declared permissions that do not match real capabilities: under-declared, wildcard, missing or over-declared.
MCP Tool Poisoning
TP1–TP4Hidden instructions, Unicode deception, parameter-description injection and description-behavior mismatch.
Pattern-count caveat: the README headline says 71 patterns while NVIDIA’s docs page says 68. The number differs between sources and releases, so read it as roughly 70 rules in 17 categories. The rule IDs in your own report are what matter.
4. Quickstart: Verified Against the README on 2026-10-14
Every command below is copied from the project README as of today (Python 3.12+ per its badge). I am documenting them here, not running them for you: read what an installer does before you execute it, which is the whole point of this article.
Install (uv tool)
uv tool install git+https://github.com/NVIDIA/skillspector.git
Scan a skill
# Scan a local skill directory skillspector scan ./my-skill/ # Scan a single SKILL.md file skillspector scan ./SKILL.md # Scan a Git repository skillspector scan https://github.com/user/my-skill # Scan a zip file skillspector scan ./my-skill.zip
Output formats
# JSON output - machine readable skillspector scan ./my-skill/ --format json --output report.json # Markdown output - for documentation skillspector scan ./my-skill/ --format markdown --output report.md # SARIF output - for CI/CD integration and IDE tooling skillspector scan ./my-skill/ --format sarif --output report.sarif
Docker, static-only (build from a checkout of the repo)
docker build -t skillspector . docker run --rm -v "$PWD:/scan" skillspector scan ./my-skill/ --no-llm
Read this before you scan private skills
With LLM analysis on, analyzer-eligible file contents are sent to the configured provider, and per the README the default provider is nv_build (NVIDIA’s hosted endpoint). Pass --no-llm to keep contents local. Even with --no-llm, the supply-chain check SC4 sends dependency names and versions (not file contents) to OSV.dev. To switch provider, set SKILLSPECTOR_PROVIDER (documented values include openai, anthropic, bedrock, gemini, ollama, azure_openai and openai_compatible) together with that provider’s API-key variable.
5. Wire It Into CI Before Third-Party Skills Reach Your Agent
The README calls the exit code and the JSON output a stable contract for CI pipelines, install gates and editor integrations. It does not ship a GitHub Actions snippet, so the script below is my own composition of documented flags. I have not run it: test it on a throwaway repository first.
Exit codes of skillspector scan (README)
0Scan completed, risk score ≤ 50 (SAFE or CAUTION) and no enabled strict gate fired.1Risk score above 50, or a strict gate fired: --fail-on-findings, --fail-on-incomplete or --min-coverage.2Error: bad input, unreadable source or internal failure.
By default SAFE and CAUTION both exit 0, so a green build does not mean no findings. Gate more strictly with --fail-on-findings (any active finding) and --fail-on-incomplete (partial coverage), or read the recommendation from the JSON report and apply your own policy. The opt-in --fail-on-findings flag arrived in v2.12.0, so check the version you install.
The pre-install workflow I would use
- Step 1 — Quarantine: Never drop a third-party skill straight into ~/.claude/skills/. Pull it into a scratch directory or let SkillSpector fetch the Git URL itself.
- Step 2 — Scan static-first: Run with --no-llm so nothing leaves your machine. Add the LLM stage only for skills you are allowed to share with a provider.
- Step 3 — Read verdict and coverage: Check risk_assessment.recommendation and analysis_completeness.is_complete in the JSON. NVIDIA’s docs say an incomplete scan is not safe to install, whatever the score.
- Step 4 — Human review, then project scope: A person reads SKILL.md and every flagged script, then the skill goes into the repo, where later changes show up in a pull request.
Illustrative CI gate (composed from documented flags, not copied from the README)
#!/usr/bin/env bash
# ci/scan-skills.sh - fail the build if a vendored skill is risky or unreadable
set -u
# Pin a release tag so scores do not drift between runs (uv accepts git refs after @)
uv tool install git+https://github.com/NVIDIA/skillspector.git@v2.12.0
mkdir -p reports
status=0
for d in .claude/skills/*/; do
skillspector scan "$d" --no-llm \
--fail-on-findings --fail-on-incomplete \
--format sarif --output "reports/$(basename "$d").sarif" || status=1
done
exit $statusAccept known findings with a baseline
Triaged findings can be suppressed so the score reflects only new issues. The baseline is a YAML file you commit, and every entry needs a reason. Fingerprints stop matching after a scanner upgrade or a content change, broad rules can hide newly malicious content, and the v2.12.0 notes warn that scores and recommendations may shift between versions, so review baselines after upgrading.
skillspector baseline ./my-skill/ -o .skillspector-baseline.yaml skillspector scan ./my-skill/ --baseline .skillspector-baseline.yaml
6. Use Cases That Earn Their Keep
Four places where a static skill scanner is worth the setup time.
Vetting a skill before you install it
Someone shares a skill in a thread or a marketplace listing. Scan the folder or its Git URL, read the report, and only then decide. This is the core job.
A PR gate for repos that vendor skills
Teams that commit their skills folder get a check on every change: SARIF output for the code-scanning view of your CI, and an exit code that blocks the merge.
Pre-publication checks for skill authors
NVIDIA runs it as the security tier before publishing to its catalog. If you ship skills to other people, run the same scan on your own work before you tag a release.
Let the agent ask first (MCP)
With the optional MCP extra, an agent can call the scanner as a tool before installing something. The HTTP transport has no authentication, so bind it to loopback only.
MCP extra (verified commands, README 2026-10-14)
uv tool install 'skillspector[mcp] @ git+https://github.com/NVIDIA/skillspector.git' claude mcp add skillspector -- skillspector mcp
7. Where It Fits: Scanner Before, Sandbox During
The README is explicit that SkillSpector is defense-in-depth, not a sandbox: it never executes the skill, and it does not contain a skill you install anyway. Those are two different controls answering two different questions.
Static scanner (SkillSpector)
- • Question: what is inside this skill?
- • When: before install and on every change
- • Strength: cheap, repeatable, catches known-bad patterns
- • Blind spot: anything that only appears at runtime
Runtime containment (sandbox, permissions)
- • Question: what can this skill do if it misbehaves?
- • When: on every execution
- • Strength: limits blast radius even for unknown tricks
- • Blind spot: says nothing about what the skill contains
A layered setup that costs an afternoon
- 1. Scan every new or updated skill in CI (static-first, strict gates).
- 2. Install at project scope so changes show up in code review.
- 3. Give the agent least-privilege tool permissions and keep production credentials out of its environment.
- 4. Run skills that bundle scripts inside a container or VM with no ambient secrets and restricted network egress.
- 5. Keep logs of what the agent executed, so a miss becomes an investigation instead of a mystery.
8. When Not to Rely on It: The False Sense of Safety
A clean report is the most dangerous output this tool can produce, because it feels like permission. The README’s Limitations section is short and worth taking literally.
Non-English content
The README says it may miss patterns written in other languages. A hostile instruction in a language the rules do not cover is a known gap.
Images
It cannot analyze text embedded in images, so instructions hidden in a screenshot or diagram are out of reach.
Encrypted or binary code
Compiled or encrypted content cannot be inspected, which is exactly where someone hiding a payload would go.
Runtime behavior
Static analysis only, no dynamic execution. Whatever a skill downloads or decides at runtime is invisible to a static pass.
Also remember
- • An incomplete scan is not a clean scan. Size limits, unsupported encodings or timeouts can leave part of a skill unread; NVIDIA’s docs say to treat is_complete: false as not safe to install.
- • Exit code 0 includes CAUTION. Without strict gates, a CI check can be green while findings exist.
- • The semantic layer can vary between runs. The baseline docs recommend --no-llm for repeatable acceptance.
- • A signature is not verification: a root-level OpenSSF Model Signing file is recognized, but the README says the signature itself is not verified.
- • Baselines can hide a new problem when a rule is too broad. Keep them narrow and review them.
✅ Good fit when...
- • You consume third-party skills or MCP servers
- • You vendor skills in git and want a PR gate
- • You publish skills and want a pre-release check
- • You need machine-readable output (JSON, SARIF) for policy
⚠️ Not a replacement for...
- • A sandbox or least-privilege permissions
- • Reading the skill yourself, especially scripts/
- • Trust in the publisher: provenance, signing, review
- • Content in languages or formats it cannot read
Golden rule
Treat DO_NOT_INSTALL as a stop sign and SAFE as “no known-bad pattern found”. The decision to install is still a human one.
Conclusion
SkillSpector earns its stars by doing one unglamorous job well: turning “is this skill sketchy?” from a gut feeling into a repeatable check with rule IDs, a score and an exit code. For anyone installing skills from strangers, which in 2026 is most of us, that is worth ten minutes to set up.
Use it as the first filter, not the last. Scan static-first, gate on completeness, install at project scope and keep a sandbox under anything that runs code. If your agents already pull skills from everywhere and nobody owns that audit, that is the kind of gap I close in project-rescue work.



