SSH MCP Server
Runs commands and moves files on remote Linux and Windows hosts over SSH, behind roles, approvals and audit
Manage a Tailscale tailnet's devices, ACLs, DNS, keys and local connection from an MCP client
By Jacob (individual) TypeScript Local · stdio DevOps and monitoringSecurity
57 popularity score ★ 150 ↓ 1.8k/wk
Opens the app, which asks before it adds the server. Then replace each <NAME> in its settings with your value.
It needs TAILSCALE_API_KEY. Replace each <NAME> with your value.
claude mcp add tailscale -e TAILSCALE_API_KEY=<TAILSCALE_API_KEY> -- npx -y @hexsleeves/tailscale-mcp-server{
"mcpServers": {
"tailscale": {
"command": "npx",
"args": [
"-y",
"@hexsleeves/tailscale-mcp-server"
],
"env": {
"TAILSCALE_API_KEY": "<TAILSCALE_API_KEY>"
}
}
}
}{
"mcpServers": {
"tailscale": {
"command": "npx",
"args": [
"-y",
"@hexsleeves/tailscale-mcp-server"
],
"env": {
"TAILSCALE_API_KEY": "<TAILSCALE_API_KEY>"
}
}
}
}{
"servers": {
"tailscale": {
"type": "stdio",
"command": "npx",
"args": [
"-y",
"@hexsleeves/tailscale-mcp-server"
],
"env": {
"TAILSCALE_API_KEY": "<TAILSCALE_API_KEY>"
}
}
}
}[mcp_servers.tailscale]
command = "npx"
args = ["-y", "@hexsleeves/tailscale-mcp-server"]
[mcp_servers.tailscale.env]
TAILSCALE_API_KEY = "<TAILSCALE_API_KEY>"gemini mcp add --scope user -e TAILSCALE_API_KEY=<TAILSCALE_API_KEY> tailscale npx -- -y @hexsleeves/tailscale-mcp-serverTAILSCALE_API_KEY |
Required: Tailscale API key. Alternatively set TAILSCALE_OAUTH_CLIENT_ID and TAILSCALE_OAUTH_CLIENT_SECRET (preferred by its docs); one of the two is needed to start. |
|---|---|
TAILSCALE_OAUTH_CLIENT_ID |
Optional: OAuth client ID, used instead of an API key; needs the secret too. |
TAILSCALE_OAUTH_CLIENT_SECRET |
Optional: OAuth client secret, set together with the client ID. |
TAILSCALE_TAILNET |
Optional: Tailnet name; defaults to - (the credential's default tailnet). |
TAILSCALE_ALLOWED_TOOL_RISK |
Optional: Highest allowed tool risk: read (default), write or admin. |
TAILSCALE_CLI_PATH |
Optional: Path to the tailscale binary; defaults to tailscale. |
TAILSCALE_API_BASE_URL |
Optional: API base URL; defaults to https://api.tailscale.com, https required except localhost. |
MCP_TRANSPORT |
Optional: stdio (default) or http. |
MCP_HTTP_BEARER_TOKEN |
Optional: Bearer token of 32+ characters, required in HTTP mode. |
MCP_HTTP_BIND_HOST |
Optional: HTTP bind address; defaults to 127.0.0.1. |
MCP_HTTP_PORT |
Optional: HTTP port; defaults to 3000. |
LOG_LEVEL |
Optional: debug, info (default), warn or error. |
Tailscale MCP Server is a community-built server, not from Tailscale, that works on a tailnet in two ways. Most of its tools call the Tailscale REST API: they list devices, authorize or remove them, turn subnet routes on or off, and read or change the ACL, policy file, DNS settings, auth keys, webhooks, device tags, file sharing and network lock. A smaller set runs the local tailscale CLI on the machine where the server runs: status, version, ping to a peer, bringing the host up or down, and choosing an exit node.
Version 1.3.4 registers 19 tools (src/mcp/tools at the v1.3.4 tag). It also offers four read-only resources (tailnet summary, device list, one device, current ACL) and two prompts, one to diagnose connectivity and one to review an ACL change.
Each tool has a risk level. With TAILSCALE_ALLOWED_TOOL_RISK left at its default of read, every tool still shows up in the client, but any call that would change something is refused when it runs. Setting it to write allows changes to ACLs, DNS, routes, tags, webhooks and the policy file. Setting it to admin also allows deleting or deauthorizing devices, connecting or disconnecting the host, creating or deleting auth keys, changing network lock and controlling exit nodes.
It runs over stdio by default. An HTTP mode that requires a bearer token is meant for reaching it privately inside a tailnet.
| Runtime | Node.js 20+ |
|---|
Node.js 20+ for npx (Bun 1.3+ also works). A Tailscale account and either an OAuth client (TAILSCALE_OAUTH_CLIENT_ID plus TAILSCALE_OAUTH_CLIENT_SECRET, which its docs prefer) or an API key (TAILSCALE_API_KEY) from the admin console; the server will not start without one of them. The CLI-backed tools (get_network_status, connect_network, disconnect_network, ping_peer, get_version, exit node set or clear) also need the tailscale CLI installed on the same machine.
Read-only unless TAILSCALE_ALLOWED_TOOL_RISK is set to write or admin; the code checks this on each call. Credentials are needed even for the CLI-only tools: the config check exits without OAuth or an API key (src/config/env.ts). HTTP mode exits without an MCP_HTTP_BEARER_TOKEN of at least 32 characters and binds to 127.0.0.1 unless --host or MCP_HTTP_BIND_HOST is given. The published Docker image starts in HTTP mode (its Dockerfile CMD passes --http), so the README's docker run -i stdio snippet stops because no bearer token is set. The GitHub README still shows an older 9-tool list and LOG_LEVEL numbers; the npm README for 1.3.4 matches the code.
It suits Tailscale admins who want an assistant to look over devices, ACLs and DNS, starting read-only and opening write or admin access only when they decide to. Because it can also bring the host machine up or down and pick exit nodes through the local CLI, it fits best on a machine that is itself on the tailnet. It is a third-party project, not Tailscale's own. Anyone who only needs to read inventory can keep the default read level. Anyone who wants a hosted endpoint will not find one here: it runs on your own machine, or on your own server in HTTP mode.
list_devicesdevice_actionmanage_routesget_network_statusconnect_networkdisconnect_networkping_peerget_versionget_tailnet_infomanage_file_sharingmanage_exit_nodesmanage_webhooksmanage_device_tagsget_version_infomanage_aclmanage_dnsmanage_keysmanage_policy_filemanage_network_lock