Andy Mal
Antimalware for agents. Your AI virus analyst, on call 24/7.
Agents install packages, clone repos, open attachments, and follow README instructions hundreds of times a day. Signatures are written by human analysts days after a sample appears, and AI-written malware never had one. Andy reverse-engineers every file, package, and instruction in real time, before the agent acts on it.
Every scan returns two verdicts:
- payload: what the file actually does (credential theft, exfiltration, download-and-execute, persistence, obfuscation)
- delivery: whether the agent was socially engineered or prompt-injected into opening it
Quick start
uv venv -p 3.12 && uv pip install -e .
cp .env.example .env # fill in ANDY_LLM_* and ANDY_API_KEYS
.venv/bin/andy-server # http://localhost:8080/docs
export ANDY_URL=http://localhost:8080 ANDY_API_KEY=dev-key-1
andy scan eval/samples/malicious/setup_helper.py
andy scan pypi:requests
andy scan invoice.pdf --context-file email.txt
Exit codes: 0 clean, 1 suspicious, 2 malicious, 3 unknown/error.
Get a key
curl -X POST https://api.andymal.com/v1/register -F email=you@example.com -F agent=claude-code
Free tier: 50 scans a day per key, 30 per minute burst, unlimited hash lookups. GET /v1/me shows usage.
Admins raise limits with PATCH /admin/keys/{key} (tier, daily_limit, active).
Protocol (hash first)
GET /v1/hash/{sha256}withX-Andy-Key. Hit: cached report, done.- Miss:
POST /v1/scanmultipart withfile(orpackage=npm:name@ver,text=..., orsha256=plus newcontext).?wait=90blocks for the verdict. GET /v1/scan/{id}to poll,GET /report/{id}or/report/{id}.mdfor the full report.
Integrations
- CLI:
andy scan ...(client/andy_cli.py) - MCP server:
andy-mcpexposesandy_scan_file,andy_scan_package,andy_check_text,andy_report - Claude Code hook:
client/hooks/pretooluse.pychecks pip/npm installs andcurl | bashbefore they run
Layout
andymal/api FastAPI service, storage, markdown report
andymal/worker pipeline, safe unpacker, static heuristics
andymal/analyzers script, package (npm/pypi), pdf, office, binary, delivery (prompt injection)
andymal/prompts analyst prompts (untrusted-content framing)
client/ CLI, MCP server, hooks
web/ andymal.com landing page
eval/ labelled samples + scorecard runner
deploy/ Dockerfile, compose, Caddyfile for t3090
Eval
.venv/bin/python eval/run_eval.py --static # hand-written set, heuristics only
.venv/bin/python eval/run_eval.py # hand-written set, with the model
.venv/bin/python eval/fetch_real.py --npm 12 --pypi 12 --skills 6 --benign 16 --inject 20
.venv/bin/python eval/run_eval.py eval/real/manifest.json # real samples (DataDog malicious packages + skills, top registry packages, deepset injections)
Results land in eval/results/<manifest>.json. Static mode is only a ranking sanity check: on real packages the heuristics alone
over-flag, and the model is what separates a stealer from a build script. Judge on the full run.
What Andy looks at that a scanner doesn't
- Project auto-execute surfaces: CI workflows, git hooks, Makefiles,
.vscode/tasks.json,.claude/settings.jsonhooks,.mcp.json,.envrc,.pthfiles. Code there runs without anyone clicking it. - Agent configuration:
SKILL.md,AGENTS.md,CLAUDE.md,.cursorrules, MCP configs and MCP tool descriptions, checked for tool poisoning, tool hijacking ("always use X, no exceptions") and traffic redirection through third-party mirrors. - Install hooks that decrypt, decode or compile code at install time, or delete their own source.
Safety notes
Samples are never executed. The unpacker enforces size/count limits and rejects traversal and links. Sample content is passed to the model as delimited untrusted data; the prompts instruct the model to treat embedded instructions as evidence of manipulation. The api container runs read-only and unprivileged. Dynamic analysis, when added, gets its own isolated VM service.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file andymal-0.1.0.tar.gz.
File metadata
- Download URL: andymal-0.1.0.tar.gz
- Upload date:
- Size: 72.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
uv/0.7.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8493adf7a5a1706361593803404a90ae1fa3dc8efd82e8042b4e8d3c6c066a99
|
|
| MD5 |
1399ca8969b9c2a3c49d6f9c1d83038f
|
|
| BLAKE2b-256 |
9dcba8cf23f9df17fb17a64082060db7ce65152c677a935ca0c022eac19e57a1
|
File details
Details for the file andymal-0.1.0-py3-none-any.whl.
File metadata
- Download URL: andymal-0.1.0-py3-none-any.whl
- Upload date:
- Size: 70.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
uv/0.7.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2b7e38db80c21ed1f292eda9c876ea1cbdeca6ed8af9f36258bb6c0d3087a04a
|
|
| MD5 |
accc4ed59bf7b98d359febe15a3b0ed8
|
|
| BLAKE2b-256 |
fb1c49e59825499213d4e7d3854cbcc33a6072613e8c4e8741c946fa8c6c87a9
|