MCP server for safe programmatic access to the local Tailscale daemon: tailnet discovery, SSH config generation, port sharing via Serve/Funnel, and latency matrices.
Strong tool definitions with clear naming, comprehensive descriptions, and well-structured schemas. All 6 tools follow verb_noun convention (tailnet_status, generate_ssh_config, share_port, share_status, stop_share, ping_all). Descriptions are detailed (100-250 chars) and explain WHAT, WHEN, and consequences. Input schemas use proper JSON Schema with types and descriptions. Risk classifications (READ_ONLY, WRITE, REVERSIBLE) are explicit. Main gaps: no output schemas documented, no pagination support for list-like results, and error handling guidance is implicit rather than explicit in tool definitions.
Generate ssh-config Host blocks for tailnet nodes (MagicDNS name preferred, Tailscale IP fallback). Dry-run by default: returns the generated config text only and writes nothing. With write=true it writes a dedicated file (~/.ssh/tailscale_dev_config) and returns instructions for adding an Include line to ~/.ssh/config (never applied automatically). Direct editing of ~/.ssh/config itself additionally requires target="user_ssh_config" and is idempotent between managed markers, never touching content outside them.
Ping tailnet peers concurrently (bounded to 5 at a time, one ping each with a timeout) and return a latency matrix: node, latency ms, path (direct vs DERP relay), or unreachable. Defaults to online peers only.
Share a local port over the tailnet via Tailscale Serve (tailnet-only by default). WARNING: setting public=true switches to Funnel and exposes the port to the OPEN INTERNET — anyone with the URL can reach it. Only set public=true when internet exposure is explicitly intended. Returns the resulting URL(s).
Report the active Tailscale Serve/Funnel sessions on this node.
Stop sharing. Without arguments clears the entire serve/funnel configuration; with httpsPort it turns off just that HTTPS serve endpoint (the port shown in share_status, typically 443 — not the local port that was proxied).
Output schemas not documented. Tool descriptions explain inputs but not return types. LLMs cannot plan downstream calls or extract required fields without knowing response structure.
share_status and stop_share lack detailed descriptions of what fields/structure they return. share_status description is only 75 chars; stop_share is 150 chars. Descriptions should explain the response format and when to call each tool.
No error recovery guidance in tool definitions. Descriptions mention 'structured error with exact fix command' for tailnet_status but other tools lack explicit error handling patterns. LLMs need to know: is this retryable? What should I do if it fails?
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 62 | 2026-07-28+ | v2 |
Report the state of the local tailnet: this node plus all peers with hostname, MagicDNS name, Tailscale IPv4/IPv6, OS, online flag, last seen, exit-node flags, and tags. Returns a structured error with the exact fix command when the tailscale binary is missing, the daemon is stopped, or the device needs login.
generate_ssh_config has complex conditional logic (write, target, onlineOnly, user) but no explicit documentation of parameter dependencies. The description mentions 'never applied automatically' and 'idempotent between managed markers' but does not state that target='user_ssh_config' requires write=true.
share_port description warns about public=true but does not provide a confirmation/dry-run pattern. Irreversible operations should support a dry-run or confirmation step to prevent accidental internet exposure.