Server data from the Official MCP Registry
Secure MCP access for private infrastructure over Tailscale — 48 tools across 9 domains
Secure MCP access for private infrastructure over Tailscale — 48 tools across 9 domains
Valid MCP server (1 strong, 1 medium validity signals). 8 known CVEs in dependencies (1 critical, 5 high severity) Package registry verified. Imported from the Official MCP Registry.
5 files analyzed · 9 issues found
Security scores are indicators to help you make informed decisions, not guarantees. Always review permissions before connecting any MCP server.
Unverified package source
We couldn't verify that the installable package matches the reviewed source code. Proceed with caution.
Set these up before or after installing:
Environment variable: TAILSCALE_API_KEY
Environment variable: TAILSCALE_OAUTH_CLIENT_ID
Environment variable: TAILSCALE_OAUTH_CLIENT_SECRET
Environment variable: TAILSCALE_TAILNET
Add this to your MCP configuration file:
{
"mcpServers": {
"io-github-itunified-io-tailscale": {
"env": {
"TAILSCALE_API_KEY": "your-tailscale-api-key-here",
"TAILSCALE_TAILNET": "your-tailscale-tailnet-here",
"TAILSCALE_OAUTH_CLIENT_ID": "your-tailscale-oauth-client-id-here",
"TAILSCALE_OAUTH_CLIENT_SECRET": "your-tailscale-oauth-client-secret-here"
},
"args": [
"-y",
"tailscale-mcp"
],
"command": "npx"
}
}
}From the project's GitHub README.
Secure MCP access for private infrastructure over Tailscale
AI agents need access to internal tools, services, and infrastructure — but exposing private systems to the internet creates unacceptable security risks. VPNs are complex, SSH tunnels are fragile, and API gateways add latency and maintenance overhead.
mcp-tailscale bridges this gap: a lightweight MCP server that gives AI agents secure, authenticated access to your Tailscale-connected infrastructure — without exposing anything to the public internet.
mcp-tailscale is an MCP Gateway Runtime that connects AI agents (Claude, GPT, custom) to your private infrastructure through Tailscale's zero-trust network. It provides 48 tools across 9 domains for managing devices, DNS, ACL policies, auth keys, users, webhooks, posture integrations, and tailnet settings — all through the Tailscale API v2.
No SSH. No shell execution. API-only. 4 runtime dependencies.
npm install -g tailscale-mcp
git clone https://github.com/itunified-io/mcp-tailscale.git
cd mcp-tailscale
npm install
cp .env.example .env # Edit with your Tailscale API key and tailnet name
npm run build
node dist/index.js # stdio transport for MCP
mcp-tailscale supports opportunistic secret loading from HashiCorp Vault via AppRole authentication. This lets you store your Tailscale credentials centrally in Vault and avoid passing sensitive values through MCP config files or shell environment variables.
At startup, the server checks whether NAS_VAULT_ADDR is set. If it is, it authenticates to Vault using AppRole credentials, reads the KV v2 secret at <mount>/data/tailscale/api, and injects the values into the process environment before the Tailscale client is initialized.
NAS_VAULT_ADDR is unset, the Vault loader is a silent no-op. The server behaves exactly as without Vault.fetch available in Node.js 20+ (no extra packages).Explicit env vars > Vault > error (missing credentials)
If TAILSCALE_API_KEY is already set in the environment, Vault is still contacted (if configured) but the explicit value wins. This lets you override Vault values per-session without touching the Vault secret.
| Variable | Required | Description |
|---|---|---|
NAS_VAULT_ADDR | Yes* | Vault server address (e.g., https://vault.example.com:8200) |
NAS_VAULT_ROLE_ID | Yes* | AppRole role ID for this server |
NAS_VAULT_SECRET_ID | Yes* | AppRole secret ID for this server |
NAS_VAULT_KV_MOUNT | No | KV v2 mount path (default: kv) |
* Only required if using Vault. When NAS_VAULT_ADDR is unset, none of these are read.
The loader reads the secret at path <mount>/data/tailscale/api (default: kv/data/tailscale/api) and maps keys as follows:
# Path: kv/tailscale/api
{
"api_key": "tskey-api-your-key",
"tailnet": "your-tailnet.ts.net"
}
| Vault Key | Maps To |
|---|---|
api_key | TAILSCALE_API_KEY |
tailnet | TAILSCALE_TAILNET |
OAuth note: the Vault loader only handles the API-key path. If you use OAuth (
TAILSCALE_OAUTH_CLIENT_ID/TAILSCALE_OAUTH_CLIENT_SECRET), set those through the normal environment — they are not currently read from Vault.
1. Write the Tailscale credentials to KV v2:
vault kv put kv/tailscale/api \
api_key="tskey-api-your-key" \
tailnet="your-tailnet.ts.net"
2. Create a Vault policy:
# tailscale-mcp-policy.hcl
path "kv/data/tailscale/api" {
capabilities = ["read"]
}
vault policy write tailscale-mcp tailscale-mcp-policy.hcl
3. Enable AppRole auth and create a role:
vault auth enable approle
vault write auth/approle/role/tailscale-mcp \
token_policies="tailscale-mcp" \
token_ttl="1h" \
token_max_ttl="4h"
4. Retrieve the role ID and generate a secret ID:
vault read auth/approle/role/tailscale-mcp/role-id
vault write -f auth/approle/role/tailscale-mcp/secret-id
{
"mcpServers": {
"tailscale": {
"command": "npx",
"args": ["@itunified.io/mcp-tailscale"],
"env": {
"NAS_VAULT_ADDR": "https://vault.example.com:8200",
"NAS_VAULT_ROLE_ID": "your-role-id",
"NAS_VAULT_SECRET_ID": "your-secret-id"
}
}
}
}
With this configuration, no Tailscale credentials appear in the MCP config — they are fetched from Vault at startup.
Add to .mcp.json in your project root:
{
"mcpServers": {
"tailscale": {
"command": "node",
"args": ["/path/to/mcp-tailscale/dist/index.js"],
"env": {
"TAILSCALE_API_KEY": "your-api-key-here",
"TAILSCALE_TAILNET": "your-tailnet-name"
},
"comment": "Or use OAuth: TAILSCALE_OAUTH_CLIENT_ID + TAILSCALE_OAUTH_CLIENT_SECRET instead of TAILSCALE_API_KEY"
}
}
}
48 tools across 9 domains:
Authentication: API key or OAuth client credentials (auto-refresh)
Claude Code skills compose MCP tools into higher-level workflows. See .claude/skills/README.md for detailed documentation.
| Skill | Slash Command | Description |
|---|---|---|
| tailscale-health | /ts-health | Tailnet health dashboard — devices, DNS, ACL, keys, connectivity |
| tailscale-live-test | /ts-test | Live integration test — read + safe writes with cleanup |
| tailscale-acl-management | — | ACL policy management — view, edit, validate, test, drift detection |
| tailscale-device-management | — | Device management — list, authorize, routes, tags, posture |
| tailscale-dns-management | — | DNS management — split DNS, nameservers, search paths, MagicDNS |
| tailscale-key-management | — | Auth key management — create, list, rotate, revoke |
| tailscale-onboarding | — | New device onboarding — auth key, authorize, tags, routes, verify |
By default, mcp-tailscale uses stdio transport. To enable HTTP/SSE:
export TAILSCALE_MCP_TRANSPORT=sse
export TAILSCALE_MCP_AUTH_TOKEN=your-secret-token
export TAILSCALE_MCP_PORT=3000 # optional, default: 3000
export TAILSCALE_MCP_HOST=localhost # optional, default: localhost
node dist/index.js
All requests require Authorization: Bearer <token>. The server will not start without TAILSCALE_MCP_AUTH_TOKEN.
| Variable | Required | Default | Description |
|---|---|---|---|
TAILSCALE_API_KEY | Yes* | — | Tailscale API key (from admin console > Settings > Keys) |
TAILSCALE_OAUTH_CLIENT_ID | Yes* | — | OAuth client ID (from admin console > Settings > OAuth) |
TAILSCALE_OAUTH_CLIENT_SECRET | Yes* | — | OAuth client secret |
TAILSCALE_TAILNET | Yes | — | Tailnet name (e.g., example.com or your org name) |
TAILSCALE_API_URL | No | https://api.tailscale.com | API base URL (override for testing) |
TAILSCALE_TIMEOUT | No | 30000 | Request timeout in milliseconds |
NAS_VAULT_ADDR | No | — | HashiCorp Vault URL, enables Vault AppRole loading (see below) |
NAS_VAULT_ROLE_ID | No | — | Vault AppRole role_id |
NAS_VAULT_SECRET_ID | No | — | Vault AppRole secret_id |
NAS_VAULT_KV_MOUNT | No | kv | Vault KV v2 mount path |
*Either TAILSCALE_API_KEY or both TAILSCALE_OAUTH_CLIENT_ID + TAILSCALE_OAUTH_CLIENT_SECRET must be set. OAuth takes priority when both are configured.
If you run a central Vault instance, mcp-tailscale can fetch its credentials
at startup via AppRole instead of passing them through the MCP config:
export NAS_VAULT_ADDR=https://vault.example.com
export NAS_VAULT_ROLE_ID=<role-id>
export NAS_VAULT_SECRET_ID=<secret-id>
# optional — defaults to "kv"
export NAS_VAULT_KV_MOUNT=kv
The loader reads KV v2 at <mount>/data/tailscale/api and expects two keys:
api_key and tailnet. Example Vault write:
vault kv put kv/tailscale/api \
api_key=tskey-api-test \
tailnet=your-tailnet-name
Precedence: process.env (explicit) > Vault. If NAS_VAULT_ADDR is unset
the loader is a silent no-op — the server behaves exactly as before. On any
Vault error (network, auth, missing path), a single-line warning is written
to stderr and the server falls back to whatever env vars are already set.
OAuth note: the Vault loader only handles the API-key path. If you use
OAuth (TAILSCALE_OAUTH_CLIENT_ID / TAILSCALE_OAUTH_CLIENT_SECRET), set
those through the normal environment — they are not currently read from
Vault.
Security: secret values are never logged. Only the KV path name and a
populated-count appear in stderr diagnostics. Uses the global fetch
(Node 20+) — no new runtime dependencies.
API Key: Create at login.tailscale.com/admin/settings/keys. The key needs read/write access to the resources you want to manage.
OAuth Client Credentials: Create at login.tailscale.com/admin/settings/oauth. OAuth tokens auto-refresh before expiry. Recommended for automated/service integrations.
| Tool | Description |
|---|---|
tailscale_device_list | List all devices in the tailnet |
tailscale_device_get | Get device details by ID |
tailscale_device_delete | Delete a device (requires confirm: true) |
tailscale_device_authorize | Authorize a pending device |
tailscale_device_routes_get | Get advertised and enabled routes |
tailscale_device_routes_set | Set enabled subnet routes |
tailscale_device_tags_set | Set ACL tags on a device |
tailscale_device_posture_get | Get custom posture attributes |
tailscale_device_posture_set | Set a custom posture attribute |
tailscale_device_expire | Expire a device key (requires confirm: true) |
tailscale_device_rename | Set a custom display name for a device |
| Tool | Description |
|---|---|
tailscale_dns_nameservers_get | Get global DNS nameservers |
tailscale_dns_nameservers_set | Set global DNS nameservers |
tailscale_dns_searchpaths_get | Get DNS search paths |
tailscale_dns_searchpaths_set | Set DNS search paths |
tailscale_dns_splitdns_get | Get split DNS configuration |
tailscale_dns_splitdns_set | Update split DNS configuration (PATCH) |
tailscale_dns_preferences_get | Get DNS preferences (MagicDNS) |
tailscale_dns_preferences_set | Set DNS preferences |
| Tool | Description |
|---|---|
tailscale_acl_get | Get the current ACL policy |
tailscale_acl_set | Replace the ACL policy (requires confirm: true) |
tailscale_acl_preview | Preview ACL policy for a user or IP |
tailscale_acl_validate | Validate an ACL policy without applying |
tailscale_acl_test | Run ACL tests defined in the policy |
| Tool | Description |
|---|---|
tailscale_key_list | List all auth keys |
tailscale_key_get | Get auth key details |
tailscale_key_create | Create a new auth key |
tailscale_key_delete | Delete an auth key (requires confirm: true) |
| Tool | Description |
|---|---|
tailscale_tailnet_settings_get | Get tailnet settings |
tailscale_tailnet_settings_update | Update tailnet settings (requires confirm: true) |
tailscale_tailnet_contacts_get | Get tailnet contact emails |
tailscale_tailnet_contacts_set | Update tailnet contacts (requires confirm: true) |
tailscale_tailnet_lock_status | Get Tailnet Lock status |
| Tool | Description |
|---|---|
tailscale_user_list | List all users (filter by type/role) |
tailscale_user_get | Get user details by ID |
| Tool | Description |
|---|---|
tailscale_webhook_list | List all webhook endpoints |
tailscale_webhook_create | Create a webhook endpoint |
tailscale_webhook_get | Get webhook details by ID |
tailscale_webhook_delete | Delete a webhook (requires confirm: true) |
| Tool | Description |
|---|---|
tailscale_posture_integration_list | List all posture provider integrations |
tailscale_posture_integration_get | Get posture integration details by ID |
tailscale_posture_integration_create | Create a posture provider integration |
tailscale_posture_integration_delete | Delete a posture integration (requires confirm: true) |
| Tool | Description |
|---|---|
tailscale_status | Tailnet status summary (device counts, online/offline) |
tailscale_api_verify | Verify API connectivity and authentication |
tailscale_log_stream_get | Get log streaming configuration |
tailscale_log_stream_set | Set log streaming configuration (requires confirm: true) |
tailscale_derp_map | Get DERP relay map |
See ARCHITECTURE.md for detailed architecture diagrams and component descriptions.
See ROADMAP.md for the product development roadmap.
npm run build # Compile TypeScript
npm test # Run unit tests (vitest)
npm run typecheck # Type check only (no emit)
See CONTRIBUTING.md for contribution guidelines. See docs/api-reference.md for the Tailscale API v2 endpoint mapping.
mcp-tailscale is the community edition — a fully functional MCP Gateway Runtime under AGPL-3.0. Self-host it, contribute to it, build on it.
What you get with the open-source edition:
For organizations that need governance, compliance, and multi-tenant capabilities on top of the open-source runtime, we offer commercial editions with enterprise features.
Planned enterprise capabilities:
See PRODUCT_PACKAGING.md for tier details.
Contact us: GitHub Sponsors
This project is dual-licensed:
If you use mcp-tailscale in a proprietary product or SaaS offering, a commercial license is required. Support development by sponsoring us on GitHub.
Be the first to review this server!
by Modelcontextprotocol · Developer Tools
Read, search, and manipulate Git repositories programmatically
by Toleno · Developer Tools
Toleno Network MCP Server — Manage your Toleno mining account with Claude AI using natural language.
by mcp-marketplace · Developer Tools
Create, build, and publish Python MCP servers to PyPI — conversationally.
by Microsoft · Content & Media
Convert files (PDF, Word, Excel, images, audio) to Markdown for LLM consumption
by mcp-marketplace · Developer Tools
Scaffold, build, and publish TypeScript MCP servers to npm — conversationally
by mcp-marketplace · Finance
Free stock data and market news for any MCP-compatible AI assistant.