mcpField
S
ScanMalware.com URL Scanner

ScanMalware.com URL Scanner

远程服务
mcp.scanmalware.com安全02 周前更新

关于 ScanMalware.com URL Scanner

ScanMalware.com URL Scanner 是基于 ScanMalware.com 公共 API 的 Python MCP 服务,为需要检查 URL 的安全工作流提供扫描与分析接口。可用工具涵盖扫描提交和多类结果查询,并支持配置扫描可见性。

主要功能

  1. 01提交 URL 扫描并指定可见性
  2. 02查询扫描结果与风险信息
  3. 03检索 JavaScript 指纹和混淆
  4. 04查看 TLS 与证书信息
  5. 05支持 HTTP 与 SSE 传输

适用场景

  1. 01分流疑似钓鱼 URL
  2. 02监控品牌仿冒扫描结果
  3. 03检查 TLS 证书与域名匹配

MCP 相关

该 MCP 服务将 ScanMalware.com API 封装为供 MCP 客户端调用的工具。通过 Streamable HTTP 或 SSE 提供连接;HTTP 传输可配置 Bearer 令牌验证。

配置

远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。

服务地址https://mcp.scanmalware.com/mcp
一键复制安装命令
Claude CodeTerminal
Cursor.cursor/mcp.json
VS Code.vscode/mcp.json
Claude Desktopclaude_desktop_config.json
Windsurf~/.codeium/windsurf/mcp_config.json

命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。

全部服务地址
Streamable HTTPhttps://mcp.scanmalware.com/mcp需要授权

工具

128
参数类型必填说明
pageinteger否
limitinteger否

详细介绍

scanmalware-mcp

精简的 Python MCP 服务,封装了 ScanMalware.com 的公开 API。

运维

部署、TLS、日志记录、安全维护以及如何连接到 DigitalOcean droplet,请参阅运维手册。

在本地运行(Streamable HTTP)

python -m venv .venv
source .venv/bin/activate
pip install -U pip
pip install .

export MCP_TRANSPORT=streamable-http
export MCP_HOST=127.0.0.1
export MCP_PORT=8000

scanmalware-mcp

使用 Docker 运行

docker build -t scanmalware-mcp .
docker run --rm -p 127.0.0.1:8000:8000 \
  -e MCP_TRANSPORT=streamable-http \
  -e MCP_HOST=0.0.0.0 \
  -e MCP_PORT=8000 \
  scanmalware-mcp

可选:设置 MCP_AUTH_TOKEN,要求 HTTP 传输使用 Authorization: Bearer <MCP_AUTH_TOKEN>。

可选的身份验证环境变量(仅在需要身份验证的端点中使用):

  • SCANMALWARE_BEARER_TOKEN

其他环境变量:

  • SCANMALWARE_BASE_URL(默认值:https://scanmalware.com)
  • SCANMALWARE_ALLOW_HTTP(默认值:false)
  • SCANMALWARE_TIMEOUT_S(默认值:30)
  • SCANMALWARE_SLOW_QUERY_TIMEOUT_S(默认值:90;用于 favicon 和技术统计、OCR 文本搜索、JS 指纹相似度计数及行为特征搜索)
  • SCANMALWARE_MAX_DOWNLOAD_BYTES(默认值:10485760)
  • SCANMALWARE_ALLOW_PRIVATE_TARGETS(默认值:false)
  • SCANMALWARE_CA_CERT(可选;用于 SSL bump 的 CA 证书包路径)

MCP 服务安全环境变量:

  • MCP_AUTH_TOKEN(如果已设置,HTTP 传输需要 Authorization: Bearer <token>)
  • MCP_RESOURCE_SERVER_URL / MCP_ISSUER_URL(可选;仅在设置了 MCP_AUTH_TOKEN 时使用)

传输说明:HTTP 传输以无状态模式运行(stateless_http=True),因此响应不包含 mcp-session-id 标头。客户端不得要求该标头。这使每个会话的状态保持不变, 从而让内存占用保持稳定。服务支持两代 MCP 协议:initialize (2024-11-05 至 2025-11-25)和 server/discover(2026-07-28)。请求使用 POST; 对 /mcp 的 GET 请求会返回 405,因为服务不提供独立的 SSE 流。

SSE 传输:设置 MCP_TRANSPORT=sse,还可以选择设置 MCP_SSE_MOUNT_PATH,以在 路径前缀下提供服务。

工具说明:submit_scan 不会调用 /api/v1/csrf-token;没有 CSRF 令牌工具。 工具说明:某些上游端点已禁用,因此不会列入工具列表(例如 get_improvements、find_screenshot_duplicates、get_ai_stats、search_js_fingerprinter2_code_hash、search_js_segments_by_tlsh)。 筛选器:每个搜索工具都可以使用默认值调用。 如果未提供模式筛选器,search_js_fingerprint_patterns 会应用 has_eval=true, 因为 API 要求提供筛选器;search_js_obfuscation 和 search_js_malware_families 则使用 API 自身的默认值。分数筛选器 使用 API 的量表,并会在请求发出前进行检查:AI 风险评分为 0-10,AI 置信度为 0-100,JS 混淆评分为 0-1,运行时 JS 风险 评分为 0-100。OCR 搜索在去除首尾空白后,至少需要三个字符。 库查询使用 get_js_library_inventory 检测到的标识符; search_js_fingerprint_by_library 接受 Next.js 作为检测到的标识符 nextjs 的别名。

扫描可见性

submit_scan 要求提供 scan_type;没有默认值。public 扫描会将目标 URL 和扫描结果发布到 ScanMalware 的公开动态中,其他用户和搜索引擎均可查看。对于客户目标、机密 URL 和安全服务项目,请谨慎选择:

  • public:发布扫描结果。只有在明确获准发布时,才可用于这些目标。
  • unlisted:不显示在公开列表中,但任何拥有直接链接的人都可以访问。
  • private:只有经过身份验证的 ScanMalware 账户才能查看结果。 需要在 MCP 服务上配置有效的 SCANMALWARE_BEARER_TOKEN; MCP_AUTH_TOKEN 仅用于控制对 MCP 服务的访问,不提供 ScanMalware 身份验证。

如果尚未为这些目标指定可见性,请先询问用户选择 unlisted 或 private,再提交。如果提交失败,不要重试并改用限制较少的可见性。 这些模式控制扫描结果的可见性;请求仍会发送到 ScanMalware,并可能记录 在服务端日志中(请参阅 MCP 隐私政策)。ScanMalware 在其隐私政策中说明了可见性选项。

示例提示词

钓鱼事件分诊(提交 → 等待 → 总结):

Submit an unlisted scan for https://example-login-update.com, wait for completion, and
return status, risk_score, and the top indicators. If high risk, include the
AI analysis and screenshot resource.

品牌侵权监控:

Search scans for "acme login" (limit 5). For each result, list scan_id,
status, risk_score, and URL. Highlight anything marked high risk.

TLS/证书检查:

For scan_id 1234...abcd, fetch TLS details and the certificate PEM download.
Summarize issuer, subject, validity dates, and SANs; flag mismatches.

部署到 DigitalOcean(Debian + Docker + Nginx)

部署包位于 deploy/ 中,会运行三个容器:

  • mcp(此服务,通过 8000 端口提供可流式传输的 HTTP)
  • nginx(前端,使用 80/443 端口;将 HTTP 重定向到 HTTPS,并将 /mcp 代理到 MCP 服务)
  • proxy(mitmproxy,检查 ScanMalware 目标并记录上游 HTTP 流量)
前置条件
  • 已通过身份验证的 doctl(doctl auth init)
  • 已上传到 DigitalOcean 的 SSH 密钥(供 doctl compute droplet create 使用)
  • 启动 Nginx 前,已在 HTTPS / TLS 所列路径配置 DNS 和 Let's Encrypt 证书
在德国(法兰克福)创建一个小型 Droplet
DROPLET_NAME=scanmalware-mcp-small
REGION=fra1
SIZE=s-1vcpu-2gb
IMAGE=debian-12-x64
SSH_KEYS=$(doctl compute ssh-key list --format ID --no-header | paste -sd, -)

doctl compute droplet create "$DROPLET_NAME" \
  --region "$REGION" \
  --size "$SIZE" \
  --image "$IMAGE" \
  --ssh-keys "$SSH_KEYS" \
  --tag-name scanmalware-mcp \
  --wait
防火墙(公开 HTTP/HTTPS + SSH)
doctl compute firewall create \
  --name scanmalware-mcp-fw \
  --inbound-rules "protocol:tcp,ports:22,address:0.0.0.0/0,address:::0/0" \
  --inbound-rules "protocol:tcp,ports:80,address:0.0.0.0/0,address:::0/0" \
  --inbound-rules "protocol:tcp,ports:443,address:0.0.0.0/0,address:::0/0" \
  --outbound-rules "protocol:icmp,ports:0,address:0.0.0.0/0,address:::0/0" \
  --outbound-rules "protocol:tcp,ports:0,address:0.0.0.0/0,address:::0/0" \
  --outbound-rules "protocol:udp,ports:0,address:0.0.0.0/0,address:::0/0" \
  --droplet-ids <droplet-id>
在 Droplet 上安装 Docker + compose

从 Docker 官方 apt 仓库安装 Docker Engine 和 Compose 插件。使用 docker compose;旧版 Python docker-compose 客户端与当前 Docker Engine 不兼容。

有关固定版本构建和维护检查,请参阅运维手册。

上传并运行
# Package exactly one commit; a tar of the working tree also picks up untracked
# files (.tools/, caches, egg-info) and uncommitted edits.
git archive --format=tar.gz -o /tmp/scanmalware-mcp.tar.gz origin/main
scp -i /path/to/key /tmp/scanmalware-mcp.tar.gz root@<droplet-ip>:/tmp/
ssh -i /path/to/key root@<droplet-ip> \
  "mkdir -p /opt/scanmalware-mcp && tar -xzf /tmp/scanmalware-mcp.tar.gz -C /opt/scanmalware-mcp"

在全新主机上,启动 MCP 和 Nginx 前,请按照 TLS 检查(mitmproxy) 构建代理并生成其 CA。作为主机设置的一部分,安装 出口规则和 Docker 启动钩子 以及日志轮换。

验证
curl -I https://mcp.scanmalware.com/
curl -sS -o /dev/null -w '%{http_code}\n' https://mcp.scanmalware.com/mcp

/ 应从 Nginx 返回 200。对 /mcp 发送 GET 请求会返回 405,这是预期行为:该服务不提供独立的 SSE 流,因此 MCP 请求使用 POST。

烟雾测试(MCP initialize + tools/list)
python - <<'PY'
import json
import httpx

URL = "https://mcp.scanmalware.com/mcp"
HEADERS = {
    "accept": "application/json, text/event-stream",
    "content-type": "application/json",
}

init_payload = {
    "jsonrpc": "2.0",
    "id": 1,
    "method": "initialize",
    "params": {
        "protocolVersion": "2025-06-18",
        "capabilities": {},
        "clientInfo": {"name": "mcp-smoke-test", "version": "0.1.0"},
    },
}

with httpx.Client(timeout=10) as client:
    init_resp = client.post(URL, headers=HEADERS, json=init_payload)
    init_resp.raise_for_status()
    # Stateless deployments return no session header.
    session_id = init_resp.headers.get("mcp-session-id")

    def extract_sse_data(text: str) -> dict:
        for line in text.splitlines():
            if line.startswith("data: "):
                return json.loads(line[len("data: "):])
        raise ValueError("No SSE data line found")

    init_message = extract_sse_data(init_resp.text)
    protocol_version = init_message["result"]["protocolVersion"]

    headers = {**HEADERS, "mcp-protocol-version": protocol_version}
    if session_id:
        headers["mcp-session-id"] = session_id

    # Send initialized notification
    client.post(
        URL,
        headers=headers,
        json={"jsonrpc": "2.0", "method": "notifications/initialized"},
    )

    tools_resp = client.post(
        URL,
        headers=headers,
        json={"jsonrpc": "2.0", "id": 2, "method": "tools/list"},
    )
    tools_resp.raise_for_status()
    tools_message = extract_sse_data(tools_resp.text)
    tool_names = [tool["name"] for tool in tools_message["result"]["tools"]]

print("protocol_version:", protocol_version)
print("tool_count:", len(tool_names))
print("tools:", ", ".join(tool_names))
PY
重新部署 / 新部署

两种常见流程:

  1. 原地更新(同一 Droplet)
# Package exactly one commit; a tar of the working tree also picks up untracked
# files (.tools/, caches, egg-info) and uncommitted edits.
git archive --format=tar.gz -o /tmp/scanmalware-mcp.tar.gz origin/main
scp -i /path/to/key /tmp/scanmalware-mcp.tar.gz root@<droplet-ip>:/tmp/
ssh -i /path/to/key root@<droplet-ip> \
  "bash /opt/scanmalware-mcp/deploy/redeploy.sh /tmp/scanmalware-mcp.tar.gz"

重新部署脚本会停止全部三个容器,替换文件,并重新构建和启动 所有镜像(docker compose up -d --build),同时保留 mitmproxy CA。它会删除 Droplet 上不在 git 中的文件(logs/ 以外的所有内容)。如果 Droplet 上还没有该脚本,请先运行一次旧版 tar + docker compose 命令来安装它。

可选的一次性仓库根目录辅助命令(它会打包工作树,包括 未提交的更改,而不是某个提交):

./deploy/push-redeploy.sh root@<droplet-ip> /path/to/key

如需在停机几秒的情况下仅更新 MCP 服务,请参阅 仅更新 MCP 服务。

  1. 滚动部署(新 Droplet)
  • 创建一个新 Droplet(见上述步骤)
  • 部署相同的部署包
  • 将 DNS 切换到新 IP
  • 准备就绪后销毁旧 Droplet
doctl compute droplet delete <old-droplet-id> --force

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。