vt_url
Submit a URL to VirusTotal to retrieve scanning results classifying it as malicious, suspicious, or harmless.
Instructions
Submit a URL to VirusTotal for scanning and get analysis results (malicious/suspicious/harmless). Requires VT_API_KEY.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | URL to scan |
Implementation Reference
- src/virustotal/index.ts:127-159 (handler)The main handler function `vtUrl` that submits a URL to VirusTotal for analysis and returns the scan results (completed/queued status and stats).
export async function vtUrl(url: string, apiKey: string): Promise<VtUrlResult> { // Submit URL for analysis await limiter.acquire(); const submitRes = await fetch(`${VT_BASE}/urls`, { method: "POST", headers: { "x-apikey": apiKey, "Content-Type": "application/x-www-form-urlencoded" }, body: `url=${encodeURIComponent(url)}`, }); if (!submitRes.ok) throw new Error(`VirusTotal URL submit failed: ${submitRes.status}`); const submitData = await submitRes.json(); const analysisId = submitData.data?.id; if (!analysisId) { return { url, status: "submitted", analysisId: undefined }; } // Try to get analysis results (may not be ready yet) try { const analysisData = await vtFetch(`/analyses/${analysisId}`, apiKey); if (analysisData?.data?.attributes?.status === "completed") { return { url, analysisId, analysisStats: analysisData.data.attributes.stats, status: "completed", }; } return { url, analysisId, status: analysisData?.data?.attributes?.status ?? "queued" }; } catch { return { url, analysisId, status: "queued" }; } } - src/virustotal/index.ts:45-50 (schema)The `VtUrlResult` interface defining the shape of the result returned by vtUrl (url, analysisId, analysisStats, status).
interface VtUrlResult { url: string; analysisId?: string; analysisStats?: VtAnalysisStats; status: string; } - src/protocol/tools.ts:219-229 (registration)The `vtUrlTool` ToolDef registration with name 'vt_url', description, Zod schema (url string), and execute handler that calls the imported vtUrl function.
const vtUrlTool: ToolDef = { name: "vt_url", description: "Submit a URL to VirusTotal for scanning and get analysis results (malicious/suspicious/harmless). Requires VT_API_KEY.", schema: { url: z.string().describe("URL to scan"), }, execute: async (args, ctx) => { const key = requireApiKey(ctx.config.vtApiKey, "VirusTotal", "VT_API_KEY"); return json(await vtUrl(args.url as string, key)); }, }; - src/protocol/tools.ts:503-503 (registration)The `vtUrlTool` is exported in the tools array so it gets registered with the MCP server.
vtUrlTool, - src/virustotal/index.ts:54-62 (helper)The `vtFetch` helper used internally by vtUrl to fetch analysis results from VirusTotal API.
async function vtFetch(path: string, apiKey: string): Promise<any> { await limiter.acquire(); const res = await fetch(`${VT_BASE}${path}`, { headers: { "x-apikey": apiKey }, }); if (res.status === 404) return null; if (!res.ok) throw new Error(`VirusTotal API error: ${res.status} ${res.statusText}`); return res.json(); }