Skip to main content
Glama
tailscale-blade-mcp

tailscale-blade-mcp

tailscale-blade-mcp

An MCP server that gives AI agents structured access to Tailscale tailnets. Built for the Model Context Protocol with security visibility and token efficiency as first-class design goals.

Why this exists

Tailscale exposes a clean REST API (v2) for managing devices, ACL policies, DNS, auth keys, users, and audit logs. This MCP wraps it with the guardrails that automated agents need:

  • Security-first tool set — 19 tools focused on what network security agents actually need: device inventory, key expiry auditing, ACL review + apply, route approval, DNS hygiene. Not a thin wrapper around every endpoint.

  • Token-efficient output — compact pipe-delimited format. A 20-device tailnet in ~40 tokens per device. Devices flagged with KEY_EXPIRY_OFF, KEY_EXPIRED, UPDATE_AVAILABLE, UNAUTHORIZED, OFFLINE at a glance.

  • Write-gated mutations — device authorization, tagging, key management, route approval, and ACL apply require explicit opt-in via TAILSCALE_WRITE_ENABLED=true. Destructive operations (delete device, revoke key) additionally require per-call confirm=true; ACL apply defaults to optimistic-concurrency (If-Match) so it won't silently clobber a concurrent edit.

  • SecOps visibility — ACL policy summary shows groups, rules, SSH rules, and tag owners. Audit log shows who changed what. Key listing flags reusable keys and expiry status.

Related MCP server: Tailnet MCP Server

How this differs from other Tailscale MCPs

tailscale-blade-mcp

HexSleeves/tailscale-mcp

jaxxstorm/tailscale-mcp

Focus

Monitoring + security (19 tools)

Management (~15 tools)

Read-only (~5 tools)

Design for

LLM agents (token-efficient)

Claude Code

General MCP

Output

Pipe-delimited, compact

Full JSON

Full JSON

Write safety

Dual-gated (env + confirm)

Direct writes

Read-only

Audit log

Yes

No

No

ACL summary

Parsed groups/rules/SSH/tags

Raw JSON

Raw JSON

Key hygiene

Flags reusable, expiry status

Basic listing

No

Marketplace

Stallari certified

Standalone

Standalone

Quick start

Published on PyPI — run it without a checkout via uvx:

# Configure
export TAILSCALE_API_KEY="tskey-api-..."

# Run the latest published release (no install step)
uvx tailscale-blade-mcp

Or install it as a tool / into an environment:

uv tool install tailscale-blade-mcp     # or: pip install tailscale-blade-mcp
tailscale-blade-mcp

From a local checkout (development):

uv pip install -e .
tailscale-blade-mcp

19 tools, 5 categories

Info (1 tool)

Tool

Purpose

Token cost

ts_info

Health check — device counts, online/offline, key expiry warnings, settings, write gate

~100

Devices (3 tools)

Tool

Purpose

Token cost

ts_devices

All devices — hostname, OS, IP, online/offline, key expiry, tags, updates

~40/device

ts_device

Full detail — addresses, client version, key status, tags, user

~120

ts_device_routes

Routes — advertised subnets, approved/unapproved status

~30/route

Network (4 tools)

Tool

Purpose

Token cost

ts_dns

DNS — nameservers, MagicDNS, search paths, split DNS

~50

ts_acl

ACL policy — groups, rules, SSH rules, tag owners

~30/rule

ts_acl_validate

Validate a policy without applying it (write-gated)

~20

ts_acl_set

Apply a full ACL policy — validates first, optimistic-concurrency If-Match guard (write-gated; needs policy-file write scope)

~30

Users & Keys (3 tools)

Tool

Purpose

Token cost

ts_keys

Auth keys — ID, reusable/ephemeral/preauth flags, tags, expiry

~25/key

ts_users

Users — name, role, status, device count, online/last seen

~25/user

ts_webhooks

Webhooks — endpoint URL, event subscriptions

~25/webhook

Audit (1 tool)

Tool

Purpose

Token cost

ts_audit_log

Configuration changes — who, what, when

~25/entry

Write Operations (7 tools, gated)

ACL apply (ts_acl_set) is also write-gated; it's listed under Network with the other ACL tools.

Tool

Gate

Purpose

ts_authorize_device

write

Authorize or deauthorize a device

ts_set_tags

write

Set ACL tags on a device

ts_expire_device

write

Force key expiry — device must re-authenticate

ts_approve_routes

write

Approve advertised subnet routes

ts_create_key

write

Create an auth key (reusable/ephemeral/preauth)

ts_delete_key

write + confirm

Revoke an auth key permanently

ts_delete_device

write + confirm

Remove a device from the tailnet

Output format

macbook | os=mac | ip=100.100.1.1 | online | expires=2026-07-11 | id=n1234567890
nas | os=linux | ip=100.100.1.2 | online | KEY_EXPIRY_OFF | UPDATE_AVAILABLE | tags=server,infra | id=n9876543210
phone | os=iOS | ip=100.100.1.3 | OFFLINE | last=2d ago | expires=2026-05-01 | id=n5555555555

Authentication

Tailscale supports two auth methods:

Method

Token prefix

Best for

API access token

tskey-api-

Personal use, quick setup

OAuth client

Bearer token from client_credentials flow

Automation, scoped permissions

Both are passed via TAILSCALE_API_KEY. For OAuth, obtain a Bearer token first and pass that.

ACL write scope. Read tools work with any valid token. Applying an ACL (ts_acl_set) additionally requires the token to carry policy-file write scope — an OAuth client with the acl scope, or an API access token from an account that can edit the tailnet policy file. A read-only token will validate fine but return a 403 on apply, with a message pointing at the scope requirement.

Security model

Layer

Mechanism

Write gate

TAILSCALE_WRITE_ENABLED=true required for any mutation

Destructive confirm

ts_delete_key and ts_delete_device require confirm=true

ACL validate-before-apply

ts_acl_set always validates the policy and refuses to apply on failure

ACL optimistic concurrency

ts_acl_set sends If-Match (the current ETag) by default; a concurrent edit fails with a re-fetch message rather than clobbering. Bypass only via allow_overwrite_concurrent=true

Credential scrubbing

API keys, Bearer tokens, Authorization headers stripped from errors

Bearer auth

Optional TAILSCALE_MCP_API_TOKEN for HTTP transport

Tailnet auto-detect

Uses - shorthand by default — no tailnet name in config

Stallari integration

From the published package (recommended — pin a version with tailscale-blade-mcp@0.7.0):

{
  "mcpServers": {
    "tailscale": {
      "type": "stdio",
      "command": "uvx",
      "args": ["tailscale-blade-mcp"],
      "env": {
        "TAILSCALE_API_KEY": "tskey-api-...",
        "TAILSCALE_WRITE_ENABLED": "false"
      }
    }
  }
}

From a local checkout (development):

{
  "mcpServers": {
    "tailscale": {
      "type": "stdio",
      "command": "uv",
      "args": ["--directory", "~/src/tailscale-blade-mcp", "run", "tailscale-blade-mcp"],
      "env": {
        "TAILSCALE_API_KEY": "tskey-api-...",
        "TAILSCALE_WRITE_ENABLED": "false"
      }
    }
  }
}

Webhook trigger patterns

  • Key expiry approaching — ts_devices flags KEY_EXPIRY_OFF and expired keys for proactive rotation

  • Unauthorized devices — ts_devices flags UNAUTHORIZED for approval workflows

  • Route approval — ts_device_routes shows unapproved subnets for security review

  • ACL changes — ts_audit_log tracks policy updates for compliance auditing

  • Stale devices — ts_devices shows OFFLINE with last-seen time for cleanup workflows

Development

make install-dev    # Install with dev + test dependencies
make test           # Unit tests (mocked, no API access needed)
make check          # Lint + format + type-check
make run            # Start MCP server (stdio)

Architecture

src/tailscale_blade_mcp/
├── server.py       — FastMCP server, 19 @mcp.tool decorators
├── client.py       — TailscaleClient wrapping httpx async, credential scrubbing
├── formatters.py   — Token-efficient output (pipe-delimited, null omission, human units)
├── models.py       — TailscaleConfig, write gate, constants
└── auth.py         — Bearer token middleware for HTTP transport

Built with FastMCP and httpx.

License

MIT

Available Tools

19 tools
ts_aclA

ACL policy summary: groups, rules, SSH rules, tag owners. Shows who can talk to whom.

Inputs: no named parameters. Returns: result

ts_acl_setA

Apply (POST) a full ACL policy to the tailnet. Requires TAILSCALE_WRITE_ENABLED=true.

Always validates the policy first and refuses to apply on validation failure. By default uses optimistic concurrency: the current ETag is sent as If-Match so a concurrent admin edit fails with a clear re-fetch message instead of silently clobbering. Pass allow_overwrite_concurrent=true to bypass the guard. Requires a token with ACL policy-file WRITE scope (a read-only key 403s). Emits a DD-338 _meta envelope (audit_surface: structured).

Inputs: policy_json (required), if_match, allow_overwrite_concurrent. Returns: result

ts_acl_validateA

Validate an ACL policy without applying it. Returns errors or 'passed'.

Inputs: policy_json (required). Returns: result

ts_approve_routesA

Approve subnet routes on a device. Requires TAILSCALE_WRITE_ENABLED=true.

Default (replace=false): additive — reads the device's currently enabled routes first and approves the union, so previously approved routes are preserved.

replace=true: raw Tailscale set-routes REPLACE semantics — the enabled set becomes exactly routes; any currently enabled route not listed is de-approved, which can sever subnet connectivity. Use only when you intend to remove approvals.

Inputs: device_id (required), routes (required), replace. Returns: result

ts_audit_logA

Configuration audit log: who changed what, when. Recent entries first.

Optional scope arg filters audit entries to those whose target is a device with a tag in the scope set. Requires a secondary fetch of the device-tag map (uncached at v1). Entries with non-device targets are excluded when scope is provided.

Inputs: count, days, scope. Returns: result

ts_authorize_deviceA

Authorize or deauthorize a device. Requires TAILSCALE_WRITE_ENABLED=true.

Inputs: device_id (required), authorized. Returns: result

ts_create_keyA

Create a new auth key. Requires TAILSCALE_WRITE_ENABLED=true.

Inputs: description, reusable, ephemeral, preauthorized, +2 more. Returns: result

ts_delete_deviceA

Delete a device from the tailnet. Requires TAILSCALE_WRITE_ENABLED=true and confirm=true.

Inputs: device_id (required), confirm. Returns: result

ts_delete_keyA

Revoke an auth key. Requires TAILSCALE_WRITE_ENABLED=true and confirm=true.

Inputs: key_id (required), confirm. Returns: result

ts_deviceA

Full detail for a single device: addresses, OS, client version, key status, tags, user.

Single-record fetch — server-side filter is device_id-shaped, not tag-shaped. The _meta envelope is emitted for audit-surface uniformity; scope= is intentionally NOT accepted here because a scope filter on a single-device-detail call is semantically incoherent.

Inputs: device_id (required). Returns: result

ts_device_routesA

Routes for a device: advertised subnets, approved/unapproved status.

Emits a DD-338 _meta envelope (audit_surface: structured) disclosing the device_id= server-side discrimination + the routes-row cardinality (advertised + enabled, union).

Inputs: device_id (required). Returns: result

ts_devicesA

List all devices: hostname, OS, IP, online/offline, key expiry, tags, update status.

Optional scope arg filters devices by DD-278 scope-tag mapping (configurable via TAILSCALE_SCOPE_{INFRASTRUCTURE,PERSONAL,HOME}_TAGS). Output includes a Track 3 _meta envelope as a JSON tail line.

Inputs: scope. Returns: result

ts_dnsB

DNS configuration: nameservers, MagicDNS status, search paths, split DNS rules.

Inputs: no named parameters. Returns: result

ts_expire_deviceA

Force key expiry on a device — it must re-authenticate. Requires TAILSCALE_WRITE_ENABLED=true.

Inputs: device_id (required). Returns: result

ts_infoA

Health check: device counts, online/offline, key expiry warnings, updates, tailnet settings, write gate.

Inputs: no named parameters. Returns: result

ts_keysA

List auth keys: ID, description, reusable/ephemeral/preauth flags, tags, expiry.

Optional scope arg filters keys by DD-278 scope-tag mapping. Output includes a Track 3 _meta envelope as a JSON tail line.

Inputs: scope. Returns: result

ts_set_tagsA

Set ACL tags on a device. Replaces existing tags. Requires TAILSCALE_WRITE_ENABLED=true.

Inputs: device_id (required), tags (required). Returns: result

ts_usersA

List users: name, login, role, status, device count, online/last seen. Sorted by case-folded loginName ascending (numeric id tie-break).

Inputs: no named parameters. Returns: result

ts_webhooksA

List configured webhooks: endpoint URL, event subscriptions, created date. Sorted by endpointId ascending.

Inputs: no named parameters. Returns: result

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A4.1/5.0

    Scored across 19 tools

    Disambiguation5/5

    Each tool targets a distinct aspect of Tailscale management: ACL policies, devices, auth keys, DNS, users, webhooks, audit, and health. Even similar-sounding tools like ts_device and ts_devices serve different purposes (single vs. list). No ambiguity.

    Naming Consistency5/5

    All tools use the 'ts_' prefix with consistent verb_noun pattern in snake_case (e.g., ts_acl_set, ts_approve_routes, ts_delete_device). There are no deviations or mixed conventions.

    Tool Count5/5

    19 tools cover the full lifecycle of Tailscale resources a reasonable granularity. The scope is not overburdened; each tool provides a specific function without redundancy.

    Completeness5/5

    The tool set covers ACL (read, validate, apply), device lifecycle (list, detail, routes, authorize, delete, expire, tags), auth keys (list, create, revoke), DNS config, users, webhooks, audit log, and health check. No obvious gaps for typical tailnet management.

    Maintenance

    ActivityInactive
    ResponsivenessOutdated data

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      A
      quality
      C
      maintenance
      Enables Claude to connect and disconnect the host machine from its Tailscale network via the local CLI, and to manage the wider tailnet (devices, routes, DNS, ACL policy, auth keys, webhooks, users, audit log) through the Tailscale REST API. Access is governed by configurable risk tiers, with destructive operations gated behind interactive human approval.
      18
      40 npm
      MIT

    Appeared in Searches