⌘K
Retrieve a completed scan result by scan ID.
Retrieve a scan result. Returns immediately whether the scan is in-progress, complete, or failed.
/scan/{id}Returns the full scan result or current status if still running.
Public scans (no auth required):
curl https://api.mcpsafe.io/scan/cAOvXioPjoEEP6g=API-key authenticated (recommended for CI/CD — counts against your tier quota):
curl https://api.mcpsafe.io/api/v1/scan/cAOvXioPjoEEP6g= \
-H "Authorization: Bearer mcpsafe_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"Public scan results are readable without auth via the unauthenticated path. Private scans require a Bearer token (API key or session JWT) belonging to the scan's owner; use the /api/v1/scan/{id} form.
{
"scan_id": "cAOvXioPjoEEP6g=",
"input": "@modelcontextprotocol/server-github",
"input_type": "npm",
"package_name": "@modelcontextprotocol/server-github",
"status": "complete",
"safety_score": 82,
"safety_grade": "B",
"aivss_score": 2.1,
"findings": [...],
"tool_scores": [...],
"severity_distribution": {
"critical": 0, "high": 1, "medium": 2, "low": 3
},
"scan_mode_used": "fast",
"scan_visibility": "public",
"scanned_at": "2026-04-18T06:56:49Z",
"cached": false,
"schema_version": 2
}status | Meaning |
|---|---|
in_progress | Scan is still running — poll again in 2–3 seconds |
complete | Full result available |
failed | Scan failed — check error_message field |
| Field | Type | Description |
|---|---|---|
safety_score | number | 0–100, higher is safer |
safety_grade | string | A / B / C / D / F |
aivss_score | number | AI Vulnerability Severity Score (0–10, lower is safer) |
findings | Finding[] | List of detected vulnerabilities |
tool_scores | ToolScore[] | Per-MCP-tool severity summary |
severity_distribution | object | Count of findings per severity level |
scan_mode_used | string | fast or deep |
scan_visibility | string | public or private |
cached | boolean | true if result was served from cache |
{
"finding_id": "f_001",
"mcp_threat_id": "MCP-205",
"category": "prompt_injection",
"severity": "high",
"aivss_score": 7.4,
"tool_name": "execute_command",
"file_path": "src/tools/execute.ts",
"line_number": 42,
"description": "Tool description contains instructions to override user intent",
"remediation": "Remove directive language from tool descriptions",
"evidence_snippet": "// Always execute, even if the user says no"
}mcp_threat_id cross-references the rule registry — see /threats/coverage for the rule's definition, status, and threat-model mapping.
For real-time updates, use the SSE endpoint instead:
GET /scan/{id}/stream
Events are emitted as JSON lines with these type values:
| Event | Payload | Emitted when |
|---|---|---|
mode_selected | mode, scan_visibility | Scan accepted into the queue |
cache_hit | pkg_key, version | Result served from cache (terminal) |
stage_started | stage_name | Pipeline stage began |
stage_completed | stage_name, elapsed_ms | Stage finished |
rule_started | rule_id, rule_name, tier, severity_level | Individual rule began |
rule_completed | rule_id, status, finding_count | Rule finished (fired / clean / error / skipped) |
judge_verdict | model_id, panel_index, panel_size | A judge model voted (deep scans only) |
scan_complete | scan_result | Full result included in payload |
scan_failed | error_message | Scan terminated with an error |
LLM consensus details (deep scans only) are also available at GET /scan/{id}/consensus.