← Back to Plugins
Tools

Agent Guard

elliottwaves-20 By elliottwaves-20 👁 112 views ▲ 0 votes

Scan AI agent skills, plugins, and MCP servers for malicious code before installation - one scan, every agent (Claude Code, Codex, Gemini, Hermes, OpenClaw). Powered by cisco-ai-skill-scanner.

GitHub

README

# agent-guard

[![skills.sh](https://skills.sh/b/elliottwaves-20/agent-guard)](https://skills.sh/elliottwaves-20/agent-guard)

**Scan any AI agent skill, plugin, or MCP server for malicious code โ€” before it ever runs on your machine.**

Skills and MCP servers are third-party code executed with your user account's permissions. A malicious one can read your SSH keys, grab `.env` files and browser sessions, exfiltrate data โ€” or hijack your AI agent through a poisoned SKILL.md (prompt injection). This skill makes **scan first, install after** the default workflow, powered by Cisco's [skill-scanner](https://github.com/cisco-ai-defense/skill-scanner) (for skills) and [mcp-scanner](https://github.com/cisco-ai-defense/mcp-scanner) (for MCP servers).

## What you get

- **Commit-pinned ZIP scanning** โ€” repos are fetched as a ZIP snapshot of one exact commit; `git clone` never touches your machine before a verdict, and the commit that was scanned is the commit that gets installed. No scan/install gap an attacker could slip a push into.
- **Skills *and* MCP servers** โ€” an MCP server is code that must run to be inspected, so naive scanning would execute it. `scan_mcp.py` scans the package **source** first (fetched from the registry, nothing executed), with an optional **Docker-sandboxed** live scan โ€” untrusted MCP code never runs unconfined on your machine.
- **Three analysis layers** โ€” static signatures, behavioral dataflow analysis, and optional LLM-powered semantic analysis with automatic false-positive filtering.
- **Bring your own LLM** โ€” Anthropic, OpenAI, local Ollama (free, no API key), or any OpenAI-compatible endpoint (OpenRouter, Groq, Azure, vLLM, LM Studio) via bundled LiteLLM.
- **Fail-closed workflow** โ€” scanner errors are never silently treated as "no findings".
- **Prompt-injection aware** โ€” content of scanned repos is treated as data, never as instructions to the reviewing agent.
- **Clear verdicts** โ€” โœ… SAFE / โš  REVIEW / ๐Ÿšซ DO NOT INSTALL, with file and line for every finding.
- **Universal installer included** โ€” after a SAFE verdict, one command installs the skill or MCP server to every agent detected on the machine (Claude Code, Claude Desktop, Codex, Antigravity/Gemini, Hermes, OpenClaw), or a subset via `--tools`.

## One scan, every agent

Skills are not a Claude-only concept: they follow the open [SKILL.md standard (agentskills.io)](https://agentskills.io), and [MCP](https://modelcontextprotocol.io) is an open protocol. The same skill or server runs in Claude Code, Codex, Gemini/Antigravity, [Hermes](https://hermes-agent.nousresearch.com), [OpenClaw](https://docs.openclaw.ai), and friends โ€” and the Cisco scanner doesn't care which agent the code is destined for.

Many people now work across several agents in parallel, not least because of per-provider rate limits. That normally means installing โ€” and *trusting* โ€” the same third-party code once per agent. agent-guard collapses this into **scan once, verdict once, install everywhere**: one command links the audited commit into every detected agent, so all your agents run exactly the same reviewed code. Use `--tools` to target only specific agents.

## Supported tools (auto-detected)

| Tool | Skills | MCP servers |
|------|--------|-------------|
| Claude Code | `~/.claude/skills/` | `claude mcp add -s user` โ†’ `~/.claude.json` |
| Claude Desktop | `~/.claude/skills/` *(shared with Claude Code)* | `%APPDATA%/Claude/claude_desktop_config.json` |
| Codex | `~/.codex/skills/` | `~/.codex/config.toml` |
| Antigravity / Gemini | `~/.gemini/config/skills/` | `~/.gemini/config/mcp_config.json` |
| Hermes (Nous Research) | `~/.hermes/skills/` | manual โ€” `mcp_servers:` block in Hermes `config.yaml` |
| OpenClaw | `~/.openclaw/skills/` | manual โ€” OpenClaw's own MCP tooling |

Detection is automatic โ€” only tools whose configs exist are touched. Claude Desktop reads skills from the same `~/.claude/skills/` as Claude Code, so that shared path is linked once and serves both. JSON configs are backed up (`.bak`) before every write. Hermes and OpenClaw use their own MCP config formats (YAML / CLI), so the installer prints instructions for those instead of modifying configs blindly.

## Prerequisites

- [uv](https://docs.astral.sh/uv/) โ€” installs the scanners in isolated environments (uv ships its own Python)
- Python 3.10+ โ€” for running `scripts/install_skill.py` and `scripts/scan_mcp.py`
- An LLM provider of your choice โ€” optional, enables LLM-powered analysis (see [LLM provider support](#llm-provider-support)); without one, skill scans run with `--use-behavioral` only
- [Docker](https://docs.docker.com/get-docker/) โ€” **optional**, only for the MCP sandbox (`scan_mcp.py ... --sandbox`, Stage 2). Skill scans and the default Stage 1 MCP source scan do **not** need Docker.

## Quick start

**Option A โ€” via [skills.sh](https://skills.sh) (any of 70+ agents):**

```bash
# Installs the skill into every agent the CLI detects (Claude Code, Codex,
# Hermes, OpenClaw, Cursor, ...). Works without git.
npx skills add elliottwaves-20/agent-guard
```

This installs the skill files. The skill drives the [cisco-ai-skill-scanner](https://github.com/cisco-ai-defense/skill-scanner) binary, so run the one-time setup afterwards to install it:

```bash
cd ~/.claude/skills/agent-guard   # or wherever the CLI placed it
./setup.sh                          # Windows PowerShell: .\setup.ps1
cp .env.example .env                # optional: pick an LLM provider
```

**Option B โ€” clone and install manually:**

```bash
git clone https://github.com/elliottwaves-20/agent-guard
cd agent-guard

./setup.sh          # Windows PowerShell: .\setup.ps1

cp .env.example .env   # optional: pick an LLM provider for deeper analysis

# Register agent-guard itself into every detected agent (auto-detects your tools):
python scripts/install_skill.py skill .
```

## Usage

### Scan a GitHub repo before installing

```bash
# Load LLM provider config (optional, enables --use-llm)
set -a && source .env && set +a

REPO="user/repo-name"
WORKDIR=$(mktemp -d)

# Pin the current commit of the default branch (works for main, master, anything)
SHA=$(curl -fsSL "https://api.github.com/repos/${REPO}/commits/HEAD" \
      | grep -m1 '"sha"' | cut -d'"' -f4)

# Download exactly that commit as ZIP โ€” no git hooks, no git attack surface
curl -fsSL "https://github.com/${REPO}/archive/${SHA}.zip" -o "$WORKDIR/scan.zip"
unzip -q "$WORKDIR/scan.zip" -d "$WORKDIR/src"

# Scan the extracted skill directory (the ZIP unpacks into <repo>-<sha>/)
# Provider and model come from .env โ€” no provider flag needed
skill-scanner scan "$WORKDIR/src"/* --use-behavioral --use-llm \
  --enable-meta --format table

# Cleanup (keep $SHA for installation)
rm -rf "$WORKDIR"
```

Scanner errors or empty output mean **no verdict** โ€” never treat a failed scan as safe.

### Scan an MCP server before installing

MCP servers need different handling than skills. A skill is Markdown that only gets *read*; an MCP server is code that must *run* to expose its tools โ€” so "just start it and scan" would already execute untrusted code. `scan_mcp.py` enforces a safe order:

**Stage 1 (default โ€” nothing from the package runs):** fetch the source straight from the registry and scan it.

```bash
# PyPI MCP server:
python scripts/scan_mcp.py pypi mcp-server-name

# npm MCP server:
python scripts/scan_mcp.py npm @scope/mcp-server-name

# source already on disk / a hosted remote MCP:
python scripts/scan_mcp.py local ./path/to/mcp-source
python scripts/scan_mcp.py remote https://example.com/mcp
```

**Stage 2 (optional โ€” live runtime check):** start the server inside a throwaway **Docker container with no access to your filesystem**, then scan its live tools and prompts.

```bash
python scripts/scan_mcp.py pypi mcp-server-name --sandbox -- uvx mcp-server-name
```

The scan reuses `SKILL_SCANNER_LLM_API_KEY` from `.env` (the behavioral source analysis is LLM-based). A clean Stage 1 scan does **not** prove runtime safety โ€” reach for `--sandbox` when a server is unfamiliar. Install only after a SAFE verdict.

### Install after a SAFE verdict

Install the same commit that was scanned:

```bash
git clone https://github.com/user/repo-name ~/path/to/workspace/repo-name
git -C ~/path/to/workspace/repo-name -c advice.detachedHead=false checkout "$SHA"

# All detected agents at once:
python scripts/install_skill.py skill ~/path/to/workspace/repo-name

# Or only specific agents:
python scripts/install_skill.py skill ~/path/to/workspace/repo-name --tools claude-code hermes
```

**MCP server (PyPI, isolated via uvx) โ€” only after `scan_mcp.py` returned SAFE:**

```bash
python scripts/install_skill.py mcp \
  --name "my-server" \
  --command "uvx" \
  --args "package-name" \
  --env "API_KEY=your-key"
```

**Dry run first** to preview every change:

```bash
python scripts/install_skill.py mcp --name foo --command uvx --args bar --dry-run
python scripts/install_skill.py skill <path> --dry-run
```

### Audit all installed skills

```bash
skill-scanner scan-all ~/.claude/skills --use-behavioral --format table
```

## LLM provider support

The LLM analyzer (`--use-llm`) works with any provider โ€” configure it once in `.env`, the scan commands stay the same:

| Provider | `.env` settings | Notes |
|----------|----------------|-------|
| **Anthropic** (default) | `PROVIDER=anthropic`, `API_KEY`, `MODEL=claude-haiku-4-5-20251001` | fast + cheap for scanning |
| **OpenAI** | `PROVIDER=openai`, `API_KEY`, `MODEL=gpt-4o-mini` | |
| **Ollama** (local) | `MODEL=ollama/<model>` | free, no API key, fully offline |
| **OpenAI-compatible** | `PROVIDER=openai-compatible`, `API_KEY`, `MODEL`, `BASE_URL` | OpenRouter, Groq, Azure OpenAI, vLLM, LM Studio, ... |

All variables use the `SKILL_SCANNER_LLM_` prefix (see `.env.example`). LiteLLM is bundled โ€” no extra install. A separate model for the meta analyzer can be set via `SKILL_SCANNER_META_LLM_*`.

**Verdict quality depends on model quality.** This tool makes 

... (truncated)
tools

Comments

Sign in to leave a comment

Loading comments...