tailscale-mcpBLOCK
Tailscale MCP server for managing your tailnet from AI assistants
Overview
From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.
[](https://yaw.sh/mcp/install?name=Tailscale&command=npx&args=-y%2C%40yawlabs%2Ftailscale-mcp&description=Manage%20your%20Tailscale%20tailnet%20-%20devices%2C%20ACLs%2C%20DNS%2C%20keys&source=https%3A%2F%2Fgithub.com%2FYawLabs%2Ftailscale-mcp)
One click adds this to your local Yaw MCP config so it's available in every Yaw Terminal session. Or install manually below.
[](https://www.npmjs.com/package/@yawlabs/tailscale-mcp) [](https://opensource.org/licenses/MIT) [](https://github.com/YawLabs/tailscale-mcp/stargazers) [](./release.sh)
Ask your agent questions about your tailnet and have it act on the answers. 97 admin-API tools + 6 optional local-CLI diagnostics + 1 always-on catalog tool + 4 resources spanning the Tailscale v2 API — devices, ACLs, DNS, keys and trust credentials, users, invites, webhooks, log streaming, posture, services, and organization tailnets. Backed by 1900+ unit tests and an opt-in live-tailnet integration suite.
Built and maintained by Yaw Labs.
What's the point if the API already exists?
You could curl the Tailscale API. The point isn't replacing curl — it's letting an agent compose multi-endpoint workflows in one turn without writing a script:
- "Which devices haven't checked in for 30 days and have key expiry disabled?" — lists devices, filters by
lastSeen(online devices carry none), filters bykeyExpiryDisabled, returns a table. Three endpoints, one question. - "Someone broke DNS at 2am — who changed what in the last 24 hours?" — pulls the audit log, filters by DNS-related actors and endpoints, reads each change's before/aft
98d127786619OBSERVED · 2026-10-08Connect
Built from this server's own package name, version and transport as found in its source — not copied from anyone's documentation, so it cannot drift against a page we do not control. Replace the environment placeholders with a token scoped to the least it needs.
claude mcp add tailscale-mcp -- npx -y @yawlabs/[email protected]
Exposed tools (102)
58 read · 32 write · 12 destructive. Blast radius: 12 tools can delete or overwrite — an agent that can be talked into calling a tool can be talked into calling this one.
| Tool | Risk | Description |
|---|---|---|
tailscale_accept_device_invite | read | Accept a device share invitation using the invite URL or code. |
tailscale_approve_user | read | Approve a pending user, granting them access to the tailnet. |
tailscale_authorize_device | read | Authorize a device that is pending authorization. |
tailscale_batch_update_posture_attributes | write | Batch update custom posture attributes across multiple devices. Each attribute key must start with |
tailscale_create_aws_external_id | write | Create or get the AWS external ID Tailscale presents when assuming your IAM role for S3 log streaming. Put it in the role trust policy |
tailscale_create_device_invite | write | Create a device share invitation that allows an external user to access a specific device in your tailnet. |
tailscale_create_oauth_app | write | Create an OAuth App for device provisioning (Tailscale alpha). Lets a third-party application enroll a device into your tailnet via the authorization-code flow, after a user consents. Returns the app |
tailscale_create_org_tailnet | write | Create a new API-only tailnet in your organization. Returns the tailnet (id, displayName, orgId, dnsName, createdAt) AND a freshly-minted OAuth client for it.\n\nSECURITY: the response body contains that OAuth client |
tailscale_create_posture_integration | write | Create a new device posture integration. |
tailscale_create_user_invite | write | Create a new user invite that allows someone to join your tailnet. |
tailscale_create_webhook | write | Create a new webhook. The response includes the webhook |
tailscale_deauthorize_device | read | Deauthorize a device, immediately removing its access to the tailnet. The device will need to be re-authorized to reconnect. |
tailscale_delete_device | destructive | Permanently remove a device from the tailnet. This is irreversible — the device must re-authenticate to rejoin. |
tailscale_delete_device_invite | destructive | Delete a device invite. This is irreversible — the invite link will stop working. |
tailscale_delete_device_posture_attribute | destructive | Delete a custom posture attribute from a device. This is irreversible. |
tailscale_delete_log_stream_config | destructive | Delete a log streaming configuration. Logs will stop being sent to the configured destination. |
tailscale_delete_oauth_app | destructive | Delete an OAuth App (Tailscale alpha). This is irreversible: the app |
tailscale_delete_posture_integration | destructive | Delete a posture integration. This is irreversible. |
tailscale_delete_service | destructive | Delete a Tailscale Service. This is irreversible — the service |
tailscale_delete_tailnet | destructive | Permanently delete a tailnet. This is IRREVERSIBLE and removes every device, user, ACL, and key in it.\n\nBy default it acts on the tailnet the current credentials point at (TAILSCALE_TAILNET, or TAILSCALE_OAUTH_TAILNET when targeting an API-only tailnet). Pass |
tailscale_delete_user | destructive | Delete a user from the tailnet. This is irreversible — the user and all their devices will be removed. |
tailscale_delete_user_invite | destructive | Delete a user invite. This is irreversible — the invite link will stop working. |
tailscale_delete_webhook | destructive | Delete a webhook. This is irreversible — the webhook secret cannot be recovered. |
tailscale_diff_acl_access | read | Answer |
tailscale_expire_device | read | Expire a device |
tailscale_get_acl | read | Get the current ACL policy for your tailnet. Returns the raw policy text with original formatting preserved, including comments and trailing commas (HuJSON). Also returns an ETag — you must pass it to tailscale_update_acl to safely update the policy. |
tailscale_get_audit_log | read | Get the tailnet audit/configuration log. Shows who changed what and when -- useful for troubleshooting and compliance. Optional actor, target and event filters narrow the query server-side, so a targeted question doesn |
tailscale_get_contacts | read | Get the tailnet contact information (security, support, admin emails). |
tailscale_get_device | read | Get detailed information about a specific device by its ID. Returns the default field subset unless fields: |
tailscale_get_device_invite | read | Get details for a specific device invite. |
tailscale_get_device_posture_attributes | read | Get all posture attributes for a device, including custom and system-managed attributes. |
tailscale_get_device_routes | read | Get the subnet routes a device advertises and which are enabled. |
tailscale_get_dns_configuration | read | Get the unified DNS configuration for your tailnet, including nameservers, search paths, split DNS, and MagicDNS preference in a single call. |
tailscale_get_dns_preferences | read | Get DNS preferences for your tailnet, including whether MagicDNS is enabled. |
tailscale_get_key | read | Get details for a specific key (auth key, API access token, OAuth client, or federated identity). A revoked or expired key is still returned, with |
tailscale_get_log_stream_config | read | Get the log streaming configuration for a specific log type. |
tailscale_get_log_stream_status | read | Get the status of log streaming for a specific log type. Shows whether logs are being delivered successfully. |
tailscale_get_nameservers | read | Get the DNS nameservers configured for your tailnet. |
tailscale_get_network_flow_logs | read | Get network traffic flow logs showing connections between devices. Shows source/destination nodes, timestamps, and traffic metadata — useful for security monitoring and debugging connectivity. |
tailscale_get_oauth_app | read | Get an OAuth App |
tailscale_get_posture_integration | read | Get details for a specific device posture integration. |
tailscale_get_search_paths | read | Get the DNS search paths configured for your tailnet. |
tailscale_get_service | read | Get details for a specific Tailscale Service, including its MagicDNS name, virtual IP, and configuration. |
tailscale_get_service_device_approval | read | Get the approval status of a specific device for a Tailscale Service. |
tailscale_get_split_dns | read | Get the split DNS configuration for your tailnet. |
tailscale_get_tailnet_settings | read | Get your tailnet settings (device approval, key expiry, HTTPS certificates, etc.). |
tailscale_get_user | read | Get details for a specific user. |
tailscale_get_user_invite | read | Get details for a specific user invite. |
tailscale_get_webhook | read | Get details for a specific webhook. |
tailscale_list_device_invites | read | List all device invites for a specific device. |
tailscale_list_devices | read | List all devices in your tailnet with their status, IP addresses, OS, and last seen time.${DEVICE_LAST_SEEN_NOTE} |
tailscale_list_keys | read | List keys in your tailnet: auth keys, API access tokens, OAuth clients and federated identities. Without |
tailscale_list_log_stream_configs | read | List all log streaming configurations for your tailnet. Fetches both |
tailscale_list_oauth_apps | read | List the OAuth Apps registered in your tailnet (Tailscale alpha). Returns an |
tailscale_list_org_tailnets | read | List the tailnets in your organization, including API-only tailnets created via the API. Paginated: returns at most |
tailscale_list_posture_integrations | read | List all device posture integrations configured for your tailnet. |
tailscale_list_service_hosts | read | List devices hosting a specific Tailscale Service. |
tailscale_list_services | read | List all Tailscale Services in your tailnet. Services provide stable MagicDNS names and virtual IPs, decoupled from individual devices. Note: services are created implicitly when a node first advertises one ( |
tailscale_list_user_invites | read | List the open (not yet accepted) user invites for your tailnet. Accepted invites are not returned. |
tailscale_list_users | read | List all users in your tailnet. |
tailscale_list_webhooks | read | List all webhooks configured for your tailnet. |
tailscale_local_service_list | read | List the Tailscale Services visible to THIS node. Complements the admin-side service tools (tailscale_list_services etc.), which report what the tailnet has configured -- this reports what this machine can actually see and reach, which is the difference that matters when debugging a service that |
tailscale_local_status | read | Get this machine |
tailscale_local_version | read | Get the version of the local |
tailscale_local_whoami | read | Show which Tailscale user and device this machine is currently authenticated as. Useful for confirming an agent host is enrolled under the identity you expect before trusting its access. Requires tailscale >= 1.102.1; returns the CLI |
tailscale_netcheck | write | Run Tailscale |
tailscale_ping | read | Probe latency to another tailnet node from this machine. Useful for connectivity debugging -- shows whether the path is direct or DERP-relayed, plus RTT. Returns the CLI |
tailscale_preview_acl | write | Preview the ACL rules that would apply to a specific user or IP address if a proposed policy were applied. |
tailscale_rename_device | destructive | Set the name of a device in the tailnet, or reset it to its OS hostname. |
tailscale_resend_contact_verification | read | Resend the verification email for a tailnet contact. |
tailscale_resend_device_invite | read | Resend a device invite email. |
tailscale_resend_user_invite | read | Resend a user invite email. |
tailscale_restore_user | read | Restore a previously suspended user, re-granting them access to the tailnet. |
tailscale_rotate_webhook_secret | read | Rotate a webhook |
tailscale_set_contacts | write | Update tailnet contact information. Each provided contact type (account/support/security) is PATCHed in parallel; per-type errors are returned alongside the successes so a partial failure doesn |
tailscale_set_device_ip | write | Set the Tailscale IPv4 address for a device. |
tailscale_set_device_posture_attribute | write | Set a custom posture attribute on a device. Creates or updates the attribute. Attribute keys must start with |
tailscale_set_device_routes | write | Set the enabled subnet routes for a device. Replaces all currently enabled routes — pass the full list of routes you want enabled. |
tailscale_set_device_tags | write | Set ACL tags on a device. Replaces all existing tags — pass the full list of tags you want applied. |
tailscale_set_devices_authorized | write | Authorize or deauthorize multiple devices in one call. Each device |
tailscale_set_dns_configuration | write | Set the unified DNS configuration for your tailnet in a single call. Replaces all DNS settings (nameservers, search paths, split DNS, MagicDNS preference). |
tailscale_set_dns_preferences | write | Set DNS preferences for your tailnet, such as enabling or disabling MagicDNS. The API reference says enabling can fail when the tailnet has no nameservers; if it does, add one with tailscale_set_nameservers first. |
tailscale_set_log_stream_config | write | Set the log streaming configuration for a specific log type. Configures where logs are sent (e.g. Axiom, Datadog, Splunk, Elasticsearch, S3).\n\n |
tailscale_set_nameservers | write | Set the DNS nameservers for your tailnet. Replaces all existing nameservers. Removing every nameserver may also change MagicDNS: the API reference says it is switched off, while Tailscale |
tailscale_set_search_paths | write | Set the DNS search paths for your tailnet. Replaces all existing search paths. |
tailscale_set_service_device_approval | write | Approve or reject a device to host a Tailscale Service. |
tailscale_set_split_dns | write | Set split DNS configuration. Maps domains to specific nameservers. Replaces the entire split DNS configuration: a domain you leave out is removed, and an empty object clears every domain. Per the API reference, setting a domain to null clears that domain |
tailscale_status | read | Check that the Tailscale API connection is working. Returns your tailnet name, device count, and confirms authentication is valid. Use this to verify setup. |
tailscale_suspend_user | read | Suspend a user, immediately revoking their access to the tailnet. Their devices will be disconnected. Can be reversed with tailscale_restore_user. |
tailscale_test_webhook | write | Send a test event to a webhook endpoint to verify it is configured correctly and receiving events. |
tailscale_tool_groups | read | Explain which of this server |
tailscale_update_acl | write | Update the ACL policy for your tailnet. Accepts the full policy as a string to preserve formatting, comments, and trailing commas (HuJSON). You MUST pass the ETag from tailscale_get_acl to prevent overwriting concurrent changes, or |
tailscale_update_device_key | write | Update a device |
tailscale_update_key | write | Update an existing key. Supported fields depend on the key type: all key types accept |
tailscale_update_posture_integration | write | Update an existing posture integration |
tailscale_update_service | write | Update a Tailscale Service |
tailscale_update_tailnet_settings | write | Update tailnet settings (device approval, auto-updates, key expiry, HTTPS certificates, network flow logging, regional routing, posture identity collection). |
tailscale_update_user_role | write | Update a user |
tailscale_update_webhook | write | Update an existing webhook |
tailscale_validate_acl | read | Validate an ACL policy without applying it. Returns any errors found, or confirms the policy is valid. |
tailscale_validate_aws_trust_policy | read | Validate that an AWS IAM role trust policy is correctly configured with the Tailscale external ID. Use this after setting up the IAM role for S3 log streaming. |
yaw-probe-c9-b | read | yaw probe c9 |
Trust audit
BLOCKgrade D · trust 69/100 Do not install this without reading the findings. The audit found something that could harm you or your machine.
| Layer | What it checks | Result |
|---|---|---|
| L0 | Provenance & inventory | PASS |
| L1 | Static analysis of the code | FAIL |
| L2 | Instruction surface (what it tells the agent) | PASS |
| L3 | Class-specific surface | WARN |
| L4 | Behavioural (sandbox) | SKIPPED |
What the source does
- Filesystem
- declared (4 observation(s))
- Network
- declared (9 observation(s))
- Shell
- declared (5 observation(s))
- Dependencies
- not all pinned
- Secrets in source
- found
Findings (16)
const SSH = "ssh -i ~/.ssh/gh_woods -o IdentitiesOnly=yes";
const token = "eyJhbGciOiJIUzI1NiJ9.aaaabbbbccccddddeeeeffff.gggghhhhiiiijjjj";
tailscale_delete_device, tailscale_delete_device_invite, tailscale_delete_device_posture_attribute, tailscale_delete_log_stream_config, tailscale_delete_oauth_app, tailscale_delete_posture_integration
const factory = new Function("process", `${match[0]}; return sandboxFlags();`) as (p: {const factory = new Function(`${pieces.join("\n")}\nreturn ${name};`) as () => T;const nodeFloorFailure = new Function(`${extracts.join("\n")}\nreturn nodeFloorFailure;`)() as (versions: {for (const rel of ["../package.json", "../../package.json", "../../../package.json"]) {writeFileSync(aclFile, `{ "acls": [{ "action": "accept", "src": ["*"], "dst": ["*:*"] }] }`);assert.ok(!body.startsWith(""), `the BOM reached the wire: ${JSON.stringify(body.slice(0, 8))}`);writeFileSync(path, `${JSON.stringify({ targets: {}, journal: [] })}`, "utf-8");@biomejs/biome, @modelcontextprotocol/sdk, @types/node, esbuild, postject, typescript, zod
- **`tailscale_list_keys` said the default listing is "auth keys only"; per the OpenAPI spec it is whatever the credential owns.** The spec's listing returns "active auth keys, API access tokens and t
- **"Create an OAuth client for our CI pipeline scoped to `devices:core:read` and `dns:read`"** — creates a trust credential via `tailscale_create_key` with `keyType=client`, returns the credentials o
| `keys` | `auth_keys:read`, `oauth_keys:read`, `federated_keys:read`, `api_access_tokens:read`, `oauth_apps:read` | `auth_keys`, `oauth_keys`, `federated_keys`, `api_access_tokens`, `oauth_apps` | Ke
| Windows | — | The installer puts `tailscale.exe` on the machine `PATH`. If you set `TAILSCALE_BINARY`, use a Windows path (`C:/Program Files/Tailscale/tailscale.exe`), not a Git Bash one (`/c/...`)
- **The bundled MCP SDK moves from 1.30.0 to 1.32.1** (GHSA-6qxp-vccf-f47h, high: the SDK's OAuth client could send credentials to an authorization server chosen by the MCP server). `build.mjs` bundle
Gates applied: no_behavioural_pass.
98d127786619full audit observations/trust-audit/mcp-server/yawlabs__tailscale-mcp.json · Report an issue / request a re-scanAudit history
Every audit this server has had. A grade with a past is a grade somebody is still checking.
| Date | Source | Verdict | Grade | Score | Change |
|---|---|---|---|---|---|
| 2026-10-08 | 98d127786619 | BLOCK | D | 69 | first audit |
Questions
What is the tailscale-mcp MCP server?
Tailscale MCP server for managing your tailnet from AI assistants
What tools does tailscale-mcp expose?
102 in total: 58 read-only, 32 that write, and 12 that can delete or overwrite (tailscale_delete_device, tailscale_delete_device_invite, tailscale_delete_device_posture_attribute, tailscale_delete_log_stream_config, tailscale_delete_oauth_app). Every one is listed on this page with its risk.
Is tailscale-mcp safe to connect to an agent?
No — not without reading the findings first. The audit graded it D (69/100) and found 1 critical or high issue in the source. Each one is listed on this page with the file and line it is on. Separately from the audit: 12 of its tools can destroy data, so scope the token you give it to what you actually need.
What credentials does tailscale-mcp need?
It reads TAILSCALE_API_KEY, TAILSCALE_OAUTH_CLIENT_ID, TAILSCALE_OAUTH_CLIENT_SECRET and TAILSCALE_OAUTH_TAILNET from the environment. Give it a token scoped to the least it needs — an agent that can be talked into calling a tool can be talked into calling it with your credentials.
How does tailscale-mcp run?
It speaks stdio, so it runs as a local process your client starts. It is published on npm as @yawlabs/tailscale-mcp at 0.21.2.
How current is this page?
The grade is for one exact copy of the source (98d127786619), read on 2026-10-08. The repository is watched and re-audited when it changes.