Run it from a URL, or from inside your editor
Assay checks a live app from the outside — no login to your app, no access to your code. You can point it at a URL yourself, or let the coding agent you’re already working with call it before the app ships.
From the web
Paste your live app’s URL at /try. No account needed for a first verdict. The scan runs in front of you and takes about a minute. Every issue comes back in plain language with the exact instruction to paste back into your builder.
From your editor (MCP)
Assay is a Model Context Protocol server. Point Claude Code, Cursor, or any MCP client at it and your agent can ask “is this safe to publish?” directly — before the app ships, instead of on a website afterwards.
This is the independence argument at its sharpest: the model that wrote the code doesn’t get to decide the code is safe. It has to ask something that isn’t it.
1. Create a key
Sign in and go to Settings → API keys. Keys start with assay_sk_ and are shown once. A key authenticates one account and can never read another’s history.
2. Add the server
Streamable HTTP transport, bearer auth. In Claude Code:
claude mcp add --transport http assay https://assaysecurity.com/api/mcp \
--header "Authorization: Bearer assay_sk_your_key_here"Or, for any client that takes a JSON config:
{
"mcpServers": {
"assay": {
"type": "http",
"url": "https://assaysecurity.com/api/mcp",
"headers": {
"Authorization": "Bearer assay_sk_your_key_here"
}
}
}
}3. The tools
- check_app_security
- Security scanner for vibe-coded and AI-built web apps. Scans a live app built with Lovable, Bolt, Replit, v0, Cursor, or any AI coding tool and finds the security holes these apps ship with: secrets and API keys exposed in the browser bundle (Stripe keys, Supabase service-role keys), a database readable without a login (Supabase row-level security disabled, Firebase rules left open), public file storage, exposed .env and .git files, and missing security headers. Returns a verdict, a 0-100 safety score, and for each issue a plain-English explanation plus the exact instruction to fix it. Use this before deploying or publishing an app, when the user asks whether their app is safe or secure, or when they ask about Supabase RLS, exposed keys, or leaked credentials. Read-only: it never writes, never exploits, and never stores the app's data. Takes about a minute. Only scan apps the user owns.
- get_last_result
- Look up the most recent Assay security check for an app the user has scanned before, without running a new one. Instant and free — it spends no scan allowance. Use this when the user asks about an app's known security state, when they want to compare against a previous result, or to avoid re-scanning something checked moments ago.
A scan counts against your plan’s allowance exactly as a web scan does. get_last_result is free and instant, so an agent can check a known state without spending one.
Proving a fix actually worked
Every finding in a report has a re-check button. It runs just that one check against the live app again and tells you whether the issue is actually gone — usually a single request, so it’s fast enough to use as a loop while you’re fixing things.
This matters for the same reason the rest of the product does. You can’t confirm your own fix any more than you can clear your own app — “I applied the change” is not the same as “the hole is closed.” The re-check is what turns one into the other.
What it checks
- Secrets in the browser bundle
- The JavaScript your app ships is public. Assay reads it the way anyone can and looks for credentials that shouldn't be there — Stripe secret keys, Supabase service-role keys, API tokens. It records the type and a redacted location, never the value.
- A database anyone can read
- The most common failure in AI-built apps: Supabase row-level security left off, or Firebase rules still in test mode, so every row is readable without a login. Assay probes this read-only and tells you which tables are open.
- Open file storage
- Public buckets that were meant to be private — uploads, avatars, documents — reachable by anyone with the URL.
- Exposed config files
- A committed .env, an exposed .git directory, a backup left in the web root. Bounded GETs for the handful of paths that leak most often.
- Missing security headers
- The response headers a published app is meant to send and a generated one usually doesn't.
What it doesn’t do
Assay reads. It never writes. No exploit is sent, nothing is changed, and your users’ data is never copied or stored — when a check proves a database is readable, the values are masked in memory and never saved.
It checks what any visitor can already reach, so it does not log in and does not see anything behind your sign-in screen. It is a bounded automated check for known misconfigurations — not a penetration test, and not a guarantee. The full list of what it misses is written down.
Scan only apps you own or are authorized to test — see our Acceptable Use Policy.
Ready? Scan your app →