Skip to main content
Glama
YawLabs

@yawlabs/tailscale-mcp

by YawLabs

List devices

tailscale_list_devices
Read-onlyIdempotent

List all devices in your tailnet with IP addresses, OS, status, and last seen time. Filter devices by properties to identify connected or ephemeral nodes.

Instructions

List all devices in your tailnet with their status, IP addresses, OS, and last seen time. 'lastSeen' is omitted while a device is connected (connectedToControl: true) and for devices that have never been online -- on a connected device a missing lastSeen means online now, not never seen.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
fieldsNoWhich device fields to return. Tailscale documents exactly two values. 'default' (also what you get when this is omitted) is the limited set: addresses, id, nodeId, user, name, hostname, clientVersion, updateAvailable, os, created, connectedToControl, lastSeen, keyExpiryDisabled, expires, authorized, isExternal, machineKey, nodeKey, blocksIncomingConnections, tailnetLockKey, tailnetLockError, tags, isEphemeral. 'all' adds advertisedRoutes, enabledRoutes, clientConnectivity (endpoints, DERP latency), sshEnabled, distro, multipleConnections and postureIdentity (serial numbers and, where a posture integration collects them, hardware/MAC addresses). Omitting it does NOT return everything. Any other value is forwarded unvalidated; Tailscale documents none.
filtersNoServer-side filters on top-level device properties, exact match only (e.g. { isEphemeral: 'true', os: 'linux' }). All filters are ANDed. Pass an array to repeat a key: { tags: ['tag:prod', 'tag:subnetrouter'] } sends tags=..&tags=.. and matches devices whose tags contain BOTH. Properties that are complex objects (e.g. clientConnectivity) cannot be filtered; repeating a key on a non-list property is undocumented upstream.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed4 schema fields changedv0.21.0
    • changedInput schema / properties / fields / description
      Previous value: -"Comma-separated list of fields to include. Omit for all fields. Valid fields: addresses, advertisedRoutes, authorized, blocksIncomingConnections, clientConnectivity, clientVersion, connectedToControl, created, distro, enabledRoutes, expires, hostname, id, isExternal, keyExpiryDisabled, lastSeen, machineKey, name, nodeId, nodeKey, os, sshEnabled, tags, tailnetLockError, tailnetLockKey, updateAvailable, user. Use 'all' for every field."New value: +"Which device fields to return. Tailscale documents exactly two values. 'default' (also what you get when this is omitted) is the limited set: addresses, id, nodeId, user, name, hostname, clientVersion, updateAvailable, os, created, connectedToControl, lastSeen, keyExpiryDisabled, expires, authorized, isExternal, machineKey, nodeKey, blocksIncomingConnections, tailnetLockKey, tailnetLockError, tags, isEphemeral. 'all' adds advertisedRoutes, enabledRoutes, clientConnectivity (endpoints, DERP latency), sshEnabled, distro, multipleConnections and postureIdentity (serial numbers and, where a posture integration collects them, hardware/MAC addresses). Omitting it does NOT return everything. Any other value is forwarded unvalidated; Tailscale documents none."
    • addedInput schema / properties / filters / additionalProperties / anyOf
      Added value: +[
      +  {
      +    "type": "string"
      +  },
      +  {
      +    "items": {
      +      "type": "string"
      +    },
      +    "minItems": 1,
      +    "type": "array"
      +  }
      +]
    • removedInput schema / properties / filters / additionalProperties / type
      Removed value: -"string"
    • changedInput schema / properties / filters / description
      Previous value: -"Server-side filters as key-value pairs. Filter by any top-level device property (e.g. { isEphemeral: 'true', os: 'linux', tags: 'tag:prod' }). Multiple filters are ANDed together."New value: +"Server-side filters on top-level device properties, exact match only (e.g. { isEphemeral: 'true', os: 'linux' }). All filters are ANDed. Pass an array to repeat a key: { tags: ['tag:prod', 'tag:subnetrouter'] } sends tags=..&tags=.. and matches devices whose tags contain BOTH. Properties that are complex objects (e.g. clientConnectivity) cannot be filtered; repeating a key on a non-list property is undocumented upstream."
  2. First observedv0.13.3

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint false, so safety is covered. The description adds valuable nuance: the lastSeen omission semantics for connected/never-online devices, and the critical gotcha that omitting 'fields' does not return all fields. This goes beyond annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but efficient, front-loading the core purpose and then adding the critical lastSeen nuance and parameter gotchas. No wasted words, though it is longer than typical.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only list tool with two optional parameters and no output schema, the description covers the key behaviors: field selection, filter semantics, and a subtle timing detail. It omits pagination and rate limits, which are less critical for a simple list operation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Both parameters have full schema coverage, but the description significantly enriches them. It explains the exact two valid values for 'fields', the default behavior, and that omitting it does not mean 'all'. For 'filters', it clarifies exact-match-only, AND semantics, and how to repeat keys for list properties. This is far more than the schema provides.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool lists all devices in the tailnet with specific attributes (status, IP, OS, lastSeen), and it is distinct from the singular tailscale_get_device sibling. The scope is unambiguous and action-oriented.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies a listing use-case but does not explicitly contrast with tailscale_get_device or other device-specific tools. There is no 'use this when' or 'use get_device for a single device' guidance, leaving the agent to infer the right selection.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Deploy Server

Other Tools