Skip to content

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

FieldTypeDefaultAllowed valuesDescription
external-controllerstring(unset)<host:port>Plain-HTTP listen address for the RESTful API.
external-controller-pipestring(unset)<pipe path>Windows named-pipe path. Only set on Windows when you want the API limited to local same-host clients.
external-controller-unixstring(unset)<socket path>Unix-domain socket path for the API.
external-controller-tlsstring(unset)<host:port>TLS-protected listen address. Requires the top-level `tls` block to carry a certificate and private key.
external-controller-corsRawCors(unset)RawCorsCORS allow-list for the HTTP API.
external-uistring(unset)<dir path>Local directory whose contents are served at /ui.
external-ui-urlstring(unset)<URL>Tarball URL fetched and unpacked to external-ui when the directory is empty.
external-ui-namestring(unset)<name>Subdirectory under external-ui to serve, allowing multiple dashboards side by side.
external-doh-serverstring(unset)<path> | <host:port>Mount a DoH endpoint at this path so other devices can use mihomo's DNS resolver.
secretstring(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

FieldTypeDefaultAllowed valuesDescription
allow-origins[]string[]<origin>Origin allow-list. Empty list means same-origin only.
allow-private-networkboolfalsetrue | falseHonor 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-controller binds to a non-loopback address, always set secret and/or external-controller-tls. The API can change every routing decision in the daemon.
  • external-ui is just a file server — it has no security beyond what CORS provides. Most users serve the dashboard from localhost and navigate to it from a browser on the same host.
  • external-controller-pipe (Windows) and external-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)

Core Tutorial by Argsment