mcpField
T
Tailnet MCP bridge

Tailnet MCP bridge

本地服务
github.com/zedong-peng云与基础设施04 天前更新

关于 Tailnet MCP bridge

Tailnet MCP bridge 是面向托管 Agent 和沙箱客户端的 stdio MCP 服务,用于访问 Tailscale tailnet 内的 MCP 服务。它内置 Tailscale 节点并将请求转发到 Streamable HTTP 端点,无需将服务暴露到公共互联网。

主要功能

  1. 01将 stdio 桥接到 Streamable HTTP
  2. 02以带标签设备加入 tailnet
  3. 03让 MCP 服务不暴露于公共互联网
  4. 04在服务重启后恢复会话
  5. 05仅重试未到达服务的请求

适用场景

  1. 01让托管 Agent 沙箱连接 tailnet 内的服务
  2. 02访问通过 tailscale serve 发布的 MCP 服务
  3. 03在服务重启后维持 MCP 会话

MCP 相关

它作为 stdio MCP 服务运行,并将请求转发到 tailnet 内的 Streamable HTTP MCP 服务。它桥接客户端的 MCP 连接,不提供自己的工具。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"zedong-peng-tailnet": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-e",
"TS_AUTHKEY",
"ghcr.io/zedong-peng/tailnet-mcp:v0.3.0"
],
"env": {
"TS_AUTHKEY": "<TS_AUTHKEY>"
}
}
}
}
启动命令docker run -i --rm -e TS_AUTHKEY ghcr.io/zedong-peng/tailnet-mcp:v0.3.0
需要配置的环境变量
TS_AUTHKEY密钥Tagged, pre-authorized auth key; only needed the first time

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
ocighcr.io/zedong-peng/tailnet-mcp:v0.3.0

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

tailnet-mcp

一个 stdio MCP 服务,会将所有内容转发到 tailnet 内的 Streamable HTTP MCP 服务。

托管 Agent(Grok、云端编码 Agent、沙盒助手)通常通过两种方式接入 MCP 服务。通过 URL:由供应商的服务连接,因此你的服务必须位于公共互联网。通过命令:Agent 在自己的计算机上启动进程,但那台计算机不在你的 tailnet 内,而且你无法在那里运行 tailscaled(没有 root 权限,也没有 TUN)。tailnet-mcp 就是通过命令接入的方式:它内嵌一个 Tailscale 节点(tsnet),以带标签的设备加入你的 tailnet,并在 stdio 与服务之间搭建桥接。你的服务仍在 tailscale serve 后面,不会暴露到互联网。

agent ──stdio──▶ tailnet-mcp (tag:agent) ══tailnet══▶ tailscale serve ──▶ MCP server on 127.0.0.1

安装

从 Releases 下载适用于 linux 或 darwin、amd64 或 arm64 的静态二进制文件,并通过 SHA256SUMS 校验。也可以自行构建:

CGO_ENABLED=0 go install github.com/zedong-peng/tailnet-mcp@latest

或者运行镜像 ghcr.io/zedong-peng/tailnet-mcp,并将卷挂载到 /home/nonroot/.local/state/tailnet-mcp。它也已列入 MCP Registry,名称为 io.github.zedong-peng/tailnet-mcp。

使用

  1. 仅向 tailnet 发布服务,并使用一个无人能猜到的路径:

    tailscale serve --bg --https=8443 --set-path=/$(openssl rand -hex 16) http://127.0.0.1:8080/mcp
    
  2. 创建一个带有 Agent 标签、一次性且预先授权的 auth key(通过管理控制台或 API),然后从 Agent 的计算机登录一次:

    TS_AUTHKEY=tskey-auth-... tailnet-mcp -hostname my-agent -url https://server.tailnet.ts.net:8443/<path> -check
    

    -check 会建立连接,将服务的工具打印到 stderr,然后退出。节点密钥保存在 -state 中(默认为 ~/.local/state/tailnet-mcp/<hostname>);请将其保存在持久存储中。带标签的节点不会过期,因此之后不再需要该密钥。

  3. 将不带密钥的相同命令注册为 Agent 的 MCP 服务:

    tailnet-mcp -hostname my-agent -url https://server.tailnet.ts.net:8443/<path>
    

每个进程都是一个独立的 tailnet 节点。要接入第二个服务,请使用不同的 -hostname 再运行一个进程。

加强防护

Agent 会读取不可信输入(网页、邮件),因此应假设它可能被诱导执行其工具所允许的任何操作。这里有三层防护,均不依赖 Agent 是否遵守约束:

  • 网络。 只授予该标签访问所需端口的权限,不授予其他权限:

    "grants": [
      {"src": ["tag:my-agent"], "dst": ["server"], "ip": ["tcp:8443"]},
    ],
    "tests": [
      {"src": "tag:my-agent", "accept": ["server:8443"], "deny": ["server:22", "server:443"]},
    ],
    

    允许一切的授权规则("src": ["autogroup:member"], "dst": ["*"])不涵盖带标签的设备,因此该标签只能获得这条授权规则授予的权限。

  • 路径。 tailscale serve --set-path 只会在保密路径上响应;端口上的任何其他路径都会返回 404。tailnet 内的其他设备无法通过猜测端口使用该服务。

  • 服务端。 在数据所在的位置强制实施权限,而不是在 Agent 中:只能保存草稿的邮件服务、仅对一个共享集合拥有只读权限的密码库账户。examples/private-tools 会设置这两者。

行为

  • 首次请求前,它会持续 ping 服务所在的节点,直到收到响应。重启后,服务可能仍持有指向该节点的过时路径,导致首次拨号超时。
  • 只会重试从未到达服务的请求,因此工具调用不会被发送两次。
  • 服务重启并丢失会话时(返回 404,或关于会话的 400),桥接程序会重新发送 initialize,然后再次发送请求。客户端不会察觉。
  • 请求失败时会返回包含原因的 JSON-RPC 错误,因此客户端不会一直等待不会到来的响应。
  • 遇到 EOF 时,它会通过 DELETE 结束会话。日志写入 stderr;stdout 只承载 MCP 帧。-v 会额外输出 tsnet 自身的日志。

不支持:可选的 GET 流,该流允许服务在响应之外发送消息。服务会在各自的响应中回答每个请求,几乎所有工具服务都是如此。

对比

  • mcp-remote 和其他 stdio 到 HTTP 的桥接工具需要一条通往服务端的网络路径。在 Agent 的沙箱中,这意味着需要一个公开 URL。
  • 在沙箱中运行 tailscale up 需要 root 权限和 TUN 设备。如果有人以用户身份登录,而不是使用带标签的密钥,沙箱就会获得该用户对整个 tailnet 的访问权限。
  • Tailscale Aperture 是服务端的网关:它聚合 HTTP MCP 服务,并按用户授予工具权限。它无法让沙箱中的 Agent 接入 tailnet,因此两者可以配合使用。

构建和测试

go test -race ./...
CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" .

标记 v* 会发布这四个二进制文件、镜像和注册表条目。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。