tailscale-mcp
MCP server for safe programmatic access to the local Tailscale daemon: tailnet discovery, SSH config generation, port sharing via Serve/Funnel, and latency matrices.
README
Tailscale MCP
MCP server for safe programmatic access to the local Tailscale daemon: tailnet discovery, SSH config generation, port sharing via Serve/Funnel, and latency matrices.
Gives agents and developer tools a safe, structured window into the local Tailscale daemon over stdio. It shells out to the tailscale CLI (resolved from PATH, with a Windows fallback to the default install location) and never handles auth keys or tailnet credentials: the CLI talks to the already-authenticated local daemon.
When the binary is missing, the daemon is stopped, or the device needs login, every tool returns a structured error with a code and the exact remedy command instead of throwing.
Installation
npx -y @tmhs/tailscale-mcp
Add to your MCP client configuration (Claude Desktop, Cursor, etc.):
{
"mcpServers": {
"tailscale": {
"command": "npx",
"args": ["-y", "@tmhs/tailscale-mcp"]
}
}
}
Requires Node 20+ and an installed, logged-in Tailscale client.
Tools
tailnet_status
Trimmed view of tailscale status --json: self node plus peers with hostname, MagicDNS name, Tailscale IPv4/IPv6, OS, online flag, last seen, exit-node flags, and tags. Input: optional onlineOnly.
{
"backendState": "Running",
"tailnet": "user@example.com",
"magicDNSSuffix": "tail1234.ts.net",
"self": {"hostname": "DEVPC", "dnsName": "devpc.tail1234.ts.net", "ipv4": "100.101.1.10"},
"peerCount": 3,
"peers": [
{"hostname": "raspi", "dnsName": "raspi.tail1234.ts.net", "ipv4": "100.101.1.20", "os": "linux", "online": true, "exitNodeOption": true, "tags": []}
]
}
generate_ssh_config
Emits ssh-config Host blocks for tailnet nodes (MagicDNS name preferred, Tailscale IP fallback). Dry-run by default: returns the generated text only. Inputs: write, target, onlineOnly, user.
write: truewrites the dedicated file~/.ssh/tailscale_dev_configand returns theInclude tailscale_dev_configinstruction for~/.ssh/config(never applied automatically).target: "user_ssh_config"(withwrite: true) edits~/.ssh/configdirectly, idempotently, between# BEGIN tailscale-mcpand# END tailscale-mcpmarkers. Content outside the markers is never touched.
{
"dryRun": true,
"hostCount": 2,
"configText": "# BEGIN tailscale-mcp\nHost raspi\n HostName raspi.tail1234.ts.net\n\nHost devbox\n HostName devbox.tail1234.ts.net\n# END tailscale-mcp"
}
share_port
Shares a local port via Tailscale Serve. Tailnet-only by default. Inputs: port (required), public, path.
{"port": 3000, "public": false, "scope": "tailnet-only (Serve)", "urls": ["https://devpc.tail1234.ts.net/"]}
public: true switches to Funnel and exposes the port to the open internet. See the security notes below.
share_status
Reports active Serve/Funnel sessions: {"active": false, "status": "No serve config"}.
stop_share
Without arguments clears the entire serve/funnel configuration. With httpsPort it turns off one HTTPS endpoint (the serve port shown in share_status, typically 443, not the proxied local port).
ping_all
Concurrent tailscale ping against peers (bounded to 5 in flight, one ping each with a timeout). Inputs: count, timeoutMs, onlineOnly (default true).
{
"pinged": 2,
"reachable": 1,
"matrix": [
{"hostname": "raspi", "target": "100.101.1.20", "reachable": true, "latencyMs": 3, "path": "direct", "via": "192.168.1.20:41641"},
{"hostname": "exitbox", "target": "100.101.1.40", "reachable": false, "latencyMs": null, "path": null, "via": null}
]
}
path distinguishes a direct peer-to-peer connection from a DERP relay, so an agent can tell "works but relayed" from "fast direct path".
Agentic workflow example
An agent asked to "deploy this to my dev VPS and show me the result" can do the whole discovery leg through this server:
tailnet_status {"onlineOnly": true}finds the VPS node and its MagicDNS name (devbox.tail1234.ts.net), with no hardcoded IPs.generate_ssh_config {"write": true, "user": "deploy"}writes~/.ssh/tailscale_dev_config; the agent shows the returned one-lineIncludeinstruction, and after the user adds it,ssh devboxresolves through the tailnet.ping_allconfirms the node is reachable and whether the path is direct or relayed before starting a large transfer.- After deploying,
share_port {"port": 8080}returns a tailnet-only URL teammates on the tailnet can open. Nothing touches the public internet unless the agent is explicitly told to passpublic: true.
Security notes on Funnel
share_portdefaults to tailnet-only Serve. Nothing is reachable from outside your tailnet.public: trueuses Tailscale Funnel: the URL is reachable by anyone on the internet, not just your tailnet. The tool description carries this warning so agents surface it before acting.- Serve and Funnel must be enabled per-tailnet in the admin console. When they are not, the tool returns a structured
SERVE_NOT_ENABLEDerror containing the exact enablement URL and changes nothing. stop_share(no arguments) is the kill switch: it clears the entire serve/funnel configuration.- This server never reads or stores
TS_AUTHKEYor any other credential.
Development
npm install
npm run build # tsc
npm test # vitest, fully offline (fixture-driven, no live tailnet)
npm run typecheck
Provider adapter pattern: src/providers/types.ts defines the TailscaleProvider interface; CliProvider (the only v0.1 implementation) spawns the CLI through an injectable process runner so tests never launch a real binary. The interface leaves room for a future LocalAPI provider speaking HTTP over the local socket or named pipe.
Project Structure
tailscale-mcp/
src/ Source code
src/providers/ TailscaleProvider interface + CliProvider
src/tools/ MCP tool registrations
test/fixtures/ Sanitized CLI output captured from a real tailnet
.github/ CI/CD workflows
Roadmap
See ROADMAP.md for the full project roadmap.
Contributing
See CONTRIBUTING.md for guidelines.
License
CC-BY-NC-ND-4.0 -- see LICENSE for details.
Built by TMHSDigital
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。
mcp-server-qdrant
这个仓库展示了如何为向量搜索引擎 Qdrant 创建一个 MCP (Managed Control Plane) 服务器的示例。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。