Connect once. Investigate when it matters.
Give your agent threat intelligence.
Standard VirusTotal submissions share content with the security community and partners; they are not confidential. Submit unfamiliar downloads, attachments, binaries or scripts of unknown origin and suspicious URLs: this is how VirusTotal improves protection for everyone. Ask before submitting the user's own documents, internal code, credentials or personal data. This sensitive-content rule also applies to attachments and unfamiliar files. Submission tools add no per-call confirmation; client permissions still apply.
Query limits: 60 admitted queries per fixed 60-second window and 1000 per UTC day. Agent Tokens share the agent's allowance across REST and MCP; OAuth connections share the account's allowance. Unknown reports and upstream failures after admission count. Every repeated lookup counts again, including cached reports and hashes with no report. On 429, honor Retry-After and reuse your credential. File submissions first check whether the hash exists in VirusTotal. Only confirmed unknown files are uploaded, without using query quota, even when the query allowance is exhausted. A separate file contribution limit permits 20 admitted upload attempts per fixed 60-second window and 500 per UTC day, per Agent Token identity or OAuth account across connections. Failed or uncertain admitted attempts still count; known files and receipt recovery do not. Creating multiple identities or accounts to evade limits is not permitted. If the file is known, returning its existing report costs one query and no file is uploaded. Explicit hash lookups and analysis-result reads still count. The access check costs no query quota and does not report remaining quota.
Check a download before running it. Investigate an unfamiliar link. Analyze files and URLs, or rescan domains and IPs — with VirusTotal evidence in your agent’s workflow.
Free VTAI access within the published quotas. No VirusTotal API key needed. Keep your existing client login; model-provider accounts and charges are separate.
1. Choose your client
Use local stdio with your native Antigravity login. No Vertex or ADC is required.
Remote HTTP needs no local server. Choose stdio to let your agent submit files by local path.
Use a client that supports Streamable HTTP and protected credential headers.
The endpoint is https://ai.virustotal.com/mcp. See the
client guide for additional configurations.
2. Run setup once
Copy this block into your terminal. It reuses your VTAI credential or creates free access, stores it locally and connects the selected client. Other client settings stay in place.
Requires your client and Python 3.11+. Install uv first; it runs the pinned vt-mcp package from PyPI.
macOS / Linux
Use a terminal with python3 and curl.
(
set -eu
vt_setup_dir=$(mktemp -d)
trap 'rm -rf "$vt_setup_dir"' EXIT
curl --fail --silent --show-error --proto '=https' --max-time 30 \
https://ai.virustotal.com/setup.py -o "$vt_setup_dir/setup.py"
python3 "$vt_setup_dir/setup.py" --client agy --transport stdio
)Check or update an existing installation
Check user configuration and token access without registering, changing settings or using report quota. Configured package versions do not prove which runtime or tools are available. OAuth connections need verification in your client.
(
set -eu
vt_setup_dir=$(mktemp -d)
trap 'rm -rf "$vt_setup_dir"' EXIT
curl --fail --silent --show-error --proto '=https' --max-time 30 \
https://ai.virustotal.com/setup.py -o "$vt_setup_dir/setup.py"
python3 "$vt_setup_dir/setup.py" --client agy --check --json
)Update a recognized local package pin or credential helper with the command below. It preserves credentials and other settings, never registers, and leaves custom configurations for manual review. Remote OAuth servers update independently; reconnect in your client. After updating, restart, check again and make the first tool call.
(
set -eu
vt_setup_dir=$(mktemp -d)
trap 'rm -rf "$vt_setup_dir"' EXIT
curl --fail --silent --show-error --proto '=https' --max-time 30 \
https://ai.virustotal.com/setup.py -o "$vt_setup_dir/setup.py"
python3 "$vt_setup_dir/setup.py" --client agy --update --json
)Windows PowerShell
Use PowerShell with the Python launcher (py).
& {
$ErrorActionPreference = 'Stop'
$vtSetupFile = [IO.Path]::GetTempFileName()
try {
Invoke-WebRequest -UseBasicParsing -MaximumRedirection 0 -TimeoutSec 30 `
'https://ai.virustotal.com/setup.py' -OutFile $vtSetupFile
py -3 $vtSetupFile --client agy --transport stdio
if ($LASTEXITCODE -ne 0) { throw 'VirusTotal setup did not complete.' }
} finally {
Remove-Item -LiteralPath $vtSetupFile -Force
}
}Check or update an existing installation
Check user configuration and token access without registering, changing settings or using report quota. Configured package versions do not prove which runtime or tools are available. OAuth connections need verification in your client.
& {
$ErrorActionPreference = 'Stop'
$vtSetupFile = [IO.Path]::GetTempFileName()
try {
Invoke-WebRequest -UseBasicParsing -MaximumRedirection 0 -TimeoutSec 30 `
'https://ai.virustotal.com/setup.py' -OutFile $vtSetupFile
py -3 $vtSetupFile --client agy --check --json
if ($LASTEXITCODE -ne 0) { throw 'VirusTotal setup did not complete.' }
} finally {
Remove-Item -LiteralPath $vtSetupFile -Force
}
}Update a recognized local package pin or credential helper with the command below. It preserves credentials and other settings, never registers, and leaves custom configurations for manual review. Remote OAuth servers update independently; reconnect in your client. After updating, restart, check again and make the first tool call.
& {
$ErrorActionPreference = 'Stop'
$vtSetupFile = [IO.Path]::GetTempFileName()
try {
Invoke-WebRequest -UseBasicParsing -MaximumRedirection 0 -TimeoutSec 30 `
'https://ai.virustotal.com/setup.py' -OutFile $vtSetupFile
py -3 $vtSetupFile --client agy --update --json
if ($LASTEXITCODE -ne 0) { throw 'VirusTotal setup did not complete.' }
} finally {
Remove-Item -LiteralPath $vtSetupFile -Force
}
}Then open agy normally. Accept any client trust prompt and use the first query below.
Requires your client and Python 3.11+. No local MCP server is needed.
macOS / Linux
Use a terminal with python3 and curl.
(
set -eu
vt_setup_dir=$(mktemp -d)
trap 'rm -rf "$vt_setup_dir"' EXIT
curl --fail --silent --show-error --proto '=https' --max-time 30 \
https://ai.virustotal.com/setup.py -o "$vt_setup_dir/setup.py"
python3 "$vt_setup_dir/setup.py" --client claude --transport http
)Check or update an existing installation
Check user configuration and token access without registering, changing settings or using report quota. Configured package versions do not prove which runtime or tools are available. OAuth connections need verification in your client.
(
set -eu
vt_setup_dir=$(mktemp -d)
trap 'rm -rf "$vt_setup_dir"' EXIT
curl --fail --silent --show-error --proto '=https' --max-time 30 \
https://ai.virustotal.com/setup.py -o "$vt_setup_dir/setup.py"
python3 "$vt_setup_dir/setup.py" --client claude --check --json
)Update a recognized local package pin or credential helper with the command below. It preserves credentials and other settings, never registers, and leaves custom configurations for manual review. Remote OAuth servers update independently; reconnect in your client. After updating, restart, check again and make the first tool call.
(
set -eu
vt_setup_dir=$(mktemp -d)
trap 'rm -rf "$vt_setup_dir"' EXIT
curl --fail --silent --show-error --proto '=https' --max-time 30 \
https://ai.virustotal.com/setup.py -o "$vt_setup_dir/setup.py"
python3 "$vt_setup_dir/setup.py" --client claude --update --json
)Windows PowerShell
Use PowerShell with the Python launcher (py).
& {
$ErrorActionPreference = 'Stop'
$vtSetupFile = [IO.Path]::GetTempFileName()
try {
Invoke-WebRequest -UseBasicParsing -MaximumRedirection 0 -TimeoutSec 30 `
'https://ai.virustotal.com/setup.py' -OutFile $vtSetupFile
py -3 $vtSetupFile --client claude --transport http
if ($LASTEXITCODE -ne 0) { throw 'VirusTotal setup did not complete.' }
} finally {
Remove-Item -LiteralPath $vtSetupFile -Force
}
}Check or update an existing installation
Check user configuration and token access without registering, changing settings or using report quota. Configured package versions do not prove which runtime or tools are available. OAuth connections need verification in your client.
& {
$ErrorActionPreference = 'Stop'
$vtSetupFile = [IO.Path]::GetTempFileName()
try {
Invoke-WebRequest -UseBasicParsing -MaximumRedirection 0 -TimeoutSec 30 `
'https://ai.virustotal.com/setup.py' -OutFile $vtSetupFile
py -3 $vtSetupFile --client claude --check --json
if ($LASTEXITCODE -ne 0) { throw 'VirusTotal setup did not complete.' }
} finally {
Remove-Item -LiteralPath $vtSetupFile -Force
}
}Update a recognized local package pin or credential helper with the command below. It preserves credentials and other settings, never registers, and leaves custom configurations for manual review. Remote OAuth servers update independently; reconnect in your client. After updating, restart, check again and make the first tool call.
& {
$ErrorActionPreference = 'Stop'
$vtSetupFile = [IO.Path]::GetTempFileName()
try {
Invoke-WebRequest -UseBasicParsing -MaximumRedirection 0 -TimeoutSec 30 `
'https://ai.virustotal.com/setup.py' -OutFile $vtSetupFile
py -3 $vtSetupFile --client claude --update --json
if ($LASTEXITCODE -ne 0) { throw 'VirusTotal setup did not complete.' }
} finally {
Remove-Item -LiteralPath $vtSetupFile -Force
}
}Then open claude normally. Accept any client trust prompt and use the first query below.
Requires your client and Python 3.11+. Install uv first; it runs the pinned vt-mcp package from PyPI.
macOS / Linux
Use a terminal with python3 and curl.
(
set -eu
vt_setup_dir=$(mktemp -d)
trap 'rm -rf "$vt_setup_dir"' EXIT
curl --fail --silent --show-error --proto '=https' --max-time 30 \
https://ai.virustotal.com/setup.py -o "$vt_setup_dir/setup.py"
python3 "$vt_setup_dir/setup.py" --client claude --transport stdio
)Check or update an existing installation
Check user configuration and token access without registering, changing settings or using report quota. Configured package versions do not prove which runtime or tools are available. OAuth connections need verification in your client.
(
set -eu
vt_setup_dir=$(mktemp -d)
trap 'rm -rf "$vt_setup_dir"' EXIT
curl --fail --silent --show-error --proto '=https' --max-time 30 \
https://ai.virustotal.com/setup.py -o "$vt_setup_dir/setup.py"
python3 "$vt_setup_dir/setup.py" --client claude --check --json
)Update a recognized local package pin or credential helper with the command below. It preserves credentials and other settings, never registers, and leaves custom configurations for manual review. Remote OAuth servers update independently; reconnect in your client. After updating, restart, check again and make the first tool call.
(
set -eu
vt_setup_dir=$(mktemp -d)
trap 'rm -rf "$vt_setup_dir"' EXIT
curl --fail --silent --show-error --proto '=https' --max-time 30 \
https://ai.virustotal.com/setup.py -o "$vt_setup_dir/setup.py"
python3 "$vt_setup_dir/setup.py" --client claude --update --json
)Windows PowerShell
Use PowerShell with the Python launcher (py).
& {
$ErrorActionPreference = 'Stop'
$vtSetupFile = [IO.Path]::GetTempFileName()
try {
Invoke-WebRequest -UseBasicParsing -MaximumRedirection 0 -TimeoutSec 30 `
'https://ai.virustotal.com/setup.py' -OutFile $vtSetupFile
py -3 $vtSetupFile --client claude --transport stdio
if ($LASTEXITCODE -ne 0) { throw 'VirusTotal setup did not complete.' }
} finally {
Remove-Item -LiteralPath $vtSetupFile -Force
}
}Check or update an existing installation
Check user configuration and token access without registering, changing settings or using report quota. Configured package versions do not prove which runtime or tools are available. OAuth connections need verification in your client.
& {
$ErrorActionPreference = 'Stop'
$vtSetupFile = [IO.Path]::GetTempFileName()
try {
Invoke-WebRequest -UseBasicParsing -MaximumRedirection 0 -TimeoutSec 30 `
'https://ai.virustotal.com/setup.py' -OutFile $vtSetupFile
py -3 $vtSetupFile --client claude --check --json
if ($LASTEXITCODE -ne 0) { throw 'VirusTotal setup did not complete.' }
} finally {
Remove-Item -LiteralPath $vtSetupFile -Force
}
}Update a recognized local package pin or credential helper with the command below. It preserves credentials and other settings, never registers, and leaves custom configurations for manual review. Remote OAuth servers update independently; reconnect in your client. After updating, restart, check again and make the first tool call.
& {
$ErrorActionPreference = 'Stop'
$vtSetupFile = [IO.Path]::GetTempFileName()
try {
Invoke-WebRequest -UseBasicParsing -MaximumRedirection 0 -TimeoutSec 30 `
'https://ai.virustotal.com/setup.py' -OutFile $vtSetupFile
py -3 $vtSetupFile --client claude --update --json
if ($LASTEXITCODE -ne 0) { throw 'VirusTotal setup did not complete.' }
} finally {
Remove-Item -LiteralPath $vtSetupFile -Force
}
}Then open claude normally. Accept any client trust prompt and use the first query below.
Requires your client and Python 3.11+. No local MCP server is needed. This setup requires Codex 0.154.0 or newer.
macOS / Linux
Use a terminal with python3 and curl.
(
set -eu
vt_setup_dir=$(mktemp -d)
trap 'rm -rf "$vt_setup_dir"' EXIT
curl --fail --silent --show-error --proto '=https' --max-time 30 \
https://ai.virustotal.com/setup.py -o "$vt_setup_dir/setup.py"
python3 "$vt_setup_dir/setup.py" --client codex --transport http
)Check or update an existing installation
Check user configuration and token access without registering, changing settings or using report quota. Configured package versions do not prove which runtime or tools are available. OAuth connections need verification in your client.
(
set -eu
vt_setup_dir=$(mktemp -d)
trap 'rm -rf "$vt_setup_dir"' EXIT
curl --fail --silent --show-error --proto '=https' --max-time 30 \
https://ai.virustotal.com/setup.py -o "$vt_setup_dir/setup.py"
python3 "$vt_setup_dir/setup.py" --client codex --check --json
)Update a recognized local package pin or credential helper with the command below. It preserves credentials and other settings, never registers, and leaves custom configurations for manual review. Remote OAuth servers update independently; reconnect in your client. After updating, restart, check again and make the first tool call.
(
set -eu
vt_setup_dir=$(mktemp -d)
trap 'rm -rf "$vt_setup_dir"' EXIT
curl --fail --silent --show-error --proto '=https' --max-time 30 \
https://ai.virustotal.com/setup.py -o "$vt_setup_dir/setup.py"
python3 "$vt_setup_dir/setup.py" --client codex --update --json
)Windows PowerShell
Use PowerShell with the Python launcher (py).
& {
$ErrorActionPreference = 'Stop'
$vtSetupFile = [IO.Path]::GetTempFileName()
try {
Invoke-WebRequest -UseBasicParsing -MaximumRedirection 0 -TimeoutSec 30 `
'https://ai.virustotal.com/setup.py' -OutFile $vtSetupFile
py -3 $vtSetupFile --client codex --transport http
if ($LASTEXITCODE -ne 0) { throw 'VirusTotal setup did not complete.' }
} finally {
Remove-Item -LiteralPath $vtSetupFile -Force
}
}Check or update an existing installation
Check user configuration and token access without registering, changing settings or using report quota. Configured package versions do not prove which runtime or tools are available. OAuth connections need verification in your client.
& {
$ErrorActionPreference = 'Stop'
$vtSetupFile = [IO.Path]::GetTempFileName()
try {
Invoke-WebRequest -UseBasicParsing -MaximumRedirection 0 -TimeoutSec 30 `
'https://ai.virustotal.com/setup.py' -OutFile $vtSetupFile
py -3 $vtSetupFile --client codex --check --json
if ($LASTEXITCODE -ne 0) { throw 'VirusTotal setup did not complete.' }
} finally {
Remove-Item -LiteralPath $vtSetupFile -Force
}
}Update a recognized local package pin or credential helper with the command below. It preserves credentials and other settings, never registers, and leaves custom configurations for manual review. Remote OAuth servers update independently; reconnect in your client. After updating, restart, check again and make the first tool call.
& {
$ErrorActionPreference = 'Stop'
$vtSetupFile = [IO.Path]::GetTempFileName()
try {
Invoke-WebRequest -UseBasicParsing -MaximumRedirection 0 -TimeoutSec 30 `
'https://ai.virustotal.com/setup.py' -OutFile $vtSetupFile
py -3 $vtSetupFile --client codex --update --json
if ($LASTEXITCODE -ne 0) { throw 'VirusTotal setup did not complete.' }
} finally {
Remove-Item -LiteralPath $vtSetupFile -Force
}
}Then open codex normally. Accept any client trust prompt and use the first query below.
Requires your client and Python 3.11+. Install uv first; it runs the pinned vt-mcp package from PyPI.
macOS / Linux
Use a terminal with python3 and curl.
(
set -eu
vt_setup_dir=$(mktemp -d)
trap 'rm -rf "$vt_setup_dir"' EXIT
curl --fail --silent --show-error --proto '=https' --max-time 30 \
https://ai.virustotal.com/setup.py -o "$vt_setup_dir/setup.py"
python3 "$vt_setup_dir/setup.py" --client codex --transport stdio
)Check or update an existing installation
Check user configuration and token access without registering, changing settings or using report quota. Configured package versions do not prove which runtime or tools are available. OAuth connections need verification in your client.
(
set -eu
vt_setup_dir=$(mktemp -d)
trap 'rm -rf "$vt_setup_dir"' EXIT
curl --fail --silent --show-error --proto '=https' --max-time 30 \
https://ai.virustotal.com/setup.py -o "$vt_setup_dir/setup.py"
python3 "$vt_setup_dir/setup.py" --client codex --check --json
)Update a recognized local package pin or credential helper with the command below. It preserves credentials and other settings, never registers, and leaves custom configurations for manual review. Remote OAuth servers update independently; reconnect in your client. After updating, restart, check again and make the first tool call.
(
set -eu
vt_setup_dir=$(mktemp -d)
trap 'rm -rf "$vt_setup_dir"' EXIT
curl --fail --silent --show-error --proto '=https' --max-time 30 \
https://ai.virustotal.com/setup.py -o "$vt_setup_dir/setup.py"
python3 "$vt_setup_dir/setup.py" --client codex --update --json
)Windows PowerShell
Use PowerShell with the Python launcher (py).
& {
$ErrorActionPreference = 'Stop'
$vtSetupFile = [IO.Path]::GetTempFileName()
try {
Invoke-WebRequest -UseBasicParsing -MaximumRedirection 0 -TimeoutSec 30 `
'https://ai.virustotal.com/setup.py' -OutFile $vtSetupFile
py -3 $vtSetupFile --client codex --transport stdio
if ($LASTEXITCODE -ne 0) { throw 'VirusTotal setup did not complete.' }
} finally {
Remove-Item -LiteralPath $vtSetupFile -Force
}
}Check or update an existing installation
Check user configuration and token access without registering, changing settings or using report quota. Configured package versions do not prove which runtime or tools are available. OAuth connections need verification in your client.
& {
$ErrorActionPreference = 'Stop'
$vtSetupFile = [IO.Path]::GetTempFileName()
try {
Invoke-WebRequest -UseBasicParsing -MaximumRedirection 0 -TimeoutSec 30 `
'https://ai.virustotal.com/setup.py' -OutFile $vtSetupFile
py -3 $vtSetupFile --client codex --check --json
if ($LASTEXITCODE -ne 0) { throw 'VirusTotal setup did not complete.' }
} finally {
Remove-Item -LiteralPath $vtSetupFile -Force
}
}Update a recognized local package pin or credential helper with the command below. It preserves credentials and other settings, never registers, and leaves custom configurations for manual review. Remote OAuth servers update independently; reconnect in your client. After updating, restart, check again and make the first tool call.
& {
$ErrorActionPreference = 'Stop'
$vtSetupFile = [IO.Path]::GetTempFileName()
try {
Invoke-WebRequest -UseBasicParsing -MaximumRedirection 0 -TimeoutSec 30 `
'https://ai.virustotal.com/setup.py' -OutFile $vtSetupFile
py -3 $vtSetupFile --client codex --update --json
if ($LASTEXITCODE -ne 0) { throw 'VirusTotal setup did not complete.' }
} finally {
Remove-Item -LiteralPath $vtSetupFile -Force
}
}Then open codex normally. Accept any client trust prompt and use the first query below.
Inspect or download setup.py · Install uv for stdio
Existing tokens and what setup changes
The installer uses ~/.config/vt-mcp/token. If your credential is elsewhere, add
--token-file /path/to/token to the Python command. Its value stays out of commands and URLs.
New access creates a VTAI agent whose handle and activity totals may appear on the public leaderboard. Setup changes this client’s user configuration and keeps credentials in files restricted to your account. Claude Code and Codex HTTP read the protected token automatically through a local helper. For stdio, uv runs the official pinned PyPI package. Existing incompatible entries are reported before creating access.
Reconnect using the same credential. An uncertain registration is not retried automatically. If a project already configures VirusTotal, it may take precedence over the user configuration.
2. Connect your editor
Already have an Agent Token? Reuse it. Otherwise, create free access below.
Confirm installation, then paste your VTAI credential into VS Code’s password prompt. The link contains only configuration; your token stays out of the URL. This uses the local Extension Host. Servers with password inputs are not forwarded to the Agent Host. If the link cannot open your editor, use the configuration below.
This imports the configuration only. Load VTAI_MCP_TOKEN into the editor’s environment using
the instructions below before connecting. The link contains no credential; a button click does not verify access.
Open Cascade’s MCP settings and its raw configuration file. The recipe below reads your protected token file; merge it with your existing servers, then refresh the tool list. Native VTAI tool calls in Cascade remain unverified.
2. Connect GitHub Copilot CLI
Reuse your existing Agent Token, or create one below. Then add the configuration for your selected client.
Reuse or create free access
Keep using your protected credential file. Continue to the configuration below; reconnecting does not require another registration.
Create a VTAI agent named “VirusTotal MCP”. Its handle and activity totals may appear on the public leaderboard. Your selected client is recorded as a setup choice, not a verified connection.
Download before leaving. The credential is never displayed or included in code examples.
Save a downloaded credential securely
On macOS or Linux, adjust your Downloads path if necessary. The destination must not already exist.
(
set -eu
install -d -m 700 "$HOME/.config/vt-mcp"
test ! -e "$HOME/.config/vt-mcp/token"
test ! -L "$HOME/.config/vt-mcp/token"
install -m 600 "$HOME/Downloads/vtai-token.txt" "$HOME/.config/vt-mcp/token"
)A browser cannot verify the saved file or its permissions. Once the protected copy exists, remove the extra download. If a credential already exists, keep it or choose another path and update the configuration. On Windows, use Windows access permissions; these POSIX commands do not apply.
Keep credentials out of prompts, tool arguments and URLs. Store them in protected files or your client’s credential settings.
Configure your client manually
First, install the local server
Install the official vt-mcp 0.9.5 package from PyPI. Requires uv; it can provision Python 3.12 when needed.
uv tool install --python 3.12 vt-mcp==0.9.5 && uv tool update-shellOpen a fresh terminal after updating PATH. If the client cannot find vt-mcp, set its absolute executable path
in the configuration.
Merge into ~/.gemini/config/mcp_config.json, preserving other servers and settings.
{
"mcpServers": {
"virustotal": {
"command": "vt-mcp",
"env": {
"VTAI_TOKEN_FILE": "~/.config/vt-mcp/token",
"VTAI_BASE_URL": "https://ai.virustotal.com/api/v3"
}
}
}
}Restart Agy and inspect /mcp. Use your native Antigravity login; Vertex and ADC are not needed.
Native tool use verified with local stdio; host permissions still apply.
Merge into .mcp.json in your trusted project, preserving other servers and settings.
{
"mcpServers": {
"virustotal": {
"type": "http",
"url": "https://ai.virustotal.com/mcp",
"headers": {
"x-apikey": "${VTAI_MCP_TOKEN}"
}
}
}
}Inspect /mcp inside the Claude Code session started with the launch block. For a standalone check, reuse the launch block with exec claude mcp list so it loads the same protected token. Keep your existing Claude login.
Native tool use verified; choose the permissions for your task.
Merge into .mcp.json in your trusted project, preserving other servers and settings.
{
"mcpServers": {
"virustotal": {
"command": "vt-mcp",
"env": {
"VTAI_TOKEN_FILE": "~/.config/vt-mcp/token",
"VTAI_BASE_URL": "https://ai.virustotal.com/api/v3"
}
}
}
}Restart Claude Code and inspect /mcp inside its session, or run claude mcp list. The local vt-mcp process reads the protected token file. Keep your existing client login.
Native tool use verified; choose the permissions for your task.
Merge into ~/.codex/config.toml, preserving other servers and settings.
[mcp_servers.virustotal]
tool_timeout_sec = 180
url = "https://ai.virustotal.com/mcp"
[mcp_servers.virustotal.env_http_headers]
x-apikey = "VTAI_MCP_TOKEN"Inspect /mcp inside the Codex session started with the launch block. For a standalone check, reuse the launch block with exec codex mcp list so it loads the same protected token. Keep your existing Codex login.
Native tool use verified; choose the permissions for your task.
Merge into ~/.codex/config.toml, preserving other servers and settings.
[mcp_servers.virustotal]
tool_timeout_sec = 180
command = "vt-mcp"
[mcp_servers.virustotal.env]
VTAI_TOKEN_FILE = "~/.config/vt-mcp/token"
VTAI_BASE_URL = "https://ai.virustotal.com/api/v3"Restart Codex and inspect /mcp inside its session, or run codex mcp list. The local vt-mcp process reads the protected token file. Keep your existing client login.
Native tool use verified; choose the permissions for your task.
Merge into ~/.cursor/mcp.json or .cursor/mcp.json in your trusted project, preserving other servers and settings.
{
"mcpServers": {
"virustotal": {
"url": "https://ai.virustotal.com/mcp",
"headers": {
"Authorization": "Bearer ${env:VTAI_MCP_TOKEN}"
}
}
}
}Close an existing Cursor GUI before launching it with the protected environment below. Replace the executable if needed, or use exec agent for Cursor CLI. Enable virustotal in MCP settings. For CLI discovery, reuse the launch block with exec agent mcp list or exec agent mcp list-tools virustotal so each check loads the same protected token.
Cursor CLI discovery and token expansion verified locally; IDE, tool calls and model workflow pending.
Merge into .vscode/mcp.json or MCP: Open User Configuration, preserving other servers and settings.
{
"inputs": [
{
"type": "promptString",
"id": "vtai-token",
"description": "VTAI Agent Token from https://ai.virustotal.com/connect/mcp",
"password": true
}
],
"servers": {
"virustotal": {
"type": "http",
"url": "https://ai.virustotal.com/mcp",
"headers": {
"Authorization": "Bearer ${input:vtai-token}"
}
}
}
}Run MCP: List Servers, start virustotal and enter the VTAI token in its password input, outside chat. Keep the input reference in JSON. This recipe targets the Copilot Extension Host; interactive inputs are not forwarded to the Agent Host. Use the separate Copilot CLI recipe for that runtime. Local configuration and transport checks cover VS Code 1.107.1.
Native HTTP tool calls and restart verified locally; model workflow against VTAI pending.
Merge into ~/.copilot/mcp-config.json, preserving other servers and settings.
{
"mcpServers": {
"virustotal": {
"type": "local",
"command": "vt-mcp",
"env": {
"VTAI_TOKEN_FILE": "~/.config/vt-mcp/token",
"VTAI_BASE_URL": "https://ai.virustotal.com/api/v3"
},
"args": [],
"tools": [
"*"
],
"timeout": 180000
}
}
}Restart Copilot CLI and inspect copilot mcp get virustotal. The tools list controls availability; Copilot permissions control execution. Your Copilot login is separate from VTAI access. Configuration recognition was checked with Copilot CLI 1.0.83.
Domain lookup verified with a model through local stdio; other tool workflows remain unverified.
Merge into ~/.config/devin/mcp_config.json or .devin/mcp_config.local.json, preserving other servers and settings.
{
"mcpServers": {
"virustotal": {
"command": "vt-mcp",
"env": {
"VTAI_TOKEN_FILE": "~/.config/vt-mcp/token",
"VTAI_BASE_URL": "https://ai.virustotal.com/api/v3"
}
}
}
}Restart Devin Local / CLI and check the effective MCP configuration for duplicate imported entries. These dedicated MCP files apply from CLI v3000.3 / Local 3.6; earlier versions use config*.json. The local vt-mcp process reads the token file.
CLI server startup checked via ACP; tool discovery, calls and model workflow pending.
Merge into Cascade MCP settings → raw mcp_config.json, preserving other servers and settings.
{
"mcpServers": {
"virustotal": {
"serverUrl": "https://ai.virustotal.com/mcp",
"headers": {
"Authorization": "Bearer ${file:~/.config/vt-mcp/token}"
}
}
}
}In Cascade, open MCP Servers and its raw configuration file. Merge the virustotal entry into the file your version opens, preserving existing settings, then refresh the MCP servers. The documented legacy path is ~/.codeium/windsurf/mcp_config.json; Devin Desktop 3.10.23 on Linux opens ~/.config/devin/mcp_config.json. Use the file opened by the app, without adding duplicate entries. Its file expansion reads and trims the protected token file: store only the token, without Bearer or dotenv syntax. An unreadable file leaves the reference unresolved. Use the separate stdio recipe for Devin Local.
Documented setup; native tool calls and model workflow pending.
Launch your client from Bash with the protected token loaded into its environment:
(
set +x
unset VTAI_MCP_TOKEN
IFS= read -r VTAI_MCP_TOKEN < "$HOME/.config/vt-mcp/token" || test -n "$VTAI_MCP_TOKEN" || exit 1
test -n "$VTAI_MCP_TOKEN" || exit 1
export VTAI_MCP_TOKEN
exec claude
)An already open app may not inherit the environment. Keep one virustotal entry;
preserve other settings. The examples contain only paths and environment-variable names.
Use the activation steps for your selected client above to discover the VirusTotal tools. Downloaded configurations contain references, not credentials; merge them into your existing settings.
Authentication and host permissions
Use your existing client login; VTAI access is separate. This token setup does not provide OAuth. A hosted connector that requires OAuth needs a separate integration.
Remote MCP accepts the same VTAI Agent Token using x-apikey or Authorization: Bearer;
send one, not both.
Agy uses local stdio for this setup. Configure your client’s tool permissions for the authorized task. The submission tools have no per-call confirmation or consent argument; host permissions still apply. See the client guide.
Make your first tool call
Ask your agent: “Use VirusTotal to check virustotal.com. Show the source, analysis date, coverage and report link.”
Confirm it calls get_domain_report. This uses one query and does not submit a file.
Available tools and a browser access check
Your client should list get_file_report, get_url_report, get_domain_report,
get_ip_report, get_analysis, submit_file, get_submission,
submit_url, reanalyze_domain and reanalyze_ip.
Local stdio adds submit_local_file, for eleven tools.
The optional check below validates your Agent Token without spending query quota. It does not check remaining quota, upstream availability or your MCP client, and does not automatically retry.
Submit a file and recover its analysis
For an unfamiliar file without a report, submit its actual bytes under the sharing guidance above.
Ask first for the user’s own or sensitive content. submit_local_file(path, expected_sha256=None)
accepts at most 32,000,000 bytes over stdio. It copies the file accessible to the local vt-mcp process;
the optional SHA-256 must match that copy.
submit_file(sha256, content_base64) accepts at most 24,000,000 decoded bytes
over HTTP or stdio. HTTP receives bytes; it cannot read a path on your machine. Base64 passes through your
MCP host and may be retained by your model provider. Standard submission is not confidential: content may be
accessible to the VirusTotal community and security partners.
If this client cannot transfer the file bytes, offer the existing VirusTotal upload page at https://www.virustotal.com/gui/home/upload under the same sharing guidance. Before uploading, manually check the file's actual hash in VirusTotal and upload only if unknown. After the user uploads the file, obtain its actual hash and look up its report. The report may not be available immediately; every repeated query consumes quota. A web upload creates no VTAI receipt. This alternative does not bypass client permissions, authentication or quota limits, and must not repeat an uncertain submission.
For submissions through this connection, keep the SHA-256. Recover an uncertain result with get_submission(sha256) using the same connection or credential,
without sending the file again. exists returns an existing report; submitted supplies an
analysis ID. Read it with get_analysis within a finite polling budget. A submission can remain
unknown permanently; do not repeat submission to resolve it.
Analyze a URL, domain or IP address
Use submit_url(url, request_id), reanalyze_domain(domain, request_id) or
reanalyze_ip(ip, request_id). Generate and persist a canonical lowercase UUIDv4 request ID before
calling. These operations use standard VirusTotal sharing without a per-operation confirmation from VTAI.
After an uncertain response, recover with get_submission(request_id=request_id) using the same
connection. Supply exactly one of sha256 or request_id. Read the returned analysis with
get_analysis(analysis_id, request_id=request_id) within a finite polling budget. Do not automatically
replay the POST; an intentional later rescan uses a new request ID.
OAuth requires vt:reports:read and vt:network-analysis:write.
An existing file permission does not authorize network analysis. Reconnect and approve the new permission
once for that connection; Agent Tokens retain their task-authorized capabilities.
Access limits and interpreting reports
Token-based REST and MCP share 60 admitted queries per fixed 60-second window and 1000 per UTC day, per agent. Unknown reports and upstream failures still consume admitted queries. Every repeated lookup counts again, including cached reports and hashes with no report. Provider limits may also apply.
A missing report or absence of detections does not establish safety. URL lookup discloses the complete URL to VTAI and VirusTotal. Use a domain lookup when paths, query parameters or fragments contain private information. Report tools and selected-analysis reads do not submit files.
Connection problems and direct API access
For 401 or 403, check credential validity and the client’s environment, input or file mapping without displaying its value.
For 400, check malformed or conflicting authentication headers. For 429, respect Retry-After and keep
the existing credential; registering another identity is not quota recovery.
A service failure is not an unknown report; a missing /mcp endpoint is a connection problem.
A tool's not_found is unknown, not evidence of safety. When further file analysis is needed,
submit actual bytes with the existing file tools; a hash cannot start analysis. Use the network submission tools
for an explicit URL/domain/IP analysis and retain its request ID for recovery.
X-VTAI-Error: unexpanded_credential means an x-apikey variable reference
was sent literally. Load the protected token into the client environment and use its documented variable syntax.
Do not paste the token into chat or register again. This specific diagnostic applies to x-apikey.
Prefer direct HTTP? Use the same token with https://ai.virustotal.com/api/v3.
Read the agent API instructions or interactive API docs.
Registration is POST /api/v3/agents/register; reconnecting does not require another registration.
Disconnect a client
Remove or disable the virustotal entry, restart the client and confirm the tools disappear.
Other clients using the same credential retain access. Remove stored credentials only when no client needs them.
Reconnect with the same credential while it remains active. VTAI history is retained.
Revoke this credential everywhere
Revoking the credential disables this agent’s access through REST and MCP in every client. Existing records remain. A query admitted before revocation may finish.
Keep your protected copy if revocation is not confirmed, so you can try again.