# mitmproxy2swagger: turning captured HTTP traffic into an OpenAPI 3.0 spec

> mitmproxy2swagger converts mitmproxy flow files and browser HAR exports into OpenAPI 3.0 documents. The workflow is a two-pass edit-and-rerun loop, and the tool is only as good as the traffic you feed it.

**alufers/mitmproxy2swagger** — Automagically reverse-engineer REST APIs via capturing traffic

- Repository: https://github.com/alufers/mitmproxy2swagger
- Stars: 9,627 · Forks: 376
- Language: HTML
- License: not declared
- Published: 2026-09-21 · Updated: 2026-09-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/alufers-mitmproxy2swagger

## What mitmproxy2swagger is for, and who ends up using it

The project describes itself as a tool for automatically converting mitmproxy captures to OpenAPI 3.0 specifications, which lets you reverse-engineer REST APIs by running an app and capturing its traffic. That framing is accurate but slightly generous. What you get after the first run is a list of observed URL paths, not a specification. The specification appears only after you decide which paths matter and rerun the tool.

The people who benefit are those staring at an undocumented HTTP API they are allowed to talk to: mobile app backends, internal services with no schema, third-party endpoints where the vendor never published a contract. If you already have an OpenAPI document, or an official SDK, this tool has nothing to add. It is also a poor fit when the API is gRPC or GraphQL over a single endpoint, because the whole approach depends on distinguishable URL paths.

The repository lists topics mitmproxy, openapi, reverse-engineering and swagger, and the README points at example_outputs for a generated schema plus an HTML file rendered through redoc-cli. That example is the honest advertisement: a schema file you could hand to a code generator, produced from traffic.

## The two-pass loop behind the generated schema

The mechanism is deliberately split in two, and the split is the design decision worth understanding.

On the first pass you supply a mitmproxy flow file, an output schema path, and an API prefix. The tool writes a schema containing an x-path-templates key: a YAML list of the paths it observed, each prefixed with ignore:. Lines closer to the top take precedence and matching is greedy, per the comment the tool writes into the file. Nothing is generated yet. You open that file in a text editor and delete the ignore: prefix from the paths you want turned into endpoints. You can also adjust the parameters appearing in those paths, which is how a concrete id such as /basket/coupons/attach/104754 becomes a templated /basket/coupons/attach/{id}.

The second pass reads the same flow file and the edited schema, then generates endpoint descriptions for the un-ignored paths. Existing endpoint descriptions are not overwritten, so the tool is safe to rerun as you capture more traffic, and the README notes that captures from several runs merge safely into one schema.

The prefix argument is the part people get wrong. The README's example shows requests to https://api.example.com/v1/login, /v1/users/2 and /v1/users/2/profile, and concludes the likely prefix is https://api.example.com/v1. Choose too broad a prefix and unrelated host paths join the template list; choose too narrow and your endpoints never appear.

## Installing mitmproxy2swagger and running a first capture

The README requires python3 and pip3, and pyproject.toml sets requires-python to >=3.12, so an older interpreter will not work. The PyPI route is one command.

```bash
pip install mitmproxy2swagger
```

There is also a Docker path, either building the image from a clone or pulling the published one. The Dockerfile sets the entrypoint to mitmproxy2swagger, so the image name is followed directly by the tool's own flags. The README shows the invocation with the working directory mounted at /app, which is what makes the input flow file and output schema reachable from inside the container.

```bash
docker run -it -v $PWD:/app mitmproxy2swagger mitmproxy2swagger -i <path_to_mitmptoxy_flow> -o <path_to_output_schema> -p <api_prefix>
```

Capture first. The README recommends mitmweb, the web interface bundled with mitmproxy. Running it prints the web UI address and the proxy port, and you point your client at that proxy following the mitmproxy documentation.

```bash
mitmweb
```

Save the traffic from the File menu, then run the first pass. The output schema will contain the x-path-templates list, and the README's example shows the shape you are editing.

```yaml
x-path-templates:
  # Remove the ignore: prefix to generate an endpoint with its URL
  # Lines that are closer to the top take precedence, the matching is greedy
  - ignore:/addresses
  - ignore:/basket
  - ignore:/basket/add
  - ignore:/basket/checkouts
  - ignore:/basket/coupons/attach/{id}
  - ignore:/basket/coupons/attach/104754
```

Strip the ignore: prefix from the paths you want, save, and run the same command a second time. Add --examples to include request and response sample data, or --headers to include header data. The README warns that both can put tokens, passwords and personal information into the schema, so treat the output as sensitive once either flag is used.

## HAR files, and why the browser route is the easier one

The README marks HAR support as new: mitmproxy2swagger will process an export from the browser DevTools Network tab, detecting the HAR file automatically and continuing exactly as it would with a mitmproxy dump. In the DevTools Network tab you click Export HAR, then pass that file to the same -i flag.

This is the lower-friction path for web APIs, and it is worth saying plainly that it is not equivalent to proxying. A HAR export only contains what that browser tab did, with no ability to intercept a native mobile client, and it carries whatever the page already loaded. The mitmproxy route can capture an app you cannot open in a browser, at the cost of installing a CA certificate and configuring a proxy. Pick based on the client you need to observe, not on which command looks shorter.

One structural note: the repository's primary language is listed as HTML, which reflects the committed example_outputs and docs rather than the implementation. The actual code lives in the mitmproxy2swagger/ package directory and is invoked through the mitmproxy2swagger console script defined in pyproject.toml.

## Where the tool stops helping

The manual editing step is not a rough edge to be sanded down later; it is the interface. The tool cannot know which observed paths are API endpoints and which are static assets, telemetry pings or third-party calls, so it marks everything and asks you to choose. On a large capture that list is long, and the greedy matching means ordering in the file matters when two templates overlap.

Descriptions are never overwritten. That protects your edits, but it also means that once an endpoint has been generated, changing your mind about its shape requires deleting the existing description before rerunning. There is no documented rollback or diff mechanism in the README, and no documented way to regenerate a single endpoint in isolation.

The flags that add data are the sharpest edge. --examples and --headers both carry the README's explicit caution about sensitive data. A schema generated from a logged-in session can contain bearer tokens, session cookies and personal fields, and that file is exactly the kind of artifact that gets committed to a repository or pasted into a ticket.

Finally, the output is a description of observed requests, not a contract. It records what the client sent during your capture, which is not the same as what the server accepts. Optional fields never exercised will be missing, and error responses will be absent unless your capture happened to include them.

## mitmproxy2swagger against writing the spec by hand

The real alternative is opening an editor and writing the OpenAPI document yourself, using the captured traffic as reference. The difference is where the tedium sits. Hand-writing gives you control over naming, descriptions, schemas and examples from the first minute, and produces a document that reflects intent rather than observation. mitmproxy2swagger front-loads the work: one command produces the path inventory, and your editing is reduced to deleting prefixes and templating ids.

For a handful of endpoints, handwriting wins. The tool's advantage grows with the number of distinct paths, because enumerating them by hand from a proxy log is the genuinely tedious part and that is precisely what x-path-templates automates. A middle path is to generate with the tool, then treat the result as a draft that gets reviewed like any other generated artifact.

Within the mitmproxy ecosystem, mitmweb and mitmdump are the capture tools you use before this one runs; mitmproxy2swagger consumes their output rather than replacing them. It is a post-processing step, not a proxy.

## Maintenance, packaging and licence

The last push to the repository was on 2026-09-14, and the most recent release is 0.15.0 from 2026-05-25, described as a uv migration with dependency updates and bugfixes. The release before that, 0.14.0 in December 2024, added mitmproxy 11 support, and 0.13.0 in January 2024 added msgpack support. The pattern is periodic maintenance tied to upstream mitmproxy changes rather than a stream of new features, which is reasonable for a tool whose job is to read another project's file format.

That coupling is the upgrade cost. pyproject.toml pins mitmproxy>=12.2.3, so a mitmproxy release that changes the flow format can require a mitmproxy2swagger release to match. If you pin mitmproxy in your own environment, check compatibility before upgrading either side. Development uses uv for dependency management, prek for formatting and linting, and pytest for tests, with openapi-spec-validator in the dev group, which suggests generated output is validated in CI.

The README states the licence is MIT, and pyproject.toml declares license = {text = "MIT"}. That is permissive, and it matters here because the generated schema is derived from captured traffic rather than from the project's source. The licence covers the tool; it says nothing about the API you captured, and the README is silent on that distinction. Whether you may reverse-engineer and redistribute a description of someone else's API is a question for your own legal review, not something this project's licence answers.

## Conclusion

Adopt mitmproxy2swagger if you have a working client, can route it through mitmweb, and need a starting OpenAPI document rather than a finished one. Skip it if you cannot legally or practically capture the traffic, or if the API is already documented, because hand-editing x-path-templates is the real work and the tool will not overwrite descriptions you have already written. Before committing to it, verify three things: that your Python is 3.12 or newer, that the flow file parses, and that the x-path-templates block lists the endpoints you expected. The --examples and --headers flags are the ones to think hardest about, since the README warns they can write tokens and personal data straight into the schema.

## FAQ

### How do I install mitmproxy2swagger on Kali Linux?

The README's installation section requires python3 and pip3 and gives pip install mitmproxy2swagger as the primary route, which works on any distribution with a Python 3.12 or newer interpreter. It also lists an Arch Linux package and a Docker build from a clone of the repository; Kali is not mentioned in the README, so the pip or Docker path is the one the documentation actually describes.

### What is the mitmproxy2swagger workflow from capture to schema?

Capture traffic with mitmproxy (the README recommends mitmweb) or export a HAR from the browser DevTools, run the tool once with -i, -o and -p, edit the x-path-templates list by removing the ignore: prefix from the paths you want, then run the same command again to generate the endpoint descriptions. Existing descriptions are not overwritten on later runs.

### Does mitmproxy2swagger work with HAR files exported from a browser?

Yes. The README describes exporting a HAR from the Network tab of the browser DevTools and passing it to the same -i flag; the tool detects the HAR file automatically and processes it the same way as a mitmproxy dump.

### What does the --examples flag do in mitmproxy2swagger?

It adds example data to requests and responses in the generated schema. The README warns that it may add sensitive data such as tokens, passwords and personal information, and the same caution applies to --headers, which adds header data.

## Sources

- [alufers/mitmproxy2swagger on GitHub](https://github.com/alufers/mitmproxy2swagger)
- [Issues](https://github.com/alufers/mitmproxy2swagger/issues)
- [README](https://github.com/alufers/mitmproxy2swagger/blob/master/README.md)
- [Releases](https://github.com/alufers/mitmproxy2swagger/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/alufers-mitmproxy2swagger
