script-decoder-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@script-decoder-mcp analyze this PowerShell script and explain what it does"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Script Decoder MCP
A defensive, static-analysis MCP server that explains what a script does — in plain English and with technical evidence — without ever executing it.
Paste a Python, PowerShell, shell, JavaScript, batch, or VBScript script (or a single command line) and get back: a behavior breakdown (network, file, process, persistence, credential-access, discovery, defense-evasion, execution), safely decoded obfuscated content, extracted indicators of compromise, a transparent risk score, and a contextual MITRE ATT&CK mapping — all with source-line evidence and explicit observed/inferred/ possible classifications.
Defensive-use statement: this project performs static analysis only. It never executes, imports, compiles-for-execution, or otherwise runs submitted content. It never sends submitted scripts or decoded content to any third-party service. It is intended for SOC analysts, incident responders, and anyone who needs to understand an unfamiliar or suspicious script before deciding what to do with it — not to enable offensive use.
Features
Five MCP tools:
analyze_script,decode_blob,extract_indicators,explain_command,compare_scripts.A local browser GUI (see Browser GUI) for the same five analyses, with no MCP client required.
Six language analyzers: Python (AST-based), PowerShell, shell (bash/sh/zsh), JavaScript, batch, and VBScript (rule-based).
Bounded recursive decoding: Base64, Base32, hex, URL encoding, Unicode escapes, HTML entities, gzip/zlib/bz2, ROT13, reversed strings, PowerShell
-EncodedCommand, integer/char-code arrays, simple string concatenation, and explicit-key XOR — chained safely up to a configurable depth, with decompression-bomb protection.IOC extraction: URLs, domains, IPv4/IPv6, emails, file paths, registry keys, hashes, mutex-like strings, user agents, named pipes, scheduled-task/service names, and common cloud resource identifiers — including defanged-notation recognition (
hxxp,example[.]com,10[.]0[.]0[.]1).Transparent, documented risk scoring (0-100) with contributing factors listed in every response — never a black box, never a malware verdict.
Conservative, local, offline MITRE ATT&CK mapping.
Prompt-injection safe: all submitted and decoded content is treated as inert data, never as instructions, and is explicitly labeled as untrusted in evidence excerpts.
Optional, local, disabled-by-default CyberChef-style adapter for a small set of additional decode operations, with no network access and an operation allowlist.
No outbound network access is required or performed during analysis.
Related MCP server: retriage
Architecture
See docs/architecture.md for the full breakdown. In short:
MCP client (e.g. Claude Desktop)
│ stdio (default) or localhost HTTP
▼
server.py (5 MCP tools)
│
├─ analyzers/ language detection + per-language static analysis (AST for
│ Python, regex/rule-based for the rest)
├─ decoding/ bounded recursive decoding engine, native decoders, optional
│ local CyberChef-style adapter
├─ extraction/ IOC extraction
├─ classification/ risk scoring + ATT&CK mapping
├─ reporting/ assembles the final structured response + summaries
└─ security/ sanitization and trust-boundary helpersNothing in this pipeline executes, imports, or evaluates submitted content. See
docs/threat-model.md for the full threat model and
SECURITY.md for the security policy.
Installation
Requires Python 3.12+.
python -m venv .venv
# Windows: .venv\Scripts\activate macOS/Linux: source .venv/bin/activate
pip install -e ".[dev]"Optional: Node.js 18+ if you want to enable the local CyberChef-style adapter (disabled by default; not required for any core functionality).
Local development
pip install -e ".[dev]"
python -m pytest
ruff check .
ruff format --check .
mypy srcRunning the server
Default transport is stdio, which is what MCP clients like Claude Desktop expect:
python -m script_decoder_mcp
# or, after `pip install -e .`:
script-decoder-mcpSet SDMCP_TRANSPORT=http (see .env.example) to run over localhost
HTTP instead; it binds 127.0.0.1 by default and is never exposed remotely without
explicit additional configuration, which this project does not provide.
Browser GUI
Prefer a browser over an MCP client? There's a local web GUI that calls the exact same
analyzer/decoder code as the MCP tools -- it's a thin FastAPI wrapper around
reporting/formatter.py, not a separate implementation, so results never drift from the
MCP server.
pip install -e ".[web]"
python -m script_decoder_mcp.web.app
# or: make webThen open http://127.0.0.1:8787. It has one tab per tool (Analyze Script, Decode
Blob, Extract Indicators, Explain Command, Compare Scripts), plus "Load good/bad example"
buttons that load examples/good_script_benign.py and
examples/bad_script_suspicious.py for a quick
before/after. Like the MCP server, it binds to 127.0.0.1 only by default
(SDMCP_WEB_HOST/SDMCP_WEB_PORT to change), has no authentication, is not meant to be
exposed beyond localhost, and never sends anything you paste anywhere beyond your own
machine.
Claude Desktop / MCP client configuration
Add to your MCP client config (see
examples/claude-desktop-config.example.json
and examples/mcp-client-config.example.json):
{
"mcpServers": {
"script-decoder": {
"command": "script-decoder-mcp",
"args": []
}
}
}If you haven't installed the console script, point command at the venv's Python and
args at ["-m", "script_decoder_mcp"] instead.
Tools
analyze_script
Statically analyzes a full script. Input: content (required), language (default
auto), filename, decode_embedded_content (default true),
include_line_references (default true), analysis_depth (quick/standard/deep,
default standard), map_to_attack (default true).
Returns a schema_version-stamped response with summary, plain_language_summary,
analyst_summary, verdict, risk_score, risk_factors, behaviors (each with
category, title, description, evidence, source_lines, confidence,
classification — observed/inferred/possible — and severity),
decoded_artifacts, indicators, imports/functions/commands,
suspicious_constructs, attack_techniques, limitations, errors, and
analysis_metadata. execution_performed is always false.
decode_blob
Decodes a single encoded/obfuscated value. Input: content (required),
encoding_hint, max_depth, use_cyberchef (default false). Returns the detected
encodings, every attempted decode chain, the successful chain (if any), decoded
text/size/hashes, any indicators found in the decoded text, and warnings. Never claims to
decode arbitrary encryption and never brute-forces a password or key.
extract_indicators
Extracts IOCs from arbitrary text or source. Input: content (required). Returns a
dictionary of indicator categories, each entry carrying value, normalized_value,
type, source_lines, context, confidence, and defanged_value.
explain_command
Explains a single command line. Input: command (required), shell
(auto/cmd/powershell/bash/zsh/python, default auto), include_tokens.
Returns executable, arguments, pipelines, redirections, environment changes, possible
side effects, and suspicious features — never runs the command.
compare_scripts
Diffs two versions of a script. Input: original_content, new_content, language
(default auto), decode_embedded_content (default true). Returns added/removed
behaviors, changed indicators, newly decoded artifacts, the risk-score delta, and
line-level change summary.
Example requests
See examples/sample_requests.md.
CyberChef integration
Disabled by default (SDMCP_CYBERCHEF_ENABLED=false). When enabled, decode_blob
(with use_cyberchef: true) can fall back to a small local Node.js worker
(cyberchef-worker/index.mjs) for a fixed, allowlisted set of operations: From Base64,
From Base32, From Hex, URL Decode, HTML Entity Decode, Gunzip, Zlib Inflate,
ROT13, Reverse.
Deviation from the original design: rather than depending on the cyberchef npm
package (a large dependency tree), the worker reimplements these named operations using
only Node.js built-ins, in a single auditable file. It performs no network access, no
filesystem access beyond stdin, and no dynamic code loading. See
cyberchef-worker/README.md for details and how to extend
it. It is never called against a public CyberChef instance, and native Python decoders
remain fully functional with or without it.
Docker
docker compose build
docker compose run --rm script-decoder-mcpThe image runs as a non-root user, uses a multistage build, and does not require network
access at runtime. See Dockerfile and
docker-compose.yml.
Security model
Static analysis only: no
eval/exec/compile-for-execution of submitted content, noos.system/shell=Trueon submitted content, no importing of submitted scripts, no outbound network requests, no DNS resolution, no reputation-service calls.Every resource limit (input size, decode output size, decompression size, recursion depth, candidate branches, analysis duration, indicators per category, evidence excerpt length) is documented in
.env.exampleand enforced insrc/script_decoder_mcp/limits.py; a threshold being hit is always reported as a limitation, never silently ignored.All submitted and decoded content is treated as untrusted data, never as instructions — see
src/script_decoder_mcp/security/.No secrets are read, stored, or logged. Logging is JSON-structured and never emits full submitted content (see
src/script_decoder_mcp/logging_config.py).Full details:
docs/threat-model.md,SECURITY.md.
Limitations
Static analysis cannot always determine runtime behavior. What a downloaded payload or a dynamically constructed command will actually do when run is not knowable from source alone, and responses/results of any network call are never fetched.
Dynamically constructed values (string building, indirect calls) lower analysis confidence and are flagged as
inferredorpossible, notobserved.Risk scoring is a heuristic, not a malware verdict; ATT&CK mapping is contextual evidence, not proof of malicious intent.
Batch and VBScript analysis is rule-based (no safe parser exists for either), so it is less thorough than the Python AST analyzer.
Encoding/administrative-tool use alone is never enough to mark something malicious.
Supported languages
Python, PowerShell, Bash/sh/zsh, JavaScript, Batch, VBScript, and single command lines
(auto, or specify explicitly).
Extending
See docs/adding-an-analyzer.md and
docs/adding-a-decoder.md.
Testing
python -m pytest -vTest fixtures under tests/fixtures/ are inert text — no functional malware,
credential-stealing code, persistence payloads, destructive scripts, or live malicious
URLs. They use reserved example domains/IPs (example.com, example.invalid,
192.0.2.0/24, 198.51.100.0/24, 203.0.113.0/24).
Two ready-to-use manual test scripts are also included:
examples/good_script_benign.py (should score low/no
risk) and examples/bad_script_suspicious.py (an
inert, non-functional script that exhibits several suspicious static patterns —
encoded payload, exec, outbound request construction — and should score meaningfully
higher). Neither script does anything if actually run; bad_script_suspicious.py is
deliberately written so it does not function even if a reader ignored this warning and
executed it.
Troubleshooting
"No dedicated analyzer is available for language..." — the language could not be detected or was not one of the six supported languages; indicator extraction and decoding still run.
CyberChef warnings in
decode_blob— expected whenSDMCP_CYBERCHEF_ENABLED=false(the default) anduse_cyberchef: truewas requested anyway; native decoders already cover the same operations.errorspopulated inanalyze_script— usually a PythonSyntaxError; the response still includes a best-effort text-based fallback analysis.
Privacy
No submitted script, decoded artifact, or any derived content is ever sent to a third-party service. The optional CyberChef worker runs locally with no network access. No telemetry is collected by default.
Deployment
Intended for local, single-user use via stdio (the MCP-recommended local transport) or
containerized via Docker for isolation. The optional HTTP transport binds 127.0.0.1 by
default; exposing it beyond localhost is out of scope for this project and would require
adding authentication, which is not currently implemented — see
docs/threat-model.md for the residual risk this leaves if you
choose to do so anyway.
Available Tools
5 toolsanalyze_scriptA
Statically analyze a script (Python, PowerShell, shell, JavaScript, batch, or VBScript) without executing it. Returns behaviors, decoded artifacts, indicators, a risk score, and plain-language and analyst summaries. Never runs the submitted content.
Inputs: content (required), filename, language, map_to_attack, +3 more. Returns: errors, hashes, imports, summary, +23 more
compare_scriptsA
Compare two versions of a script and report added/removed behaviors, changed indicators, newly decoded artifacts, and the risk score delta. Neither script is executed.
Inputs: new_content (required), original_content (required), language, decode_embedded_content. Returns: summary, limitations, schema_version, added_behaviors, +6 more
decode_blobA
Safely decode an encoded or obfuscated value (Base64, hex, URL encoding, Base32, Unicode escapes, HTML entities, gzip/zlib/bz2, explicit-key XOR, ROT13, reversed strings, PowerShell -EncodedCommand, integer/char arrays, simple string concatenation) without executing the result.
Inputs: content (required), max_depth, encoding_hint, use_cyberchef. Returns: hashes, warnings, indicators, decoded_size, +8 more
explain_commandA
Explain a single command line in plain English without executing it: executable, arguments, pipelines, redirections, environment changes, and suspicious features.
Inputs: command (required), shell, include_tokens. Returns: shell, tokens, summary, arguments, +11 more
extract_indicatorsA
Extract potential security indicators (URLs, domains, IPs, emails, file paths, registry keys, hashes, and more) from text or source code, including defanged notations. Never resolves domains or makes network requests.
Inputs: content (required). Returns: indicators, total_count, schema_version, truncated_categories
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 5 tools
Each tool has a clearly distinct purpose: analyzing a full script, decoding a single blob, extracting indicators, explaining a command line, and comparing script versions. Although analyze_script returns decoded artifacts and indicators, the dedicated tools serve standalone use cases without ambiguity.
All tool names follow a consistent verb_noun pattern: analyze_script, decode_blob, extract_indicators, explain_command, compare_scripts. The naming convention is uniform and predictable.
Five tools is well-scoped for a static script decoding and analysis server. Each tool covers a distinct capability without redundancy or bloat.
The tool surface covers the full static analysis workflow: analyzing scripts, decoding blobs, extracting indicators, explaining commands, and comparing versions. There are no obvious missing operations for the stated purpose of safely decoding and analyzing scripts without execution.
Maintenance
Related MCP Connectors
Scan PDFs, Office docs, and RAG files for malware exploits, macros, CVEs, and AI prompt injection.
1Signed sandbox verdicts on any artifact, plus an agent marketplace. No key, no signup, no payment.
Reputation for IPs, domains, URLs, hashes, emails, phones; CVEs; injection and email scans
Scan Android and iOS apps for security issues: findings, MASVS mapping and pentest reports.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceEnables secure static analysis of Microsoft Office documents and related file types for malicious content, integrating with systems that support the MCP protocol.4-
- AlicenseNot gradedqualityCmaintenanceEnables MCP clients to run hardened, read-only radare2-based static binary triage tools, including disassembly, cross-reference following, string decoding, function renaming, and evidence-checked report generation without executing the sample.MIT
- AlicenseNot gradedqualityBmaintenanceEnables agents to inspect and reverse engineer native binaries, JavaScript/Electron applications, .NET assemblies, websites, and runtime behavior, returning evidence-backed findings that can be explained, implemented, or tested.351,882 npm4MIT
- AlicenseAqualityCmaintenanceEnables agents like Claude Code and Codex to statically scan .zip, .exe, .dll files and GitHub repositories for malware without executing them, explaining likely false positives and letting users dig into reports through natural language.5MIT