#3203·mihomo

[Feature] Expose Tailscale authentication state and AuthURL via external-controller API

Author: 2017jwCreated Sep 12, 2026Updated Sep 12, 2026
Labelsenhancement

Verification Steps

  • I have read the documentation and confirmed that this feature is not implemented
  • I have searched for the feature request I want to propose in the Issue Tracker and did not find it
  • I am a non-Chinese user.

Description

I would like to request a structured external-controller API for the type: tailscale outbound, mainly to expose Tailscale authentication state and interactive login information.

Mihomo already supports the Tailscale outbound (#2783), and the existing external-controller already exposes many runtime capabilities such as proxies, connections, logs, traffic, and rules.

However, when a Tailscale outbound is configured without an auth-key and interactive authentication is required, frontend applications currently do not have a stable structured API to retrieve:

  • the current Tailscale state, such as NeedsLogin, Starting, or Running
  • the interactive authentication AuthURL
  • current Tailscale IP addresses and other basic runtime information
  • optionally, actions to trigger login or logout

Existing logs already show that Mihomo is aware of the Tailscale backend state transitions, for example:

Switching ipn state NoState -> NeedsLogin
LocalBackend state is NeedsLogin; running StartLoginInteractive...
Switching ipn state NeedsLogin -> Starting
Switching ipn state Starting -> Running

Similar logs can be seen in #2804.

At the moment, a GUI or another client using external-controller has two practical choices when supporting first-time Tailscale login:

  1. require the user to provide an auth-key in advance, or
  2. subscribe to /logs and parse the authentication URL from log messages

The second approach is fragile and does not seem suitable as a stable programmatic interface, because log wording and log levels may change.

It would be useful if Mihomo Core could expose this state through a structured runtime API.

For example:

http
GET /proxies/{name}/tailscale

Possible response:

json
{
  "state": "NeedsLogin",
  "authUrl": "https://login.tailscale.com/a/xxxx",
  "ips": [],
  "hostname": "mihomo"
}

After authentication:

json
{
  "state": "Running",
  "authUrl": "",
  "ips": ["100.x.x.x"],
  "hostname": "mihomo"
}

The exact API path does not matter. Another option would be to extend the existing:

http
GET /proxies/{name}

response with additional runtime fields when the proxy type is tailscale.

If explicit control of the authentication lifecycle is desirable, APIs such as the following could also be considered:

http
POST /proxies/{name}/tailscale/login
POST /proxies/{name}/tailscale/logout

Use case

This is especially useful on mobile platforms.

On Android, only one application can normally own the active VPNService. Using Mihomo's built-in Tailscale outbound makes it possible for one core to handle both regular proxy traffic and Tailnet / Headscale private-network traffic.

An ideal frontend flow would be:

Tailscale outbound
-> NeedsLogin
-> frontend gets AuthURL
-> open browser for Tailscale / Headscale authentication
-> Starting
-> Running

instead of relying on log parsing.

Reference

sing-box provides a useful reference for this type of integration.

Its Tailscale endpoint supports interactive authentication and management from GUI clients:

https://sing-box.sagernet.org/configuration/endpoint/tailscale/

Starting from sing-box 1.14.0, its API service also includes Tailscale operations and is shared by its GUI, CLI, and Dashboard:

https://github.com/SagerNet/sing-box/releases/tag/v1.14.0

This does not mean Mihomo should use the same API or gRPC design. The point is only that exposing Tailscale authentication and runtime state from the core is useful for frontend integration, and Mihomo already has a mature external-controller that could serve this purpose.

Related issues:

  • #2783 — add Tailscale outbound (tsnet-based)
  • #2804 — Android Tailscale outbound stuck at NeedsLogin