Skip to main content

agentscan

The trust layer for AI agent skills.

A deterministic, local security scanner for AI agent skills — plus the Trusted Distribution: a curated, continuously audited package registry.

pip install agentscan-cli

agentscan scan ~/.claude/skills     # free, local, deterministic
agentscan activate                  # Trusted Distribution license
agentscan search                    # what's available
agentscan install security-engineer # one command, verified
agentscan update                    # like brew upgrade

The scanner (free, open source, MIT)

Scan any skill, MCP server, or agent config for what it actually does — shell, exfiltration, secrets, supply-chain, obfuscation — before you run it in your agent.

  • Facts, not verdicts. Every finding is a checkable fact with file:line. The scanner never calls anything "malicious" — that verdict is yours.
  • Deterministic, not ML. Regex, entropy, structure. Same input, same report, every time.
  • Zero dependency, zero execution. Pure Python stdlib. Never runs a skill, never calls out, works offline.
$ agentscan scan ~/Downloads/suspicious-skill

agentscan 0.4.0  /home/you/Downloads/suspicious-skill
scanned 1 artifact(s), 14 finding(s)

  ARTIFACT  [claude-skill] auto-updater
  CRITICAL [exfil] Local secret read piped to network
           SKILL.md:41
  CRITICAL [secrets] AWS Access Key
           SKILL.md:24
  ...
  summary: critical=3 high=2 medium=5 low=2 info=2
  note: findings are observed patterns, not verdicts. Review each before acting.

Exit codes: 0 clean · 1 findings at/above threshold · 2 usage error.

What it checks

Check Observes
shell bash/sh/python -c/node -e/exec/eval/subprocess invocations
filesystem rm -r/-f, shutil.rmtree, git reset --hard/clean/push --force, chmod 777
network curl/wget/fetch/requests, URLs, credential-in-URL, IP literals, cleartext http
secrets 20+ token formats (AWS, GitHub, Slack, Stripe, OpenAI, Anthropic, JWT, PEM…)
license declared license — recognized vs. unrecognized vs. missing
supply_chain curl|bash pipes, git clone, unpinned pip/npm, script downloads
prompt_patterns high-risk prompt-manipulation phrasing — flagged, never "detected"
exfil credentialed webhooks, env-in-URL, secret-read → network
obfuscation decode-to-execute chains, nested eval/exec, hex escapes
config_tamper remote MCP servers, hook commands, npm lifecycle scripts

Artifacts detected: claude-skill, mcp-server, cursor-rules, context-file, github-actions, npm-package, generic.

Usage

python3 -m agentscan <dir>                  # human report
python3 -m agentscan <dir> --json           # machine-readable
python3 -m agentscan <dir> --sarif          # SARIF 2.1.0 (GitHub code scanning)
python3 -m agentscan <dir> --severity high  # only high+ fails exit code

The Trusted Distribution (paid)

Access to curated, security-reviewed packages. Buy once ($49), receive a license key, activate, install. No dashboard, no browser login, no accounts — it's a developer tool.

Buy ($49, Polar checkout)
  ↓
License key (shown on your Polar purchases page)
  ↓
pip install agentscan-cli
  ↓
agentscan activate            → Polar /v1/customer-portal/license-keys/validate (direct)
  ↓
agentscan search              → GET  /api/packages
  ↓
agentscan install <package>   → GET /api/download/<id> (license-gated) → sha256 → extract → install
  ↓
agentscan update              → like brew upgrade

Architecture

PyPI (agentscan CLI, MIT)
   ↓
Polar (payment + license keys — source of truth, no users table)
   ↑ direct validation (public endpoint, no server in the middle)
   |
agentscan.baldbee.me (Next.js site + API route handlers)
   ├── /api/packages       public catalog
   └── /api/download/[id]  license-gated tarball proxy
   ↓
agentscan-registry (private GitHub repo)
   ├── packages/        source of truth
   ├── packages.json    generated catalog (sha256 per package)
   └── GitHub Releases  tarball distribution
   ↓
~/.agentscan/  license · installed.json · config.json · cache/
~/.claude/skills/<skill-id>/            Claude Code install
~/.config/opencode/skills/<skill-id>/   OpenCode install
~/.agents/skills/<skill-id>/            Codex install (+ AGENTS.md at repo root)
~/.hermes/skills/<skill-id>/            Hermes install ($HERMES_HOME honored)
~/.grok/skills/<skill-id>/              Grok Build install ($GROK_HOME honored)

The website and API are the same Next.js application. No separate backend, no database, no object storage. Git is the source of truth; GitHub Releases are the CDN. License validation is on-demand against Polar — nothing is stored server-side, no webhooks, no subscriptions.

The Polar organization id is public metadata and is baked into the CLI as a constant (DEFAULT_POLAR_ORGANIZATION_ID in agentscan/config.py). Users never configure it — install, activate, done.

Commands

agentscan scan .                    # scan a directory of agent skills (free)
agentscan activate                  # prompt for license → verify → store
agentscan logout                    # remove local license
agentscan whoami                    # show active license
agentscan search                    # browse the catalog (package cards)
agentscan install <package>         # verified install, runtime auto-detected
agentscan install <p> --runtime codex   # install into a specific runtime
agentscan update                    # upgrade installed packages
agentscan verify                    # signature · latest · audit · intact

Package names are matched flexibly — any of these work:

agentscan install security-engineer
agentscan install "Security Engineer"
agentscan install Security Engineer
agentscan install security
agentscan install secuirty        # typos are suggested, not silent

Runtimes

Packages install into the agent runtimes found on your machine:

Runtime Detected via Skills install to
Claude Code ~/.claude or claude ~/.claude/skills/<skill-id>/
OpenCode ~/.config/opencode or opencode ~/.config/opencode/skills/<skill-id>/
OpenAI Codex ~/.codex, ~/.agents, or codex ~/.agents/skills/<skill-id>/ + AGENTS.md
Hermes $HERMES_HOME, ~/.hermes, or hermes $HERMES_HOME/skills/<skill-id>/ (default ~/.hermes/skills/)
Grok Build $GROK_HOME, ~/.grok, or grok $GROK_HOME/skills/<skill-id>/ (default ~/.grok/skills/)

agentscan install detects installed runtimes automatically. When several are present it installs into all of them; when none are detected it prompts, or you can pick explicitly:

agentscan install security-engineer --runtime claude
agentscan install security-engineer --runtime opencode
agentscan install security-engineer --runtime codex
agentscan install security-engineer --runtime hermes
agentscan install security-engineer --runtime grok
agentscan install security-engineer --runtime all

Hermes follows the agentskills.io open standard: skills are discovered recursively under its skills root and load as slash commands (/skill-name). HERMES_HOME is the official override and is honored when set (it also covers named profiles).

Grok Build (xAI) reads the same agentskills.io SKILL.md standard and discovers skills recursively under skills/ dirs — including ~/.grok/skills/, ~/.agents/skills/, and ~/.claude/skills/. GROK_HOME is the official home override and is honored when set. Skills load as slash commands (/skill-name) and grok inspect lists everything discovered.

Codex installs also write the package's AGENTS.md (the agents.md convention) to the repository root when you are inside a git work tree. The file is marked with a <!-- agentscan:<package> --> comment; reinstalling replaces that section, and the rest of your AGENTS.md is left untouched.

Add --quiet (or -q) to suppress progress lines for automation; results and errors still print. Run agentscan --help for examples.

Local state

Everything lives in ~/.agentscan/:

~/.agentscan/
  license          the activated license (JSON)
  installed.json   {package-id: {version, runtimes: {runtime: {skills: [...]}}}}
  config.json      api_url override (optional)
  cache/           downloaded tarballs

Package format

A package is not just a skill. It may contain agents, skills, slash commands, templates, workflows, and knowledge:

security-engineer/
  manifest.json     id, title, version, description, license, requires
  agents/           optional agent definitions
  skills/           SKILL.md files
  commands/         optional slash commands
  templates/        optional templates
  knowledge/        reference material
  audit.json        latest deterministic scan result
  signature.sig     placeholder — real signing lands with the Polar milestone
  README.md

manifest.json ships one package definition per the catalog shape:

{ "packages": [ { "id": "security-engineer", "title": "Security Engineer",
  "version": "1.0.1", "description": "…", "sha256": "…",
  "release": "v1.0.1", "asset": "security-engineer-1.0.1.tar.gz" } ] }

Status of the paid layer

  • License verification is real. agentscan activate validates the key against Polar's public customer-portal endpoint on demand. No mock, no database, no webhooks.
  • Downloads are real and license-gated. The CLI sends the license key as Authorization: Bearer <key>; the site validates it against Polar before proxying the tarball from the private GitHub registry. Checksums are verified end to end (server-side and CLI-side).
  • signature.sig is a placeholder; cryptographic signing is designed in (agentscan verify is structured to add it without CLI changes).

The numbers (4,000 skills measured)

We scanned a random sample of 4,000 unique skills across 174 public repos:

Signal % of skills
No recognizable license 93.6%
Invokes shell / interpreter 75.3%
Supply-chain patterns (curl|bash, unpinned installs) 23.1%
Credential-format strings 14.7%
Destructive filesystem ops 7.6%
Exfiltration sinks 4.2%
Prompt-manipulation phrasing 3.3%
Obfuscation chains 0.4%
Any high/critical finding 18.0%

Full methodology: CORPUS-REPORT.md


Development

python3 -m unittest discover -s tests -v   # 49 tests

Pure stdlib, Python 3.8+, works offline. To point the CLI at a local server:

export AGENTSCAN_API_URL=http://localhost:3100   # overrides the default API

License

MIT © baldbee

Independent project. Not affiliated with Anthropic, Snyk, or any vendor. Patterns modeled on gitleaks/trufflehog (secrets), OWASP Agentic Top 10, MCPGuard threat taxonomy, and Snyk's ToxicSkills findings.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

agentscan_cli-0.8.0.tar.gz (55.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

agentscan_cli-0.8.0-py3-none-any.whl (53.0 kB view details)

Uploaded Python 3

File details

Details for the file agentscan_cli-0.8.0.tar.gz.

File metadata

  • Download URL: agentscan_cli-0.8.0.tar.gz
  • Upload date:
  • Size: 55.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.11.15

File hashes

Hashes for agentscan_cli-0.8.0.tar.gz
Algorithm Hash digest
SHA256 dd454d373246eed49751b6914a24f558b7ac7fe697716e7bb1ea7083191c8890
MD5 53eb1022b101b8f9ef8a013dee7182cb
BLAKE2b-256 21334804f9ae76bea04d98c02427109b134efd401a2b732a8aeee5858269f7a3

See more details on using hashes here.

File details

Details for the file agentscan_cli-0.8.0-py3-none-any.whl.

File metadata

  • Download URL: agentscan_cli-0.8.0-py3-none-any.whl
  • Upload date:
  • Size: 53.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.11.15

File hashes

Hashes for agentscan_cli-0.8.0-py3-none-any.whl
Algorithm Hash digest
SHA256 81ebd7fa00ed30bf47741350dfefdf7a7c407747b18a2ead607815fffa405740
MD5 43bad8afed7a7475b5d4a2288f1b9199
BLAKE2b-256 140839896bbe0bc2046ee3b07dba01f77903e2ac9519449d54b7363937f2f2f0

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page