Tailnet MCP Server
Why I built this: I built this to learn Tailscale - this was my first time using it. From past experience debugging network issues, I thought having an MCP to feed network state directly into an LLM could make diagnosing connectivity problems much easier than context-switching between CLI output and chat windows.
---
A Model Context Protocol (MCP) server that exposes your Tailscale tailnet as a queryable resource for LLMs. Query devices, check connectivity, and get network status directly from your AI assistant.
Prerequisites
- Docker
- A Tailscale account with at least one device on your tailnet
Setup & Test
- Clone & enter the repo:
git clone https://github.com/AlexSKorn/TailscaleMCP.git
cd TailscaleMCP
- Get an Auth Key: Go to your Tailscale Admin Console, click "Generate auth key", and copy the key (starts with
tskey-auth-).
- Configure & start:
make setup # creates .env from template
# edit .env and paste your TS_AUTHKEY
make docker-up # start containers
make docker-test # should print "Connection test: OK"
- Try it interactively with the MCP Inspector:
npx @modelcontextprotocol/inspector docker compose exec -T tailnet-mcp python -m tailnet_mcp.server
Open the URL shown in your terminal (usually http://localhost:3000), click Connect and then "List Tools", then pick any tool and click "Run".
Available Tools
| Tool | Input | What it does | |------|-------|-------------| | list_devices | {} or {"online_only": true} | List all devices on your tailnet | | get_device | {"hostname": "your-device"} | Detailed info for a specific device | | get_tailnet_status | {} | Network overview (MagicDNS, version, device count) | | check_connectivity | {"hostname": "your-device"} | Ping a device and report latency | | list_exit_nodes | {} | List available exit nodes |
Cleanup
make docker-down # stop containers (keeps state)
make docker-clean # stop and remove all data
---
Architecture
MCP Client (stdio) ←→ tailnet-mcp (FastMCP) ←→ tailscale (Unix socket)
↓
/localapi/v0/*
- MCP client sends tool calls via stdio
- Server translates them to Tailscale Local API requests over a Unix socket
- Tailscale daemon responds with network state
- Server formats responses for human readability
Key design decisions:
- Read-only — the server cannot modify Tailscale settings, add/remove devices, or change ACLs
- Local API only — all calls stay on the local machine (no external network calls, no stored credentials)
- Async throughout — httpx for socket I/O, subprocess for pings
Project Structure
src/tailnet_mcp/
├── server.py # MCP server & tool definitions
├── tailscale.py # Tailscale local API client (async httpx over Unix socket)
├── models.py # Pydantic data models
tests/
└── test_server.py # pytest + pytest-asyncio tests
Development
pip install -e ".[dev]" # install with dev dependencies
make test # run tests
make check-all # lint + format + type-check + tests
License
MIT






