Skip to main content
Glama

pyobfus: the Python obfuscator

PyPI version PyPI downloads Documentation Status License Python OpenSSF Best Practices DOI

pyobfus is a local-first, AST-based Python obfuscator for Python 3.9–3.15. It obfuscates multi-file projects and packages as a whole: names are renamed consistently across modules and imports are rewritten to match, so Community output is still ordinary .py that runs without pyobfus installed. Keep the mapping file from the build private, and pyobfus --unmap turns a production traceback back into your original names, for you or an AI coding agent. Community is Apache-2.0, has no file or line limits, and requires no trial.

Use the released CLI or MCP workflow to evaluate a delivery: scan, build, run your application checks on the output, and restore a traceback. The changelog and support matrix record maintained compatibility and tested limits. Start custom integration with configuration or a thin wrapper when these interfaces fit your task.

What's new in v0.13.0: Community pre-commit hooks stop pyobfus mapping files and PEM private keys from being committed (pyobfus-no-private-material) and check built output before pushing (pyobfus-check-delivery). They read files locally, print only paths and reasons, and need no licence.

Earlier releases: see the changelog.

Why pyobfus

Advantage

What it means in practice

Complete Community edition

Obfuscate real projects without a file/line cap or trial clock. Optional limits are your CI safety rails, not an upgrade gate.

Diagnosable protection

Keep the private mapping and restore identifiers in production tracebacks without giving customers the original source.

Evidence, not a black box

Scan, preview, verify syntax, retain provenance and compare reproducible build reports.

Portable and local-first

Source stays local and there is no telemetry (what goes over the network); Community emits ordinary cross-platform Python without a native build matrix.

Explicit security claims

Tested, verified-once and advisory-only claims are separated; deterrents are not presented as irreversible security.

Related MCP server: MCP Python Toolbox

Quick start

pip install pyobfus

# Check compatibility, preview, then build
pyobfus --check src/
pyobfus src/ -o dist/ --dry-run --json
pyobfus src/ -o dist/ --save-mapping mapping.json --verify-syntax
# --verify-syntax only compiles the output; run your own tests against dist/

# Restore names when a production traceback arrives
pyobfus --unmap --trace error.log --mapping mapping.json

Independent-file directory builds (--no-cross-file) support --save-mapping since 0.9.0. Their version-2 mapping resolves each traceback frame against its own file; names in excerpts and unframed logs stay unchanged. See the debugging guide.

Since 0.7.1, add opt-in --verify-names to check newly unbound globals without execution. Success JSON reports partial coverage explicitly; see name verification for usage and limits. Check the final directory or wheel with pyobfus --check-delivery dist/ --json before shipping.

For framework presets, configuration discovery, packaging and verification, start at the task-oriented documentation.

Minimal example

Input:

def greet(name):
    message = f"Hello, {name}!"
    return message

print(greet("world"))

Run pyobfus input.py -o output.py. Representative Community output:

def I0(I1):
    I2 = f"Hello, {I1}!"
    return I2

print(I0("world"))

Both print Hello, world!. Generated identifiers can differ with input and configuration; verify the exact output with your own tests. Keep a mapping when you need to restore names from a shipped traceback.

Parameter names are preserved by default in every preset. Explicit --no-preserve-param-names or YAML preserve_param_names: false keeps legacy renaming with a warning: keyword calls may raise TypeError or silently bind incorrectly. Rebuild from original source and keep the new mapping with the new artifact; mapping numbers can change and old mappings cannot decode rebuilt output. Cross-file directory builds (the default) still preserve parameters; legacy --no-cross-file directory builds follow the option.

Features at a glance

Community includes name mangling with import rewriting across a project (directories also rename function locals; parameters and methods remain unchanged there; single files also rename methods and preserve parameters by default, see the guide), string and numeric transforms, framework-aware presets, config-aware pre-flight scanning (including coarse hardcoded-secret screening without displaying values), SARIF, structured dry-run, reverse traceback mapping, syntax verification, provenance, reproducible output and verifiable build reports.

Pro builds require an active trial or a registered license. This applies to CLI flags, presets, configuration files, MCP builds, and direct library transforms. Installing the bundled Pro components alone does not activate Pro. See the activation and offline-use guide.

Professional adds four kinds of commercial value:

  • Protection strength: AES encryption, control-flow flattening, dead-code injection, anti-debugging, Selective Opacity and sealing.

  • Protected assets: import strings, embedded data, Runtime String Vault and protected tracebacks.

  • Distribution control: device, expiry, run-count, platform and application-supplied-key policies.

  • Accountability: forensic watermarking and buyer-specific builds.

The durable classification rule is documented in the Community / Pro boundary policy.

🔌 Companion MCP server: pyobfus-mcp

Install the MCP server with no API key and no source upload:

uvx pyobfus-mcp
# or: pip install pyobfus-mcp

It exposes structured tools for scanning, configuration, protection, verification, preset explanation, tier recommendations and traceback mapping. See the MCP package guide and its registration in the official MCP Registry.

Agent and editor integrations

  • pyobfus-review and pyobfus-protect skills separate read-only review from build-producing work. See skills.

  • The VS Code extension provides inline risk diagnostics and traceback reversal; it is also on Open VSX.

  • zhurong2020/pyobfus-action@v1 runs scans or verified builds in GitHub Actions with SARIF support.

  • The stable JSON CLI includes reason codes and an ai_hint next action.

  • Agent-readable project facts are published in llms.txt, while contributor instructions live in AGENTS.md.

All Agent guidance is public and human-auditable. pyobfus does not serve hidden instructions or different facts based on User-Agent.

Configuration

Generate a starting configuration or use a named preset:

pyobfus --init src/
pyobfus src/ -o dist/ --preset django
pyobfus --list-presets

Community presets include safe, balanced, aggressive, fastapi, django, flask, pydantic, click, sqlalchemy and ml. See the documentation home and pyobfus --help for current options. Optional max_files and max_total_loc values are user-selected safety limits at every tier.

How do I debug an obfuscated crash with an AI assistant?

Build with --save-mapping mapping.json, keep that file private, then run:

pyobfus --unmap --trace error.log --mapping mapping.json

The restored identifiers can be read by you or an AI assistant without giving the customer your mapping or original source. --trace-marker can also stamp generated files with the exact recovery command.

Purchase Professional Edition

Pro builds in CI need PYOBFUS_LICENSE_KEY or a registered runner. The secret verifies online without consuming device slots; see CI licensing.

Professional Edition is $45 USD, one time—not a subscription. A five-day trial requires no registration or card:

pyobfus-trial start

The trial is an honor-system convenience control, not a security boundary. Visit the product and purchase page for current payment methods, refund terms and purchase steps. After purchase, use the license activation guide.

Runtime-backed Pro artifacts depend on the separately redistributable, pure-Python pyobfus-runtime package. Target machines do not need the complete proprietary builder or a licence key.

Security and limitations

Obfuscation raises the cost of inspection; it does not make client-side Python irreversible. Runtime-decrypted material can be observed by a determined attacker. Keep credentials and authorization decisions behind environment, secret-manager or server boundaries.

Comparison and deployment guides

Architecture and development

The product line separates the Apache-2.0 Core, proprietary Pro builder, redistributable runtime, MCP package, editor extension and GitHub Action. See:

Community and citation

Use GitHub Issues for bugs and Discussions for questions and ideas. Citation metadata is in CITATION.cff, with archival DOI 10.5281/zenodo.20846053.

Core is Apache-2.0; Professional implementation is proprietary. See LICENSE-NOTICE.md. Selected Professional Edition mechanisms are patent pending (CN 202610712171X, not yet granted).

Available Tools

9 tools
check_deliveryA

Check an output directory or .whl right before shipping: fails on a pyobfus mapping file, a private key or an original source file inside it, and warns about Python files the build did not produce or Pro options the build skipped. Pass the build's --build-report and --provenance-manifest JSON for the full check. Read-only: files are hashed, never imported or executed, and contents are not returned.

Inputs: path (required), build_report, provenance_manifest. Returns: result

check_obfuscation_risksA

Scan a Python project for patterns that may break obfuscation (eval/exec, dynamic attribute access, framework reflection, unsafe model loading). Returns severity counts, detected frameworks (FastAPI/Django/Flask/Pydantic/Click/SQLAlchemy/ML), and a suggested preset. Also locates requirements*.txt / pyproject.toml and, only if verify_dependencies_online=true, checks each declared dependency against public PyPI to flag AI-hallucinated ('slopsquatting') package names -- off by default, this tool makes no outbound network calls unless you opt in. By default the scan honors the project's pyobfus config; set use_project_config=false for the legacy config-free scan.

Inputs: path (required), use_project_config, verify_dependencies_online. Returns: result

explain_presetA

Describe what a named preset changes: exclude names count, exclude patterns, preserve_param_names, docstring handling. For Pro presets, returns full pro_unlock metadata (trial command, checkout URL, price, money-back guarantee).

Inputs: name (required). Returns: result

generate_pyobfus_configA

Generate a pyobfus.yaml for a Python project. Auto-detects frameworks and applies the matching preset. By default returns the YAML text without writing to disk; set write=true to persist.

Inputs: path (required), write, preset_override. Returns: result

list_presetsA

List every pyobfus preset available, grouped by tier (community / framework-aware / Pro).

Inputs: no named parameters. Returns: result

protect_projectA

One call to protect a Python project end-to-end AND verify it still works: scans risks, picks a framework-aware preset, obfuscates, then byte-compiles + import-smoke-tests the output in isolated subprocesses and returns verified:true/false. Writes a private de-obfuscation mapping alongside (not inside) the output. Use this when the user wants to 'protect/obfuscate before shipping' and expects a green check, not just a transform.

Inputs: path (required), preset, verify, timeout, +4 more. Returns: result

recommend_tierB

Analyze a Python project and recommend pyobfus tier (community vs Pro) with reasons. Combines a preflight scan with a sensitive-string-literal heuristic. Returns free_action and pro_action with concrete next-step commands.

Inputs: path (required). Returns: result

start_pro_trialA

Return structured guidance for starting the 5-day pyobfus Pro trial. Does NOT invoke the side effect — the user runs pyobfus-trial start in their shell. Detects whether a trial is already active and surfaces the appropriate next step plus post-trial purchase URL.

Inputs: no named parameters. Returns: result

unmap_stack_traceA

Reverse obfuscated identifiers in a stack trace using a pyobfus mapping.json. Accepts the trace as plain text and the path to a mapping file produced by --save-mapping.

Inputs: trace (required), mapping_path (required). Returns: result

Tool Schema Changelog

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

Loading tool schema changelog…

    TDQS

    A4/5.0

    Scored across 9 tools

    Disambiguation4/5

    Most tools target distinct stages of the obfuscation lifecycle (scan, config, protect, ship, debug), but three tools — check_obfuscation_risks, recommend_tier, and protect_project — all perform project scans, and list_presets vs explain_preset sit close together, creating mild boundary ambiguity.

    Naming Consistency5/5

    Every tool follows a clean verb_noun snake_case pattern (start_pro_trial, list_presets, protect_project, check_delivery, unmap_stack_trace), with no mixed conventions or vague verbs.

    Tool Count5/5

    Nine tools is well-scoped for a Python obfuscation server, with each tool earning its place across the protect-scan-config-verify-ship-debug workflow without redundancy.

    Completeness4/5

    The lifecycle is well covered end-to-end: risk scanning, config generation, protection, delivery checks, stack-trace unmapping, and tier recommendation. Minor gaps exist around Pro license activation (only trial-start guidance) and a standalone obfuscate-without-verify path.

    Maintenance

    ActivityActive
    ResponsivenessLimited data

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      A
      quality
      D
      maintenance
      Model Context Protocol server for fetching web content and processing images. This allows Claude Desktop (or any MCP client) to fetch web content and handle images appropriately.
      1
      910 npm
      41
      MIT
    • A
      license
      Not graded
      quality
      F
      maintenance
      A Model Context Protocol server that enables AI assistants like Claude to perform Python development tasks through file operations, code analysis, project management, and safe code execution.
      9
      MIT
    • A
      license
      Not graded
      quality
      C
      maintenance
      A custom Model Context Protocol server that gives Claude Desktop and other LLMs access to file system operations and command execution capabilities through standardized tool interfaces.
      23
      Apache 2.0
    • F
      license
      B
      quality
      D
      maintenance
      A Model Context Protocol server that enables Claude users to access specialized OpenAI agents (web search, file search, computer actions) and a multi-agent orchestrator through the MCP protocol.
      4
      10
      -