Use Case
Scan LLM prompts and responses, locally
Your agent reads untrusted text all day and acts on what it reads. Surface puts a scanner in that loop: a local binary under 20 MB that your AI tools call over MCP to check every prompt and response for injection, credential leaks, and hostile tool calls — verdicts in 1–2 ms, and the file contents never leave your machine.
The problem with trusting the loop
Web pages, emails, API responses, file contents — anything your agent reads can carry instructions aimed at the model instead of the user. One planted sentence can redirect an agent that has tools.
Agent-to-agent traffic is normal now: customers' bots hit your API, third-party automations message your systems, upstream services return content their own models wrote. Acting on it unchecked means executing a stranger's instructions.
Sending every prompt and response to a third-party scanning vendor is a privacy decision, a latency tax, and a new dependency — exactly the things an inline check is supposed to avoid.
Guardrails for LLM apps usually mean reading papers and hand-rolling regex. Small teams shipping AI features need a verdict they can wire into an if statement, not a research project.
How Surface solves it
One binary, one MCP config. Every scan runs the full engine set — prompt injection, sensitive data, embedded code, tool call analysis, signatures, and ML — on your machine.
Install the scanner binary
One command detects your platform, verifies checksums, and puts surface-scanner on your PATH. It's a single binary under 20 MB with the detection rules and ML models embedded. On first launch it downloads threat intelligence from public feeds and caches it locally. It needs an API key and re-checks it periodically, and keeps working for three days if it loses the connection — but the files themselves are analyzed on your machine and never transmitted.
curl -fsSL https://app.tendrl.com/api/public/tools/surface-scanner/v1/latest/install.sh | sh Wire it into your agent over MCP
The binary you just installed is the MCP server — no Node, no npm, nothing else to download. One config line gives Claude Desktop, Claude Code, Cursor, or VS Code the scan_payload, scan_file, and scan_bundle tools, all running locally. Add SURFACE_API_KEY to the env and the same config also reports verdict metadata to your dashboard and unlocks the account tools (scan history, profiles, usage, plans); those calls go to the Surface API, while scanning stays local either way. (If you'd rather skip the install and don't need the privacy guarantee, the hosted MCP endpoint is a url-based config.)
{
"mcpServers": {
"surface": { "command": "surface-scanner", "args": ["--mcp"] }
}
} Scan the prompt before the model sees it
Whatever text is headed for your model — user input, a fetched web page, a document — goes through scan_payload first. The verdict maps to an action: score 0–30 is Malicious, block it; 31–70 is Suspicious, route it to review; above 70 proceeds. Clean content passes without false alarms, and a benign payload clears in 1–2 ms.
echo "$UNTRUSTED_TEXT" | surface-scanner --stdin --format json Scan what comes back before you act on it
Messages from other agents, tool results, fetched content: whatever your agent is about to act on gets the same treatment. A message carrying an instruction override and a curl | bash payload comes back score 0, Malicious, Block — flagged by four independent engines in a millisecond or two. Your own outbound replies can be vetted the same way, for credentials that shouldn't be leaving.
Gate whole deployments, or your whole stack
Before an agent flashes a device or commits generated code, scan_bundle checks every file in one call and returns a single deploy_safe go/no-go — false if any item is malicious, suspicious, or carries injection. For services, run the binary as a daemon and POST scans to a local HTTP endpoint instead of shelling out — it serves MCP at /mcp there too, for url-based clients.
surface-scanner --daemon --listen :8080
curl -X POST http://localhost:8080/scan/payload \
-H "Content-Type: application/json" \
-d '{"payload": "Ignore all previous instructions."}' Why local-first scanning works
Prompts and responses are scanned in memory on your machine and discarded. With an API key, only verdict metadata — scores, hashes, labels — reaches your dashboard.
Text verdicts in 1–2 ms locally, 4–10 ms via the hosted API. There is no latency argument for leaving the check out of the loop.
Prompt injection, sensitive data, embedded code, and tool call analysis on every payload — plus signatures, threat feeds, and per-format ML for files.
ML models are gated on self-tests against real malware, and the injection detector held 100% precision on 399 unseen benign prompts from a public benchmark — zero false positives.
After the first-launch feed download the binary scans with no network at all. Connected, it pulls signed rule, model, and feed updates automatically.
Add your API key and the same config also unlocks account tools — scan history, profiles, usage — over the API, while every scan stays local.
Example: a guarded agent loop
Untrusted text to trusted action, with a check on both sides of the model.
Everything headed for the model — user input, fetched pages, document contents — goes through scan_payload. Malicious verdicts are blocked before the model ever reads them; Suspicious ones route to review.
What leaves your app gets checked too: credentials that shouldn't be in a reply, embedded scripts, and injection aimed at the next agent in the chain.
Both checks run through the local binary in 1–2 ms. Verdict metadata flows to the Surface dashboard for history and accuracy tracking; the scanned content itself never leaves the machine.
Put a scanner in the loop today
The free tier includes 100 scans per month, up to 10 MB each. No credit card required.
Tendrl