Why the External Controller Matters on macOS

Clash Verge Rev is more than a tray icon that turns a proxy on or off. Under the interface, it manages profiles, proxy groups, listeners, rule providers, DNS behavior, and a running Mihomo-compatible core. The external controller is the HTTP API that lets a local Web dashboard communicate with that core. Once it is configured correctly, you can inspect active connections, change proxy groups, review logs, and verify whether a rule is behaving as expected without opening every settings panel in the desktop application.

On macOS, this feature is useful when the graphical interface is hidden in the menu bar, when you want a second monitor to display traffic information, or when you are troubleshooting a subscription that appears healthy but routes an application incorrectly. It also gives technically minded users a clearer operational view: instead of guessing whether a request used DIRECT, a regional group, or a fallback node, you can inspect the live connection and identify the selected policy.

The external controller is not the same thing as the local mixed port. The mixed port accepts proxied HTTP and SOCKS traffic from applications. The controller port accepts management requests from a dashboard or API client. A browser pointed at the mixed port will not show a management page, and a dashboard pointed at the mixed port will usually report a refused connection or an unexpected response. Keeping those two listeners conceptually separate prevents many first-time configuration errors.

Scope: Keep the controller bound to localhost unless you have a specific, secured administrative network design. Do not expose an unauthenticated management API to Wi-Fi, the public internet, or an untrusted container.

Prepare Clash Verge Rev Before Editing the Controller

Start by opening the current Clash Verge Rev build and confirming that a profile is loaded. The exact labels can vary slightly between releases, but the controller setting is normally available under a section such as Settings, Advanced, Core, or External Controller. If the application has multiple profiles, first activate the profile that you actually use. Editing a dormant profile can create the illusion that the controller is broken when the running core is reading a different configuration.

Before changing anything, note the local ports already in use. A typical setup may contain a mixed port for browser traffic, a SOCKS port for tools that require it, a DNS listener, and a controller port for API access. These ports must be distinct. macOS does not allow two processes to bind the same TCP port on the same address, and the resulting error may appear only in the application log rather than as a clear settings warning.

It is also worth closing other Clash-family clients during the initial test. ClashX, another Verge installation, a development Mihomo process, and a background service can all compete for similar listeners. If the controller request reaches the wrong process, the response may look valid but describe a different profile or core. A clean baseline is easier to verify than a machine running several proxy clients at once.

Decide where the dashboard will run. For a dashboard opened on the same Mac, binding the controller to 127.0.0.1 or localhost is normally the safest choice. If you plan to open the dashboard from another trusted device, the controller must listen on a LAN address, but that design requires a strong secret, firewall rules, and an understanding of which devices can reach the port. In most personal setups, remote access is unnecessary and increases the attack surface without improving daily workflow.

Configure the External Controller and API Secret

In the controller settings, enter a dedicated local port such as 9090 or another unused value. The number itself is not special; consistency matters more than choosing a fashionable default. If another application already owns that port, select a different one and restart the core. Avoid changing the mixed port at the same time, because changing two variables makes it harder to determine which edit solved or caused the problem.

Next, set an API secret. Use a long, randomly generated value rather than a short word such as clash, your Mac username, or the name of your Wi-Fi network. The secret is sent by the dashboard in an authorization header, so anyone who can reach an unprotected controller may be able to change proxy groups, read connection metadata, or inspect logs. A password manager is a better place to store the value than a screenshot or a plain-text note synchronized to every device.

A local-only configuration commonly follows this conceptual pattern:

external-controller: 127.0.0.1:9090
secret: "replace-with-a-long-random-secret"

Treat this snippet as a configuration model rather than a command to paste blindly. Clash Verge Rev may expose the same values through a graphical form, a generated profile, or a core-specific settings file. If the application regenerates configuration files when a profile is updated, manually editing the generated YAML may be temporary. Prefer the application’s persistent setting when it provides one, and use the core configuration only when you understand which file has authority.

Save the setting, restart the active core, and watch the status area for a successful launch. A controller port that is configured but not actually loaded is a common source of confusion. The dashboard cannot connect until the running core has reopened its listeners. If the interface shows a restart prompt, complete it before testing from the browser.

Security habit: Never publish the controller secret in a support screenshot, commit it to a public repository, or place it inside a shareable subscription URL. Rotate it immediately if you believe another person or application has obtained it.

Test the Controller Port on macOS

Test locally before opening a dashboard. In Terminal, send a request to the controller endpoint with the secret in the authorization header:

curl -i \
  -H "Authorization: Bearer YOUR_CONTROLLER_SECRET" \
  http://127.0.0.1:9090/version

A successful response normally contains an HTTP success status and a JSON object describing the running core version. The exact fields depend on the core and application release, so focus first on the connection result, the authorization behavior, and whether the response is valid JSON. A connection refusal usually means no process is listening at that address and port. A timeout suggests a routing, firewall, or address problem. A response indicating unauthorized access usually means the listener is alive but the secret is missing or incorrect.

You can also inspect the listening socket with a macOS command such as:

lsof -nP -iTCP:9090 -sTCP:LISTEN

Replace 9090 with the port you selected. The result should identify the process that owns the listener. If it shows a different Clash client, stop that client and repeat the test. If it returns nothing, revisit the active profile and restart sequence. This check is valuable because it separates “the setting is visible in the GUI” from “the operating system has a process accepting connections.”

Once the version endpoint works, test a read-only endpoint such as the proxies resource through your dashboard or API client. Confirm that the displayed proxy groups match the active Clash Verge Rev profile. If the endpoint responds but the dashboard shows empty groups, the dashboard may expect a different API version, a different controller path, or a WebSocket capability that the selected core does not provide.

Connect a Web Dashboard Safely

Open the dashboard only after the direct API test succeeds. In the dashboard connection form, enter the controller URL, for example http://127.0.0.1:9090, and provide the same secret without extra spaces. Do not enter the mixed port here. The URL should point to the management API, while application traffic continues to use the mixed or SOCKS listener configured elsewhere.

If the dashboard is delivered from a different origin, the browser may enforce cross-origin rules even when the controller itself is healthy. Some dashboards are designed to run from a local file, a bundled page, or a trusted hosted address; others require the controller to permit a specific external origin. Avoid solving this by allowing every origin indefinitely. A broad cross-origin setting can make a forgotten browser tab or malicious page more dangerous, especially if the controller is bound beyond localhost.

The first useful dashboard checks are operational rather than cosmetic. Confirm that the current mode is the one you expect, inspect the active proxy group, and open the connections view while loading a known website. Look at the selected rule and policy for the connection. If the dashboard reports activity but the application still fails, the problem may be DNS resolution, a rule mismatch, an upstream node issue, or a browser-specific proxy setting rather than controller connectivity.

When connecting from another Mac on the same network, replace the loopback address with the host Mac’s LAN address only if the controller is configured to listen on that interface. Then restrict macOS firewall access to the trusted network and keep the API secret strong. Hotel networks, office Wi-Fi, and shared apartments are not automatically trusted simply because they display a familiar network name. For routine personal administration, returning to localhost is the safer end state.

Troubleshoot Common External Controller Errors

Connection refused or failed to fetch

Start with the address and port, then verify the listener with lsof. A refused connection generally means the controller is disabled, the core has not restarted, the port is occupied by another process, or the dashboard is using the mixed port by mistake. Check whether Clash Verge Rev is running in its normal mode and whether a profile error prevented the core from launching. Do not assume that a visible tray icon proves the API listener is active.

Unauthorized, forbidden, or invalid secret

Compare the secret character by character and remove accidental quotation marks copied from a YAML file. Some dashboards preserve an old token in browser storage, so delete the saved connection and enter the current value again. If you recently rotated the secret, restart the dashboard rather than relying on an already open tab. For a clean test, use curl and explicitly send the Authorization: Bearer header.

Dashboard loads but shows no data

An empty dashboard does not always mean the controller is offline. The API may answer correctly while the dashboard is requesting endpoints unsupported by the selected core. Check the browser developer console for failed requests and compare the requested paths with the core’s documented API. Also confirm that the dashboard is connected to the same controller port as the running profile and not to an old port remembered from a previous installation.

macOS firewall or network-extension interference

A firewall prompt, security product, corporate VPN, or network extension may block the dashboard or the core even when localhost tests appear inconsistent. Test from Terminal first, then test the dashboard in the same browser. If localhost works but a LAN address fails, inspect firewall and interface binding rules. If both fail after a macOS update, review the application’s permissions and restart the core rather than repeatedly changing proxy groups.

FAQ: Clash Verge Rev External Controller on macOS

Which port should I use for the controller?

Use any unused local TCP port, commonly a number such as 9090. The important requirements are that the port is free, the running core actually binds to it, and the dashboard uses the same address and port. Keep it different from the mixed port, SOCKS port, and any other listener to make troubleshooting straightforward.

Can I access the controller from an iPhone or another Mac?

You can, but remote access should be deliberate. Bind the controller to a trusted LAN interface, use a strong secret, restrict firewall access, and avoid shared or public Wi-Fi. If you only need administration on the Mac where Clash Verge Rev runs, keep the listener on 127.0.0.1; localhost access is safer and simpler.

What should I do if the API secret was exposed?

Rotate it immediately in Clash Verge Rev, restart the active core, and reconnect every dashboard using the old value. Review recent connection and log activity if the controller was reachable beyond localhost. Treat an exposed secret as a credential compromise, not merely a cosmetic configuration mistake.

Why does the dashboard fail when the mixed port works?

The mixed port is designed for proxy traffic, while the external controller port is designed for management API requests. A browser or application can successfully use the mixed port while a dashboard fails because it needs API endpoints, authorization, and sometimes WebSocket support. Point each tool at the listener intended for its job.

Compared with lightweight menu-bar clients that hide controller details, or generic Web dashboards that provide little guidance when ports and API versions diverge, Clash V.CORE offers a clearer operational foundation for this macOS workflow: separate listeners, inspectable routing state, profile-aware management, and practical visibility into active connections. If you want a maintained Clash environment that makes external-controller testing easier rather than turning every error into guesswork, visit the download page and try Clash V.CORE on your Mac.

// Editor's Pick

Clash V.CORE for Clearer macOS Control

Manage profiles, inspect live connections, and validate controller settings with a focused Clash workflow built for practical troubleshooting.

  • Local external-controller support
  • Profile-aware proxy group management
  • Live connection and routing visibility
  • Separate mixed and management ports
  • Reliable macOS desktop workflow
Get Clash V.CORE →