Metadata-Version: 2.5
Name: andymal
Version: 0.1.1
Summary: Andy Mal - antimalware for agents. Scan files, packages and instructions with a real-time AI virus analyst before your agent acts on them.
Project-URL: Homepage, https://andymal.com
Project-URL: Documentation, https://api.andymal.com/docs
Author-email: Andy Mal <hello@andymal.com>
License-Expression: MIT
License-File: LICENSE
Keywords: agents,malware,mcp,prompt-injection,security,supply-chain
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Security
Requires-Python: >=3.10
Requires-Dist: fastapi>=0.115
Requires-Dist: httpx[socks]>=0.27
Requires-Dist: mcp<2,>=1.2
Requires-Dist: oletools>=0.60
Requires-Dist: openai>=1.40
Requires-Dist: pefile>=2023.2.7
Requires-Dist: psycopg[binary]>=3.1
Requires-Dist: puremagic>=1.20
Requires-Dist: pydantic-settings>=2.3
Requires-Dist: pydantic>=2.7
Requires-Dist: pypdf>=4.2
Requires-Dist: python-multipart>=0.0.9
Requires-Dist: rich>=13.7
Requires-Dist: socksio>=1.0
Requires-Dist: sqlalchemy>=2.0
Requires-Dist: typer>=0.12
Requires-Dist: uvicorn[standard]>=0.30
Provides-Extra: dev
Requires-Dist: pytest>=8; extra == 'dev'
Description-Content-Type: text/markdown

# 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

```bash
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

```bash
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)

1. `GET /v1/hash/{sha256}` with `X-Andy-Key`. Hit: cached report, done.
2. Miss: `POST /v1/scan` multipart with `file` (or `package=npm:name@ver`, `text=...`, or `sha256=` plus new `context`). `?wait=90` blocks for the verdict.
3. `GET /v1/scan/{id}` to poll, `GET /report/{id}` or `/report/{id}.md` for the full report.

## Integrations

- CLI: `andy scan ...` (`client/andy_cli.py`)
- MCP server: `andy-mcp` exposes `andy_scan_file`, `andy_scan_package`, `andy_check_text`, `andy_report`
- Claude Code hook: `client/hooks/pretooluse.py` checks pip/npm installs and `curl | bash` before 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

```bash
.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.json` hooks, `.mcp.json`, `.envrc`, `.pth` files. 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.
