Andy Mal
Antimalware for agents. Your AI virus analyst, on call 24/7.
Coding agents install packages, clone repos, open attachments and follow README instructions hundreds of times a day. Signature-based antivirus is written by human analysts days after a sample appears, and AI-written malware never had a signature. Andy reverse-engineers every file, package and instruction your agent is about to act on, in real time, before it runs.
Every scan returns two verdicts:
- payload: what the file does when opened, installed or executed (credential theft, exfiltration, download-and-execute, persistence, obfuscation, install-time decryption)
- delivery: whether the agent was socially engineered or prompt-injected into opening it (hidden instructions, forged system messages, tool poisoning in MCP servers and skills, "ignore previous instructions")
This repository is the open-source client, the integrations, and the benchmark. The analysis engine runs
at api.andymal.com and is not part of this repo. Website: https://andymal.com
Install
pip install andymal
curl -X POST https://api.andymal.com/v1/register -F email=you@example.com -F agent=claude-code # free key
export ANDY_API_KEY=andy_...
Free tier: 50 scans a day, 30 a minute, unlimited hash lookups.
Use
andy scan invoice.pdf --context-file email.txt # a file, plus what the agent was told
andy scan pypi:requets # a package, before installing it
andy scan npm:lodahs@latest
andy scan ./cloned-repo # a directory (zipped and scanned as one sample)
cat README.md | andy scan - # any text that asks the agent to do something
andy scan --json ... # machine-readable
Exit codes: 0 clean, 1 suspicious, 2 malicious, 3 unknown or error. Hash first: the client sends a
SHA-256 before uploading; anything Andy has seen returns in milliseconds.
MCP server (Claude Code, Claude Desktop, Cursor, Hermes, OpenCode, any MCP client)
{"mcpServers": {"andy": {"command": "andy-mcp", "env": {"ANDY_API_KEY": "andy_..."}}}}
Tools: andy_scan_file(path, context), andy_scan_package("npm:name@ver" | "pypi:name==ver"),
andy_check_text(text, source), andy_report(scan_id). See integrations/mcp.
Claude Code hook
Automatically checks pip install, npm install, npx and curl | bash before they run, and blocks on
malicious. See integrations/claude-code.
Verdict shape
{"verdict": "malicious", "action": "block", "confidence": 0.95,
"summary": "Postinstall decrypts an embedded blob, compiles it with bytenode and deletes the source ...",
"payload": {"verdict": "malicious", "score": 0.95, "findings": [...]},
"delivery": {"verdict": "clean", "score": 0.0, "findings": []},
"iocs": {"urls": [], "domains": [], "ips": [], "paths": []},
"report_url": "https://api.andymal.com/report/<id>"}
action is what your agent should do: allow, isolate (run only in a throwaway sandbox without
credentials), or block. A result with extra.degraded: true was produced by heuristics only because the
analyst model was unavailable; treat it as advisory.
Benchmark
bench/ is a labelled, reproducible benchmark you can run against the public API with your own key:
python bench/run.py # synthetic samples in bench/samples
python bench/fetch_real.py --npm 12 --pypi 12 --skills 6 --benign 16 --inject 20
python bench/run.py bench/real/manifest.json # real samples (see below)
fetch_real.py pulls malicious npm/PyPI packages and malicious agent skills from
DataDog/malicious-software-packages-dataset,
benign top packages from the registries, and prompt-injection texts from deepset/prompt-injections.
Samples are never executed anywhere; Andy's analysis is static plus an AI analyst. Downloaded samples stay
in the gitignored bench/real/.
Current numbers on that set (2026-09-04): 55/64, zero false positives, 24/24 malicious packages, 5/6 malicious skills; the misses are deepset entries that are not attacks on an agent ("write c++ code"). Send a PR with cases Andy gets wrong: that is the most useful contribution.
Contributing
Client code, integrations for other agents, and benchmark cases are welcome. Issues about detection quality should include the scan id or report URL. MIT licensed.
Metadata
Release files for andymal 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| andymal-0.2.0.tar.gz | 17.3 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| andymal-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 26.5 kB
Release files / andymal-0.2.0.tar.gz
| Download URL | andymal-0.2.0.tar.gz |
|---|---|
| Size | 17.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
dc61ab8d2e306e3065197165d5b8b78845ae8be0ccc3fe74ce208c7094719c2a
|
|
BLAKE2b-256 checksum How to use checksums |
0746439413cfe54315a8458698a75ac3be5e4aeff85afc759d6c36c9534090c4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.7.12
|
Release files / andymal-0.2.0-py3-none-any.whl
| Download URL | andymal-0.2.0-py3-none-any.whl |
|---|---|
| Size | 9.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
9e6d9300a09ea71a0dce0ed1d5c1beb8fa382ab5b9ad347af75688550c2d7a12
|
|
BLAKE2b-256 checksum How to use checksums |
603c4d4f446776d0c19479bbe676e92ae28570bf3466f9934f772f4483dcc226
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.7.12
|
Security for andymal 0.2.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.