Module structure
The layout of a module file: manifest fields, parameters, domain rules, HTTP rules and actions, and scripts.
A module is one JSON object in UTF-8, up to 256 KiB. Parsing is strict: unknown fields, versions, actions and values are rejected, nothing may follow the closing brace, and an error shows its line and column. Scripts are separate JavaScript text, written inside the manifest or downloaded from an HTTPS address; there is no archive format.
Manifest
| Field | Type | Required | Meaning |
|---|---|---|---|
schemaVersion |
number | Yes | Must be 1. |
id |
string | Yes | Lowercase letters, digits, ., _, -, up to 64, starting with a letter or digit. Names the module and its storage; two enabled modules cannot share an id. |
name |
string | Yes | 1–80 characters. |
version |
string | Yes | 1–32 characters, any format. |
author |
string | No | Up to 80. Shown as declared by the module. |
description |
string | No | Up to 500. |
icon |
string | No | An HTTPS image address. The app downloads it (up to 256 KiB), shrinks it and stores it. |
parameters |
list | No | Values the user can set. |
mitmHosts |
list of strings | No | Up to 64 hosts whose HTTPS traffic is decrypted. |
excludedHosts |
list of strings | No | Up to 64 exceptions to mitmHosts. |
domainRules |
list | No | Block or allow domains. No certificate needed. |
domainSets |
list | No | Up to 2 large domain lists from a file. |
httpRules |
list | No | Up to 256 rules for requests and responses. Need mitmHosts. |
scripts |
list | No | JavaScript for the script action. |
Host names are an exact name or *.example.org (subdomains only, at least two labels after *.). IP addresses are not allowed. Names are normalised.
Parameters
Each entry has id (letters, digits, _, up to 32, unique), an optional title, type (string, int, number or bool), a required default and an optional enum. A value outside the type or the enum is rejected, never replaced silently. On the module card an enum is a choice, a bool a switch, the rest a field. Values survive an update while the type and enum still fit. A rule can use a parameter only as a whole string, "{{id}}", in header values, query values and JSON edits.
Domain rules and sets
| Field | Values |
|---|---|
domainRules[].action |
block or allow |
domainRules[].match |
exact, or suffix for the domain and its subdomains |
domainRules[].domain |
the name |
domainSets[].id, asset, sha256, format, action |
a list file next to the manifest (up to 4 MiB), its required SHA-256, text or mrs, and block or allow |
The longest match wins; on a tie the exact one. allow lifts only this filter’s block, not a REJECT from your profile. Blocking covers any port, TCP and UDP. A text list has one domain per line: example.com exactly, +.example.com the domain and subdomains, *.example.com subdomains only. Because the list file is fetched from the manifest’s folder, domainSets work only when the module is installed from a link.
HTTP rules
| Field | Meaning |
|---|---|
id |
Rule name. |
phase |
request or response. |
host |
An exact name or *.suffix; must be covered by mitmHosts. |
method |
Empty or ANY, GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS. |
path |
Exactly one of exact, prefix (both start with /) or regex (up to 512 characters). |
status |
Response codes to match; response phase only. |
action |
See below. |
action.type |
Phase | What it does |
|---|---|---|
block |
request | The request is not sent; the status is 400–599. |
respond |
request | A local reply: status, headers.set, a text body up to 64 KiB. |
edit |
both | headers.set and delete; query.set and delete on requests. |
json |
response | Up to 32 edits of set or delete at a path such as a.b.0.c. |
script |
both | Runs a script by its id; needBody passes the body. |
Rules cannot change Host, Content-Length, Transfer-Encoding, Connection, Upgrade, TE or Trailer. The first matching rule of a phase ends processing.
Scripts
A script has an id and exactly one source: source (text) or sourceURL (HTTPS, up to 8 KiB) with a required sha256. A script from a link is downloaded and checked before installation; while running, the network is not used.
The engine is QuickJS, without JIT and without system modules. A script defines a synchronous transform(event, context) that returns a patch or null to leave the exchange as is. async is not supported.
| Object | Contents |
|---|---|
event |
phase, rule, request (url, method, headers), response (status, headers; response phase only), body (only with needBody, already decompressed). Headers are [name, value] pairs. |
context |
parameters, storage (get, set, delete, keys; JSON values; this module only), utf8 (encode, decode). |
| patch | path, query, headers (replaces the whole list), status, body, or respond. The scheme, host, port and destination cannot be changed. |
There is no fetch, sockets, timers, console, file access or import, and no access to the certificate, subscriptions, VPN settings or other modules.
Permissions shown in the preview
They are worked out from the content; a module cannot declare less: block connections to domains, change requests or responses of selected hosts, read request and response bodies, run the module’s code on the device, see the headers and cookies of these requests.
Found a mistake? Open an issue on GitHub.