关于 Tailscale
面向管理 Tailscale 节点和 tailnet 的 MCP 服务,通过本地 CLI 操作节点,并通过控制平面 REST API 管理 tailnet。工具按权限层级和预设筛选,并提供只读资源、提示词及诊断命令。
主要功能
- 01通过 CLI 管理本地节点
- 02通过 REST API 管理 tailnet
- 03按权限层级和预设提供工具
- 04提供节点与 tailnet 只读资源
- 05支持提示词及参数补全
适用场景
- 01检查本地节点状态
- 02查询 tailnet 设备和策略
- 03在许可范围内更改配置
- 04排查连接问题或审查策略
MCP 相关
作为 MCP 服务,它向客户端开放 Tailscale 节点和 tailnet 的工具、资源、提示词及补全。节点工具依赖 tailscale CLI,tailnet 工具则需要控制平面凭据;默认传输方式为 stdio,也可使用带令牌保护的 HTTP。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
npx -y @tailscale-mcp/tailscale-mcpTAILSCALE_API_KEY密钥A control-plane API access token. One of this, the OAuth client pair, or the OAuth JWT file is needed for the tailnet tools; without any of them only the local tools are offered.TAILSCALE_OAUTH_CLIENT_ID密钥An OAuth client id, used with TAILSCALE_OAUTH_CLIENT_SECRET when there is no API access token.TAILSCALE_OAUTH_CLIENT_SECRET密钥The OAuth client secret that goes with TAILSCALE_OAUTH_CLIENT_ID.TAILSCALE_TAILNETThe tailnet the control-plane tools act on. Without it they act on the one the credential belongs to.TAILSCALE_MCP_PRESETWhich tools are offered: minimal, core or full.TAILSCALE_MCP_ALLOW_WRITEOffer the tools that change something. Read-only without it.TAILSCALE_MCP_ALLOW_DESTRUCTIVEOffer the tools that remove or sever something. Implies the write tier.本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
tailscale-mcp
一个用于 Tailscale 的 MCP 服务。它运行所在的节点通过 tailscale 命令行界面驱动;其背后的 tailnet 通过控制平面 REST API 驱动。
186 个工具,每个动词对应一个工具,参数真实,注释如实。Tailscale 返回的 JSON 会原样保留,因此你从 Tailscale 文档中学到的内容仍然适用。发生故障时,你会得到固定的错误代码和提示,而不是一大堆标准错误输出。
这两个接口都是可选的,缺少任何一个都不会导致服务无法运行。没有 tailscale 二进制文件,就不会提供驱动此节点的工具;没有控制平面凭据,就不会提供驱动 tailnet 的工具。tailscale-mcp diagnose 会说明这台机器具备哪一种。
在 macOS 上,该二进制文件是 Tailscale 应用安装到 /usr/local/bin 的 tailscale shim。应用程序包内的可执行文件不能替代它,也不会被接受:在登录 shell 之外运行时,它会启动图形界面,而不是响应调用,因此本地工具虽然会被提供,但每次调用都会失败。
安装
| 渠道 | 方法 |
|---|---|
| npm | npx -y @tailscale-mcp/tailscale-mcp — 为你的机器下载发行版二进制文件,并且只有在发行版自己的 SHA256SUMS 确认其可信后才会运行 |
| 容器 | docker run -i --rm -e TAILSCALE_API_KEY ghcr.io/tailscale-mcp/tailscale-mcp |
| Homebrew | brew trust tailscale-mcp/tap && brew install tailscale-mcp/tap/tailscale-mcp — Homebrew 6 在受信任之前不会加载第三方 tap;并且会在其识别的每个平台上首次报告 Invalid formula 错误 |
| Bundle | 从 releases 下载适用于你平台的 .mcpb 并打开 — 适用于可安装 bundle 的 MCP 客户端,例如 Claude Desktop |
| 从源代码构建 | cargo install tailscale-mcp |
发行版压缩包位于发行版页面,旁边附有 SHA256SUMS:适用于 x86_64 和 arm64 的 macOS 和 Linux,以及适用于 x86_64 的 Windows。
配置客户端连接
tailscale-mcp setup claude-code
会输出适用于你的客户端的配置片段 — claude-code、claude-desktop、vscode、cursor 或 zed — 并说明应将其放在哪里。它不会写入任何内容:配置片段由你自行粘贴,并且会省略凭据,原因见下一节。
通过 npm 安装时无需先安装任何内容,客户端可以携带设置:
{
"mcpServers": {
"tailscale": {
"command": "npx",
"args": ["-y", "@tailscale-mcp/tailscale-mcp"],
"env": {
"TAILSCALE_MCP_ALLOW_WRITE": "true"
}
}
}
}
这些设置足以启动服务。没有凭据时,它会提供驱动此节点的工具,并隐藏操作 tailnet 的工具;tailscale-mcp diagnose 会说明你具备哪一种。
身份验证
setup 不会打印自己的凭据,因为它打印到的文件会被人直接粘贴到问题和聊天中,而不会重新查看。添加凭据是一个需要单独、慎重进行的步骤。上述 env 块中有两种形式——API 访问令牌:
"env": {
"TAILSCALE_API_KEY": "tskey-api-…",
"TAILSCALE_MCP_ALLOW_WRITE": "true"
}
或 OAuth 客户端:
"env": {
"TAILSCALE_OAUTH_CLIENT_ID": "k123456CNTRL",
"TAILSCALE_OAUTH_CLIENT_SECRET": "tskey-client-…",
"TAILSCALE_MCP_ALLOW_WRITE": "true"
}
凭据表列出了其他形式,包括用于联合身份的 JWT 文件。每种工具都可以使用其中任意一种凭据:选择哪种方式并不影响你能用服务做什么,因此值得从其他角度考虑。
对于要长期保留的配置,优先使用 OAuth 客户端。 原因在于客户端配置的本质:有人只编写一次,之后便忘了它,而其中的密钥会一直保留,直到卸载工具。
API 访问令牌在三个方面都不适合这种情况。它属于某个人,承载此人能够执行的所有操作,因此文件泄露暴露的是此人的整个账户,而不只是你启用的工具。它会过期——但对于一份自创建后就再也没人查看过的文件来说,表现出来的不是凭据过期,而是服务无缘无故停止工作。并且它本身就是持有者令牌,因此静态存储的内容就是打开大门的钥匙。
OAuth 客户端则在这三方面恰好相反。它属于 tailnet,因此不会随着设置它的人离开而失效,撤销它也不会影响此人的访问权限。它的作用域会将权限限制在你启用的工具集实际调用的范围内。它不会自行过期,而文件中保存的不是密钥,而是生成密钥的方式——它发给此服务的令牌有效期为一小时,因此从备份或屏幕共享中复制出来的内容,到被使用时价值已所剩无几。
控制平面会首先提供 API 访问令牌,而且用它进行试用更快捷。等到你打算长期保留这份文件时,值得将其替换掉。
级别与预设
两个相互独立的选项决定了会话提供哪些内容。
级别决定工具允许执行多危险的操作。读取工具不会更改任何内容,并且始终会提供。写入工具会更改可恢复的配置。破坏性工具会删除某些内容,或以无法简单撤销的方式暴露某些内容——例如删除设备、撤销密钥,或将服务发布到互联网。读取级别始终启用;写入和破坏性级别默认关闭,必须手动启用。高于允许级别的工具不会列出,而不是在调用时遭到拒绝。
预设决定总体上提供多少功能。minimal 包含 Agent 回答问题和修复常见问题所需的功能;core 增加其他日常管理功能;full 则增加覆盖整个 tailnet 和不可逆操作的功能。两个工具集不属于任何预设,必须按名称指定:local-debug 是 Tailscale 自带的诊断功能,local-passthrough 是一个可以运行任意 tailscale 子命令的工具。
| 预设 | 读取 | 使用 --allow-write | 使用 --allow-destructive | 工具集 |
|---|---|---|---|---|
minimal | 37 | 51 | 55 | 4 |
core(默认) | 57 | 106 | 126 | 13 |
full | 68 | 126 | 155 | 18 |
在 full 中添加 --toolsets +local-debug,+local-passthrough,即可启用全部 186 个工具。
有些破坏性工具还要求额外提供一个参数:confirm: true。这些工具会影响整个 tailnet,或者可能导致此服务无法访问其所控制的节点或 tailnet——例如让节点退出登录、删除其自身设备,或部署会锁定调用者的策略。服务不会判断这些操作是否错误,而是要求调用者明确表示自己确实要执行这些操作。
- docs/tools.md — 列出每个工具、所属级别及其功能。 根据代码生成。
- docs/configuration.md — 列出每个环境变量和标志,以及默认值。
- docs/errors.md — 列出每个错误代码及其处理方法。
资源、提示词和补全
九个资源——八个固定资源和一个按设备标识符寻址的模板—— 向客户端提供本地节点的状态、偏好设置、netcheck 报告和 tailnet 锁定状态,以及 tailnet 的策略文件、设备、DNS 配置和 设置。它们均为只读,仅在对应界面启用时出现,而且 没有订阅。
三个提示词用于引导一系列工具调用:diagnose_connectivity、
review_policy_change 和 audit_tailnet_access。它们遵循与资源相同的规则:只有在所需界面启用时才会出现,而
diagnose_connectivity 会从两个界面读取信息,并且只执行会话实际能够完成的步骤。
这两个界面提供的四个参数槽位中,三个已实现补全,因此客户端可以提供候选值,而不必让用户猜测:设备模板的标识符、diagnose_connectivity 的对端,以及
audit_tailnet_access 的主体——候选值依次为用户、标签和设备,这样即使 tailnet 有数千台设备,仍能在协议发送的百个值中显示那少数用户。第四个槽位 review_policy_change 的目标是一个描述意图的句子,补全它就等于凭空编造。提供的每个值都是服务端能够接受的值——设备通过其 MagicDNS 名称提供,绝不会通过可能被两台机器共用的主机名提供——而无法提供答案的来源会返回空结果,而不是错误。按照规范,此方法受到速率限制,因为每次按键都会发起请求。
请注意,协议只会补全提示词参数和资源模板变量,除此之外别无其他:工具参数无法补全,因此这只对上述四个槽位有帮助,对 186 个工具则毫无作用。客户端的支持情况不一——Claude Code 会补全资源模板,VS Code 两者都支持,而有些客户端两者都不支持——因此,这项改进只会在读取它的地方发挥作用,在其他地方则不会产生影响。
传输方式
默认使用 Stdio。改用 --http 时,则通过 127.0.0.1:8449 提供 Streamable HTTP,并使用 TAILSCALE_MCP_HTTP_TOKEN 中的 bearer token 进行保护,同时设有主机和来源允许列表、请求正文大小限制、按地址设置的速率限制,以及开放的健康检查端点。若要绑定到回环地址以外的地址,必须明确提供该 token,或明确指定 --http-no-auth。
安全
各等级的作用。 高于允许等级的工具不会出现在工具列表中,因此调用方无法通过猜测名称来调用它,模型也无法被诱导去调用一个从未提供过的工具。默认设置为只读。在破坏性等级之上添加 confirm,可为值得确认的操作增加一道信号。密钥不会进入参数列表、日志行或错误消息;生成的密钥或邀请 URL 只会原样返回一次,此处不会留存副本。每个工具结果和每条错误在输出时都会经过相同的脱敏处理。
各等级不具备的作用。 它们不是授权系统,也不是沙箱。
- 等级是 服务端 的属性,而不是调用方的属性。与同一服务端通信的所有人都会获得相同的工具。如果两个调用方应拥有不同权限,请运行两个服务端。
- 允许某个等级,就会允许该等级中的所有工具。没有针对单个工具的开关;
--toolsets是更粗粒度的调节项,用于缩小会话可访问的范围。 - 凭证才是真正的边界。只读 OAuth 客户端会让 tailnet 写入工具在控制平面上失败,无论此服务端提供什么工具;这才是应当依赖的边界。限制凭证的范围,并使用等级来防止无意操作。
- 本地工具以运行此服务端的用户身份运行。Tailscale 自身的操作员检查仍然有效——拒绝非操作员执行的命令在此处也会被拒绝,并返回
needs_operator——但以操作员身份运行的服务端可以执行操作员能执行的操作。 - 读取并非无害。读取等级会返回真实的网络拓扑:节点名称、地址、用户、策略。任何能读取工具输出的主体都能读取这些信息。
服务端绝不会提升权限。 它不会使用 sudo、不会请求提权,也不会更改自身权限或安装任何内容。它以启动时用户的身份运行 tailscale 二进制文件,并发送提供给它的控制平面凭证。Tailscale 因调用方身份而拒绝的操作会原样传递,不会绕过限制。有四个工具会写入文件:其中三个——证书、Taildrop 投递文件、指标文件——写入调用指定的路径;tailscale_configure_kubeconfig 则写入客户端自身会编辑的 kubeconfig。这四个工具都以运行服务端的用户身份写入;tailscale_run 也如此。它不属于任何预设,一旦按名称调用,就能执行这些相同的写入操作,以及 tailscale 二进制文件能执行的其他任何操作。
通过 HTTP 访问时,默认设置较为谨慎——仅限 loopback、必须提供令牌、不允许浏览器源——并且每项设置都只能通过专门的标志有意放宽。
与其他 Tailscale MCP 服务的比较
此服务严格包含此前的三个服务 (rtailscale、 HexSleeves/tailscale-mcp、 YawLabs/tailscale-mcp),但下表列出了四项例外。
| 能力 | rtailscale | HexSleeves | YawLabs | 此服务 |
|---|---|---|---|---|
| 设备:列出、获取 | 是 | 仅列出 | 是 | 是,包含在下方的 tailnet-devices 中 |
| 设备:授权、删除、过期、重命名、设置 IP、密钥过期 | 授权、删除 | 授权、删除、过期 | 是 | 全部支持,共 15 个工具 |
| 设备路由、标签 | 获取路由 | 是 | 是 | 是,包含在下方的 tailnet-devices 中 |
| 姿态属性 | — | — | 是 | 是,包含在下方的 tailnet-devices 中 |
| 策略文件:获取、设置、预览、验证 | 获取 | 获取、设置、验证 | 是,使用 If-Match | 是,每次写入都使用版本标识符 |
| DNS:名称服务器、偏好设置、搜索路径、分割 DNS | 获取 | 是 | 11 个工具 | 11 个工具 |
| 身份验证密钥 | 列出 | 是 | 是 | 5 个工具 |
| OAuth 客户端 | — | — | 4 个工具 | 5 个工具 |
| 用户 | 列出 | — | 7 个工具 | 7 个工具 |
| Tailnet 设置、联系人 | — | 部分支持 | 5 个工具 | 5 个工具 |
| Webhook | — | 是 | 7 个工具 | 7 个工具 |
| 姿态集成 | — | — | 5 个工具 | 5 个工具 |
| 审计和网络流日志、日志流传输 | — | — | 9 个工具 | 8 个工具 |
| 邀请:设备和用户 | — | — | 11 个工具 | 11 个工具 |
| 服务 | — | — | 7 个工具 | 7 个工具 |
| 组织 Tailnet | — | — | 3 个工具 | 3 个工具 |
| 本地状态、IP、whois、whoami、版本 | — | 状态、版本 | 4 个工具 | 25 个工具 |
| Ping、netcheck、routecheck、DNS 查询、出口节点 | — | ping、出口节点 | ping、netcheck | 是,包含在上方的 local-status 中 |
| 偏好设置、启动、关闭、登录、登出、配置文件 | — | 启动、关闭 | — | 8 个工具 |
| Serve 和 funnel | — | — | — | 10 个工具 |
| Taildrive、文件传输、证书、kubeconfig | — | — | — | 11 个工具 |
| Tailnet lock | — | 桩 | — | 8 个工具,另有状态和日志 |
| Tailscale 自有调试接口 | — | — | — | 30 个工具 |
任意 tailscale 子命令 | — | — | — | 1 个工具,默认关闭 |
| 资源 | 1 | 4 | 4 | 9 |
| 提示词 | 1 | 2 | 0 | 3 |
| 传输方式 | stdio、HTTP | stdio、HTTP | stdio | stdio、HTTP |
| 工具数量 | 1 个,含 10 项操作 | 19 个,其中 1 个是桩 | 102 | 186 个工具 |
有一项低于 YawLabs,但并没有因此缺少任何能力:他们的两个工具是对多个端点的聚合,而此服务一次只公开一个端点——一个工具可在单次调用中读取两种日志类型的流配置,另一个工具可在单次调用中授权设备列表。此处可通过反复调用单项工具实现同样的功能。它们计入了对方的工具数量,但未计入此处,因此日志一行显示为 9 对 8。
其他服务具备而此服务刻意不提供的四项功能:
- 没有配置文件。 rtailscale 读取
config.toml。这里的所有设置都是环境变量或标志,因为 MCP 客户端配置可以设置这些内容;额外增加一个真相来源,只会让设置多一个藏身之处。 - 没有工具架构资源。 rtailscale 将自己的工具架构作为资源提供。MCP 已经有
tools/list;再提供一份副本,可能会与第一份不一致。 - 此版本不提供面向浏览器客户端的 OAuth 资源服务器模式。 rtailscale 可以充当 OAuth 资源服务器,让浏览器客户端向其进行身份验证。这里的 HTTP 传输接受 bearer token。这是暂缓提供,并非拒绝支持。
- 没有额外的枚举环境变量配置项。 其他项目中的若干设置接受文档所列集合之外的值,或者读取未记录的变量。这里的每项设置都列在 docs/configuration.md 中,超出可选集合的值会导致启动错误,并列出可选项。
开发
cargo test --workspace --all-targets # the whole suite, offline
cargo clippy --workspace --all-targets -- -D warnings
cargo fmt --all --check
测试套件不需要 tailscale 二进制文件、凭据或网络:tailscale 二进制文件由模拟对象替代,控制平面则是一个模拟 HTTP 服务器。需要真实节点和 tailnet 的端到端测试由环境变量控制;未设置这些变量时,测试会报告已跳过。
docs/tools.md 是生成文件。添加或更改工具后:
UPDATE_DOCS=1 cargo test -p tailscale-mcp --test docs_are_current
架构决策见 docs/adr/,本代码库遵循的词汇规范见 CONTEXT.md,构建过程中做出的每项判断见 DECISIONS.md,发布流程见 RELEASING.md。
许可证
Apache-2.0。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。