Debugging on a Mac
On a Mac, Chute and the traffic you want to look at are on the same machine, so most of what the iPhone guide spends steps on — a cable, a listener, a password — is not needed. What replaces it is a different question: is the traffic reaching Chute at all, because on macOS an application can simply decline to use the proxy.
1. Make the traffic go through Chute
Two mechanisms, and they are independent — the menu shows both:
- System Proxy — the toggle at the top of the menu. Registers Chute as the system HTTP/SOCKS proxy. Applications that read the system proxy settings (browsers, most GUI apps) go through Chute; ones that do not are unaffected.
- Enhanced Mode (⌘E) — captures traffic at the network layer, so an application's opinion about proxies stops mattering. This is what you want when an app has no proxy support at all. See Enhanced Mode for the approval flow and the two implementation types.
Terminal tools are the usual surprise: curl, git, npm and friends read HTTP_PROXY/HTTPS_PROXY from the environment, not the system settings. The menu's Copy Shell Export Command (⌘C) puts the right line on the clipboard —
export HTTPS_PROXY=http://127.0.0.1:8118;export HTTP_PROXY=http://127.0.0.1:8118;export NO_PROXY=127.0.0.1,localhost,.example.com
— with your actual HTTP listener port and a NO_PROXY built from your skip-proxy list, so command-line tools bypass exactly what the system proxy bypasses. Paste it into the shell you are testing from; it applies to that shell only.
You should see: the main window's Traffic tab filling with rows as you use the app. No rows means the traffic never reached Chute — go back to this step rather than looking for a decryption problem.
2. Read the Traffic tab
Traffic lists live connections with a search field and a count (N active). Show columns ▾ switches the layout:
- Double-row (the default) — two lines per connection, comfortable for browsing.
- Wide table — one row per connection across all columns: Host, Process, Rule, Policy, Proto, Upload, Download, Totals, State. Sortable by clicking a header.
- Group by app — connections collected under the application that opened them, with its name and icon. This is the fastest way to answer "what is this process talking to".
Right-click a row for Show Details, Copy Host, Copy Details, Filter Logs (jumps to the Log tab already filtered to this connection) and Close Connection.
Show Details opens a window with the connection's Host, Process, Protocol, Remote, Rule, Policy, Rewrites, Upload, Download and State — everything about how it was routed.
The Traffic tab does not show request and response bodies. That is what the detail window's Requests & History button is for: it opens the Web Console, which does. The console's home page opens, not that particular connection.
3. Test a rule without making a request
The Rules tab has a Test Rule… button. Type a URL or a bare domain, press Test, and Chute answers with the host and port it parsed, the DNS result, the matched rule, the policy that rule chose, and any notes.
Use it whenever the question is "why did this go direct" or "which of my two rules wins" — it consults the running rule set, so it also tells you whether the configuration you edited is actually the one that is loaded. Reload the configuration (⌘R) if the answer looks stale. The same question over the API is POST /api/rules/match.
4. Turn on recording and decryption
Both live in the menu, and both act on the running kernel:
- Traffic Capture (⌘B) — keeps request and response bodies, i.e. the
replicasetting. Off by default; nothing has bodies until it is on. - Enable MitM (⌘M) — turns on decryption for the hosts in the
[MITM]hostnamelist.
Neither is written back to the configuration file: after Reload Configuration or a restart, the file's replica and [MITM] enable win.
The CA is a single step on macOS. In the configuration window open MitM:
- Generate New Certificate, or Import Certificate from PKCS#12 File.
- Install the Certificate to System — macOS asks for an administrator password and adds it to the System keychain as a trusted root. There is no separate "trust" step as there is on iOS.
- Export the Certificate writes a
.pemcopy, which is how you get the same CA onto a phone, an Apple TV or a container.
5. Narrow to one process
macOS is the platform where Chute knows which application opened a connection, and rules can use it:
[Rule]
PROCESS-NAME,curl,DIRECT
PROCESS-NAME,MyApp,MyProxy
See Process Rule for PROCESS-NAME, PROCESS-PATH and PROCESS-NAME-REGEX. Combined with Group by app in the Traffic tab, this lets you route one application through a proxy — or through a mock — while everything else on the machine carries on normally.
6. What only works on a Mac
data=file paths in Map Local. The file is read by the device running Chute, at request time. On a Mac that device is the machine you are editing on, so a real path works, and editing the file changes the next response with no reload. On a phone the same path means nothing — that is why the iPhone guide usesbase64=instead.- The files on disk. Log shards, the run marker and captures live under
~/Chute/Share/<run id>/; see File Locations (macOS). You can attach them to a bug report directly instead of going through a share sheet. - Serving other devices. With
allow-wifi-accesson, other machines on the network can point their proxy settings at this Mac. Their traffic then appears in the same views, under Remote in Dashboard's client sidebar — which is how you inspect a device Chute does not run on at all, a Windows laptop or a smart TV included.
7. When the Traffic tab is not enough
- Web Console — menu bar → Open Web Console. Bodies, HAR export, the Rules page that says which rewrites have fired, and the Diagnostics probes. Needs
external-http-controllerin[General]. - Chute Dashboard — a separate free app. For the local kernel put
external-controller-access = <password>@127.0.0.1:6170in[General], then connect Dashboard's Remote tab to127.0.0.1with that port and password. Worth it for the MitM tool panels and the HAR/curl exports on a right-click. - The Log tab — raise the level with
loglevel = verbosefirst, and revert afterwards. Filter Logs on a connection row narrows the tab to that one connection.