> **Building with AI coding agents?** Install the authstack plugin with one command. This equips your agent with accurate Scalekit implementation patterns.
>
> **Recommended** (the `-y` flags skip prompts, so the command runs without an interactive terminal):
> ```bash
> npx -y @scalekit-inc/cli setup -y
> ```
>
> Global:
> ```bash
> npm install -g @scalekit-inc/cli
> scalekit setup -y
> ```
>
> Supports Claude Code, Cursor, GitHub Copilot, Codex + skills for other Agent Skills-compatible agents in `~/.agents/skills`.
> Skills: integrate-agentkit, implement-saaskit, add-mcp-oauth, implement-sso, implement-scim.
> [Full setup guide](https://docs.scalekit.com/dev-kit/build-with-ai/)

---

# Connect AI agents to Tailscale

The Tailscale connector lets your AI agent act in each user's Tailscale account. Each user connects their own Tailscale access token once, and Scalekit sends it with every call, so your agent never handles credentials. It comes with 41 tools.

**Authentication:** Bearer Token
**Categories:** Developer Tools, Monitoring
**Tools:** 41: 22 read, 16 write, 3 destructive
**Users sign in with:** Access token
**Built by:** Scalekit connector
**Try it:** [Playground in the Scalekit dashboard](https://app.scalekit.com/ws/signup?sk_intent=playground&provider=TAILSCALE)

## Setup

1. ### Install the SDK

   **Node.js**

   ```bash
   npm install @scalekit-sdk/node dotenv
   ```

   **Python**

   ```bash
   pip install scalekit-sdk-python python-dotenv
   ```

2. ### Set your credentials

   Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**.

   ```sh title=".env"
   SCALEKIT_ENVIRONMENT_URL=<your-environment-url>
   SCALEKIT_CLIENT_ID=<your-client-id>
   SCALEKIT_CLIENT_SECRET=<your-client-secret>
   ```

3. ### Create the Tailscale connection

   In **AgentKit > Connections**, create a Tailscale connection. The name you give it is the `connection_name` your code passes. See [Configure connections](/agentkit/connections/).

4. ### Authorize a user and make your first call

   **Node.js** (`quickstart.mts`)

   ```typescript
   import { ScalekitClient } from '@scalekit-sdk/node'
   import 'dotenv/config'
   import { createInterface } from 'node:readline/promises'

   const scalekit = new ScalekitClient(
     process.env.SCALEKIT_ENVIRONMENT_URL,
     process.env.SCALEKIT_CLIENT_ID,
     process.env.SCALEKIT_CLIENT_SECRET,
   )
   const actions = scalekit.actions

   const connector = 'tailscale'
   const identifier = 'user_123'

   // Generate an authorization link for the user
   const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier })
   console.log('Authorize Tailscale:', link)
   const rl = createInterface({ input: process.stdin, output: process.stdout })
   await rl.question('Press Enter after authorizing...')
   rl.close()

   // Make your first call
   const result = await actions.executeTool({
     connector,
     identifier,
     toolName: 'tailscale_get_contacts',
     toolInput: {},
   })
   console.log(result)
   ```

   ```bash
   npx tsx quickstart.mts
   ```

   **Python** (`quickstart.py`)

   ```python
   import os
   from scalekit import ScalekitClient
   from dotenv import load_dotenv
   load_dotenv()

   scalekit_client = ScalekitClient(
       env_url=os.getenv("SCALEKIT_ENVIRONMENT_URL"),
       client_id=os.getenv("SCALEKIT_CLIENT_ID"),
       client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"),
   )
   actions = scalekit_client.actions

   connection_name = "tailscale"
   identifier = "user_123"

   # Generate an authorization link for the user
   link_response = actions.get_authorization_link(
       connection_name=connection_name,
       identifier=identifier,
   )
   print("Authorize Tailscale:", link_response.link)
   input("Press Enter after authorizing...")

   # Make your first call
   result = actions.execute_tool(
       tool_input={},
       tool_name="tailscale_get_contacts",
       connection_name=connection_name,
       identifier=identifier,
   )
   print(result)
   ```

   ```bash
   python quickstart.py
   ```

   Each user opens the link once and enters their Tailscale credentials there. See [Authorize a user](/agentkit/tools/authorize/) for the full flow and statuses.

## Tools

Pass the exact name to `execute_tool`, with an input like each tool's example. To ask for a tool that's missing, use the [request form](https://scalekitsupport.portal.usepylon.com/forms/request-a-connector-tool).

**Node.js**

```typescript
const result = await actions.executeTool({
  toolName: 'tailscale_get_configuration_audit_logs',
  toolInput: {
    end: '<end>',
    start: '<start>',
  },
  connector: 'tailscale',
  identifier: 'user_123',
})
```

**Python**

```python
result = actions.execute_tool(
    tool_name="tailscale_get_configuration_audit_logs",
    tool_input={
        "end": "<end>",
        "start": "<start>",
    },
    connection_name="tailscale",
    identifier="user_123",
)
```

`result.data` is the app's response as JSON, and `result.execution_id` (`executionId` in Node.js) is the ID of the call.

### `tailscale_get_configuration_audit_logs`

Get Configuration Audit Logs · Read-only

Retrieve configuration audit log entries, the record of admin changes to a tailnet, for a time window.
Returns a logs array with one entry per configuration change, including when it happened, who made it and what changed.
Use get_configuration_audit_logs to see who changed settings, ACLs or devices. Use get_network_flow_logs for traffic data.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `end` (`string`, required): End Time as an RFC 3339 timestamp, for example '2026-10-01T00:00:00Z'. Logs older than the retention window (30 days) are trimmed to the window.
- `start` (`string`, required): Start Time as an RFC 3339 timestamp, for example '2026-10-01T00:00:00Z'. Logs older than the retention window (30 days) are trimmed to the window.
- `tailnet` (`string`, optional): Tailnet to operate on. Use '-' (a dash) for the default tailnet of the connected API token, or pass the organization name shown on the Tailscale admin console General settings page, for example 'example.com' or 'alice@gmail.com'. Default: `-`.

Example input: `{"end":"<end>","start":"<start>"}`

### `tailscale_get_contacts`

Get Contacts · Read-only

Retrieve the account, support and security contact emails of a tailnet.
Returns account, support and security objects, each with email, fallbackEmail and needsVerification.
Use get_contacts to read contact emails. Use update_contact to change one.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `tailnet` (`string`, optional): Tailnet to operate on. Use '-' (a dash) for the default tailnet of the connected API token, or pass the organization name shown on the Tailscale admin console General settings page, for example 'example.com' or 'alice@gmail.com'. Default: `-`.

Example input: `{}`

### `tailscale_get_device`

Get Device · Read-only

Retrieve the details of one device, including addresses, tags, OS, client version, key expiry and connection state.
Returns the device object; pass fields=all to also include enabledRoutes, advertisedRoutes, clientConnectivity and postureIdentity.
Use get_device when you already know the device ID. Use list_devices to discover IDs.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `device_id` (`string`, required): ID of the device. The preferred form is the node ID returned as nodeId by the list devices tool (for example 'nABC123CNTRL'); the legacy numeric id (for example '12345') also works.
- `fields` (`string`, optional): Which fields to return: 'default' omits routes, clientConnectivity and postureIdentity; 'all' returns every field. One of: `default`, `all`.

Example input: `{"device_id":"<device_id>"}`

### `tailscale_get_device_routes`

Get Device Routes · Read-only

Retrieve the subnet routes a device advertises and the subset that is enabled.
Returns advertisedRoutes and enabledRoutes, each an array of CIDR strings.
Use get_device_routes before set_device_routes to see which advertised routes still need approval.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `device_id` (`string`, required): ID of the device. The preferred form is the node ID returned as nodeId by the list devices tool (for example 'nABC123CNTRL'); the legacy numeric id (for example '12345') also works.

Example input: `{"device_id":"<device_id>"}`

### `tailscale_get_dns_configuration`

Get DNS Configuration · Read-only

Retrieve the full DNS configuration of a tailnet in one call.
Returns nameservers, splitDNS, searchPaths and preferences (including magicDNS and overrideLocalDNS).
Use get_dns_configuration for a complete snapshot. Use the narrower get_dns_nameservers, get_split_dns or get_dns_search_paths for one part.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `tailnet` (`string`, optional): Tailnet to operate on. Use '-' (a dash) for the default tailnet of the connected API token, or pass the organization name shown on the Tailscale admin console General settings page, for example 'example.com' or 'alice@gmail.com'. Default: `-`.

Example input: `{}`

### `tailscale_get_dns_nameservers`

Get DNS Nameservers · Read-only

Retrieve the global DNS nameservers configured for a tailnet.
Returns dns (an array of nameserver IP addresses) and magicDNS (whether MagicDNS is on).
Use get_dns_nameservers to read the global resolvers. Use get_split_dns for per-domain resolvers.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `tailnet` (`string`, optional): Tailnet to operate on. Use '-' (a dash) for the default tailnet of the connected API token, or pass the organization name shown on the Tailscale admin console General settings page, for example 'example.com' or 'alice@gmail.com'. Default: `-`.

Example input: `{}`

### `tailscale_get_dns_preferences`

Get DNS Preferences · Read-only

Retrieve the DNS preferences of a tailnet.
Returns magicDNS, a boolean that says whether MagicDNS is enabled.
Use get_dns_preferences to check MagicDNS. Use set_dns_preferences to change it.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `tailnet` (`string`, optional): Tailnet to operate on. Use '-' (a dash) for the default tailnet of the connected API token, or pass the organization name shown on the Tailscale admin console General settings page, for example 'example.com' or 'alice@gmail.com'. Default: `-`.

Example input: `{}`

### `tailscale_get_dns_search_paths`

Get DNS Search Paths · Read-only

Retrieve the DNS search paths configured for a tailnet.
Returns searchPaths, an array of domain suffixes.
Use get_dns_search_paths to read the search domains. Use set_dns_search_paths to change them.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `tailnet` (`string`, optional): Tailnet to operate on. Use '-' (a dash) for the default tailnet of the connected API token, or pass the organization name shown on the Tailscale admin console General settings page, for example 'example.com' or 'alice@gmail.com'. Default: `-`.

Example input: `{}`

### `tailscale_get_key`

Get Key · Read-only

Retrieve the details of one auth key, API access token or OAuth client.
Returns id, description, created, expires, revoked, invalid and capabilities; the secret key value is never returned after creation.
Use get_key when you know the key ID. Use list_keys to discover IDs.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `key_id` (`string`, required): ID of the key, as returned by list_keys or create_auth_key, for example 'kABC123CNTRL'.
- `tailnet` (`string`, optional): Tailnet to operate on. Use '-' (a dash) for the default tailnet of the connected API token, or pass the organization name shown on the Tailscale admin console General settings page, for example 'example.com' or 'alice@gmail.com'. Default: `-`.

Example input: `{"key_id":"<key_id>"}`

### `tailscale_get_network_flow_logs`

Get Network Flow Logs · Read-only

Retrieve network flow log entries for a time window. Network flow logging must be enabled for the tailnet.
Returns a logs array; each entry has logged, nodeId, start, end, virtualTraffic, subnetTraffic, exitTraffic and physicalTraffic.
Use get_network_flow_logs to inspect traffic between devices. Use get_configuration_audit_logs for admin changes.
Large windows return a lot of data, so keep the range short.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `end` (`string`, required): End Time as an RFC 3339 timestamp, for example '2026-10-01T00:00:00Z'. Logs older than the retention window (30 days) are trimmed to the window.
- `start` (`string`, required): Start Time as an RFC 3339 timestamp, for example '2026-10-01T00:00:00Z'. Logs older than the retention window (30 days) are trimmed to the window.
- `tailnet` (`string`, optional): Tailnet to operate on. Use '-' (a dash) for the default tailnet of the connected API token, or pass the organization name shown on the Tailscale admin console General settings page, for example 'example.com' or 'alice@gmail.com'. Default: `-`.

Example input: `{"end":"<end>","start":"<start>"}`

### `tailscale_get_policy_file`

Get Policy File · Read-only

Retrieve the tailnet's current access control policy file as JSON.
Returns the policy object with sections such as acls, grants, groups, hosts, tagOwners, autoApprovers, ssh and tests; with details=true the response also lists warnings and errors.
Use get_policy_file to read the current policy before changing it with update_policy_file.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `details` (`boolean`, optional): Set to true to also return warnings and errors found in the policy file, such as references to users that no longer exist.
- `tailnet` (`string`, optional): Tailnet to operate on. Use '-' (a dash) for the default tailnet of the connected API token, or pass the organization name shown on the Tailscale admin console General settings page, for example 'example.com' or 'alice@gmail.com'. Default: `-`.

Example input: `{}`

### `tailscale_get_split_dns`

Get Split DNS · Read-only

Retrieve the split DNS settings of a tailnet, the map from domain to the nameservers that resolve it.
Returns an object whose keys are domains and whose values are arrays of nameserver addresses.
Use get_split_dns to read per-domain resolvers. Use get_dns_nameservers for the global resolvers.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `tailnet` (`string`, optional): Tailnet to operate on. Use '-' (a dash) for the default tailnet of the connected API token, or pass the organization name shown on the Tailscale admin console General settings page, for example 'example.com' or 'alice@gmail.com'. Default: `-`.

Example input: `{}`

### `tailscale_get_tailnet_settings`

Get Tailnet Settings · Read-only

Retrieve the settings of a tailnet such as device approval, key expiry duration, auto updates and HTTPS.
Returns fields including devicesApprovalOn, devicesAutoUpdatesOn, devicesKeyDurationDays, usersApprovalOn, networkFlowLoggingOn, httpsEnabled and routeSelection.
Use get_tailnet_settings to read configuration. Use update_tailnet_settings to change it.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `tailnet` (`string`, optional): Tailnet to operate on. Use '-' (a dash) for the default tailnet of the connected API token, or pass the organization name shown on the Tailscale admin console General settings page, for example 'example.com' or 'alice@gmail.com'. Default: `-`.

Example input: `{}`

### `tailscale_get_user`

Get User · Read-only

Retrieve one user's profile, role, status and device count.
Returns id, displayName, loginName, role, status, type, tailnetId, deviceCount, created, lastSeen and currentlyConnected.
Use get_user when you know the user ID. Use list_users to find IDs.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `user_id` (`string`, required): ID of the user, as returned by list_users, for example 'u123456CNTRL'.

Example input: `{"user_id":"<user_id>"}`

### `tailscale_get_user_invite`

Get User Invite · Read-only

Retrieve one user invitation.
Returns id, role, email, tailnetId, inviterId, lastEmailSentAt and inviteUrl when present.
Use get_user_invite when you know the invite ID. Use list_user_invites to find IDs.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `user_invite_id` (`string`, required): ID of the user invite, as returned by list_user_invites or create_user_invites, for example '29214'.

Example input: `{"user_invite_id":"<user_invite_id>"}`

### `tailscale_list_devices`

List Devices · Read-only

List every device in a tailnet with its addresses, hostname, OS, tags, authorization state and last-seen time.
Returns a devices array; each entry has id, nodeId, name, hostname, addresses, user, tags, os, clientVersion, authorized, lastSeen and keyExpiryDisabled.
Use list_devices to browse or find a device ID. Use get_device for one device's full details.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `fields` (`string`, optional): Which device fields to return: 'default' omits enabledRoutes, advertisedRoutes, clientConnectivity and postureIdentity; 'all' returns every field. One of: `default`, `all`.
- `tailnet` (`string`, optional): Tailnet to operate on. Use '-' (a dash) for the default tailnet of the connected API token, or pass the organization name shown on the Tailscale admin console General settings page, for example 'example.com' or 'alice@gmail.com'. Default: `-`.

Example input: `{}`

### `tailscale_list_keys`

List Keys · Read-only

List the auth keys, API access tokens and OAuth clients in a tailnet.
Returns a keys array of entries with id and, depending on the key, description, created, expires and capabilities.
Use list_keys to find a key ID. Use get_key for the full details of one key.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `all` (`boolean`, optional): Set to true to list keys for every user in the tailnet instead of only keys owned by the token's user. Requires an admin token.
- `tailnet` (`string`, optional): Tailnet to operate on. Use '-' (a dash) for the default tailnet of the connected API token, or pass the organization name shown on the Tailscale admin console General settings page, for example 'example.com' or 'alice@gmail.com'. Default: `-`.

Example input: `{}`

### `tailscale_list_user_invites`

List User Invites · Read-only

List the open invitations that let people join a tailnet.
Returns an array of invites; each has id, role, email, inviterId, lastEmailSentAt and, when applicable, inviteUrl.
Use list_user_invites to find an invite ID. Use create_user_invites to send new invitations.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `tailnet` (`string`, optional): Tailnet to operate on. Use '-' (a dash) for the default tailnet of the connected API token, or pass the organization name shown on the Tailscale admin console General settings page, for example 'example.com' or 'alice@gmail.com'. Default: `-`.

Example input: `{}`

### `tailscale_list_users`

List Users · Read-only

List the users in a tailnet, optionally filtered by type or role.
Returns a users array; each entry has id, displayName, loginName, role, status, type, deviceCount, created and lastSeen.
Use list_users to browse or find a user ID. Use get_user for one user.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `role` (`string`, optional): Only return users with this role: owner, member, admin, it-admin, network-admin, billing-admin or auditor. One of: `owner`, `member`, `admin`, `it-admin`, `network-admin`, `billing-admin`, `auditor`.
- `tailnet` (`string`, optional): Tailnet to operate on. Use '-' (a dash) for the default tailnet of the connected API token, or pass the organization name shown on the Tailscale admin console General settings page, for example 'example.com' or 'alice@gmail.com'. Default: `-`.
- `type` (`string`, optional): Only return users of this type: 'member' for users that belong to the tailnet, or 'shared' for users with access through device sharing. One of: `member`, `shared`.

Example input: `{}`

### `tailscale_preview_policy_rule_matches`

Preview Policy Rule Matches · Read-only

Show which rules in a policy file apply to a given user or to an IP address and port, without saving the policy.
Returns matches (each with users, ports and lineNumber) plus the type and previewFor values echoed back.
Use preview_policy_rule_matches to see the effect of a draft policy. Use validate_policy_file to check a policy for errors.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `policy` (`object`, required): The complete tailnet policy file as a JSON object, using the same sections as the admin console policy editor such as acls, grants, groups, hosts, tagOwners, autoApprovers, ssh, nodeAttrs and tests. Example: {"acls": [{"action": "accept", "src": ["*"], "dst": ["*:*"]}]}. It is evaluated but not saved.
- `preview_for` (`string`, required): The value to match rules against: a user's email such as 'user1@example.com' when type is 'user', or an IP and port such as '10.0.0.1:80' when type is 'ipport'.
- `type` (`string`, required): Kind of value given in preview_for: 'user' for a user's email or 'ipport' for an IP address and port. One of: `user`, `ipport`.
- `tailnet` (`string`, optional): Tailnet to operate on. Use '-' (a dash) for the default tailnet of the connected API token, or pass the organization name shown on the Tailscale admin console General settings page, for example 'example.com' or 'alice@gmail.com'. Default: `-`.

Example input: `{"policy":{},"preview_for":"<preview_for>","type":"user"}`

### `tailscale_run_policy_tests`

Run Policy Tests · Read-only

Run access tests against the tailnet's current saved policy file without changing it.
Returns an empty body or an object without a message when every test passes; otherwise an object with a message and a data array naming the failing tests.
Use run_policy_tests to check expected allow and deny outcomes. Use validate_policy_file to test a draft policy instead.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `tests` (`array`, required): List of access tests to run, each an object with src and the accept and/or deny destinations, for example [{"src": "user1@example.com", "accept": ["example-host-1:22"], "deny": ["example-host-2:100"]}].
- `tailnet` (`string`, optional): Tailnet to operate on. Use '-' (a dash) for the default tailnet of the connected API token, or pass the organization name shown on the Tailscale admin console General settings page, for example 'example.com' or 'alice@gmail.com'. Default: `-`.

Example input: `{"tests":[]}`

### `tailscale_validate_policy_file`

Validate Policy File · Read-only

Check that a draft policy file parses and passes its own tests, without saving it.
Returns an empty body or an object without a message when the policy is valid; otherwise an object with a message and a data array describing the errors, warnings or failing tests.
Use validate_policy_file before update_policy_file. Use run_policy_tests to test the current saved policy instead.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `policy` (`object`, required): The complete tailnet policy file as a JSON object, using the same sections as the admin console policy editor such as acls, grants, groups, hosts, tagOwners, autoApprovers, ssh, nodeAttrs and tests. Example: {"acls": [{"action": "accept", "src": ["*"], "dst": ["*:*"]}]}. It is validated but not saved.
- `tailnet` (`string`, optional): Tailnet to operate on. Use '-' (a dash) for the default tailnet of the connected API token, or pass the organization name shown on the Tailscale admin console General settings page, for example 'example.com' or 'alice@gmail.com'. Default: `-`.

Example input: `{"policy":{}}`

### `tailscale_authorize_device`

Authorize Device · Write

Authorize or deauthorize a device on a tailnet that has device approval enabled.
Returns an empty JSON object on success.
Use authorize_device to approve a pending device or revoke access. Only meaningful when device approval is turned on in the tailnet settings.

Read only: no. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `authorized` (`boolean`, required): Set to true to authorize the device or false to deauthorize it.
- `device_id` (`string`, required): ID of the device. The preferred form is the node ID returned as nodeId by the list devices tool (for example 'nABC123CNTRL'); the legacy numeric id (for example '12345') also works.

Example input: `{"authorized":true,"device_id":"<device_id>"}`

### `tailscale_create_auth_key`

Create Auth Key · Write

Create an auth key that lets new devices join the tailnet.
Returns the new key's id, the secret key value (shown only once), created and expires times, and the capabilities granted.
Use create_auth_key to onboard devices or CI jobs. Use delete_key to revoke a key.
Store the returned key securely; it cannot be retrieved again.

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `description` (`string`, optional): Short note on what the key is for, up to 50 letters, digits, spaces or hyphens, for example 'ci-runner-key'.
- `ephemeral` (`boolean`, optional): Set to true if devices registered with this key are ephemeral and are removed automatically after going offline. Default: `false`.
- `expiry_seconds` (`integer`, optional): Seconds until the key expires, for example 86400 for one day. Defaults to 90 days when omitted.
- `preauthorized` (`boolean`, optional): Set to true if devices registered with this key skip manual approval when device approval is enabled. Default: `false`.
- `reusable` (`boolean`, optional): Set to true if the key can register more than one device. Defaults to a single-use key. Default: `false`.
- `tags` (`array`, optional): Tags applied to devices that register with this key, for example ["tag:ci"]. Each tag must start with 'tag:' and be owned in the policy file. Required when the token comes from an OAuth client.
- `tailnet` (`string`, optional): Tailnet to operate on. Use '-' (a dash) for the default tailnet of the connected API token, or pass the organization name shown on the Tailscale admin console General settings page, for example 'example.com' or 'alice@gmail.com'. Default: `-`.

Example input: `{}`

### `tailscale_create_user_invites`

Create User Invite · Write

Invite one person to join the tailnet with a chosen role, by email or as a shareable link.
Returns an array with the created invite: id, role, email, tailnetId, inviterId, lastEmailSentAt and inviteUrl when no email was sent or the email is outside the tailnet domain.
Use create_user_invites to onboard users. Use delete_user_invite to withdraw an invitation.

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `email` (`string`, optional): Email address to send the invite to, for example 'user@example.com'. If left blank no email is sent and the response contains an invite URL to share manually.
- `role` (`string`, optional): Role the invited user receives when they accept: member, admin, it-admin, network-admin, billing-admin or auditor. Defaults to member. One of: `member`, `admin`, `it-admin`, `network-admin`, `billing-admin`, `auditor`.
- `tailnet` (`string`, optional): Tailnet to operate on. Use '-' (a dash) for the default tailnet of the connected API token, or pass the organization name shown on the Tailscale admin console General settings page, for example 'example.com' or 'alice@gmail.com'. Default: `-`.

Example input: `{}`

### `tailscale_expire_device_key`

Expire Device Key · Write

Expire a device's node key so the device must re-authenticate before it can use the tailnet again.
Returns an empty JSON object on success.
Use expire_device_key to force a device to log in again. Use delete_device to remove the device entirely.

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `device_id` (`string`, required): ID of the device. The preferred form is the node ID returned as nodeId by the list devices tool (for example 'nABC123CNTRL'); the legacy numeric id (for example '12345') also works.

Example input: `{"device_id":"<device_id>"}`

### `tailscale_rename_device`

Rename Device · Write

Set the machine name of a device, which becomes its MagicDNS name.
Returns an empty JSON object on success.
Use rename_device to change a device's name. Names must be valid DNS labels.

Read only: no. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `device_id` (`string`, required): ID of the device. The preferred form is the node ID returned as nodeId by the list devices tool (for example 'nABC123CNTRL'); the legacy numeric id (for example '12345') also works.
- `name` (`string`, required): New machine name for the device, a valid DNS label such as 'web-server-1'. Do not include the tailnet domain suffix.

Example input: `{"device_id":"<device_id>","name":"<name>"}`

### `tailscale_set_device_key`

Update Device Key Settings · Write

Turn node key expiry on or off for a device.
Returns an empty JSON object on success.
Use set_device_key to stop a device's key from ever expiring or to restore expiry. Use expire_device_key to expire the key now.

Read only: no. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `device_id` (`string`, required): ID of the device. The preferred form is the node ID returned as nodeId by the list devices tool (for example 'nABC123CNTRL'); the legacy numeric id (for example '12345') also works.
- `key_expiry_disabled` (`boolean`, required): Set to true so the device's key never expires, or false to re-enable key expiry.

Example input: `{"device_id":"<device_id>","key_expiry_disabled":true}`

### `tailscale_set_device_routes`

Set Device Routes · Write

Set which of a device's advertised subnet routes are enabled. The list replaces the current enabled routes; an empty list disables all.
Returns advertisedRoutes and enabledRoutes after the change.
Use set_device_routes to approve or revoke subnet routes. Use get_device_routes to read the current state first.
Routes must already be advertised by the device.

Read only: no. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `device_id` (`string`, required): ID of the device. The preferred form is the node ID returned as nodeId by the list devices tool (for example 'nABC123CNTRL'); the legacy numeric id (for example '12345') also works.
- `routes` (`array`, required): Complete list of subnet routes to enable, as CIDR strings, for example ["10.0.0.0/16", "192.168.1.0/24"]. Routes not in this list become disabled; pass an empty array to disable all routes.

Example input: `{"device_id":"<device_id>","routes":[]}`

### `tailscale_set_device_tags`

Set Device Tags · Write

Replace the ACL tags on a device. Each tag must start with 'tag:' and be defined in the policy file's tagOwners.
Returns an empty JSON object on success.
Use set_device_tags to change a device's tags. Pass an empty list to remove all tags.

Read only: no. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `device_id` (`string`, required): ID of the device. The preferred form is the node ID returned as nodeId by the list devices tool (for example 'nABC123CNTRL'); the legacy numeric id (for example '12345') also works.
- `tags` (`array`, required): Complete list of tags for the device, for example ["tag:prod", "tag:server"]. Each tag must start with 'tag:' and be owned in the tailnet policy file. An empty array removes all tags.

Example input: `{"device_id":"<device_id>","tags":[]}`

### `tailscale_set_dns_nameservers`

Set DNS Nameservers · Write

Replace the global DNS nameservers for a tailnet. An empty list removes them.
Returns dns (the nameservers now set) and magicDNS (whether MagicDNS is on).
Use set_dns_nameservers to change global resolvers. Use update_split_dns or set_split_dns for per-domain resolvers.
Removing all nameservers automatically turns MagicDNS off.

Read only: no. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `dns` (`array`, required): Complete list of nameserver IP addresses to use, for example ["8.8.8.8", "1.1.1.1"]. An empty array clears the list.
- `tailnet` (`string`, optional): Tailnet to operate on. Use '-' (a dash) for the default tailnet of the connected API token, or pass the organization name shown on the Tailscale admin console General settings page, for example 'example.com' or 'alice@gmail.com'. Default: `-`.

Example input: `{"dns":[]}`

### `tailscale_set_dns_preferences`

Set DNS Preferences · Write

Turn MagicDNS on or off for a tailnet.
Returns magicDNS with the new status.
Use set_dns_preferences to toggle MagicDNS. Turning it on fails unless at least one global nameserver is set.

Read only: no. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `magic_dns` (`boolean`, required): Set to true to enable MagicDNS or false to disable it.
- `tailnet` (`string`, optional): Tailnet to operate on. Use '-' (a dash) for the default tailnet of the connected API token, or pass the organization name shown on the Tailscale admin console General settings page, for example 'example.com' or 'alice@gmail.com'. Default: `-`.

Example input: `{"magic_dns":true}`

### `tailscale_set_dns_search_paths`

Set DNS Search Paths · Write

Replace the DNS search paths for a tailnet. An empty list clears them.
Returns searchPaths, the search domains now set.
Use set_dns_search_paths to change search domains. Use get_dns_search_paths to read them first.

Read only: no. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `search_paths` (`array`, required): Complete list of DNS search domains, for example ["corp.example.com", "example.net"]. An empty array clears the list.
- `tailnet` (`string`, optional): Tailnet to operate on. Use '-' (a dash) for the default tailnet of the connected API token, or pass the organization name shown on the Tailscale admin console General settings page, for example 'example.com' or 'alice@gmail.com'. Default: `-`.

Example input: `{"search_paths":[]}`

### `tailscale_set_split_dns`

Set Split DNS · Write

Replace the entire split DNS map of a tailnet. Domains you leave out are removed.
Returns the split DNS map now in effect.
Use set_split_dns to overwrite all split DNS settings. Use update_split_dns to change only some domains.

Read only: no. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `split_dns` (`object`, required): Object mapping each domain to the list of nameserver IP addresses that should resolve it, for example {"internal.example.com": ["10.0.0.2"], "corp.example.net": ["10.0.0.3", "10.0.0.4"]}. This replaces all existing split DNS settings; an empty object removes them.
- `tailnet` (`string`, optional): Tailnet to operate on. Use '-' (a dash) for the default tailnet of the connected API token, or pass the organization name shown on the Tailscale admin console General settings page, for example 'example.com' or 'alice@gmail.com'. Default: `-`.

Example input: `{"split_dns":{}}`

### `tailscale_update_contact`

Update Contact · Write

Change the email address for one of a tailnet's contacts. A changed address is emailed a verification link.
Returns an empty JSON object on success.
Use update_contact to set the account, support or security contact. Use get_contacts to read current values.

Read only: no. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `contact_type` (`string`, required): Which contact to change: 'account' for billing and account notices, 'support' for support updates, or 'security' for security notices. One of: `account`, `support`, `security`.
- `email` (`string`, required): New email address for the contact, for example 'security@example.com'.
- `tailnet` (`string`, optional): Tailnet to operate on. Use '-' (a dash) for the default tailnet of the connected API token, or pass the organization name shown on the Tailscale admin console General settings page, for example 'example.com' or 'alice@gmail.com'. Default: `-`.

Example input: `{"contact_type":"account","email":"<email>"}`

### `tailscale_update_policy_file`

Update Policy File · Write

Replace the tailnet's entire access control policy file. Sections you leave out are removed.
Returns the saved policy as JSON; the call fails if the policy is malformed or its tests fail.
Use update_policy_file to change access rules. Call get_policy_file first and send back the full edited policy. Use validate_policy_file to check a policy without saving it.

Read only: no. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `policy` (`object`, required): The complete tailnet policy file as a JSON object, using the same sections as the admin console policy editor such as acls, grants, groups, hosts, tagOwners, autoApprovers, ssh, nodeAttrs and tests. Example: {"acls": [{"action": "accept", "src": ["*"], "dst": ["*:*"]}]}. This object fully replaces the existing policy file.
- `tailnet` (`string`, optional): Tailnet to operate on. Use '-' (a dash) for the default tailnet of the connected API token, or pass the organization name shown on the Tailscale admin console General settings page, for example 'example.com' or 'alice@gmail.com'. Default: `-`.

Example input: `{"policy":{}}`

### `tailscale_update_split_dns`

Update Split DNS · Write

Change split DNS for only the domains you name, leaving other domains untouched. A null value for a domain clears its nameservers.
Returns the full split DNS map after the update.
Use update_split_dns for partial changes. Use set_split_dns to replace the whole map.

Read only: no. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `split_dns` (`object`, required): Object mapping each domain to the list of nameserver IP addresses that should resolve it, for example {"internal.example.com": ["10.0.0.2"], "corp.example.net": ["10.0.0.3", "10.0.0.4"]}. Set a domain to null to clear its nameservers.
- `tailnet` (`string`, optional): Tailnet to operate on. Use '-' (a dash) for the default tailnet of the connected API token, or pass the organization name shown on the Tailscale admin console General settings page, for example 'example.com' or 'alice@gmail.com'. Default: `-`.

Example input: `{"split_dns":{}}`

### `tailscale_update_tailnet_settings`

Update Tailnet Settings · Write

Change one or more tailnet settings. Settings you leave blank stay as they are.
Returns an empty JSON object on success.
Use update_tailnet_settings to turn device approval, auto updates, flow logging or HTTPS on or off, or to change the key expiry duration.
Call get_tailnet_settings first to see current values.

Read only: no. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `devices_approval_on` (`boolean`, optional): Set to true to require an admin to approve new devices, or false to let them join freely.
- `devices_auto_updates_on` (`boolean`, optional): Set to true to turn on automatic Tailscale client updates for devices, or false to turn them off.
- `devices_key_duration_days` (`integer`, optional): Number of days before a device's node key expires, for example 90.
- `https_enabled` (`boolean`, optional): Set to true to enable HTTPS certificates for the tailnet, or false to disable them.
- `network_flow_logging_on` (`boolean`, optional): Set to true to turn on network flow logging for the tailnet, or false to turn it off.
- `posture_identity_collection_on` (`boolean`, optional): Set to true to let devices report posture identity such as serial numbers, or false to stop collection.
- `tailnet` (`string`, optional): Tailnet to operate on. Use '-' (a dash) for the default tailnet of the connected API token, or pass the organization name shown on the Tailscale admin console General settings page, for example 'example.com' or 'alice@gmail.com'. Default: `-`.
- `users_approval_on` (`boolean`, optional): Set to true to require an admin to approve new users, or false to let them join freely.

Example input: `{}`

### `tailscale_delete_device`

Delete Device · Destructive

Remove a device from its tailnet. The device must re-authenticate to rejoin.
Returns an empty JSON object on success.
Use delete_device to permanently remove a device. Use expire_device_key to force re-authentication while keeping the device entry.

Read only: no. Destructive: yes. Idempotent (safe to retry): yes.

Inputs:

- `device_id` (`string`, required): ID of the device. The preferred form is the node ID returned as nodeId by the list devices tool (for example 'nABC123CNTRL'); the legacy numeric id (for example '12345') also works.

Example input: `{"device_id":"<device_id>"}`

### `tailscale_delete_key`

Delete Key · Destructive

Revoke and delete an auth key, API access token or OAuth client.
Returns an empty JSON object on success.
Use delete_key to revoke a key permanently. Devices already registered with the key are not removed.

Read only: no. Destructive: yes. Idempotent (safe to retry): yes.

Inputs:

- `key_id` (`string`, required): ID of the key to delete, as returned by list_keys, for example 'kABC123CNTRL'.
- `tailnet` (`string`, optional): Tailnet to operate on. Use '-' (a dash) for the default tailnet of the connected API token, or pass the organization name shown on the Tailscale admin console General settings page, for example 'example.com' or 'alice@gmail.com'. Default: `-`.

Example input: `{"key_id":"<key_id>"}`

### `tailscale_delete_user_invite`

Delete User Invite · Destructive

Withdraw a pending user invitation so it can no longer be accepted.
Returns an empty JSON object on success.
Use delete_user_invite to cancel an invite. Use list_user_invites to find the ID.

Read only: no. Destructive: yes. Idempotent (safe to retry): yes.

Inputs:

- `user_invite_id` (`string`, required): ID of the user invite to delete, as returned by list_user_invites, for example '29214'.

Example input: `{"user_invite_id":"<user_invite_id>"}`

## Related

Other Developer Tools connectors ([all 117](/agentkit/connectors/?category=developer-tools)):

- [GitHub](/agentkit/connectors/github/): Scalekit connector, OAuth, 217 tools
- [Microsoft Entra ID](/agentkit/connectors/microsoftentraid/): Scalekit connector, OAuth, 82 tools
- [Datadog](/agentkit/connectors/datadog/): Scalekit connector, API key, 105 tools


---

## More Scalekit documentation

| Resource | What it contains | When to use it |
|----------|-----------------|----------------|
| [/llms.txt](/llms.txt) | Structured index with routing hints per product area | Start here — find which documentation set covers your topic before loading full content |
| [/llms-full.txt](/llms-full.txt) | Complete documentation for all Scalekit products in one file | Use when you need exhaustive context across multiple products or when the topic spans several areas |
| [sitemap-0.xml](https://docs.scalekit.com/sitemap-0.xml) | Full URL list of every documentation page | Use to discover specific page URLs you can fetch for targeted, page-level answers |
