Headscale MCP connector
This server does not currently have a deployable release on Glama. Follow the repository's setup instructions to install and configure it for your MCP client, including any required credentials and local dependencies.
headscale-mcp (Headscale MCP connector)
MCP connector for a self-hosted Headscale control server. It speaks the Headscale HTTP API over stdio and over stateless Streamable HTTP on localhost.
Headscale is BSD-3-Clause software. This connector is an independent HTTP client of that API. It is not affiliated with the Headscale project or with Tailscale. Bring your own API key from the server you run.
This connector covers all 29 operations in headscale.openapi.json (Headscale v0.29.6) plus one virtual policy diff. Operations are grouped into 8 toolsets. Enable a subset with HEADSCALE_TOOLSETS so the model only sees the tools you need.
Self-hosted Headscale only. There is no default base URL. HEADSCALE_URL is required and must be your server origin, for example http://127.0.0.1:8080. A trailing /api/v1 is stripped. Calls go to {HEADSCALE_URL}/api/v1. Hosts on tailscale.com and tailscale.io are refused. This connector does not speak the Tailscale SaaS API.
Setup
npm install
npm run ci
npm start
npm run start:httpnpm start speaks stdio. npm run start:http serves Streamable HTTP at http://127.0.0.1:3000/mcp and GET /health. HTTP mode has no authentication. Keep it on localhost.
Create an API key with headscale apikeys create. The connector sends it as Authorization: Bearer and never prints it.
{
"mcpServers": {
"headscale": {
"command": "node",
"args": ["/workspace/connectors/headscale/dist/index.js"],
"env": {
"HEADSCALE_URL": "http://127.0.0.1:8080",
"HEADSCALE_API_KEY": "...",
"HEADSCALE_ALLOW_WRITES": "false",
"HEADSCALE_TOOLSETS": "nodes,users,policy,meta",
"HEADSCALE_CONTACT": "you@example.com"
}
}
}
}Docker (HTTP, no authentication, localhost only):
docker build -t headscale-mcp .
docker run -p 3000:3000 \
-e HEADSCALE_URL=http://host.docker.internal:8080 \
-e HEADSCALE_API_KEY=... \
headscale-mcpDo not put the API key in the image.
Regenerate the operations registry after a Swagger bump:
npm run gen:operationssrc/operations.ts is generated. Do not edit it by hand.
Related MCP server: tailscale-blade-mcp
Config
Variable | Meaning |
| Required. Self-hosted Headscale origin. |
| API key. Sent as |
| Must be the literal |
| Comma list of toolsets, or |
| Local request budget. Default 30. |
| Upstream timeout. Default 20000. |
| GET cache TTL. Default 60. Writes clear the cache. |
| Contact token in the User-Agent. Must not be the API key. |
|
|
| HTTP port. Default 3000. |
Safety
Reads run without confirm. check_policy is a read. Headscale validates the policy in a sandbox and does not save it. diff only GETs the current policy.
Every other non-GET is a write. A write needs confirm: true (a boolean, not the string "true") and HEADSCALE_ALLOW_WRITES=true. Otherwise the tool returns a dry-run preview of the method, path, query, and redacted body, and it sends no write. set_policy is the exception on the read side of a preview. Its preview GETs the current policy so the preview can include a line diff. It still does not PUT until both gates pass. A confirmed set_policy with an empty policy string is refused before any request.
Preview and tool descriptions warn on node delete and expire, user delete, pre-auth key create, delete, and expire, API key create, delete, and expire, node tags, approved routes, policy set (a bad policy can lock all nodes out), node register, auth approve, and the debug node creator.
Creating a pre-auth key or an API key returns the secret once, with a note that it is shown only once. List and get responses, and every preview, keep the id or prefix and mask the secret. The caller's own HEADSCALE_API_KEY is redacted everywhere, including inside that one-time response.
Node ids and user ids stay strings and must be numeric. The spec has no pagination parameters.
Errors use a stable prefix. [unauthorized] is 401. [forbidden] is 403. [not-found] is 404. [invalid] is 400 or 422. [rate-limit] is 429 and includes Retry-After. Server errors, network errors, and timeouts have their own codes. Stack traces and filesystem paths are stripped. Responses larger than 1 MB are rejected.
Tools
Default HEADSCALE_TOOLSETS publishes 4 tools. HEADSCALE_TOOLSETS=all publishes 8 tools (30 actions). Each tool takes action plus params, query, body, and confirm when the tool has writes.
Toolset | Tool | Actions | Default |
nodes |
| 9 | yes |
users |
| 4 | yes |
policy |
| 4 | yes |
meta |
| 1 | yes |
preauth_keys |
| 4 | no |
api_keys |
| 4 | no |
auth |
| 3 | no |
debug |
| 1 | no |
debug is only enabled by all. debug_create_node inserts a node without a real client. It is for tests. The tool description says so.
Policy actions are get_policy, check_policy, diff, and set_policy. diff takes a proposed HuJSON or JSON policy string and returns added and removed line counts plus a compact line diff.
Example. List users, preview a create, then confirm it:
{ "action": "list_users" }{ "action": "create_user", "body": { "name": "lab" } }{ "action": "create_user", "body": { "name": "lab" }, "confirm": true }Live check
npm run live-check talks to a real Headscale when HEADSCALE_URL and HEADSCALE_API_KEY are set. It creates throwaway users, keys, and a debug node, checks previews first, then deletes them. It reads policy, checks and diffs a permissive policy, sets that policy, and restores the previous policy. If the previous policy was empty, it writes the same permissive default back. If those variables are unset, it prints a skip message and exits 0. It prints pass and fail lines only.
LIVE-CHECK.md says what the script covers. This session did not run it against a server.
What this is not
This is not a Tailscale.com or Tailscale SaaS client. Those hosts are rejected.
This is not a WireGuard or Tailscale node. It does not join a tailnet, ship DERP, or install tailscaled.
This is not a full replacement for the headscale CLI install path. Server bootstrap, config files, and database migrations stay on the host.
debug_create_node is not a supported way to enroll production devices. Use register or a pre-auth key for that, and treat the debug tool as test-only.
Compared with a small community server that exposes about 17 tools and no ACL actions, this connector covers the v0.29.6 Swagger, gates writes, and adds policy get, check, diff, and set.
Attribution
Headscale is BSD-3-Clause. This connector does not copy Headscale source. It calls the HTTP API described by the Swagger file in this repo.
License
MIT, see LICENSE. This is an independent, unofficial connector and is not endorsed by the Headscale project or its owners.
headscale.openapi.json is generated from juanfont/headscale (BSD-3-Clause, Copyright (c) 2020, Juan Font).
This server cannot be deployed
Maintenance
Related MCP Connectors
Tailscale device, route, DNS, key, user, and ACL management over MCP and CLI.
Read devices, users, keys, ACLs and DNS for a tailnet; manage devices, routes and auth keys.
Manage cron/heartbeat checks, read pings and flips, pause/resume/delete on Healthchecks.io.
Manage ngrok from your agent: endpoints, domains, and traffic policy.
Related MCP Servers
- AlicenseAqualityCmaintenanceProduction-ready MCP server for Tailscale management with 48 tools across 9 domains: Devices, DNS/Split DNS, ACL policies, Auth Keys, Users, Webhooks, Posture Integrations, Tailnet Settings, and Diagnostics. Supports stdio and SSE transport with Bearer token authentication. Built with TypeScript strict mode, Zod validation, and zero shell execution. AGPL-3.0 + Commercial dual-licensed.4993 npm1AGPL 3.0
- AlicenseAqualityCmaintenanceEnables AI agents to securely interact with Tailscale tailnets for device inventory, ACL review, key hygiene, and more, with token-efficient output and write-gated mutations.19MIT
- AlicenseAqualityBmaintenanceEnables administrators to manage Keycloak realms, users, roles, clients, groups, and more through its Admin REST API, with safe-by-default configuration and destructive operation confirmation.56109 npm3MIT
- AlicenseNot gradedqualityAmaintenanceEnables an MCP client to inspect and administer a Tailscale node through the local tailscale CLI and the wider tailnet through the control-plane REST API, exposing 186 read, write, and destructive tools plus resources, prompts, and completions. Tier and preset dials keep dangerous operations unlisted until explicitly enabled, and both surfaces degrade gracefully when the CLI or a credential is absent.16Apache 2.0