Most GUI clients (Clash Verge, the Clash for Windows family) already ship with a built-in dashboard, so day-to-day use usually needs no extra setup. But if you're running the Mihomo core directly, or you want a more powerful third-party dashboard for inspecting traffic, you'll need to enable external control manually and pair it with a browser dashboard project.
What is external control?
The Clash core itself runs a RESTful API service that listens on the address and port specified in your config. Every GUI client, CLI tool, and browser dashboard essentially talks to the core through this same API — querying the current node, switching proxy groups, and streaming live logs are all done through the API, with no need to restart the core itself.
In other words, the core handles the actual traffic forwarding while the dashboard is just a "gauge cluster" sitting on top — the two are completely decoupled. That's also why actions like switching nodes or flushing the DNS cache take effect instantly in most dashboards, without needing to reload the entire config file.
Enabling external control
Add the following two lines to your config file, then restart the core once for them to take effect:
external-controller: 127.0.0.1:9090 secret: 'replace-with-a-strong-secret' # Dashboard access key — be sure to change this
external-controller is the address and port your dashboard connects to, and secret is the access key you'll enter the first time you connect a dashboard. If you're using a GUI client with a built-in dashboard, both of these are usually already configured for you and can be viewed directly in the settings — no need to edit the config file by hand.
Keep the listen address at 127.0.0.1 — don't bind to 0.0.0.0 and expose it to the public internet. This is the step most people overlook, and it's also the one with the worst consequences.
Which dashboard should you use?
| Dashboard | Highlights | Best for |
|---|---|---|
| yacd | Lightweight, clean UI — the connection list and traffic graph are the core features | Users who just want to see connection status without extra bells and whistles |
| metacubexd | More full-featured, with rule testing, subscription management, and multiple themes | Users who want the dashboard to handle more day-to-day tasks and reduce switching between apps |
| Built-in client dashboard | Integrated with the GUI client, no extra deployment needed | Users already on a GUI client like Clash Verge or CFW |
Both yacd and metacubexd are open-source static web projects — you can deploy them on any static host, or simply open the local files directly in a browser. To connect, just enter the external-controller address and secret you configured earlier.
The three most-used dashboard views
- Connections: Lists every active connection in real time, including the destination domain, the matched rule, and the node it's routed through. This is the most useful view when you're trying to figure out why a site went through direct connection.
- Proxies: Shows every proxy group and node latency, and lets you manually switch nodes or trigger a speed test — functionally identical to the node panel inside a GUI client.
- Logs: Streams the core's runtime logs live. This is the first place to check when a rule isn't matching or a subscription fails to parse.
Security considerations
External control is essentially an admin interface with no rate limiting and very coarse permissions — anyone with access effectively has full control of that Clash instance, including the ability to see every connection you make, switch nodes, and even read sensitive information from your config. So:
- Keep the listen address at 127.0.0.1 so it's only reachable locally. If you genuinely need remote access, forward the port through an SSH tunnel rather than exposing it directly.
- Use a long, random string for secret — avoid anything guessable like a birthday or username.
- If you have LAN sharing enabled (allow-lan), don't let the external control port open to the LAN along with it — manage the two listen scopes separately.
Once everything's set up, just open the dashboard, enter the address and key, and you'll see live connections right away. Compared to restarting the client and testing nodes one by one every time you make a change, this "watch while you tweak" workflow is far more efficient — especially when you're debugging rules or tracking down why a site isn't loading correctly.
Managing multiple devices and cores
If you're running Clash on several devices at once — say, a home router, an always-on NAS, and a local test instance on your laptop — switching addresses back and forth in the same dashboard gets tedious. In this case, give each instance's external-controller a different port, then save multiple connection profiles in the dashboard so you can switch between them like browser bookmarks, without retyping the address every time.
It's also worth setting a separate secret for each instance rather than reusing the same one everywhere out of convenience — if one instance's key ever leaks, the others stay unaffected. Instances that run long-term on a router or NAS have a larger attack surface, so rotating their keys should be a higher priority.
Troubleshooting connection failures
When a dashboard fails to connect, it's almost always one of the following. Go through them in order and you'll usually find the culprit:
- Wrong address or port: Double-check that the address and port entered in the dashboard exactly match the external-controller value in your config file — watch for a missing protocol prefix or port number.
- Secret mismatch: If you changed secret in the config file but haven't restarted the core, the new key hasn't taken effect yet, and the dashboard will keep reporting authentication failures.
- The core isn't listening on that address: If you're accessing the dashboard from another device but the core's external-controller is still set to 127.0.0.1, it's only reachable locally, so remote devices naturally can't connect. This is exactly why we recommend against loosening the listen scope — use an SSH tunnel for remote access instead of opening up the listen address directly.
- Browser cross-origin restrictions: Some browsers place extra restrictions on HTTP pages accessing local addresses. If your connection gets blocked by the browser, try a different browser or use the local deployment method provided by the dashboard project.
Working through these checks resolves the vast majority of connection issues. The dashboard itself isn't complicated — most cases of "it just won't connect" come down to configuration details, not an actual problem with the dashboard or the core.