scan_url
Analyze a URL for malware and phishing using 70+ security engines. Poll for verdict: malicious, suspicious, clean, or timeout.
Instructions
Submit a URL for malware and phishing analysis across 70+ security engines. Returns an analysis_id immediately (async). Call check_scan_result with the analysis_id every 5 seconds until verdict is returned. Verdicts: malicious | suspicious | clean | timeout. Use before navigating to an unfamiliar URL or when a user forwards a suspicious link. Requires subscription API key — coming soon for pay-as-you-go. Subscription: rapidapi.com/relayshield
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | URL to scan (must start with http:// or https://) |
Implementation Reference
- src/relayshield_mcp/server.py:324-329 (handler)Dispatch handler that executes the scan_url tool logic by sending a POST request to the /scan-url endpoint with the provided URL argument.
if name == "scan_url": return await client.post( f"{base}/scan-url", headers=headers, json={"url": arguments["url"]}, ) - Tool definition with input schema: requires a 'url' parameter of type string with URI format.
types.Tool( name="scan_url", description=( "Submit a URL for malware and phishing analysis across 70+ security engines. " "Returns an analysis_id immediately (async). " "Call check_scan_result with the analysis_id every 5 seconds until verdict is returned. " "Verdicts: malicious | suspicious | clean | timeout. " "Use before navigating to an unfamiliar URL or when a user forwards a suspicious link. " "Requires subscription API key — coming soon for pay-as-you-go. " "Subscription: rapidapi.com/relayshield" ), inputSchema={ "type": "object", "required": ["url"], "properties": { "url": { "type": "string", "format": "uri", "description": "URL to scan (must start with http:// or https://)", } }, }, ), - src/relayshield_mcp/server.py:64-231 (registration)scan_url is registered as one of the tools in the list_tools() decorator on the MCP server under the name 'scan_url'.
@app.list_tools() async def list_tools() -> list[types.Tool]: return [ types.Tool( name="check_breach", description=( "Check whether an email address appears in known data breaches. " "Uses Have I Been Pwned (HIBP) — 13 billion+ compromised accounts. " "Returns breach count and details (breach name, date, exposed data classes). " "Use before allowing high-risk actions that depend on credential integrity. " "Pay-as-you-go: $0.10 USDC per check (x402 on Base). " "Subscription: rapidapi.com/relayshield" ), inputSchema={ "type": "object", "required": ["email"], "properties": { "email": { "type": "string", "format": "email", "description": "Email address to check", } }, }, ), types.Tool( name="check_sim_swap", description=( "Detect whether a SIM swap or eSIM provisioning event has occurred on a phone number " "in the last 24 hours. Uses Twilio Lookup v2 with live carrier data. " "Returns swapped (bool), swap timestamp, and current carrier. " "Use when a user reports losing mobile service, or before completing a high-risk " "action that depends on SMS-based authentication. " "Pay-as-you-go: $0.25 USDC per check (x402 on Base). " "Subscription: rapidapi.com/relayshield" ), inputSchema={ "type": "object", "required": ["phone"], "properties": { "phone": { "type": "string", "description": "Phone number in E.164 format (e.g. +14155551234)", "pattern": "^\\+[1-9]\\d{6,14}$", } }, }, ), types.Tool( name="check_domain_lookalikes", description=( "Detect typosquat and lookalike domains impersonating a brand. " "Generates hundreds of permutations (TLD swaps, character typos, homoglyphs, " "phishing prefixes/suffixes), resolves them in parallel via DNS, and enriches " "live results with Certificate Transparency data (cert count, recent issuance). " "Returns all lookalike domains that are currently registered and resolving. " "Use to find domains impersonating your brand, or before an employee clicks a " "link that resembles a company domain. " "Pay-as-you-go: $0.50 USDC per scan (x402 on Base). " "Subscription: rapidapi.com/relayshield" ), inputSchema={ "type": "object", "required": ["domain"], "properties": { "domain": { "type": "string", "description": "Root domain to scan (e.g. acme.com — no scheme or path needed)", } }, }, ), types.Tool( name="check_oauth_watchlist", description=( "Check whether any high-risk OAuth-capable SaaS apps connected to an email account " "have appeared in recent data breaches. Monitors a curated watchlist of apps " "(Slack, Notion, GitHub, Zapier, Vercel, Loom, HubSpot, AI tools, and more). " "An attacker who breaches these services may obtain OAuth tokens granting access " "to your Google Workspace or Microsoft 365 without touching your password. " "Returns matched breached apps and recommended revocation steps. " "Pay-as-you-go: $0.15 USDC per check (x402 on Base). " "Subscription: rapidapi.com/relayshield" ), inputSchema={ "type": "object", "required": ["email"], "properties": { "email": { "type": "string", "format": "email", "description": "Email address whose connected OAuth apps to check", } }, }, ), types.Tool( name="scan_url", description=( "Submit a URL for malware and phishing analysis across 70+ security engines. " "Returns an analysis_id immediately (async). " "Call check_scan_result with the analysis_id every 5 seconds until verdict is returned. " "Verdicts: malicious | suspicious | clean | timeout. " "Use before navigating to an unfamiliar URL or when a user forwards a suspicious link. " "Requires subscription API key — coming soon for pay-as-you-go. " "Subscription: rapidapi.com/relayshield" ), inputSchema={ "type": "object", "required": ["url"], "properties": { "url": { "type": "string", "format": "uri", "description": "URL to scan (must start with http:// or https://)", } }, }, ), types.Tool( name="scan_file", description=( "Submit a file for binary malware analysis across 70+ AV engines. " "Provide a publicly accessible download URL — RelayShield handles the download. " "Returns an analysis_id immediately (async). " "Call check_scan_result with the analysis_id every 5 seconds until verdict is returned. " "Verdicts: malicious | suspicious | clean | timeout. " "Use when a user receives an email attachment and forwards the download link. " "Requires subscription API key — coming soon for pay-as-you-go. " "Subscription: rapidapi.com/relayshield" ), inputSchema={ "type": "object", "required": ["file_url"], "properties": { "file_url": { "type": "string", "format": "uri", "description": "Publicly accessible URL to download the file from", }, "filename": { "type": "string", "description": "Optional filename hint (e.g. invoice_march.pdf)", }, }, }, ), types.Tool( name="check_scan_result", description=( "Poll for the result of a previously submitted URL or file scan. " "Call every 5 seconds after scan_url or scan_file until status is 'completed'. " "Returns verdict (malicious/suspicious/clean) and engine vote counts, " "or {status: pending} if the scan is still running. " "Free with a paid scan (no additional charge)." ), inputSchema={ "type": "object", "required": ["analysis_id"], "properties": { "analysis_id": { "type": "string", "description": "analysis_id returned by scan_url or scan_file", } }, }, ), ] - src/relayshield_mcp/server.py:242-253 (registration)The scan_url tool is in VT_COMING_SOON set, meaning it returns a 'coming_soon' error if no subscription API key is provided (PAYG access pending VT licensing).
# VT-licensed tools require a subscription key — return coming soon for PAYG callers if not API_KEY and name in VT_COMING_SOON: return [types.TextContent(type="text", text=json.dumps({ "ok": False, "tool": name, "status": "coming_soon", "message": ( f"{name} requires a subscription API key. " "VT commercial licensing is pending for pay-as-you-go access. " "Subscribe at rapidapi.com/relayshield for early access." ), }))] - src/relayshield_mcp/server.py:45-53 (helper)Pricing helper dictionary lists scan_url as 'coming soon' for pay-as-you-go users.
PAYG_PRICING: dict[str, str] = { "check_breach": "$0.10 USDC", "check_sim_swap": "$0.25 USDC", "check_domain_lookalikes": "$0.50 USDC", "check_oauth_watchlist": "$0.15 USDC", "check_scan_result": "$0.00 USDC (free — poll result of a paid scan)", "scan_url": "coming soon", "scan_file": "coming soon", }