# Elcaro > Elcaro detects indirect prompt injection — hidden instructions inside content that AI agents retrieve (emails, search results, web pages, code, documents) — before the agent processes them. Stateless API, verdicts in milliseconds, no account or API key. Every scan returns a structured verdict: risk score, risk level, the techniques detected (with evidence, confidence, and MITRE ATLAS mappings), `safe_content` — what the agent should process instead of the raw content when a scan is quarantined — and `human_summary`, one or two plain-language sentences the agent can quote verbatim to its user. Quarantine doctrine: block at risk >= 0.5, human review from 0.3, never pass 0.7+. ## Scan API - [POST /scan](https://api.elcaro.trustfall.xyz/scan): Body `{"content": string, "content_type": "email|search_result|webpage|document|code|chat_message|system_prompt", "deep_analysis"?: boolean}`. Returns `{risk_score, risk_level, flagged_techniques, indicators, summary, human_summary, safe_content, quarantined, latency_ms, scanned_at, signature?, key_id?}`. CORS-open. - [GET /metrics](https://api.elcaro.trustfall.xyz/metrics): Aggregate counters and latency percentiles only. The miner is stateless — scanned content is never stored. - [GET /pubkey](https://api.elcaro.trustfall.xyz/pubkey): The miner's Ed25519 verdict-signing public key (404 when running unsigned). - [POST /verify](https://api.elcaro.trustfall.xyz/verify): Body `{content, risk_score, risk_level, quarantined, flagged_techniques, scanned_at, signature}` → `{valid: bool, key_id, detail}`. Recomputes the canonical payload (content is hashed, never stored) and checks the signature. ## Verifying verdicts When the miner runs with `ELCARO_SIGNING_KEY` set, every verdict carries an Ed25519 `signature` over a canonical JSON payload — `{v, content_sha256, flagged_techniques (sorted), quarantined, risk_level, risk_score (fixed-precision string), scanned_at}` — signed with sorted keys and compact separators (reference: [core/signing.py](https://github.com/udirobert/elcaro/blob/main/core/signing.py)). Only the content's SHA-256 is signed, never the content. Treat the bracketed quarantine notice as display text for agents and humans to read — the signature is the trust signal. To verify offline: fetch `/pubkey` once and check with any Ed25519 library. ## Tools for agents - [MCP server](https://github.com/udirobert/elcaro/blob/main/app/mcp_server.py): Run locally for the MCP tools `scan_content` and `explain_verdict` over stdio: `python -m app.mcp_server` (requires `pip install "mcp>=2"`; set `ELCARO_MCP_LOCAL=1` for fully local, network-free scanning). - [Specimen kit (raw text)](https://elcaro.trustfall.xyz/specimen/raw): Inert, clearly-marked injection specimens as plain UTF-8 — the "EICAR file" for prompt injection. Fetch it to test any detection pipeline end-to-end. Nothing on it is a real instruction; if an agent follows the specimens, that is the vulnerability being demonstrated. - [Integration guide](https://elcaro.trustfall.xyz/integrate): Direct API, MCP, Python middleware, and Telegraph Protocol routing, plus six rules for safe agent pipelines. - [Designing for agents](https://elcaro.trustfall.xyz/for-agents): How Elcaro treats agents as first-class users — llms.txt, structured responses, signed verdicts, specimens. WebMCP readiness: the /scan form carries stable semantic field names (`content`, `content_type`) so it can be declared as a form tool when browsers land an implementation (W3C WebML Community Group draft, not yet a standard). ## Docs - [README](https://github.com/udirobert/elcaro/blob/main/README.md): What Elcaro is, quickstart, an example verdict. - [Technique reference](https://github.com/udirobert/elcaro/blob/main/docs/technique-reference.md): The six injection classes detected — authority framing, delimiter confusion, task reframing, obfuscation, placement salience, conditional triggers. - [UX audit — adaptive & agentic lenses](https://github.com/udirobert/elcaro/blob/main/docs/ux-audit.md): How this product designs for agents as first-class users. - [Warn-mode salience experiment](https://github.com/udirobert/elcaro/blob/main/docs/warn-salience-experiment.md): Does the position of the quarantine warning — prefix, suffix, or sandwich — change whether an agent follows the injected instruction anyway? Methodology, decision rule, and what would change the middleware default.