An MCP (Model Context Protocol) server for managing Tailscale resources using the official Tailscale Go client library v2. This server provides complete coverage of the Tailscale API with enhanced, self-descriptive tools powered by OpenAPI documentation.
This MCP server provides 42 comprehensive tools organized into logical categories, each with detailed descriptions, OAuth scopes, use cases, and security considerations:
- tailscale_devices_list - List all devices with optional detailed fields
- tailscale_device_get - Get comprehensive device information
- tailscale_device_delete - Permanently remove devices from tailnet
- tailscale_device_authorize - Authorize/deauthorize devices for access control
- tailscale_device_set_name - Set device names (affects Magic DNS)
- tailscale_device_set_tags - Assign tags for ACL-based access control
- tailscale_device_expire - Force device re-authentication
- tailscale_device_routes_list - List subnet routes and exit node configuration
- tailscale_device_routes_set - Configure subnet routing and exit nodes
- tailscale_keys_list - List all authentication keys with capabilities
- tailscale_key_get - Get detailed key information and usage statistics
- tailscale_key_create - Create reusable, ephemeral, or preauthorized keys
- tailscale_key_delete - Revoke authentication keys
- tailscale_users_list - List all users with roles and status
- tailscale_user_get - Get detailed user profile information
- tailscale_user_approve - Approve users for tailnet access
- tailscale_user_suspend - Temporarily suspend user access
- tailscale_user_restore - Restore suspended users
- tailscale_user_delete - Permanently remove users
- tailscale_contacts_get - Get tailnet contact preferences
- tailscale_contact_update - Update contact information for notifications
- tailscale_dns_nameservers_get - Get configured DNS nameservers
- tailscale_dns_nameservers_set - Set custom DNS nameservers
- tailscale_dns_preferences_get - Get MagicDNS and DNS preferences
- tailscale_dns_preferences_set - Configure MagicDNS and DNS behavior
- tailscale_dns_searchpaths_get - Get DNS search domain suffixes
- tailscale_dns_searchpaths_set - Set DNS search paths for short names
- tailscale_policy_get - Get current ACL policy file (HuJSON)
- tailscale_policy_set - Update ACL policy with security rules
- tailscale_policy_validate - Validate policy files before deployment
- tailscale_webhooks_list - List webhook endpoints for event notifications
- tailscale_webhook_create - Create webhooks for external integrations
- tailscale_webhook_get - Get webhook configuration and statistics
- tailscale_webhook_delete - Remove webhook endpoints
- tailscale_logging_configuration_get - Get audit log streaming configuration
- tailscale_logging_network_get - Get network flow log configuration
- tailscale_device_posture_integrations_list - List security posture integrations
- tailscale_device_posture_integration_create - Create posture provider integrations
- tailscale_device_posture_integration_get - Get posture integration details
- tailscale_device_posture_integration_delete - Remove posture integrations
- tailscale_tailnet_settings_get - Get comprehensive tailnet settings
- tailscale_tailnet_settings_update - Update tailnet configuration
- Valid Tailscale account with API access
- Tailscale API key or OAuth client credentials
- Choose one deployment method:
- Docker (recommended) - Docker and Docker Compose
- Binary - Go 1.24 or later
- Source - Go 1.24 or later + Git
The easiest way to run the Tailscale MCP server is using Docker:
# Using API key authentication
docker run -d \
--name tailscale-mcp-server \
--restart unless-stopped \
-e TAILSCALE_API_KEY="tskey-api-..." \
-e TAILSCALE_TAILNET="your-tailnet" \
tailscale-mcp-server:latest
# Using OAuth authentication
docker run -d \
--name tailscale-mcp-server \
--restart unless-stopped \
-e TAILSCALE_CLIENT_ID="your-client-id" \
-e TAILSCALE_CLIENT_SECRET="your-client-secret" \
-e TAILSCALE_TAILNET="your-tailnet" \
tailscale-mcp-server:latest- Clone the repository:
git clone <repository-url>
cd mcp- Create environment file:
# Copy example environment file
cp .env.example .env
# Edit with your credentials
vim .env- Start the server:
# Build and start
docker-compose up -d
# View logs
docker-compose logs -f
# Stop the server
docker-compose down# Build the image
docker build -t tailscale-mcp-server:local .
# Run with local image
docker run -d \
--name tailscale-mcp-server \
-e TAILSCALE_API_KEY="tskey-api-..." \
tailscale-mcp-server:local- Clone the repository and navigate to the MCP directory:
git clone <repository-url>
cd mcp- Install dependencies:
go mod tidy- Build the server:
go build -o tailscale-mcp-server ./cmd# Download and install directly
go install github.com/pnocera/tailscale-mcp-server/cmd@latestThe server supports both API key and OAuth authentication methods for maximum flexibility.
export TAILSCALE_API_KEY="tskey-api-..."
export TAILSCALE_TAILNET="your-tailnet-name" # Optional, defaults to "-"export TAILSCALE_CLIENT_ID="your-oauth-client-id"
export TAILSCALE_CLIENT_SECRET="your-oauth-client-secret"
export TAILSCALE_TAILNET="your-tailnet-name" # Optional, defaults to "-"- If both
TAILSCALE_CLIENT_IDandTAILSCALE_CLIENT_SECRETare set, OAuth is used - Otherwise, API key authentication is used with
TAILSCALE_API_KEY
# Using API key authentication
TAILSCALE_API_KEY="tskey-api-..." ./tailscale-mcp-server
# Using OAuth authentication
TAILSCALE_CLIENT_ID="..." TAILSCALE_CLIENT_SECRET="..." ./tailscale-mcp-server
# With custom tailnet
TAILSCALE_API_KEY="tskey-api-..." TAILSCALE_TAILNET="mycompany.com" ./tailscale-mcp-serverWith Docker:
# Add Docker container to Claude Code
claude mcp add tailscale docker run --rm -i \
-e TAILSCALE_API_KEY="tskey-api-..." \
tailscale-mcp-server:latestWith Binary:
# Add binary to Claude Code
claude mcp add tailscale /path/to/tailscale-mcp-serverWith Docker:
{
"mcpServers": {
"tailscale": {
"command": "docker",
"args": [
"run", "--rm", "-i",
"-e", "TAILSCALE_API_KEY=tskey-api-...",
"-e", "TAILSCALE_TAILNET=your-tailnet",
"tailscale-mcp-server:latest"
]
}
}
}With Binary:
{
"mcpServers": {
"tailscale": {
"command": "/path/to/tailscale-mcp-server",
"env": {
"TAILSCALE_API_KEY": "tskey-api-...",
"TAILSCALE_TAILNET": "your-tailnet"
}
}
}
}Instant Setup:
# Bash/Linux/macOS - Quick run with environment validation
./scripts/quick-run.sh
# PowerShell/Windows - Quick run with environment validation
.\scripts\quick-run.ps1
# Custom image
./scripts/quick-run.sh ghcr.io/myuser/tailscale-mcp-server:v1.0.0Registry Publishing:
# Bash - Build and push to registry
./scripts/build-and-push.sh
./scripts/build-and-push.sh ghcr.io/myuser v1.0.0
./scripts/build-and-push.sh docker.io/myuser latest linux/amd64
# PowerShell - Build and push to registry
.\scripts\build-and-push.ps1
.\scripts\build-and-push.ps1 -Registry "ghcr.io/myuser" -Tag "v1.0.0"
.\scripts\build-and-push.ps1 -Registry "docker.io/myuser" -Platform "linux/amd64"# Check container status
docker ps | grep tailscale-mcp-server
# View container logs
docker logs tailscale-mcp-server
# Restart container
docker restart tailscale-mcp-server
# Update to latest image
docker pull tailscale-mcp-server:latest
docker stop tailscale-mcp-server
docker rm tailscale-mcp-server
# Then run with new image// List all devices with detailed information
{
"name": "tailscale_devices_list",
"arguments": {
"fields": "all"
}
}
// Get specific device details
{
"name": "tailscale_device_get",
"arguments": {
"device_id": "device-id-here",
"fields": "all"
}
}
// Authorize a device
{
"name": "tailscale_device_authorize",
"arguments": {
"device_id": "device-id-here",
"authorized": true
}
}
// Set device tags for ACL-based access control
{
"name": "tailscale_device_set_tags",
"arguments": {
"device_id": "device-id-here",
"tags": ["tag:server", "tag:production"]
}
}// Create a reusable, preauthorized key with tags
{
"name": "tailscale_key_create",
"arguments": {
"reusable": true,
"ephemeral": false,
"preauthorized": true,
"description": "CI/CD deployment key",
"tags": ["tag:ci", "tag:automated"],
"expiry_seconds": 86400
}
}
// List all authentication keys
{
"name": "tailscale_keys_list",
"arguments": {}
}// Set custom DNS nameservers
{
"name": "tailscale_dns_nameservers_set",
"arguments": {
"nameservers": ["8.8.8.8", "8.8.4.4", "1.1.1.1"]
}
}
// Enable MagicDNS for easy device connectivity
{
"name": "tailscale_dns_preferences_set",
"arguments": {
"magic_dns": true
}
}
// Set DNS search paths for short hostnames
{
"name": "tailscale_dns_searchpaths_set",
"arguments": {
"search_paths": ["company.com", "internal.local"]
}
}// Get current ACL policy
{
"name": "tailscale_policy_get",
"arguments": {}
}
// Validate policy before applying
{
"name": "tailscale_policy_validate",
"arguments": {
"policy": "{\n \"acls\": [\n {\n \"action\": \"accept\",\n \"src\": [\"tag:server\"],\n \"dst\": [\"tag:database:5432\"]\n }\n ]\n}"
}
}
// Update ACL policy
{
"name": "tailscale_policy_set",
"arguments": {
"policy": "{\n \"acls\": [\n {\n \"action\": \"accept\",\n \"src\": [\"*\"],\n \"dst\": [\"*:*\"]\n }\n ]\n}"
}
}// Create webhook for device events
{
"name": "tailscale_webhook_create",
"arguments": {
"endpoint_url": "https://your-app.com/webhook",
"subscriptions": ["device.created", "device.deleted", "user.approved"]
}
}
// Create device posture integration
{
"name": "tailscale_device_posture_integration_create",
"arguments": {
"provider": "crowdstrike",
"client_id": "your-client-id",
"client_secret": "your-client-secret",
"tenant_id": "your-tenant-id"
}
}The server follows a clean, modular architecture:
βββ cmd/
β βββ main.go # Entry point and server setup
βββ internal/
β βββ config/ # Configuration management
β βββ client/ # Tailscale client wrapper
β βββ handlers/ # MCP request handlers
βββ pkg/
β βββ tools/ # Tool implementations
β βββ devices.go # Device management (9 tools)
β βββ keys.go # Key management (4 tools)
β βββ users.go # User & contact management (8 tools)
β βββ dns.go # DNS & policy management (9 tools)
β βββ additional.go # Advanced features (12 tools)
βββ tailscale_api_docs/ # OpenAPI documentation
βββ .gitignore # Git ignore rules
βββ LICENSE.md # MIT License
βββ README.md # This file
- Modular: Each tool category is organized in separate files
- Self-descriptive: Tools include comprehensive descriptions from OpenAPI docs
- Type-safe: Full Go type safety with structured request/response handling
- Error-resilient: Comprehensive error handling with informative messages
- OAuth-ready: Support for both API key and OAuth authentication
Each tool specifies the required OAuth scope in its description:
devices:read/devices:write- Device managementkeys:read/keys:write- Authentication key managementusers:read/users:write- User managementdns:read/dns:write- DNS configurationacl:read/acl:write- ACL policy managementwebhooks:read/webhooks:write- Webhook managementlogging:read- Log configuration accessposture:read/posture:write- Device posture managementsettings:read/settings:write- Tailnet settings
- Store API keys and OAuth credentials securely
- Use environment variables for sensitive configuration
- Implement proper access controls in your MCP client
- Regularly rotate API keys and OAuth credentials
- Monitor API usage through Tailscale admin console
- Identify the OpenAPI endpoint in
tailscale_api_docs/tailscaleapi.yaml - Choose the appropriate file in
pkg/tools/based on functionality - Add the tool definition in the
RegisterToolsmethod:
tool := mcp.NewTool(
"tailscale_new_tool",
mcp.WithDescription("Detailed description with OAuth scope and use cases"),
mcp.WithString("param", mcp.Description("Parameter description"), mcp.Required()),
)
mcpServer.AddTool(tool, dt.NewToolHandler)- Implement the handler function following existing patterns
- Test thoroughly and update documentation
All tools include:
- Detailed functionality description
- OAuth scope requirements
- Use cases and examples
- Security considerations
- Links to Tailscale documentation
# Run all tests
go test ./...
# Run tests with race detection
go test -race ./...
# Run tests with coverage
go test -coverprofile=coverage.out ./...
go tool cover -html=coverage.out# Linux
GOOS=linux GOARCH=amd64 go build -o tailscale-mcp-server-linux ./cmd
# macOS
GOOS=darwin GOARCH=amd64 go build -o tailscale-mcp-server-macos ./cmd
# Windows
GOOS=windows GOARCH=amd64 go build -o tailscale-mcp-server.exe ./cmd# Build for multiple architectures
docker buildx create --use
docker buildx build --platform linux/amd64,linux/arm64 \
-t tailscale-mcp-server:latest --push .
# Build for specific platform
docker build --platform linux/amd64 -t tailscale-mcp-server:amd64 .
docker build --platform linux/arm64 -t tailscale-mcp-server:arm64 .The server provides structured logging for:
- Authentication attempts
- API requests and responses
- Error conditions
- Performance metrics
- Monitor API usage in the Tailscale admin console
- Track OAuth token usage and refresh cycles
- Review audit logs for security compliance
- Multi-stage build for minimal attack surface
- Scratch base image (< 20MB final image)
- Non-root user execution (UID 65534)
- Read-only filesystem support
- No new privileges security option
- Dropped capabilities for enhanced security
- Optimized binary with static linking
- Resource limits (128MB RAM, 0.5 CPU by default)
- Health checks for container monitoring
- Graceful shutdown handling
- Automatic restarts on failure
- Structured logging to stdout/stderr
- Environment-based configuration
- Multi-architecture support (AMD64, ARM64)
# View real-time logs
docker logs -f tailscale-mcp-server
# Check health status
docker inspect --format='{{.State.Health.Status}}' tailscale-mcp-server
# Monitor resource usage
docker stats tailscale-mcp-server- tailscale.com/client/tailscale/v2 - Official Tailscale Go client library
- github.com/mark3labs/mcp-go - MCP protocol implementation for Go
- golang.org/x/oauth2 - OAuth 2.0 client library
- Standard Go libraries - JSON, HTTP, context, logging
This project is licensed under the MIT License. See LICENSE.md for details.
Contributions are welcome! Please ensure all new tools include:
- Complete input validation with proper error messages
- Comprehensive error handling for all failure scenarios
- Detailed descriptions following the OpenAPI documentation pattern
- JSON response formatting consistent with existing tools
- OAuth scope specifications in tool descriptions
- Unit tests for core functionality
- Documentation updates in this README
- Fork the repository
- Create a feature branch:
git checkout -b feature/new-tool - Implement your changes with tests
- Run the test suite:
go test ./... - Update documentation as needed
- Submit a pull request with a clear description
- Tailscale API Documentation - Official API reference
- MCP Protocol Specification - MCP protocol details
- Tailscale Knowledge Base - Comprehensive guides and tutorials
- Go Client Library Documentation - Official Go client docs
- Issues: Report bugs and request features on GitHub
- Documentation: Refer to the Tailscale Knowledge Base
- Community: Join the Tailscale community forums
Made with β€οΈ for the Tailscale and MCP communities. This server provides the most comprehensive Tailscale MCP integration available, with self-descriptive tools powered by official OpenAPI documentation.