// SIGN IN TO CONTINUE
Single sign-on required
The documentation is available to signed-in users. Sign in with any provider — it's free.
Drive it from an AI agent (MCP)
// scan → fix → rescan, hands-offNewScan ships an MCP server mounted on the running app, so any MCP-capable AI agent (Claude Code, Claude Desktop, or your own client) can start scans, read the results, and — because the same agent also edits your codebase — fix the issues it finds and rescan to confirm, looping until every finding is resolved, proven a false positive, or deferred. The MCP tools reuse the exact same handlers as the HTTP API and web console, so nothing behaves differently here.
1 — START NEWSCAN
Run NewScan the usual way (Docker Desktop → run the app). It serves the console and the MCP endpoint on the same port. The MCP server lives at /mcp over the streamable-HTTP transport; confirm the app is healthy first.
$ docker compose up # or double-click the app; opens http://localhost:9700 $ curl http://127.0.0.1:9700/api/health {"ok":true,"version":"…","has_key":true}
2 — CONNECT THE MCP SERVER TO YOUR AGENT
Point your agent at the endpoint. With Claude Code it's one command:
$ claude mcp add --transport http newscan http://127.0.0.1:9700/mcp
For any other MCP client, add an HTTP / streamable-HTTP server with URL http://127.0.0.1:9700/mcp. The bare path 307-redirects to /mcp/ — every compliant client follows it automatically. On the default loopback bind no transport auth is needed; if you expose the port, put it behind a reverse proxy or bearer token, and optionally restrict targets with the NEWSCAN_MCP_ALLOW_HOSTS environment variable.
3 — SET UP THE AI LAYER (OPTIONAL)
NewScan runs its full deterministic scan with no AI at all — the quick and baseline profiles need no key and no setup, and they still run every algorithmic detector. AI is an optional second pass that escalates near-misses with target-crafted payloads. The full and safe profiles use it, so pick one of these two options before asking your agent for a full scan:
- Bring your own key (BYOK) — open the console's Settings panel and paste a provider key (Anthropic, OpenAI, Google, …), or put it in .env. Keys stay on your machine; you are billed by that provider. Settings values take effect immediately, no restart.
- NewScan AI (hosted, metered) — no provider account needed. Enroll from Settings → NewScan AI; calls run through our gateway and are billed to your card monthly against a spend cap. Nothing else changes: same scans, same tools.
Either way the agent doesn't pass a key — it just names a profile. Check what's active before scanning:
$ curl http://127.0.0.1:9700/api/health {"ok":true,"version":"…","model":"…","has_key":true} # has_key:false → use profile quick|baseline
4 — THE TOOLS YOUR AGENT GETS
Thirteen tools cover the whole lifecycle:
- start_scan — launch a scan; returns a run_id immediately (scans run for minutes in the background).
- get_scan_status — poll status + live counts until it's completed.
- get_findings — the flattened findings + observations (each with an id, severity, evidence, and location).
- get_report — the full report as json, sarif, md, csv, xlsx, or har (includes the pass/fail severity gate).
- mark_false_positive — resolve an item the agent has triaged as not-real; it's suppressed from findings, every report, and the gate.
- create_tickets — file the run's still-open findings into your GitHub or Jira (Pro; set the destination once on your account page). Re-filing updates existing tickets instead of duplicating.
- list_scans / cancel_scan — enumerate history/in-flight runs and stop one early.
- proxy_start / proxy_status / proxy_stop / proxy_reset / proxy_setup — capture real traffic through a proxy first (browse the app while signed in), then scan exactly that surface with the identity it captured.
5 — START AN (AUTHENTICATED) SCAN
Just tell your agent what to scan — e.g. "scan http://localhost:3000 in web mode, authenticated, and find the vulnerabilities." It calls start_scan. Pass every credential up front in the auth list so a scan never blocks on a prompt. Supported type values: bearer, api_key, basic, oauth2, login (form/SPA), and hmac.
# arguments the agent sends to start_scan { "target": "http://localhost:3000", "scan_mode": "web", # api | web | network | host | wifi | segmentation "profile": "full", # full | safe | quick | baseline (quick/baseline need no AI key) "goal": "Find and help me fix the security issues.", "auth": [ { "type": "bearer", "name": "user", "role": "user", "token": "eyJhbGci…" }, { "type": "oauth2", "name": "admin", "role": "admin", "token_url": "/oauth/token", "grant_type": "client_credentials", "client_id": "…", "client_secret": "…" } ] } # → returns immediately: { "run_id": "56e2eda6…", "model": "…" }
6 — WATCH IT, THEN READ THE RESULTS
The agent polls get_scan_status with the run_id until the status is completed, then pulls the results. Every finding carries an id, a calibrated severity, the exact location, and the evidence/reproduction that proved it — enough for the agent to act without guessing.
# get_scan_status → { "status": "completed", "counts": { "findings": 3, … } } # get_findings → each item: { id, title, severity, category, cwe, where, detail, evidence } # get_report(json) also returns the gate: { "gate": { "fail": true, "worst_rank": 4 } }
7 — LET THE AGENT FIX THE CODE & RESCAN (THE LOOP)
This is the point of driving NewScan from an agent: it doesn't just report — it fixes. Give it your repo and let it run the loop until the gate passes:
- 1. Read a finding (title, location, evidence).
- 2. Reproduce it against the running target to confirm it's real (not a false positive).
- 3. Edit the source to fix the root cause.
- 4. Redeploy / restart the target so the fix is live.
- 5. Call start_scan again and confirm the finding is gone and nothing regressed.
- 6. Repeat until get_report's gate reads fail: false.
A prompt that kicks the whole thing off: "Using the newscan MCP server, scan this app authenticated, then fix each real finding in the code and rescan until they're all resolved or a proven false positive."
8 — RESOLVE FALSE POSITIVES
When the agent triages a finding as not-real, it calls mark_false_positive with the finding id(s) and a note. The mark persists for that run and drops the item from get_findings, every export, and the severity gate — so a clean gate means "no unresolved real findings," not "nothing was flagged."
# mark_false_positive { "run_id": "56e2eda6…", "finding_ids": ["7343c054fd56"], "note": "reflection is JSON-only, not executed" } # → { "ok": true, "gate": { "fail": false, … } }
9 — HAND THE REST TO YOUR TEAM (TICKETS)
Findings the agent can't fix itself — a config change, a vendor bug, a deliberate risk decision — belong with a human. create_tickets files everything still open into your GitHub Issues or Jira, so triage is the selection: anything the agent resolved via mark_false_positive is left out. Each ticket carries the evidence, a curl reproduction, remediation and the triage note, and re-filing after a rescan updates the existing ticket instead of duplicating it.
Requires NewScan Pro and a destination picked once at Account → Settings → Integrations (one system at a time). Without that setup the tool returns an error naming the missing step and files nothing.
# create_tickets { "run_id": "56e2eda6…" } # → { "provider": "github", "results": [ { "id": "…", "action": "created", "key": "#42", "url": "…" } ] }
10 — GUARDRAILS
Every scan is scope-locked to the target you give it and bounded by hard caps (token budget, iteration cap, a doom-loop guard). The MCP server adds a global concurrent-run limit (NEWSCAN_MCP_MAX_RUNS, default 3) and an optional target allow-list (NEWSCAN_MCP_ALLOW_HOSTS). NewScan is an offensive tool: only point it at systems you own or are explicitly authorized to test.