Tailscale MCP: Connect Tailscale with Claude A developer publishing as HexSleeves released a Model Context Protocol server, @hexsleeves/tailscale-mcp-server, that connects Claude to Tailscale's CLI and REST API for automated network management. The server is distributed via npm, Docker Hub (hexsleeves/tailscale-mcp-server) and the GitHub Container Registry (ghcr.io/hexsleeves/tailscale-mcp-server), and exposes tools including list_devices, device_action, manage_routes, get_network_status, connect_network, disconnect_network, ping_peer, get_version and get_tailnet_info. It is configured in Claude Desktop through ~/.claude/claude_desktop_config.json with TAILSCALE_API_KEY and TAILSCALE_TAILNET environment variables. A modern Model Context Protocol MCP https://modelcontextprotocol.io server that provides seamless integration with Tailscale's CLI commands and REST API, enabling automated network management and monitoring through a standardized interface. - NPM : @hexsleeves/tailscale-mcp-server https://www.npmjs.com/package/@hexsleeves/tailscale-mcp-server - Docker Hub : hexsleeves/tailscale-mcp-server https://hub.docker.com/r/hexsleeves/tailscale-mcp-server - GitHub Container Registry : ghcr.io/hexsleeves/tailscale-mcp-server https://github.com/users/HexSleeves/packages/container/package/tailscale-mcp-server - Device Management : List, authorize, deauthorize, and manage Tailscale devices - Network Operations : Connect/disconnect, manage routes, and monitor network status - Security Controls : Manage ACLs, device tags, and network lock settings - Modern Architecture : Modular tool system with TypeScript and Zod validation - CLI Integration : Direct integration with Tailscale CLI commands - API Integration : REST API support for advanced operations Run directly without installation: Method 1: Explicit package syntax most reliable npx --package=@hexsleeves/tailscale-mcp-server tailscale-mcp-server Method 2: Direct syntax may work depending on npx version npx -y @hexsleeves/tailscale-mcp-server Note : Method 1 with --package= syntax is more reliable across different npx versions and environments. Or install globally: npm install -g @hexsleeves/tailscale-mcp-server tailscale-mcp-server Pull and run from Docker Hub docker run -d \ --name tailscale-mcp \ -e TAILSCALE API KEY=your api key \ -e TAILSCALE TAILNET=your tailnet \ hexsleeves/tailscale-mcp-server:latest Pull and run from GitHub Container Registry docker run -d \ --name tailscale-mcp \ -e TAILSCALE API KEY=your api key \ -e TAILSCALE TAILNET=your tailnet \ ghcr.io/hexsleeves/tailscale-mcp-server:latest Use the included docker-compose.yml docker-compose up -d Add to your Claude Desktop configuration ~/.claude/claude desktop config.json : { "mcpServers": { "tailscale": { "command": "npx", "args": "--package=@hexsleeves/tailscale-mcp-server", "tailscale-mcp-server" , "env": { "TAILSCALE API KEY": "your-api-key-here", "TAILSCALE TAILNET": "your-tailnet-name" } } } } { "mcpServers": { "tailscale": { "command": "docker", "args": "run", "--rm", "-i", "-e", "TAILSCALE API KEY=xxxxxxxxxxxxx", "-e", "TAILSCALE TAILNET=your-tailnet", "hexsleeves/tailscale-mcp-server:latest" } } } { "mcpServers": { "tailscale-docker": { "command": "docker", "args": "run", "--rm", "-i", "-e", "TAILSCALE API KEY=xxxxxxxxxxxxx", "-e", "TAILSCALE TAILNET=your-tailnet", "ghcr.io/hexsleeves/tailscale-mcp-server:latest" } } } Required for API operations export TAILSCALE API KEY="your-api-key" export TAILSCALE TAILNET="your-tailnet" Optional: Custom API base URL export TAILSCALE API BASE URL="https://api.tailscale.com" Optional: Logging configuration export LOG LEVEL="1" 0=DEBUG, 1=INFO, 2=WARN, 3=ERROR export MCP SERVER LOG FILE="tailscale-mcp-{timestamp}.log" Enable file logging - list devices - List all devices in the Tailscale network - device action - Perform actions on specific devices authorize, deauthorize, delete, expire-key - manage routes - Enable or disable routes for devices - get network status - Get current network status from Tailscale CLI - connect network - Connect to the Tailscale network - disconnect network - Disconnect from the Tailscale network - ping peer - Ping a peer device - get version - Get Tailscale version information - get tailnet info - Get detailed network information For local development and testing, clone the repository and set up the development environment: Clone the repository git clone https://github.com/HexSleeves/tailscale-mcp-server.git cd tailscale-mcp-server Install dependencies npm install Build the project npm run build Copy the example environment file cp .env.example .env Create logs directory mkdir -p logs Edit .env with your actual Tailscale credentials TAILSCALE API KEY=your-actual-api-key TAILSCALE TAILNET=your-actual-tailnet The .env.example file contains all available configuration options with documentation. Key variables for testing: - TAILSCALE API KEY : Get from Tailscale Admin Console https://login.tailscale.com/admin/settings/keys - TAILSCALE TAILNET : Your organization/tailnet name - LOG LEVEL : Set to 0 for debug logging during development - MCP SERVER LOG FILE : Enable server logging to file - MCP LOG FILE : Enable test script logging to file For development, configure Claude Desktop to use your local build: { "mcpServers": { "tailscale-dev": { "command": "node", "args": "/path/to/your/tailscale-mcp-server/dist/index.js" , "env": { "TAILSCALE API KEY": "your-api-key-here", "TAILSCALE TAILNET": "your-tailnet-name", "LOG LEVEL": "0" } } } } { "mcpServers": { "tailscale-dev": { "command": "npm", "args": "run", "start" , "cwd": "/path/to/your/tailscale-mcp-server", "env": { "TAILSCALE API KEY": "your-api-key-here", "TAILSCALE TAILNET": "your-tailnet-name", "LOG LEVEL": "0" } } } } Build for development npm run build:dev Build and watch for changes npm run build:watch Run in development mode with auto-restart npm run dev Run tests npm test Run tests in watch mode npm run test:watch Run tests with coverage npm run test:coverage Test with MCP Inspector npm run inspector Lint code npm run lint Format code npm run format The project includes an interactive publishing script that handles version bumping and publishing to multiple registries: Run the interactive publish script npm run publish Or run directly ./scripts/publish.sh The script will guide you through: 1. Version Bumping : Choose between patch, minor, major, or skip 2. NPM Publishing : Optionally publish to npm registry 3. Docker Hub : Optionally build and publish Docker images 4. GitHub Container Registry : Optionally publish to GHCR 5. Git Operations : Automatically commit version changes and create tags - Interactive prompts for each publishing step - Automatic version bumping with semantic versioning - Git integration with automatic tagging and commits - Multi-registry support npm, Docker Hub, GHCR - Safety checks for uncommitted changes - Colored output for better visibility - Error handling with proper exit codes - Performance optimized with pre-calculated version previews - NPM : Logged in with npm login and proper access to the package - Docker Hub : Logged in with docker login - GHCR : Logged in with docker login ghcr.io using a GitHub token - Git : Clean working directory or confirmation to proceed with uncommitted changes For Docker-based development: Build development image docker build -t tailscale-mcp-dev . Run with development environment docker run -it --rm \ -v $ pwd :/app \ -v /app/node modules \ -e TAILSCALE API KEY=your api key \ -e TAILSCALE TAILNET=your tailnet \ -e LOG LEVEL=0 \ tailscale-mcp-dev Or use Docker Compose for development docker-compose -f docker-compose.dev.yml up src/ ├── server.ts Main server implementation ├── tools/ Modular tool definitions │ ├── index.ts Tool registry system │ ├── device-tools.ts Device management tools │ └── ... Additional tool modules ├── tailscale/ Tailscale integrations │ ├── tailscale-api.ts REST API client │ ├── tailscale-cli.ts CLI wrapper │ └── index.ts Exports ├── types.ts Type definitions ├── logger.ts Logging utilities └── index.ts Entry point 1. Create a new tool module in src/tools/ : python import { z } from "zod"; import type { ToolModule, ToolContext } from "./index.js"; const MyToolSchema = z.object { param: z.string .describe "Description of parameter" , } ; async function myTool args: z.infer