← Discover MCPs and Agents
h
MCPAI & MLGitHub

hol-guard

Open-source antivirus for AI agents: block risky tools, secret access, prompt injection, malicious packages, MCP servers, plugins, and skills at runtime.

Links

README

From the repo.

HOL Guard: Open-Source Antivirus for AI Agents

HOL Guard Version Plugin Scanner Version HOL Guard Downloads Plugin Scanner Downloads Python 3.10+ CI Publish Container Image OpenSSF Scorecard License GitHub Stars Lint: ruff

HOL whole dark logoStop risky AI actions before they compromise your machine. HOL Guard is a local-first security layer for AI agents, tools, plugins, skills, MCP servers, and package installs.

Install HOL Guard
Read the documentation
PyPI Package (hol-guard)
Report an Issue

HOL Guard reviews agent actions before they run: shell commands, file access, package installs, and MCP tool calls. It detects secret exposure, destructive operations, prompt injection, and supply-chain risks, then allows, blocks, or requests approval according to your policy.

Run it locally without an account. Use the CLI and local dashboard to manage protection, resolve approvals, and inspect decision history. Optional Guard Cloud adds shared history, team policy, and fleet management.

Get started · Supported agents · Plugin scanner · Documentation · Contribute an extension · Development

Install HOL Guard

Requires Python 3.10 or newer and pipx.

pipx install hol-guard
hol-guard init

The first-run wizard discovers supported agents and walks you through protection setup. It asks before each setup change, including opening the dashboard, installing agent integrations, and connecting optional cloud services.

Check your installation:

hol-guard --version
hol-guard status

To update an existing installation:

hol-guard update

For manual setup, see the installation guide. Annotated release notes with upgrade context live at hol.org/guard/releases; raw releases and prereleases are on the GitHub releases page.

What HOL Guard Protects

SurfaceProtection
Shell commands and file accessReviews destructive operations, sensitive file access, credential exposure, and suspicious outbound commands.
Package installsEvaluates supported package-manager operations against supply-chain intelligence before installation.
Plugins, skills, and agent configurationInventories local artifacts and reviews new or changed tools before launch.
MCP servers and toolsInspects server configuration and reviews tool calls through supported hooks and managed proxies.
Prompts and tool resultsScreens supported events for prompt injection and sensitive content.
Approvals and evidenceRoutes decisions to native prompts or the approval center, and records local receipts for review.

Guard connects through native agent hooks, managed MCP proxies, and launch integrations. Coverage depends on the events each agent exposes; the support matrix documents enforcement, approval delivery, and failure behavior per integration.

Supported AI Agents

Codex, Claude Code, GitHub Copilot CLI, Cursor, Cline, Gemini CLI, Grok, Hermes, Kimi Code, Pi, oh-my-pi, OpenClaw, OpenCode, Antigravity, and ZCode. Paseo is supported through these native provider integrations, with per-provider coverage.

For example, to set up Codex explicitly:

hol-guard install codex
hol-guard run codex --dry-run
hol-guard run codex

The dry run records the current artifact state before launch. For Codex, Guard installs native pre-tool hooks and refuses a managed launch if those hooks are missing or disabled.

Agent support matrix · Troubleshooting

Everyday Use

TaskCommand
Check protection statushol-guard status
Diagnose an agent integrationhol-guard doctor codex
Inspect changes before launchhol-guard diff codex
Review pending approvalshol-guard approvals
Approve or deny a requesthol-guard approvals approve <request-id> / hol-guard approvals deny <request-id>
Read decision historyhol-guard receipts
List tracked artifactshol-guard inventory
Export an AI bill of materialshol-guard abom --format json
Scan workspace dependencieshol-guard supply-chain scan
Connect optional cloud synchol-guard connect

Understand a paused command

Inspect the command's classification and matching rules:

hol-guard command test 'rm -rf ./build'
hol-guard command explain 'git clean -ndx'
hol-guard command extensions command.git --json

command test and command explain inspect the command without executing it or creating an approval. Use hol-guard approvals to resolve a pending request and hol-guard receipts to review the recorded decision.

The Extension directory lists command coverage generated from the Rust-compiled catalog. External contributions require explicit opt-in; required core protections remain enabled. To add coverage, follow the Extension contribution guide.

Check a package

hol-guard supply-chain sync
hol-guard supply-chain scan
hol-guard supply-chain explain minimist@1.2.5 --ecosystem npm

The package verdict includes the available advisory evidence and ecosystem coverage. See the get-started guide for package-manager interception and the remediation guide for handling false positives.

Plugin Scanner

This repository also ships plugin-scanner, a CLI for maintainers who want security and quality checks before publishing agent plugins, skills, and MCP integrations.

pipx install plugin-scanner
plugin-scanner scan .
plugin-scanner lint .
plugin-scanner verify .
CommandPurpose
scanSecurity findings and a quality report across detected package surfaces.
lintRule-level authoring feedback.
verifyInstall-surface and runtime readiness checks.
submitA submission artifact for one plugin package.
doctorComponent diagnostics and troubleshooting bundles.

The scanner detects Codex, Claude Code, DeepSeek Harness, Gemini CLI, Kimi Code, and OpenCode package formats. Use plugin-scanner --list-ecosystems to list them or --ecosystem to select one. At a Codex marketplace root, it discovers local plugin entries automatically.

Checks cover manifests, secrets, MCP transport and command configuration, approval defaults, skills, dependency lockfiles, and GitHub Actions permissions. Optional Cisco integrations add skill and MCP analysis. Reports support text, JSON, Markdown, and SARIF.

plugin-scanner scan . --format sarif --output plugin-scanner.sarif
plugin-scanner scan . --fail-on-severity high

Quality grades use the checks applicable to each package. Trust scoring has separate provenance and weights; see the skill, MCP, and plugin scoring references.

GitHub Actions

Add the scanner to a plugin repository:

name: Plugin security
on: [push, pull_request]

permissions:
  contents: read

jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
      - uses: hashgraph-online/ai-plugin-scanner-action@fdb49f9d85321a2ced2933301b395dd3c1ce9c8f # v1.2.631
        with:
          plugin_dir: "."
          min_score: 80
          fail_on_severity: high

See the action documentation for SARIF uploads, submission workflows, and machine-readable outputs. The action source is maintained in action/.

Optional Cisco analysis

The baseline packages work without Cisco dependencies. To add Cisco skill scanning, use Python 3.11 through 3.14 and install the extra in an isolated environment:

pipx install 'plugin-scanner[cisco]'

For Cisco MCP analysis, use the repository's Docker image or the cisco-mcp dependency group:

uv sync --extra dev --extra cisco --group cisco-mcp --python 3.13
uv run plugin-scanner scan . --cisco-skill-scan on --cisco-mcp-scan on

The published cisco extra provides skill scanning; the separate cisco-mcp group supplies the MCP scanner. Dependency versions and Python constraints are maintained in pyproject.toml.

Ecosystem Support

EcosystemDetection surfaces
Codex.codex-plugin/plugin.json, marketplace.json, .agents/plugins/marketplace.json
Claude Code.claude-plugin/plugin.json, .claude-plugin/marketplace.json
DeepSeek Harnesspackage.json with dsh.bundle, declared patches, and Cordis apply(ctx) exports, or dsh.bundle.mode set to "patch" for patch-only bundles
Gemini CLIgemini-extension.json, commands/**/*.toml
Kimi Codekimi.plugin.json, .kimi-plugin/plugin.json, declared skills, agents, commands, prompts, and MCP servers
OpenCodeopencode.json, opencode.jsonc, .opencode/commands, .opencode/plugins

Use --ecosystem auto to detect supported packages in a repository, or select an ecosystem explicitly:

plugin-scanner scan ./plugins-repo --ecosystem claude
plugin-scanner scan ./dsh-plugin --ecosystem deepseek-harness

What The Scanner Checks

CategoryCoverage
Manifest validationRequired fields, versions, declared paths, interface metadata, links, and assets.
SecurityHardcoded secrets, unsafe MCP commands and transports, and risky approval defaults.
Operational securityGitHub Actions permissions and pinned dependencies, privileged checkout patterns, Dependabot, and lockfiles.
Plugin packagingREADME and license files, skill frontmatter, ignore rules, and accidentally committed environment files.
MarketplaceManifest validity, local package discovery, and safe source paths.
Skill and MCP analysisAnalyzer availability, findings, and analyzability from optional Cisco integrations.
Code qualityDynamic code execution and shell-injection patterns.

How Trust Scoring Works

Plugin Scanner reports a quality grade alongside trust provenance. Quality scores are normalized across applicable checks, so optional surfaces do not inflate a package's grade.

Skill trust uses the HCS-28 baseline adapter IDs, weights, and denominator rules. MCP and Codex plugin trust use explicit adapters, weights, and contribution modes documented in the local specifications:

CLI Usage

# Structured security report
plugin-scanner scan ./my-plugin --format json --profile public-marketplace

# Inspect authoring rules
plugin-scanner lint ./my-plugin --list-rules
plugin-scanner lint ./my-plugin --explain README_MISSING

# Apply supported mechanical fixes
plugin-scanner lint ./my-plugin --fix --profile strict-security

# Verify package readiness; --online permits live probes
plugin-scanner verify ./my-plugin --format json
plugin-scanner verify ./my-plugin --online --format text

# Generate a submission artifact for one plugin
plugin-scanner submit ./my-plugin --profile public-marketplace --attest dist/plugin-quality.json

# Collect component diagnostics
plugin-scanner doctor ./my-plugin --component mcp --bundle dist/doctor.zip

For a repository marketplace, scan, lint, verify, and doctor can target the root. submit targets one plugin package.

Codex Spec Alignment

The scanner recognizes Codex plugin manifests, interface metadata, declared assets, and marketplace packages:

  • Local manifest paths use ./ prefixes; lint --fix preserves or adds them.
  • .agents/plugins/marketplace.json is the preferred marketplace location, with root marketplace.json supported for compatibility.
  • Interface validation checks declared links and assets without requiring an undocumented type field.
  • verify --online checks HTTP remote reachability. Stdio server execution is skipped for manual review.

See the Codex plugin documentation and Model Context Protocol specification for upstream formats.

Config + Baseline Example

Configure the scanner in .plugin-scanner.toml:

[scanner]
profile = "public-marketplace"
baseline_file = "baseline.txt"
ignore_paths = ["tests/*", "fixtures/*"]

[rules]
disabled = ["README_MISSING"]
severity_overrides = { CODEXIGNORE_MISSING = "low" }

The GitHub Action requires trust_repository_policy: true before repository-owned configuration and baselines can change its verdict. Enable that option only for policy you intend the workflow to trust.

Report Formats

FormatUse
textTerminal summaries with category totals and findings.
jsonStructured reports for scripts and integrations.
markdownReview-ready reports for pull requests and issues.
sarifGitHub code scanning and security automation.

GitHub Action

The AI Plugin Scanner Action supports security gates, SARIF uploads, submission intake, and registry payloads. Its source lives in action/, and the publication workflow distributes the action bundle.

The legacy HOL Codex Plugin Scanner Action remains available for existing workflows.

Plugin Author Submission Flow

Use submission_enabled: true to open or reuse a submission issue when a plugin meets the configured threshold. submission_token must have permission to create issues in the target submission repository. The action emits submission status and issue URLs as outputs.

See the action's input reference for submission_score_threshold, submission_token, and the target repository options.

Registry Payload For Plugin Ecosystem Automation

Set registry_payload_output to write a machine-readable payload for a registry or badge pipeline. The action also exposes score, grade, grade_label, max_severity, and findings_total outputs and can write a job summary.

The HOL Registry Broker plugin is an example of an agent plugin in the HOL Plugin Registry. Its registry listing provides current trust information.

Why HOL Guard

AI agents can run commands, install dependencies, read files, and call external tools within one session. HOL Guard reviews those actions at supported execution points and keeps the policy decision, approval request, and receipt together.

Use it for AI agent security on a developer machine, MCP security around connected tools, and supply-chain checks for packages and plugins. Teams can add Guard Cloud for shared approvals and policy management while retaining local protection.

Frequently Asked Questions

What is HOL Guard?

HOL Guard is open-source antivirus and runtime protection for AI agents. It reviews supported tool calls, shell commands, file access, and package operations for risks such as secret exposure, prompt injection, destructive actions, and malicious dependencies.

Does HOL Guard work without a cloud account?

Yes. Local protection, CLI commands, approvals, and receipts work without signing in. Guard Cloud is optional and adds synchronized evidence, team controls, and fleet visibility. See Local Guard vs. Guard Cloud for the feature boundary.

Which AI agents does HOL Guard support?

Guard includes adapters for Codex, Claude Code, GitHub Copilot CLI, Cursor, Cline, Gemini CLI, Grok, Hermes, Kimi Code, Pi, oh-my-pi, OpenClaw, OpenCode, Antigravity, and ZCode. Paseo is supported through these native provider integrations, with per-provider coverage. The support matrix explains which events and enforcement paths each adapter supports.

What is the difference between HOL Guard and Plugin Scanner?

Install hol-guard to protect agent activity on your machine. Install plugin-scanner to inspect plugin packages and enforce security and quality checks in CI. This repository builds and publishes both distributions.

How does HOL Guard protect MCP servers?

Guard inspects MCP server configuration and reviews supported MCP tool calls through agent hooks and managed proxies. Plugin Scanner checks MCP configuration and HTTP remote reachability; optional Cisco MCP analysis adds static security findings.

Why did Guard pause my command?

The action may need approval under your active policy, or its tools or artifacts may have changed. Start with hol-guard approvals, inspect the command with hol-guard command explain '<command>', and use hol-guard receipts to review the recorded decision.

Documentation

GuideContents
Get startedInstallation, manual setup, package protection, and common commands.
Agent supportIntegration coverage and approval behavior.
ArchitectureRuntime components and decision flow.
Policy specificationGuardPolicy document format.
Policy recipesConfiguration examples for common workflows.
ExtensionsBuilt-in command rules and contribution guidance.
Native extension authoringCanonical JSON sources, the Rust compiler, portable fixtures, and review kits.
Contribute an extensionGenerate, review, integrate, and test a new extension with the CLI.
Local vs. cloudLocal capabilities and optional cloud services.
TroubleshootingDiagnosis and recovery.
SecurityVulnerability reporting and disclosure policy.

Contribute a New Extension

Command extensions are authored as declarative JSON compiled and evaluated by Rust. Add metadata, permissions, matcher trees, and safe variants in contributions/command-sources/command.<name>.json, then verify behavior with portable JSON fixtures. Most extensions compose existing native operations; a new Rust operation is needed only when the existing matcher contracts cannot express the behavior.

ContributionAuthoring inputVerification
Command coveragecontributions/command-sources/command.<name>.jsonPortable fixtures evaluated by guard-command-source test.
MCP server knowledgecontributions/mcp-servers/<id>.jsonMCP contribution tests and native catalog validation.
New matcher semanticsReviewed Rust changes in rust/crates/guard-command/Native contract, admission, evaluation, and regression tests.

The Rust compiler generates command descriptors, the catalog, and the native matcher program. Python remains part of the CLI, build orchestration, and tests; new command coverage does not require a Python detector or registry registration. See the authoring guide for direct source authoring and the architecture for the runtime boundary.

The Extension Builder CLI can create those command sources and portable fixtures from exported command metadata. It also supports MCP inventories. It works offline and reads the export without importing or running the target tool.

Use the Builder's plan-and-apply flow to create the canonical source and fixture. Open a draft PR early for scope review. Before marking that PR ready for review, run scripts/prepare_extension_contribution.py --source ... --fixture ... to synchronize deterministic projections, then run hol-guard extensions handoff --repo . --source ... --fixture .... The handoff check catches missing generated descriptors, catalog entries, and source bindings before final review.

1. Define the coverage in the PR. Check the Extension directory and current open pull requests for existing or overlapping coverage. For a new capability, open a draft PR with the Command extension template and include the proposed command.<name> ID, supported operations, destructive examples, safe counterparts, and upstream references. Scope review happens on the PR; a separate issue is not required. Extend an existing extension when it already owns the operation.

Follow the development setup, then run the examples below from your HOL Guard checkout. uv run --no-sync uses that checkout's installed development version.

2. Generate a contribution kit. This example uses the checked-in, synthetic samplectl inventory. For your own contribution, replace the input and metadata with your tool's export and public publisher details.

uv run --no-sync hol-guard extensions generate --from cli \
  --input docs/guard/extension-builder/examples/cli-surface.json \
  --slug samplectl --executable samplectl --name 'Sample CLI' \
  --publisher community.example --publisher-name 'Example Maintainer' \
  --homepage https://example.test/samplectl \
  --upstream-version 1.0.0 --output samplectl-kit

uv run --no-sync hol-guard extensions validate samplectl-kit

The output directory must be new, with an existing parent directory. A command kit includes discovery.json, review.json, report.json, the canonical JSON source, a portable native fixture, a generated descriptor, and a file manifest. MCP kits contain their contribution metadata and generated Python tests.

Other inputs: --from help reads saved command help; --from click reads a Click Context.to_info_dict() export; --from oclif reads oclif.manifest.json; --from mcp reads a complete exported tools/list result; and --from snapshot replays discovery.json. The cli example above uses normalized guard.cli-surface.v1 JSON.

For MCP contributions, the generator uses --launcher and --package instead of --executable. See the MCP kit example for a complete command and pagination requirements.

3. Review the operations and regenerate. Read report.json and compare the discovered operations with the upstream implementation. Copy the review file before editing:

cp samplectl-kit/review.json samplectl-review.json

Edit samplectl-review.json, keeping its discovery binding and operation IDs intact. CLI operations use review or block; the root operation stays review. Set reviewed: true for entries you have assessed, with rationale and a public HTTPS evidence reference. Add safeArgv only for exact, verified safe invocations. The review format includes a complete entry example.

Recompile the saved snapshot after reviewing it:

uv run --no-sync hol-guard extensions generate --from snapshot \
  --input samplectl-kit/discovery.json \
  --review samplectl-review.json --output samplectl-reviewed

uv run --no-sync hol-guard extensions validate samplectl-reviewed
uv run --no-sync hol-guard extensions diff samplectl-kit samplectl-reviewed

"$HOL_GUARD_NATIVE_SOURCE_COMPILER" test \
  < samplectl-reviewed/artifacts/tests/fixtures/command-source-samplectl.v1.json

diff exits 0 for equal kits and 1 when valid kits differ. The Rust fixture runner evaluates command text without executing it. If the upstream export changes, generate and review a new snapshot.

4. Preview and apply the integration. On your contribution branch, preview the changes to the current checkout:

uv run --no-sync hol-guard extensions apply samplectl-reviewed --repo .

Inspect the listed paths and generated files. Copy the printed plan digest into the following command before running it:

uv run --no-sync hol-guard extensions apply samplectl-reviewed --repo . \
  --expected-plan THE_PRINTED_PLAN_DIGEST \
  --write

The write integrates the canonical source, fixture, generated contribution descriptor, external trust map, packaging, and authoring ownership records. Regenerate the complete program and catalog in the next step. Existing IDs or conflicting files stop integration for review.

5. Test and submit a pull request. Follow the native validation sequence to regenerate the complete catalog, rebuild the compiler and runtime against that program, and run the contribution's fixtures against the integrated sources. This also covers updating an existing extension, where an addition to the packaged baseline would conflict with the existing ID. Then run the contribution checks and regenerate the public directory:

uv run --no-sync python scripts/release/stage_guard_cloud_review_artifacts.py
uv run --no-sync pytest -q \
  tests/test_guard_extension_contribution.py \
  tests/test_guard_extension_trust.py \
  tests/test_native_source_program.py \
  tests/test_guard_command_extension_registry.py
uv run --no-sync python scripts/export_extension_directory.py
uv run --no-sync python scripts/export_extension_directory.py --check
uv run --no-sync python scripts/render_command_extension_directory.py
uv run --no-sync python scripts/render_command_extension_directory.py --check
git diff --check

Add fixture cases for destructive operations, safe previews, aliases, reordered flags, quoting, malformed input, and compound commands. Run the Rust checks when changing native semantics and the relevant Python checks when changing tooling. Inspect the final diff, commit the canonical inputs, generated projections, fixtures, and authoring records, and update the existing draft PR against main with the test results. Mark it ready for review after the handoff check passes. Keep scratch kit directories and raw upstream exports out of the PR.

Community contributions remain External and off by default. Tests must prove they are inert until a local administrator enables them. Generating, applying, or merging a contribution does not activate it, and its rules cannot weaken Guard's required protections.

Full builder reference · Contribution review requirements · External extension contract · Builder validation

Development

The development toolchain includes Python 3.10 or newer, uv, and Rust 1.88.0, pinned in rust/rust-toolchain.toml. Rust builds the native runtime and extension compiler; Python supplies the CLI and development tooling. The commands below use a POSIX shell from the repository root. See CONTRIBUTING.md for Windows setup and the checks for each kind of change.

git clone https://github.com/hashgraph-online/hol-guard.git
cd hol-guard
uv sync --frozen --extra dev
rustup toolchain install 1.88.0 --profile minimal --component rustfmt --component clippy
cargo +1.88.0 build --locked --release --manifest-path rust/Cargo.toml \
  -p guard-command --bin guard-command-source
cargo +1.88.0 build --locked --release --manifest-path rust/Cargo.toml \
  -p hol-guard-runtime

export HOL_GUARD_NATIVE_SOURCE_COMPILER="$PWD/rust/target/release/guard-command-source"
export HOL_GUARD_NATIVE_TEST_SOURCE_COMPILER="$HOL_GUARD_NATIVE_SOURCE_COMPILER"
export HOL_GUARD_NATIVE_BINARY="$PWD/rust/target/release/hol-guard-runtime"

uv run --no-sync python scripts/build_native_command_program.py \
  --compiler "$HOL_GUARD_NATIVE_SOURCE_COMPILER" --check
uv run --no-sync pytest tests/test_guard_extension_builder_public_docs.py \
  tests/test_native_source_program.py --tb=short

Those compiler overrides are for an editable checkout. Installed native wheels use their bundled compiler and verify its manifest. After changing canonical sources or Rust semantics, regenerate the projections and rebuild as described in the validation guide.

For Python tooling and package changes:

uv run --no-sync ruff check src tests
uv run --no-sync ruff format --check src tests
uv build

For optional Cisco coverage, use the dependency group command above. See CONTRIBUTING.md for contribution requirements and the testing matrix for integration tests.

Resources

Community

Maintained by Hashgraph Online.

License

Licensed under Apache-2.0.

Collected info

  • 627 stars
  • 73 forks
  • Language: Python
  • Source updated: 9/19/2026

Config for your environment

Replace {MCP_ENDPOINT_URL} with this MCP’s endpoint URL (from its repo or docs above). No API key — you connect directly.

Tool

OS

Config file: ~/.cursor/mcp.json

{
  "mcpServers": {
    "mcp-server": {
      "url": "{MCP_ENDPOINT_URL}"
    }
  }
}

Paste into mcpServers in the config file. Restart Cursor after saving.

If this MCP is also published on mcpchannel.ai, you can subscribe from Browse and use the gateway config there instead.