External Controller (Clash API)
mihomo implements the Clash RESTful API. All Clash dashboards (metacubexd, yacd, Clash Dashboard) talk to mihomo through it. This page documents the cluster of top-level keys that configure where the API listens, the bundled UI, and CORS.
Top-level keys
| Field | Type | Default | Allowed values | Description |
|---|---|---|---|---|
external-controller | string | (unset) | <host:port> | Plain-HTTP listen address for the RESTful API. |
external-controller-pipe | string | (unset) | <pipe path> | Windows named-pipe path. Only set on Windows when you want the API limited to local same-host clients. |
external-controller-unix | string | (unset) | <socket path> | Unix-domain socket path for the API. |
external-controller-tls | string | (unset) | <host:port> | TLS-protected listen address. Requires the top-level `tls` block to carry a certificate and private key. |
external-controller-cors | RawCors | (unset) | RawCors | CORS allow-list for the HTTP API. |
external-ui | string | (unset) | <dir path> | Local directory whose contents are served at /ui. |
external-ui-url | string | (unset) | <URL> | Tarball URL fetched and unpacked to external-ui when the directory is empty. |
external-ui-name | string | (unset) | <name> | Subdirectory under external-ui to serve, allowing multiple dashboards side by side. |
external-doh-server | string | (unset) | <path> | <host:port> | Mount a DoH endpoint at this path so other devices can use mihomo's DNS resolver. |
secret | string | (unset) | <bearer token> | Bearer token required for all API calls. Strongly recommended whenever external-controller binds to a non-loopback address. |
Source: config/config.go:393-460 · pinned at v1.19.27 (5184081)
external-controller-cors
| Field | Type | Default | Allowed values | Description |
|---|---|---|---|---|
allow-origins | []string | [] | <origin> | Origin allow-list. Empty list means same-origin only. |
allow-private-network | bool | false | true | false | Honor private-network preflight requests so dashboards on private LANs can hit the API. |
Source: config/config.go:213-216 · pinned at v1.19.27 (5184081)
Example
yaml
external-controller: 127.0.0.1:9090
external-controller-cors:
allow-origins:
- https://metacubex.github.io
- http://localhost:5173
allow-private-network: true
external-ui: /etc/mihomo/ui
external-ui-url: https://github.com/MetaCubeX/metacubexd/archive/refs/heads/gh-pages.zip
external-ui-name: metacubexd
secret: <random-string-here>Notes
- If
external-controllerbinds to a non-loopback address, always setsecretand/orexternal-controller-tls. The API can change every routing decision in the daemon. external-uiis just a file server — it has no security beyond what CORS provides. Most users serve the dashboard fromlocalhostand navigate to it from a browser on the same host.external-controller-pipe(Windows) andexternal-controller-unix(Linux/macOS) are useful when you want only same-host clients to reach the API; pair them with file-system ACLs.
Source: config/config.go:213-460 · v1.19.27 (5184081)
