Chute Dashboard

Chute Dashboard is a free macOS application that connects to a running Chute — Chute iOS over Wi-Fi or a USB cable, Chute Android over the network or adb, or Chute Mac on the same machine — and shows what that instance is doing: every connection with the rule and policy that decided it, the decrypted request and response for hosts covered by HTTPS decryption, DNS answers, UDP sessions. It also lets you shape the traffic while you watch it: the MitM host list and every rewrite and Mock Response family can be edited live.

This is not the Web Console. The console is served by the engine itself and opened in a browser; Dashboard is a separate app that talks to the engine over its binary control channel, which is why it needs external-controller-access on the device rather than external-http-controller. The two overlap, and each has things the other does not — see What Dashboard cannot reach. A Dashboard on the same Mac as the engine is the exception: it connects to a local socket the engine always opens, and needs no configuration at all.

Dashboard's interface is localized into the same languages as this manual, except Arabic; on an Arabic system it shows English.

Allowing Dashboard to connect

Nothing listens until the device says so.

Chute iOS — in the configuration editor open External Controller:

  1. Turn on External Controller Access — the switch whose footnote reads Allow Chute Dashboard/Chute CLI to Connect.
  2. Set a Port and a Password. The password cannot be empty, and it must be one of your own: a listener that is reachable from the network refuses to start with an empty or default password.
  3. Leave Allow Access From Wi-Fi off unless you need it. Off is the default and means the listener stays on the phone itself — a USB cable still reaches it, other devices on the Wi-Fi do not. On means anyone on the network who knows the password can read everything the run has seen.
  4. Save, then start (or restart) the tunnel. The Control Panel now shows External Access Port: <port> — that line is the confirmation that the listener is up.

Chute Mac — the same three values live in [General]:

[General]
external-controller-access = password@127.0.0.1:6170

127.0.0.1 keeps it to the Mac you are on; a LAN address or 0.0.0.0 opens it to other machines. The configuration window's General section has fields for the same key. A Dashboard running on the same Mac does not need this key at all — see Connect to Local Machine below.

Chute Android — in the configuration editor open External Controller and write the same value into External Access:

  • password@127.0.0.1:6170 is enough for Connect via USB: Dashboard runs adb forward for that port and connects through the cable, so the listener can stay on the phone itself. This needs adb on the Mac — Dashboard looks under ANDROID_HOME and ANDROID_SDK_ROOT, on the PATH, in /usr/local/bin and /opt/homebrew/bin, and in ~/Library/Android/sdk — and USB debugging on the phone, with this Mac allowed.
  • password@0.0.0.0:6170 opens it to the network for Connect to Remote Machine. As on iOS, a listener that is reachable from the network refuses to start with an empty or default password.

Save, then start (or restart) the VPN. The Control Panel's External Access switch then shows the address it listens on, and turns the listener off and on while the VPN runs.

Connecting

Dashboard opens with the New Dashboard window; each connection gets its own window, so several devices can be open at once. Three ways in:

Fields When
Connect to Local Machine none Chute Mac on this same Mac. Dashboard talks to the engine's local socket directly — no host, no port, no password, and no external-controller-access line.
Connect to Remote Machine Host, Port, Password The device's Wi-Fi address (iPhone: Settings → Wi-Fi → ⓘ), or another Mac's address. Needs Allow Access From Wi-Fi on the phone.
Connect via USB Device, Port, Password An iPhone connected by cable and trusted by this Mac, or an Android device visible to adb. Pick it from Device: and enter the port you configured — Dashboard finds the cable channel by itself, running the adb port forward for Android. Works with Allow Access From Wi-Fi off, and shows cellular traffic too, since the device need not be on Wi-Fi at all.

A remote machine is remembered only when you save it: Save stores the host, port and password under a name you choose, and those names are what the Saved Remote Machine tab lists next time.

If the password is wrong the window says Password does not match, over USB as over the network. If the device cannot be reached, the window opens all the same and shows Connecting…: an iPhone on USB stays there while Dashboard keeps retrying, until the phone answers or you click Close, and every other connection ends in Connection Closed. If the device goes away later — the tunnel stopped, the cable was pulled, the phone changed networks — the Dashboard window reports Connection Closed and offers Reconnect.

The window

The toolbar switches between five views — Recent, Active, DNS, UDP and MitM — and its Filter field on the right is a search box for the host pattern, shared with the filter bar. That bar appears on its own on Recent and Active, and is hidden on DNS, UDP and MitM. The panel in the lower left is the live upload and download speed; click it to expand the graph.

The Recent and Active views each carry a Reload button, and Recent a Clean that empties the list. Next to them are two switches that act on the running engine, exactly as the switches in the apps do:

  • Enable Traffic Capture → Disable Traffic Capture: turns on the capture of request and response bodies (the replica setting). Without it rows still appear with their routing, but the data tabs cannot be selected. The button reads Traffic Capture until the device has reported which way it is set.
  • Enable MitM (N rules) → Disable MitM (N rules): turns HTTPS decryption on for the N hosts in the MitM host list; with an empty list the count is left off. The switch does nothing useful until the device has a trusted CA and at least one host — see the HTTPS decryption page.

Neither switch edits the configuration file; a restart returns to what the file says.

The sidebar groups connections by client: All Clients, then Local for clients on the device itself and Remote for other machines that use this Chute as their proxy. Selecting one narrows every list to it. When the device is Chute Mac, local clients are the applications, by name and icon, and the context menu offers Show in Finder.

Active and Recent

Active is what is open right now; Recent is the device's history, read back from the run's records and listed by connection number — the newest at the bottom. Click a column header to sort by that column instead. Both share one set of columns:

Column
ID The engine's connection number — the same number the console and the apps show
Date, Duration When it started, and how long it has lasted or lasted
Client The process (Chute Mac), the app's package name (Chute Android), or the local address
Method, Server, Status Method is the connection type — HTTP, HTTPS, SOCK, TCP or UDP, not the request's verb; Server is the destination host:port; Status is the connection's state: Active, Completed or Suspend
Policy The policy the rule chose
Upload, Download Bytes each way
Flags What Chute did to the connection — see the legend below

The Flags column is the quickest way to tell whether a rule you wrote is being applied:

Flag Meaning
M Decrypted (MitM intercepted)
H A header was modified
B A Body Rewrite rule or a script changed a body
R A rewrite rule fired
K Answered by a Mock Response rule rather than by the server

B means the content of a body changed: a body Chute held only to check it against the rules, or re-chunked or re-compressed without changing what it says, is not marked.

Recent holds up to 5,000 rows; Load Older at the bottom of the list fetches the next page from the device, and the list refreshes on its own every few seconds. When the active list is longer than one control packet can carry, a note under the table says the engine truncated it — the rows are there on the device, and Recent will show them once they close.

Right-click a row for Copy curl Command, Export Selected as HAR… / CSV…, Export All as HAR… / CSV… and Set Filter to <host>; an active row also offers Kill Connection, which closes it on the device. Right-clicking inside a selection of several rows keeps it, so Export Selected as HAR… / CSV… take every selected row; the items for one connection act on the row you clicked. Four more act on the device's rules for that host, the shortest way from a connection you are looking at to the rule that changes it: Add MitM Rule for, Enable MitM for, Add Header Rewrite for and Add Body Rewrite for <host>.

Notice: A row is a connection, not a request. A keep-alive connection that carried several requests is still one row, and the captured data holds all of those messages back to back; the headers shown are one request's. A browser opening a page therefore produces fewer rows than the page has resources.

The filter bar

The filter bar narrows what is shown. It does not change what the device records — for that, use [Replica] on the device.

Control Choices
Filter Host/URL… Text matched against the host, host:port, the process or app, the policy, the rule and the connection type — not against the URL's path
Method GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS, CONNECT
Status 1xx – 5xx
Traffic Active, Completed, Suspend
Type JSON, HTML, XML, Image, Text, Binary — from the response's content type
Duration < 100ms, 100ms–1s, 1s–5s, > 5s
Size < 1 KB, 1–100 KB, 100 KB–1 MB, > 1 MB
MitM Only Decrypted connections only
Modified Connections whose headers a rule changed, or whose body a rule or a script changed — H or B. An R-only or K-only row does not pass.

Clear Filters returns to everything.

Connection detail

Select a row and its detail opens in a panel below the list. The tabs, left to right:

General — what the list shows, laid out with room: the connection type and the status code; the outbound mode, the policy and the rule that matched; bandwidth and peak speeds; local and remote addresses; the start time; the SSL/MitM state (Intercepted, Header Modified, Body Modified, Mocked); and Rules Fired — the rewrite and Mock Response rules that changed this connection, quoted in the rule's own words. The list is capped at both ends: the engine keeps at most 16 hits per connection, and Dashboard shows 8 of them and appends … N more, so a rule that fires on every chunk crowds out the rest.

Timing — how the connection's setup was spent, as the engine measured it:

Line Counted from → to
Proxy Ready Cost The client's connection arriving → Chute ready to handle it
DNS Resolve → the name resolved (absent when the rule did not need an address)
Rule Cost → the rule table decided
Remote Ready Cost → the chosen outbound connected and ready
Active The connection's whole lifetime, from arrival to close

A line whose value is zero is left out rather than shown as zero, so a connection whose rule needed no address has no DNS Resolve line at all. A slow request is usually slow in exactly one of the others, and which one says where to look: DNS in the DNS section, Remote Ready in the policy or the server behind it.

Req Hdr / Resp Hdr — the headers as a table, with Query Parameters and Cookies broken out for the request and Cookies for the response. A header a rule modified is highlighted. Copy Selected copies the selected rows.

Req Data / Resp Data — the captured body, as Hex, Text, JSON (an expandable tree, with search) or Image (Fit / Actual Size); it opens as Text, whatever the body is, and multipart bodies are split into their parts. Export as bin saves the raw bytes, and the Text view offers Open in Sublime Text and Open in VSCode when either is installed. The two tabs can be selected only when there is captured data: recording was on when the connection ran, and the [Replica] filters let the host through.

Notice: Bodies are shown as they were captured. A compressed response — Content-Encoding: gzip — is not decompressed here, so its Text and JSON views are noise; the Hex view and Export as bin give you the bytes to decompress elsewhere. The device refuses to hand over a body larger than 2 MiB — the tab then reads Unable to load this body — and the Hex view shows the first 1 MiB.

DNS and UDP

DNS is the device's resolver cache: each domain with the addresses it resolved to, the server that answered first (Chute queries every configured server at once — see DNS), the TTL and where the record came from. That last column is the origin — Config, System or Dynamic — not a DNS record type. The TTL is reported as at least 600 seconds, so a shorter one reads as 600.

Right-click for Copy Domain, Copy IPs, Copy DNS Server and Set Filter to <domain>; a dynamically resolved record also offers Delete DNS Record of <domain>. Purge DNS Cache at the bottom empties the cache outright. Those last two act on the device's cache, not on Dashboard's view of it.

UDP lists UDP sessions — host, server, policy and state. There are no bodies for UDP.

MitM Tools

The MitM view manages the five rule families on the device, in five panels: MitM Rules, Header Rewrite, Body Rewrite, Mock Response and URL Rewrite. What is true of all of them:

  • The list is the running engine's copy of the rules, which starts as what the configuration file declared.
  • Adding a rule sends it to the device, which parses it as it would parse a configuration line; a line that does not parse is refused with an error rather than stored. A MitM Rules host is the exception — it is a pattern, not a rule line, and any non-empty string is appended as typed.
  • Changes live in the running engine only. They are not written to the configuration file, and a reload or restart brings back what the file says. Use the panels to find the rule that works, then write it into the configuration.
  • Whether a rule is being applied shows up in the list's Flags column (R, K) and in the detail panel's Rules Fired.

MitM Rules — one host pattern per rule, host[:port][/path], with a - prefix to exclude: *.google.com, api.example.com:8443, api.example.com/v2/*, -*.apple.com. The same grammar as the hostname key on the HTTPS decryption page. The count on the toolbar's MitM switch is the length of this list.

Header Rewrite — a form: URL Regex, Request or Response, Add / Replace / Delete / Replace (regex), Header Name, Header Value; with Replace (regex) a Value Regex is added, and what it matches in the header's value is replaced with the Replacement. Dashboard composes the configuration line for you; the grammar is on the Header Rewrite page.

Body Rewrite — one configuration line, typed as you would write it in the file, in any of the spellings the engine reads: Surge's http-response url-regex pattern replacement (or http-request), its http-response-jq url-regex jq-program (or http-request-jq), url-regex response regex pattern replacement (or request), and url-regex jsonpath-response jsonpath $.path value (or jsonpath-request). See Body Rewrite.

Mock Response — URL Regex, the Response Body type — file (a path; Browse…), text, base64 or tiny-gif (a built-in 1×1 transparent GIF, no content) — an optional Status Code, and optional Response Headers as Name: Value pairs separated by |.

Notice: A file path is read by the device running Chute, at request time. A path on your Mac is meaningful when Dashboard is connected to Chute Mac on that same machine, and meaningless when it is connected to an iPhone — the phone has no /Users/…. For a remote device, choose text or base64 so the content travels inside the rule (see Mock Response), or serve the file from a URL and use URL Rewrite.

URL Rewrite — URL Regex, Target and Type: header rewrites the request in place (Surge's Map Remote), 302 and 307 redirect the client, and reject, reject-200, reject-img, reject-dict, reject-array, reject-tinygif answer without contacting the server. See URL Rewrite.

Exporting

  • HAR — right-click on the list: the selected rows or all of them, as a HAR 1.2 file you can open in a browser's developer tools (Network → import), Charles or Proxyman. One entry per row that has a captured HTTP request; the others — plain TCP, for one — are left out, and the file's comment says how many. Bodies are included when recording was on: Dashboard fetches them from the device first, under a sheet that reads Exporting HAR… — Fetching the captured bodies from the device. — with a progress bar and Cancel, which abandons the export. A body over 512 KiB is recorded by its size only, and one export carries at most 64 MiB of bodies.
  • CSV — a fixed set of columns for a spreadsheet: ID,Method,URL,Status Code,Status,Duration,Upload,Download,Process,Start Time. It is not the list's own columns; there is no Date, Client, Server, Policy or Flags column in it. Method is the request's method and URL the full URL, as in the HAR export: HTTPS that went through the HTTP proxy without being decrypted gives CONNECT and https://host. A row with no HTTP request — plain TCP, or HTTPS that TUN carried without decrypting it — gives its connection type and host there instead.
  • Copy curl Command — a curl invocation that repeats the request from your Mac, with its method, headers and body; a body is fetched from the device first. Content-Length is left to curl to compute. A row that is only a tunnel — a CONNECT that was not decrypted, or plain TCP — gives just curl and the URL.
  • Export as bin — one body, as captured.

Dashboard builds its HAR from the list and the bodies it fetches from the device. The engine can also build one itself — with the matched rule, the policy and the fired rewrites in a _kl object per entry, and send/receive timings taken from the capture — via the console's Export HAR or GET /api/connections/export?format=har.

What Dashboard cannot reach

Dashboard speaks the engine's binary control channel, and some of what the engine can do exists only on the HTTP Control API. For these, use the Web Console or the API:

  • the diagnostic bundle, health, refusal counters and events;
  • the per-rule hit totals of the console's Rules page, and the did this rule ever fire answer they give;
  • the engine's own HAR, above;
  • the log.

One more thing worth knowing before you rely on it:

  • On iPhone, Apple TV and Android, HTTPS decryption and body capture are licensed features. Without a license Dashboard still connects and shows every connection with its rule and policy, but HTTPS rows are never decrypted — no M flag — and the data tabs cannot be selected. On iPhone and Android the app's MitM switch does not stay on and a purchase prompt appears instead; Apple TV has no MitM row on its control screen at all. See License and Activation.
S. Smart Rabbit LLC © All Rights Reserved            updated 2026-09-25 00:02:29

results matching ""

    No results matching ""