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-controller-routing-markint0<uint32>Linux SO_MARK (fwmark) set on the API listener sockets (plain and TLS) so policy routing can treat controller traffic specially. 0 disables.
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:402-470 · pinned at v1.19.31 (ab405ba)

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:216-219 · pinned at v1.19.31 (ab405ba)

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:216-470 · v1.19.31 (ab405ba)

Core Tutorial by Argsment