Skip to content

feat(tailscale): add Tailscale integration with 20 API operations#3868

Merged
waleedlatif1 merged 3 commits intostagingfrom
waleedlatif1/add-tailscale
Mar 31, 2026
Merged

feat(tailscale): add Tailscale integration with 20 API operations#3868
waleedlatif1 merged 3 commits intostagingfrom
waleedlatif1/add-tailscale

Conversation

@waleedlatif1
Copy link
Copy Markdown
Collaborator

Summary

  • Add complete Tailscale integration with 20 API operations
  • Device management: list, get, delete, authorize, set tags, update key
  • Route management: get and set device routes
  • DNS management: nameservers, preferences, search paths (get/set each)
  • Auth key management: create, list, get, delete
  • ACL retrieval and user listing
  • API key auth with Bearer token

Type of Change

  • New feature

Testing

Tested manually

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

@vercel
Copy link
Copy Markdown

vercel bot commented Mar 31, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Mar 31, 2026 11:16pm

Request Review

@cursor
Copy link
Copy Markdown

cursor bot commented Mar 31, 2026

PR Summary

Medium Risk
Introduces new security/network-management API calls (device deletion, ACL retrieval, DNS/route changes) and wires them into the block/tool registries; incorrect parameter mapping or API handling could cause disruptive tailnet changes.

Overview
Adds a new Tailscale block and wires it into the Sim block registry, landing-page integrations list, and icon mappings, including a new TailscaleIcon.

Implements and registers 20 new tailscale_* tools that call the Tailscale API (device lifecycle/authorization/tags, routes, DNS nameservers/preferences/search paths, users, auth keys, and ACL retrieval) using API-key Bearer auth with request/response shaping.

Updates docs by adding tools/tailscale.mdx and including tailscale in tools/meta.json so the integration appears in the docs navigation.

Written by Cursor Bugbot for commit 8c0616a. Configure here.

@waleedlatif1 waleedlatif1 changed the base branch from main to staging March 31, 2026 23:02
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Mar 31, 2026

Greptile Summary

This PR adds a complete Tailscale integration with 20 API operations covering device management, DNS configuration, auth key lifecycle, ACL retrieval, and user listing. The implementation follows the established tool pattern used across the codebase and is generally well-executed.

Key highlights:

  • All 20 tools correctly check response.ok before calling .json(), with a .catch(() => ({})) guard on the error branch — the pattern is now consistent throughout.
  • apiKey.trim() is applied in every tool's Authorization header.
  • The expirySeconds null/undefined guard in create_auth_key.ts was fixed to use an explicit !== undefined && !== null check.
  • The block's single params-mapper design keeps the block config simple at the cost of passing a few extra (harmless) fields to tools that don't need them.
  • One minor remaining issue: the block's expirySeconds mapper uses Number(params.expirySeconds) without an isNaN guard, meaning a non-numeric user input would serialize as null in JSON and produce an unclear API error.

Confidence Score: 5/5

Safe to merge — all prior P1 concerns are resolved and only a minor input-validation improvement remains.

All three previously identified issues (unconditional .json(), missing apiKey.trim(), and the falsy expirySeconds check) are confirmed fixed in the head commit. The only remaining finding is a P2 style suggestion around NaN serialization for non-numeric expirySeconds input, which does not cause silent data loss.

apps/sim/blocks/blocks/tailscale.ts line 275 — Number() without isNaN guard for expirySeconds.

Important Files Changed

Filename Overview
apps/sim/blocks/blocks/tailscale.ts Block config for 20 Tailscale operations with correct conditional visibility and param mapping. Minor: Number(params.expirySeconds) can produce NaN for non-numeric input.
apps/sim/tools/tailscale/create_auth_key.ts Auth key creation with correct Tailscale request body format; expirySeconds null/undefined guard is properly fixed; tag splitting and capability mapping look correct.
apps/sim/tools/tailscale/list_devices.ts Correct response.ok guard before .json() and apiKey.trim() applied; device field mapping is comprehensive.
apps/sim/tools/tailscale/get_acl.ts Correctly uses Accept: application/json to force JSON response format; ETag is captured from headers and handled gracefully with ?? ''.
apps/sim/tools/tailscale/types.ts Comprehensive type definitions for all Tailscale tool params and responses; properly extends ToolResponse.
apps/sim/tools/tailscale/set_device_routes.ts Correctly parses comma-separated route strings into an array for the Tailscale API body; response mapping uses API data.
apps/sim/tools/tailscale/authorize_device.ts Correct authorized: boolean body sent to Tailscale; response echoes params since the API returns an empty 200 body.
apps/sim/tools/tailscale/list_auth_keys.ts Correctly navigates nested capabilities.devices.create structure from the Tailscale API response.
apps/sim/tools/tailscale/set_dns_preferences.ts MagicDNS boolean is correctly sent; block mapper properly converts 'true'/'false' strings to booleans before passing to this tool.

Sequence Diagram

sequenceDiagram
    participant User as User / Workflow
    participant Block as TailscaleBlock
    participant Mapper as params mapper
    participant Tool as Tool (e.g. tailscale_create_auth_key)
    participant API as Tailscale API

    User->>Block: Select operation + fill inputs
    Block->>Mapper: tool: `tailscale_${operation}`<br/>params: map UI fields → typed params
    Mapper->>Tool: { apiKey, tailnet, deviceId?, tags?, ... }
    Tool->>API: HTTP request<br/>Authorization: Bearer apiKey.trim()
    alt response.ok
        API-->>Tool: 200 JSON body
        Tool-->>Block: { success: true, output: { ... } }
    else error
        API-->>Tool: 4xx/5xx (JSON or non-JSON)
        Tool-->>Block: { success: false, error: message ?? fallback }
    end
    Block-->>User: output fields available downstream
Loading

Reviews (2): Last reviewed commit: "fix(tailscale): safe response.json() pat..." | Re-trigger Greptile

@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

@cursor review

Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

@waleedlatif1 waleedlatif1 merged commit d99dd86 into staging Mar 31, 2026
12 checks passed
@waleedlatif1 waleedlatif1 deleted the waleedlatif1/add-tailscale branch March 31, 2026 23:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant