Skip to main content
Glama
arielfikru

scanything

by arielfikru

Scanything

Scan any file for malware, with an AI that explains false positives.

Scanything dissects a .zip, .exe, .dll or a GitHub repository without ever running it, tells you whether it looks malicious, explains whether an antivirus alert is probably a false positive, and lets you chat about the result. It works inside Claude Code and Codex as an MCP server, or on its own with your API key.

🇮🇩 Bahasa Indonesia: docs/README.id.md

Quick start

pip install "scanything[pe] @ git+https://github.com/arielfikru/scanything"

Then pick one:

scanything setup                 # use it from Claude Code / Codex (agent mode)
export NETRA_API_KEY=...         # or OPENROUTER_API_KEY / OPENAI_API_KEY
scanything ~/Downloads/file.zip  # standalone AI analyst (orchestrator mode)

No key and no agent? scanything file.zip --no-llm still gives the full static report.

Checking a repository before you clone it? scanything https://github.com/OWNER/REPO downloads the archive pinned to one commit and scans it in memory. Nothing is cloned, built or run.

Related MCP server: Malware-Sandbox-mcp

Two modes, one engine

🤖 Agent mode (MCP)

🧠 Orchestrator mode

The AI is

your coding agent: Claude Code, Codex, any MCP client

Scanything's built-in analyst

You need

the agent you already use

an API key: Netra, OpenRouter, OpenAI, or any OpenAI-compatible server

Start with

scanything setup, then ask your agent

scanything file.zip

Good for

working in your editor or terminal agent

standalone use, scripts, CI

Both modes use the same tools: scan_file, scan_github, get_report_section, search_strings, list_files, vt_lookup.

🤖 Agent mode: Claude Code & Codex

scanything setup              # both agents
scanything setup claude       # only Claude Code
scanything setup --dry-run    # show what would happen

Agent

MCP server

Skill

Claude Code

claude mcp add --scope user scanything -- <python> -m scanything mcp

~/.claude/skills/scanything/SKILL.md

Codex

codex mcp add scanything -- <python> -m scanything mcp

~/.codex/skills/scanything/SKILL.md

No codex CLI on PATH? Add this to ~/.codex/config.toml:

[mcp_servers.scanything]
command = "/path/to/python"
args = ["-m", "scanything", "mcp"]

Restart the agent and ask:

> is ~/Downloads/Game_Setup.zip a virus? Defender says Wacatac

The agent calls scan_file, digs with search_strings and get_report_section, and answers with a verdict, the false-positive reasoning, the scan_id, and a next step.

🧠 Orchestrator mode: your own API key

Put one key in ~/.config/scanything/.env (template: .env.example) or export it, then:

$ scanything Game_Setup.zip --vt

== scanything: Game_Setup.zip ==
scan_id scn_9f2c41d0b7e3a8c5d1e6f402  ·  file_id (sha256) 5d41…c2a9  ·  ruleset rs_ace23f4945c8
Heuristic verdict: SUSPICIOUS  (score 11, 3 file(s), static only)

  #  type         size  score  name
  0  zip        4.1 MB      4  Game_Setup.zip
  1  pe         9.8 MB      7    └ Setup.exe
  2  text        312 B      0    └ readme.txt

[*] Asking deepseek/deepseek-v4-flash-0731 via netra for a verdict...
   ↳ get_report_section(files[1].pe.suspicious_imports)
   ↳ search_strings({"file_index": 1, "pattern": "webhook|telegram"})

## Verdict: LIKELY FALSE POSITIVE (confidence 75%)
...
verdict_id vrd_3b8e…  ·  scan_id scn_9f2c41d0b7e3a8c5d1e6f402
you> why does Defender call it Wacatac?

Providers

--provider

Key

Default model

netra ⚡ recommended

NETRA_API_KEY

deepseek/deepseek-v4-flash-0731

openrouter

OPENROUTER_API_KEY

anthropic/claude-haiku-5.5

openai

OPENAI_API_KEY

gpt-6-luna

custom

LLM_API_KEY + LLM_BASE_URL

LLM_MODEL

  • Without --provider, Scanything uses LLM_PROVIDER, else the first key it finds (Netra → OpenRouter → OpenAI).

  • --model or LLM_MODEL picks any other model. scanything models lists what your provider serves right now.

  • Models without tool calling still work: Scanything falls back to plain chat, or pass --no-tools.

Options

scanything setup.exe --vt                   # VirusTotal hash lookup (never uploads)
scanything locked.zip --password infected   # encrypted archives
scanything file.exe --no-llm --json-out file.report.json   # offline, no AI
scanything file.exe --no-chat --md-out verdict.md          # CI / batch
scanything file.exe --provider openrouter --model anthropic/claude-sonnet-5.5 --lang en
scanything https://github.com/OWNER/REPO --no-llm             # a repository, pinned to its latest commit
scanything github:OWNER/REPO@v1.2.0                          # a branch, tag or commit

Flag

Meaning

--vt, --vt-max N

VirusTotal lookup of up to N hashes (needs VT_API_KEY)

--clamav

also run clamscan

--yara PATH

YARA rule file or folder

--password

zip password (infected, malware, virus are always tried)

--no-llm, --no-chat, --no-tools

static only, verdict only, model without function calling

--provider, --model, --base-url, --lang

override .env

--json-out, --md-out

save the full report, save the AI transcript

GITHUB_TOKEN (optional) raises GitHub's rate limit and gives access to private repositories you can read.

In chat: /save [file.md], /exit. Config is read from ./.env, then ~/.config/scanything/.env.

What it checks

Layer

What Scanything looks at

Archive

nested zips, zip-slip paths, zip bombs, password-protected executables, decoy names (invoice.pdf.exe, RLO tricks), scripts, shortcuts and disk images inside

PE (.exe, .dll)

sections and entropy, W+X sections, entry point, imports grouped by behaviour (injection, keylogging, download, anti-debug…), Authenticode presence and certificate names, version info, overlay including anti-scan padding, embedded PEs

Toolchain DB

a Detect It Easy style database of about 40 signatures: installers (NSIS, Inno, WiX, 7-Zip SFX…), runtimes (PyInstaller, Nuitka, AutoIt, Go, Rust, .NET, Electron…), compilers (MSVC Rich header, MinGW, Delphi, VB6), packers (UPX, ASPack, MPRESS…), protectors (VMProtect, Themida, Enigma…) and .NET obfuscators, each with its false-positive note

Strings & IOCs

URLs, IPs, registry keys, PowerShell cradles, LOLBins, shadow-copy deletion, Defender tampering, stealer paths, Discord/Telegram exfil, miners, ransom notes, EICAR, prompt-injection text

Hidden strings

FLOSS-style recovery without emulation: x86 stack strings, single-byte XOR, base64 blobs and embedded PEs, PowerShell -EncodedCommand. Decoded text goes through the IOC rules and search_strings (prefixed [decoded])

Source code

in repositories and any archive: npm install hooks, setup.py that execs or downloads, exec(base64…), eval(atob…), VS Code tasks that run on folder open, MSBuild build events, workflows that leak secrets or run fork PRs with secrets, curl … | sh, code hidden far right, Trojan Source bidi characters

Repository

stars against owner-account age (star farming), new repository, fork, archived. Metadata never changes scan_id; the code is pinned by commit

Optional engines

VirusTotal hash lookup, ClamAV, YARA, osslsigncode signature verification

MITRE ATT&CK

Signals map to the ATT&CK technique they are typical of, like capa does, and the summary lists every technique with its evidence (T1490 Inhibit System Recovery <- #1 shadow_copy_delete). A mapping means "this evidence is typical of the technique", not proof that the file performs it.

How false positives are judged

Every signal carries an fp_note saying when it is harmless, and the AI weighs those against the evidence.

Usually a false positive

Usually real

1–3 VirusTotal engines, all generic/ML names (Wacatac, Generic, ML.Attribute, Artemis)

named malware families across many engines

PyInstaller, Nuitka, AutoIt or Go binaries

injection + network + persistence together

UPX packing, NSIS or Inno Setup installers

stealer paths plus an exfil channel

signed by a known publisher (verified with osslsigncode)

decoy extensions, padded overlays, encrypted archives hiding an exe

Scan IDs

Every result gets IDs, like the hash-based IDs of malware scanning platforms.

ID

Deterministic?

Computed from

file_id

✅ always

SHA-256 of the file (same as VirusTotal)

scan_id

✅ same file + name + Scanything version + ruleset

hash of the static analysis

ruleset

✅

hash of every detection rule table

verdict_id

❌ one per AI answer

hash of scan_id + provider + model + answer

scan_id ignores volatile data (timestamps, local path, VirusTotal/ClamAV results), so anyone scanning the same file with the same version gets the same id. It also seals the report:

from scanything.ids import scan_id_of
assert scan_id_of(report) == report["ids"]["scan_id"]   # fails if the JSON was edited

With --json-out, the report also holds verdict = {verdict_id, scan_id, label, confidence, provider, model, created}.

Try it safely

python scripts/make-test-samples.py   # harmless samples in ./samples (gitignored)
scanything samples/eicar.zip          # EICAR: every AV flags it, it does nothing
scanything samples/stealer_lookalike.exe

The samples are one-instruction PE stubs with malware-like strings, plus the standard EICAR test file. None of them does anything when run.

We highly recommend Netra Runtime for orchestrator mode: fast inference, an OpenAI-compatible API, and DeepSeek V4 Flash 0731 handles the tool calling the analyst relies on. It is the first provider Scanything looks for, so NETRA_API_KEY is all you need. Save a key from your clipboard with scripts/save-netra-key (macOS).

The recommendation appears in this README, as a CLI hint when no key is set, as a one-line footer when Netra produced the verdict, and in the agent instructions only if you ask which provider to use. It never appears inside a verdict or affects how files are judged. SCANYTHING_NO_RECOMMEND=1 hides it.

How it works

file or GitHub repo ──► scanner (recursive, in memory, never executed)
           ├─ static: type, hashes, entropy, strings/IOCs, PE, toolchain DB, decoded strings, code rules
           ├─ archive: entries, passwords, bombs, nested files
           └─ engines (optional): VirusTotal, ClamAV, YARA, osslsigncode
        ──► report: signals + fp_notes + heuristic score + file_id / scan_id
        ──► tools: scan_file · scan_github · get_report_section · search_strings · list_files · vt_lookup
              ├─ MCP server ──► Claude Code / Codex / any MCP client     (agent mode)
              └─ built-in analyst ──► Netra / OpenRouter / OpenAI       (orchestrator mode)

Module

Role

static.py

file type, string and IOC rules, PE parser

signatures.py / deobf.py

toolchain signature DB / hidden-string recovery

repo.py

GitHub download pinned to a commit, source code and metadata rules

attack.py

signal → MITRE ATT&CK mapping

scanner.py

recursive scan, zip handling, YARA, signature verification

engines.py

VirusTotal and ClamAV

api.py

scan_path(), shared by the CLI and the MCP server

report.py / ids.py

report, compact AI view, terminal summary / deterministic ids

agent.py / providers.py

OpenAI-compatible client, tool loop, chat / provider presets

mcp_server.py / setup_agents.py

MCP server (stdio) / scanything setup

skills/SKILL.md

agent skill

Content from a scanned file is untrusted: both the MCP instructions and the analyst prompt say so, and text that tries to steer an AI is flagged as a prompt_injection signal.

Limits

  • Static analysis can never prove a file is safe. When in doubt, use a sandbox (ANY.RUN, Hybrid Analysis, Tria.ge) or the vendor's published hash.

  • No machine-learning score: there is no trained, openly licensed model small enough for a stdlib-only core, and an unexplained number would undercut the false-positive reasoning. VirusTotal results already include vendors' ML engines.

  • Hidden-string recovery is pattern based, not emulation: multi-byte XOR, RC4 and runtime-built strings are not recovered.

  • Repositories: up to 10,000 archive entries and 3,000 analyzed files, 512 MiB archive. Only what is in the repository is scanned, not the dependencies it pulls at install time.

  • 7z, RAR and ISO are detected but not unpacked yet: extract them without running anything, then scan the contents.

  • Authenticode is only verified when osslsigncode is installed; otherwise Scanything reports its presence and certificate names.

  • The AI can be wrong. Treat its verdict as a second opinion with cited evidence.

Development

git clone https://github.com/arielfikru/scanything && cd scanything
python -m venv .venv && .venv/bin/pip install -e ".[dev]"
.venv/bin/pyflakes scanything tests && .venv/bin/pytest -q

See CONTRIBUTING.md, AGENTS.md and SECURITY.md. Never commit live malware.

License

MIT, see LICENSE.

Available Tools

5 tools
get_report_sectionA
Read-only

Return part of the FULL JSON report by path, e.g. 'files[1].pe.imports', 'files[0].archive.entries', 'files[2].iocs', 'engines'. Empty path lists top-level keys.

NameRequiredDescriptionDefault
pathYes
scan_idYesscan_id returned by scan_file

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare this as a safe read-only operation with openWorldHint false, so the safety profile is covered. The description adds useful behavioral context about report navigation and empty-path behavior, but does not explain invalid-path handling or what a returned section looks like.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded, compact, and every clause carries useful information: the return concept, several path examples, and the empty-path behavior. There is no redundant or filler text.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only report-navigation tool with no output schema and only two parameters, the description provides enough to call it correctly. A note about invalid paths or scan readiness would make it fully complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is only 50%, and the path parameter is undocumented in the schema. The description compensates well with concrete path examples and the empty-path rule for listing top-level keys, though it does not formally define the path syntax.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states a specific verb and resource: returning a portion of the FULL JSON report by path. This distinguishes it functionally from scan_file, list_files, and search_strings, though no sibling is named explicitly, so it falls short of the top score.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explains path mechanics but gives no guidance on when to choose this tool over alternatives such as search_strings or list_files. It also omits preconditions such as needing a completed scan or a valid scan_id, leaving selection to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_filesB
Read-only

List all analyzed files with index, parent, type, size, score and sha256.

NameRequiredDescriptionDefault
scan_idYesscan_id returned by scan_file

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds useful context about what is returned (all analyzed files with specific fields), but it does not mention ordering, pagination, or any other operational behavior beyond the structured annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence that clearly states the action and the returned fields with no wasted words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only listing tool with one fully documented required parameter and annotations covering safety, the description is largely complete: it states what is listed and which fields appear in the result. Minor gaps around ordering or pagination remain, but no output schema exists and the description carries the key return-value information.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema has 100% description coverage and documents the sole scan_id parameter as 'scan_id returned by scan_file'. The description adds no additional parameter meaning beyond that schema, which is the baseline for high schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb and resource: 'List all analyzed files' and enumerates the returned fields (index, parent, type, size, score, sha256). This clearly tells an agent what the tool does, but it does not explicitly distinguish the tool from siblings like search_strings or scan_file.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no explicit when-to-use guidance, prerequisites, or alternatives. An agent must infer that this is used after scan_file to inventory results; there is no statement about when to choose this over search_strings or other siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

scan_fileA
Read-only

Statically scan a file on disk (zip, exe, dll, script, anything) for malware and false-positive indicators. The file is never executed. Returns a compact report and a deterministic scan_id for follow-up tools.

NameRequiredDescriptionDefault
pathYesabsolute path to the file
passwordNozip password (infected/malware/virus are tried)
virustotalNohash lookup on VirusTotal (needs VT_API_KEY; never uploads)

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false; the description adds genuinely new behavioral facts — the file is never executed, output is a compact report, and a deterministic scan_id is produced for chaining. It omits cost/size limits, failure modes, and does not discuss the optional VirusTotal network call despite openWorldHint=false.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, no filler: the scan action first, the safety guarantee second, the return contract last. Every sentence carries information an agent needs.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description correctly supplies the return contract (compact report plus deterministic scan_id) and the no-execution guarantee. It falls slightly short on what to do with scan_id, error behavior for unsupported or locked files, and the network implications of the virustotal option.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already explains path, zip password, and virustotal. The description adds nothing parameter-specific beyond noting zip among the file types, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource (statically scan a file on disk) and enumerates covered file types (zip, exe, dll, script), so it is clearly the on-disk counterpart to scan_github. It never names that sibling explicitly, which is the only thing keeping it from a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied: 'for follow-up tools' hints at get_report_section/search_strings, and 'file on disk' implies the split with scan_github. There is no explicit statement of when to prefer this over scan_github or what happens when a file type isn't supported.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

scan_githubA
Read-only

Download a public GitHub repository (zip archive pinned to one commit) and scan it statically: install hooks, obfuscated exec/eval, auto-run VS Code tasks, risky workflows, binaries inside, plus repository metadata. Nothing is cloned, built or run. Returns the same compact report and scan_id as scan_file.

NameRequiredDescriptionDefault
repoYeshttps://github.com/OWNER/REPO[/tree/REF] or github:OWNER/REPO[@REF]
virustotalNohash lookup of the binaries inside

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true; the description is consistent and adds real value with "zip archive pinned to one commit" and "Nothing is cloned, built or run", which tells the agent scanning is static and deterministic. It omits GitHub API rate limits and any size/private-repo restrictions, which are relevant for an openWorld network tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single dense sentence, front-loaded with the action and immediately followed by what is checked and the safety guarantee. No filler sentences.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description compensates by referencing the report shape via scan_file. It stops short of describing report contents or limits, but for a two-parameter scan tool this is largely sufficient.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents both parameters and their accepted formats. The description adds only the implied notion that a scan is pinned to a single commit/REF, which the schema itself already conveys via the [/tree/REF] syntax; the virustotal option is not amplified at all.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ("Download a public GitHub repository ... and scan it statically") and enumerates exactly what is examined: hooks, obfuscated exec/eval, VS Code tasks, workflows, binaries, metadata. It also ties itself to its sibling by promising "the same compact report and scan_id as scan_file", so an agent can distinguish this from scan_file at a glance.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Makes the usage context clear — public repos only, and the "Nothing is cloned, built or run" note tells the agent this is a safe static analysis path. It does not explicitly state when to prefer it over scan_file (repo URL vs local file), leaving that inference to the agent.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_stringsB
Read-only

Case-insensitive regex search over printable strings extracted from one file.

NameRequiredDescriptionDefault
limitNomax results, default 40, max 200
patternYes
scan_idYesscan_id returned by scan_file
file_indexYes

TDQS

B3.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so safety is covered. The description adds useful traits: case-insensitive matching, regex semantics, and that it searches printable strings from a single file. It does not disclose result format, regex dialect, or how matches are returned.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single dense sentence with zero waste; the core matching semantics and scope are front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description should indicate what a match looks like (offsets? string context? counts?), and it does not. For a search tool returning potentially many results, this leaves a meaningful gap beyond what annotations and schema cover.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 50%: 'limit' and 'scan_id' are documented in the schema, but 'pattern' and 'file_index' are not. The description clarifies that pattern is a case-insensitive regex and that scope is one file, partially compensating for file_index, but adds no format detail for pattern syntax or indexing conventions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: regex search over printable strings extracted from one file. Clear what it does, though differentiation from siblings (scan_file, list_files) is only implicit — 'extracted from one file' hints it operates on prior scan output rather than raw files.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No explicit when-to-use or when-not guidance, and no sibling alternatives named. The dependency on a prior scan is only inferable from the schema's 'scan_id returned by scan_file', not from the description itself.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 5 tool updatesv0.1.0
    • First observedget_report_section
    • First observedlist_files
    • First observedscan_file
    • First observedscan_github
    • First observedsearch_strings

TDQS

A3.9/5.0

Scored across 5 tools

Disambiguation5/5

Each tool has a clearly distinct role: scan a local file, scan a GitHub repo, retrieve a report section, search strings in one file, or list analyzed files. The two scan tools differ by input source and the follow-up tools target different inspection needs.

Naming Consistency5/5

All tool names follow a consistent snake_case verb_noun pattern: scan_file, scan_github, get_report_section, search_strings, list_files. There are no mixed conventions or vague names.

Tool Count5/5

Five tools is well-scoped for a static malware scanning service. There are two entry-point scan tools and three focused follow-up tools, with no obvious redundancy.

Completeness4/5

The surface covers scanning local files and GitHub repos, then inspecting results via file listing, report sections, and string search. Minor gaps exist, such as no explicit full-report retrieval or batch scanning, but core workflows are covered.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    B
    maintenance
    Integrates 15+ static application security testing tools (Semgrep, Bandit, TruffleHog, etc.) with Claude Code AI, enabling automated vulnerability scanning and security analysis through natural language commands. Supports cross-platform operation with remote execution on dedicated security VMs.
    6
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables scanning of AI agent code for security vulnerabilities such as prompt injection, tool abuse, and data exfiltration, directly from MCP-compatible clients like Claude Code.
    34 PyPI
    3
    LGPL 3.0
  • A
    license
    A
    quality
    D
    maintenance
    Enables scanning of Claude Code skills, plugins, or MCP servers for malware before installation via static analysis.
    1
    14 npm
    MIT