Skip to main content

Flask Production MCP

A static production-readiness auditor for Flask applications, usable three ways:

  • a CLI (flask-production-mcp audit) for local runs and scripts
  • a pre-commit hook and a GitHub Action so it runs at the right moments
  • an MCP server so an AI coding agent can call it while building

It answers "is this Flask app ready to deploy?" — not just "does it have security bugs?" — across nine categories:

Category What it checks
flask app-factory / blueprint discovery, route inventory, duplicate routes, debug mode enabled
architecture extensions bound at import time, module-level Flask() beside a factory, hardcoded SECRET_KEY fallback, db.create_all() instead of migrations, unguarded app.run(), unregistered blueprints
templates POST forms with no CSRF field, | safe / {% autoescape false %} on dynamic data, url_for() to an endpoint that doesn't exist
deployment Dockerfile running as root, dev server as the container command, base image on :latest, debug mode via env, secrets baked into an image/compose file, DB port published to the host, Gunicorn reload = True, dev server in a Procfile/entrypoint, committed .env, Nginx (server_tokens, missing forwarded headers, client_max_body_size, HTTP-only edge)
testing no test suite at all, a low line-rate in an existing coverage.xml, a test count that looks thin next to the number of routes
security eval/exec, pickle loads, hardcoded secrets, missing auth on sensitive routes, missing rate limiting, debug config — plus Bandit, folded in and de-duplicated
database SQLAlchemy models / relationships / indexes, raw SQL, missing indexes on filtered columns, likely N+1 access
dependencies known CVEs via pip-audit (PyPI + OSV) — requirements*.txt, or uv.lock / poetry.lock / Pipfile.lock, or the exact-pinned deps in a bare pyproject.toml
code_quality bare/broad except, print(), breakpoint(), assert in app code, TODO/FIXME (test modules excluded)

All analysis is static. The target application is never imported or executed; virtual-environments, caches and build dirs are skipped.

Findings: blockers vs. advisories vs. notes

Every finding has a severity and a confidence. The audit sorts them:

Tier Rule Gates a release?
blockers high-confidence critical/high yes
advisories other critical/high/medium — needs a judgement call no (configurable)
notes low / info cleanups no

The overall_score is confidence-weighted: a confirmed critical bites hard, a long tail of "consider an index" guesses barely moves it. A project is production_ready when it has no blockers and no single category has collapsed below the score floor (default 50).

Install

pip install flask-production-mcp

# with the dependency-CVE and Bandit scanners:
pip install "flask-production-mcp[scanners]"

# or, from a checkout:
uv sync --extra scanners

Python 3.11+. The base install is MCP + the static analyzers. The scanners extra adds pip-audit (needs network) and bandit; without it the audit reports those scans as skipped rather than failing.

CLI

flask-production-mcp audit path/to/your/flask/app
Flask Production Audit  --  /path/to/app
------------------------------------------------------------
Overall score  71/100          NOT READY

  flask          100   clean
  architecture    96   1 finding
  templates       55   1 finding (1 blocker)
  deployment     100   clean
  testing         92   1 finding
  security       100   clean
  database        76   6 findings
  dependencies   100   clean
  code_quality    79   7 findings

BLOCKERS (1)
  x [TMPL-CSRF-001] templates  app/templates/admin/products.html:242
      POST form has no CSRF token field
      -> Add a hidden CSRF field inside the form ...

Result: NOT production ready
  - 1 blocker(s) in templates
Flag Effect
--json emit the full JSON result
--github emit GitHub Actions ::error / ::warning annotations + job summary
--fail-on {blockers,advisories,any,never} what makes exit code 1
--skip-deps skip the CVE scan (no network)
--skip-bandit skip the Bandit scan
--config FILE use a specific config TOML
-q print blockers only

Exit codes: 0 pass · 1 fail (per --fail-on) · 2 bad usage.

Configuration

flask-production.toml in the project root, or [tool.flask-production] in pyproject.toml. See flask-production.toml.example.

fail_on = "blockers"
category_floor = 50
scan_dependencies = true
run_bandit = true
ignore = ["DB-PERF-001"]        # drop rules by id
select = []                      # if set, run ONLY these

[severity]
"ARCH-SEC-001" = "high"          # re-grade a rule for this project

pre-commit

# .pre-commit-config.yaml
repos:
  - repo: https://github.com/yemibalogun/flask-production-mcp
    rev: v0.1.0
    hooks:
      - id: flask-production-audit

The hook runs offline (--skip-deps --skip-bandit -q) and fails the commit on blockers only. Override args: to change that.

GitHub Action

# .github/workflows/audit.yml
jobs:
  flask-production-audit:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: yemibalogun/flask-production-mcp@v0.1.0
        with:
          path: .
          fail-on: blockers      # or advisories / any / never

Findings appear as inline annotations on the PR and in the job summary.

MCP server

flask-production-mcp serve      # stdio

Register with an MCP client (Claude Code / Desktop):

{
  "mcpServers": {
    "flask-production": {
      "command": "flask-production-mcp",
      "args": ["serve"]
    }
  }
}

Then: "Run a production audit on /path/to/my_flask_app and list the blockers."

Tools

Tool Purpose
audit_flask_production Start here. Unified audit: overall_score, per-category score, production_ready + blocking_reasons, blockers / advisories / notes.
inspect_flask_project Structure only: file counts, blueprints, routes, indicators.
audit_flask Flask route/debug findings.
audit_architecture Flask-architecture rules.
audit_templates Jinja/HTML template findings.
audit_deployment Dockerfile / compose / Gunicorn / Nginx / Procfile findings.
audit_testing Test-suite presence and rough adequacy.
audit_security Security audit (incl. Bandit).
audit_database Database architecture + performance findings.
audit_dependencies Dependency CVE scan.
audit_code_quality Production code-quality findings.

Every audit_* tool returns the same envelope (success, project_path, score, summary, findings, recommendations, errors).

Development

uv run pytest
uv run ruff check src tests
uv run mypy src
src/flask_production_mcp/
├── cli.py                  # audit / serve subcommands
├── config.py               # flask-production.toml loader + finding policy
├── server.py               # MCP server, registers the tools
├── models/findings.py      # Finding / AuditSummary / AuditResult
├── analyzers/
│   ├── base.py             # scoring (weighted), classification
│   ├── exclusions.py       # shared file-walk + exclusion rules
│   ├── flask.py            # discovery + analyze_flask
│   ├── architecture.py     # Flask-architecture rules
│   ├── templates.py        # Jinja/HTML rules
│   ├── deployment.py       # Dockerfile / compose / Gunicorn / Nginx rules
│   ├── testing.py          # test-suite health
│   ├── security.py         # analyze_security
│   ├── bandit_scan.py      # Bandit integration
│   ├── database.py         # analyze_database
│   ├── dependencies.py     # pip-audit (requirements / lock / pyproject pins)
│   ├── code_quality.py     # analyze_code_quality_file
│   └── production.py       # analyze_production (unified, parallel)
└── tools/                  # one thin MCP wrapper per analyzer

Scope

Everything is static — the app is never run. So it does not do performance profiling or dynamic/runtime security testing (both need a live app + database), and the testing category reads an existing coverage.xml rather than producing one. Unpinned dependencies in a bare pyproject.toml can't be resolved to exact versions without installing — add a lock file for full CVE coverage.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

flask_production_mcp-0.1.0.tar.gz (77.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

flask_production_mcp-0.1.0-py3-none-any.whl (95.4 kB view details)

Uploaded Python 3

File details

Details for the file flask_production_mcp-0.1.0.tar.gz.

File metadata

  • Download URL: flask_production_mcp-0.1.0.tar.gz
  • Upload date:
  • Size: 77.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for flask_production_mcp-0.1.0.tar.gz
Algorithm Hash digest
SHA256 f91eec49ff5a85894a9461c7bd7c8693d068c7da87d4a4e8664a2c0fbe0085cb
MD5 2c5f18cd0dd34c0ac234e6cdc7867ce7
BLAKE2b-256 df320229ac06eeb18bfb81c590df7a1ec01f417cb8c4287a7ebace8ba942067c

See more details on using hashes here.

Provenance

The following attestation bundles were made for flask_production_mcp-0.1.0.tar.gz:

Publisher: publish.yml on yemibalogun/flask-production-mcp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file flask_production_mcp-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for flask_production_mcp-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 1d13ab58fbd5b2ddb3e293a1355ca3eb32857c35e8f231e307abd57582c2984d
MD5 08bb7e8704a850df52a67932b663a732
BLAKE2b-256 2e2eda046f448dc4e2663e2c325b5cc8bf1250e5ebb20fb6a0bbcb099c65038a

See more details on using hashes here.

Provenance

The following attestation bundles were made for flask_production_mcp-0.1.0-py3-none-any.whl:

Publisher: publish.yml on yemibalogun/flask-production-mcp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page