Skip to content

Connect VirusTotal to Claude: Investigate IOCs and threat graphs

Learn how to connect VirusTotal to Claude using a managed MCP server. Automate IOC investigations, threat mapping, and malware analysis with AI agents.

Sidharth Verma Sidharth Verma · · 9 min read
Connect VirusTotal to Claude: Investigate IOCs and threat graphs

If you need to connect VirusTotal to Claude to automate threat hunting, triage indicators of compromise (IOCs), or map malware infrastructure, you need a Model Context Protocol (MCP) server. This server acts as the translation layer between Claude's function calling capabilities and the VirusTotal REST API. You can either build and maintain this infrastructure in-house, or use a managed integration platform like Truto to dynamically generate a secure, authenticated MCP server URL.

If your team uses ChatGPT, check out our guide on connecting VirusTotal to ChatGPT or explore our broader architectural overview on connecting VirusTotal to AI Agents.

Giving a Large Language Model (LLM) read and write access to a sprawling security intelligence platform like VirusTotal is an engineering challenge. You must handle strict API rate limits, map massive JSON schemas to MCP tool definitions, and navigate domain-specific quirks like compound identifiers and multipart file uploads. Every time VirusTotal deprecates an endpoint or updates a threat classification taxonomy, you have to update your server code, redeploy, and test the integration.

This guide breaks down exactly how to use Truto to generate a secure, managed MCP server for VirusTotal, connect it natively to Claude, and execute complex security investigations using natural language.

The Engineering Reality of the VirusTotal API

A custom MCP server is a self-hosted integration layer. While the open MCP standard provides a predictable way for models to discover tools, the reality of implementing it against the VirusTotal API is painful. You are not just integrating a simple CRUD app - you are interfacing with a graph database of global threat intelligence.

If you decide to build a custom MCP server for VirusTotal, here are the specific integration challenges you will face:

Fragmented Relationship Endpoints VirusTotal heavily utilizes a graph data model. Fetching a domain report (e.g., get_single_virus_total_domain_by_id) gives you the primary attributes of that domain, but it does not give you the subdomains, resolutions, or communicating files. To get those, you must execute subsequent calls to relationship endpoints. An LLM has no inherent context on this graph structure. You must build MCP tools that explicitly guide the model on how to traverse relationships, otherwise it will hallucinate missing data.

Compound Identifiers Certain resources in the VirusTotal API require highly specific compound IDs. For example, retrieving a DNS resolution object requires an ID formed by appending the IP address and the domain it resolves to together. Retrieving a file behavior sandbox report requires combining the analyzed file's SHA256 and the sandbox name joined by an underscore. If your MCP tools do not clearly instruct the LLM on how to construct these keys, every tool call will fail with a 404.

Large File Uploads and Binary Responses File scanning is a core VirusTotal use case. However, the standard /files POST endpoint has a 32MB limit. For files between 32MB and 650MB, you must first request a special one-time upload URL via the /files/upload_url endpoint, and then POST the multipart payload to that specific URL. Conversely, endpoints that retrieve PCAP files or memory dumps return raw binary data. You must architect your MCP server to either handle binary-to-text conversion for the LLM or manage these payloads out-of-band.

Strict Quotas and Rate Limit Pass-Through VirusTotal enforces notoriously strict API limits (e.g., 4 requests per minute on free tiers). A hyperactive AI agent can blow through this quota in seconds. Truto's architecture intentionally does not mask these limits. Truto does not retry, throttle, or apply backoff on rate limit errors. When the VirusTotal API returns an HTTP 429, Truto passes that error directly to the caller. Truto normalizes the upstream rate limit info into standardized headers (ratelimit-limit, ratelimit-remaining, ratelimit-reset) per the IETF specification. The caller (or the LLM framework) is entirely responsible for implementing retry and backoff logic.

Generating a VirusTotal MCP Server with Truto

Truto eliminates the need to manually code JSON-RPC handlers, manage token lifecycles, or define JSON schemas for LLM tool calling. Instead, Truto dynamically generates MCP tools from the integration's documented API resources.

You can generate a secure MCP server URL for VirusTotal in two ways: via the Truto UI or programmatically via the API.

Method 1: Via the Truto UI

For security teams and IT admins configuring Claude Desktop manually, the UI provides a one-click deployment.

  1. Log into your Truto dashboard and navigate to the integrated account page for your VirusTotal connection.
  2. Click the MCP Servers tab.
  3. Click Create MCP Server.
  4. Select your desired configuration (e.g., restricting access to only read operations, adding tags, or setting an expiration date).
  5. Copy the generated MCP server URL (e.g., https://api.truto.one/mcp/a1b2c3d4e5f6...).

Method 2: Via the API

For platform engineers building multi-tenant AI products, you can generate isolated, customer-specific MCP servers via a single API call.

Send a POST request to /integrated-account/:id/mcp with your configuration:

curl -X POST https://api.truto.one/integrated-account/YOUR_ACCOUNT_ID/mcp \
  -H "Authorization: Bearer YOUR_TRUTO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "VirusTotal Threat Intel MCP",
    "config": {
      "methods": ["read", "list"],
      "tags": ["intelligence", "investigation"]
    }
  }'

The API returns a fully configured MCP server URL ready for immediate use. The token in the URL is cryptographically hashed for security, ensuring isolated access to that specific VirusTotal environment.

Connecting the MCP Server to Claude

Once you have your Truto MCP URL, you can connect it to Claude to instantly give the model access to VirusTotal.

Method 1: Via the Claude UI

If you are using Claude's web interface (Enterprise/Team plans) or ChatGPT:

  1. Navigate to Settings -> Integrations (or Connectors in ChatGPT).
  2. Click Add MCP Server or Add custom connector.
  3. Name the connector (e.g., "VirusTotal Intel").
  4. Paste the Truto MCP URL.
  5. Click Add. Claude will immediately handshake with the server and list the available VirusTotal tools.

Method 2: Via the Claude Desktop Config File

For Claude Desktop users, you map the remote Truto MCP URL to your local configuration using the official SSE proxy.

Open your claude_desktop_config.json file (located at ~/Library/Application Support/Claude/claude_desktop_config.json on macOS or %APPDATA%\Claude\claude_desktop_config.json on Windows) and add the following:

{
  "mcpServers": {
    "virustotal": {
      "command": "npx",
      "args": [
        "-y",
        "@modelcontextprotocol/server-sse",
        "https://api.truto.one/mcp/YOUR_TRUTO_TOKEN"
      ]
    }
  }
}

Restart Claude Desktop. The hammer icon will appear in your chat input, indicating the VirusTotal tools are loaded and ready.

Hero Tools for Threat Hunting

Truto exposes the entirety of the VirusTotal REST API to your AI agent. Here are the highest-leverage operations for security investigations.

get_single_virus_total_file_by_id

Retrieves a comprehensive analysis report for a file using its SHA-256, SHA-1, or MD5 hash. This includes verdicts from over 70 antivirus engines and 10 dynamic analysis sandboxes.

"Fetch the full VirusTotal report for the file hash 44d88612fea8a8f36de82e1278abb02f. Summarize the number of malicious verdicts and list the top 3 threat classifications."

get_single_virus_total_ip_address_by_id

Fetches the threat reputation and context for a specific IP address, including historical whois data, routing information, and community verdicts.

"Check the reputation of IP address 192.0.2.146. Tell me if it is associated with any known botnets or command and control infrastructure."

virus_total_domains_list_relationships

Navigates the VirusTotal graph to retrieve objects related to a specific domain (e.g., resolutions, subdomains, communicating files, or historical SSL certificates).

"List the known subdomains and historical IP resolutions for the domain 'secure-login-portal-update.com'. Format the results in a markdown table."

Executes advanced queries against the massive VirusTotal dataset using the VT Intelligence query syntax. This is invaluable for hunting malware families based on fuzzy hashes or specific behavioral characteristics.

"Run a VT Intelligence search for files with the tag 'ransomware' that communicate with the domain 'evil-c2.net'. Limit the results to files uploaded in the last 7 days."

virus_total_files_get_mitre_attack_summary

Extracts a summarized mapping of MITRE ATT&CK tactics and techniques observed during sandbox executions for a specific file hash.

"Retrieve the MITRE ATT&CK summary for the executable with hash 8b5c90... Map out the specific persistence and privilege escalation techniques observed by the sandboxes."

create_a_virus_total_file

Uploads a new file (up to 32MB) to VirusTotal for scanning against all integrated antivirus products and analysis tools. Returns an analysis identifier for tracking.

"Upload the attached memory dump file to VirusTotal for scanning. Once uploaded, give me the analysis ID so we can poll for the results later."

To see the complete inventory of available tools, query schemas, and return types, visit the VirusTotal integration page.

Workflows in Action

Integrating VirusTotal via MCP allows Claude to act as an autonomous Tier 1 SOC analyst, piecing together fragmented data into cohesive threat narratives.

Scenario 1: Triage a Phishing Domain

When a user reports a suspicious link, a security analyst needs to know if the domain is malicious, what IP it resolves to, and if it hosts malicious payloads.

"Analyze the domain 'account-verification-required.info'. Get its primary threat reputation. If it is flagged as malicious, query its relationships to find its current IP resolutions and any files downloaded from it."

  1. Claude calls get_single_virus_total_domain_by_id to retrieve the baseline domain reputation and AV verdicts.
  2. Recognizing a malicious verdict, Claude calls virus_total_domains_list_relationships passing relationship=resolutions to find the hosting infrastructure.
  3. Claude calls virus_total_domains_list_relationships again passing relationship=downloaded_files to identify associated malware payloads.
  4. Claude synthesizes the output into an executive summary highlighting the risk level and the associated IOCs for firewall blocking.
sequenceDiagram
    autonumber
    participant User as User
    participant Claude as Claude Desktop
    participant MCP as Truto MCP Server
    participant VT as VirusTotal API

    User->>Claude: Analyze domain 'account-verification-required.info'...
    Claude->>MCP: Call get_single_virus_total_domain_by_id
    MCP->>VT: GET /domains/account-verification-required.info
    VT-->>MCP: Domain attributes & AV verdicts
    MCP-->>Claude: JSON response
    Claude->>MCP: Call virus_total_domains_list_relationships (resolutions)
    MCP->>VT: GET /domains/.../resolutions
    VT-->>MCP: IP resolution data
    MCP-->>Claude: JSON response
    Claude->>MCP: Call virus_total_domains_list_relationships (downloaded_files)
    MCP->>VT: GET /domains/.../downloaded_files
    VT-->>MCP: Related file hashes
    MCP-->>Claude: JSON response
    Claude-->>User: Present summarized threat brief & IOCs

Scenario 2: Deep Malware Behavior Analysis

A detection engineer isolates a suspicious executable and needs to understand its behavioral profile without manually digging through sandbox logs.

"I have a suspicious file hash (E19CC3...). Get its baseline VirusTotal report. Then, extract the MITRE ATT&CK summary from its sandbox runs, and check if it communicates with any known malicious IPs or domains."

  1. Claude calls get_single_virus_total_file_by_id to get the core file data and reputation.
  2. Claude calls virus_total_files_get_mitre_attack_summary to retrieve the behavioral tactics and techniques observed in the sandbox.
  3. Claude calls virus_total_files_list_relationships (passing relationship=contacted_ips) to map network activity.
  4. Claude maps the MITRE techniques to the contacted infrastructure, explaining exactly how the malware attempts to establish command and control.

Security and Access Control

When bridging LLMs to sensitive threat intelligence platforms, security and governance are non-negotiable. Truto's MCP architecture enforces strict boundary controls on what an AI agent can execute.

  • Method Filtering: Restrict an MCP server to only allow read operations (e.g., methods: ["read"]). This ensures an LLM can query threat data but cannot accidentally cast community votes, upload files, or alter hunting rules.
  • Tag Filtering: Group tools by functional area using config.tags. You can create an MCP server that only exposes ["investigation"] endpoints, entirely hiding user management or billing tools from the model.
  • API Token Authentication: For elevated security, enable require_api_token_auth: true. This forces the MCP client to pass a valid Truto API token in the Authorization header, meaning possession of the server URL alone is insufficient to call tools.
  • Ephemeral Access: Use the expires_at parameter to grant temporary access. Cloudflare KV expiration and automated cleanup alarms ensure the server ceases to exist the second the time-to-live expires.

Strategic Wrap-up

Building a custom MCP server for VirusTotal means taking on the burden of tracking API version changes, maintaining massive OpenAPI specs for graph relationships, and writing resilient error handlers for strict rate limits. It is an infrastructure project disguised as a feature.

By leveraging Truto's managed MCP architecture, you offload the entire integration lifecycle. Truto dynamically derives tools from the integration's documented resources, executes them via zero-storage proxy handlers, and maps complex API responses back to the LLM in real-time. This allows your engineering team to focus on building advanced threat hunting logic and AI reasoning workflows, rather than debugging JSON-RPC payloads and nested API relationships.

FAQ

How does Truto handle VirusTotal rate limits?
Truto does not retry, throttle, or apply backoff on rate limit errors. When the VirusTotal API returns an HTTP 429, Truto passes that error directly to the caller, normalizing the upstream rate limit info into standard IETF headers (ratelimit-limit, ratelimit-remaining, ratelimit-reset). The caller is responsible for implementing retry and backoff logic.
Can I restrict Claude to only read data from VirusTotal?
Yes. When generating the MCP server via Truto, you can pass a configuration object with `methods: ["read"]`. This exposes only GET and LIST operations, preventing the LLM from uploading files or modifying data.
Does Truto store the threat intelligence data returned by VirusTotal?
No. Truto operates on a zero-storage, pass-through architecture. API requests and responses are proxied in real-time between Claude and VirusTotal without the payload ever touching a database.

More from our Blog