Skip to content

Commit f01eba0

Browse files
committed
feat(tailscale): expand and validate API operations
1 parent 09d3bef commit f01eba0

53 files changed

Lines changed: 4652 additions & 1756 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎apps/docs/content/docs/integrations/tailscale.mdx‎

Lines changed: 792 additions & 200 deletions
Large diffs are not rendered by default.

‎apps/sim/blocks/blocks/tailscale.ts‎

Lines changed: 563 additions & 81 deletions
Large diffs are not rendered by default.

‎apps/sim/tools/generated/tool-ids.ts‎

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

‎apps/sim/tools/generated/tool-metadata.ts‎

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

‎apps/sim/tools/generated/tool-outputs.ts‎

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

‎apps/sim/tools/registry.ts‎

Lines changed: 49 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5938,30 +5938,46 @@ import {
59385938
tableUpsertRowTool,
59395939
} from '@/tools/table'
59405940
import {
5941+
tailscaleApproveUserTool,
59415942
tailscaleAuthorizeDeviceTool,
59425943
tailscaleCreateAuthKeyTool,
59435944
tailscaleDeleteAuthKeyTool,
5945+
tailscaleDeleteDeviceAttributeTool,
59445946
tailscaleDeleteDeviceTool,
59455947
tailscaleDeleteUserTool,
59465948
tailscaleExpireDeviceKeyTool,
59475949
tailscaleGetAclTool,
59485950
tailscaleGetAuthKeyTool,
5951+
tailscaleGetDeviceAttributesTool,
59495952
tailscaleGetDeviceRoutesTool,
59505953
tailscaleGetDeviceTool,
5954+
tailscaleGetDnsConfigurationTool,
59515955
tailscaleGetDnsPreferencesTool,
59525956
tailscaleGetDnsSearchpathsTool,
5957+
tailscaleGetSplitDnsTool,
5958+
tailscaleGetTailnetSettingsTool,
5959+
tailscaleGetUserTool,
59535960
tailscaleListAuthKeysTool,
59545961
tailscaleListDevicesTool,
59555962
tailscaleListDnsNameserversTool,
59565963
tailscaleListUsersTool,
5964+
tailscaleRestoreUserTool,
59575965
tailscaleSetAclTool,
5966+
tailscaleSetDeviceAttributeTool,
5967+
tailscaleSetDeviceNameTool,
59585968
tailscaleSetDeviceRoutesTool,
59595969
tailscaleSetDeviceTagsTool,
5970+
tailscaleSetDnsConfigurationTool,
59605971
tailscaleSetDnsNameserversTool,
59615972
tailscaleSetDnsPreferencesTool,
59625973
tailscaleSetDnsSearchpathsTool,
5974+
tailscaleSetSplitDnsTool,
5975+
tailscaleSetUserRoleTool,
59635976
tailscaleSuspendUserTool,
59645977
tailscaleUpdateDeviceKeyTool,
5978+
tailscaleUpdateSplitDnsTool,
5979+
tailscaleUpdateTailnetSettingsTool,
5980+
tailscaleValidateAclTool,
59655981
} from '@/tools/tailscale'
59665982
import { tavilyCrawlTool, tavilyExtractTool, tavilyMapTool, tavilySearchTool } from '@/tools/tavily'
59675983
import {
@@ -8251,30 +8267,46 @@ export const tools: Record<string, ExecutableToolConfig> = {
82518267
supabase_storage_get_public_url: supabaseStorageGetPublicUrlTool,
82528268
supabase_storage_create_signed_url: supabaseStorageCreateSignedUrlTool,
82538269
supabase_storage_create_signed_upload_url: supabaseStorageCreateSignedUploadUrlTool,
8254-
tailscale_list_devices: tailscaleListDevicesTool,
8255-
tailscale_get_device: tailscaleGetDeviceTool,
8256-
tailscale_delete_device: tailscaleDeleteDeviceTool,
8270+
tailscale_approve_user: tailscaleApproveUserTool,
82578271
tailscale_authorize_device: tailscaleAuthorizeDeviceTool,
8258-
tailscale_set_device_tags: tailscaleSetDeviceTagsTool,
8259-
tailscale_get_device_routes: tailscaleGetDeviceRoutesTool,
8260-
tailscale_set_device_routes: tailscaleSetDeviceRoutesTool,
8261-
tailscale_update_device_key: tailscaleUpdateDeviceKeyTool,
8272+
tailscale_create_auth_key: tailscaleCreateAuthKeyTool,
8273+
tailscale_delete_auth_key: tailscaleDeleteAuthKeyTool,
8274+
tailscale_delete_device: tailscaleDeleteDeviceTool,
8275+
tailscale_delete_device_attribute: tailscaleDeleteDeviceAttributeTool,
8276+
tailscale_delete_user: tailscaleDeleteUserTool,
82628277
tailscale_expire_device_key: tailscaleExpireDeviceKeyTool,
8278+
tailscale_get_acl: tailscaleGetAclTool,
8279+
tailscale_get_auth_key: tailscaleGetAuthKeyTool,
8280+
tailscale_get_device: tailscaleGetDeviceTool,
8281+
tailscale_get_device_attributes: tailscaleGetDeviceAttributesTool,
8282+
tailscale_get_device_routes: tailscaleGetDeviceRoutesTool,
8283+
tailscale_get_dns_configuration: tailscaleGetDnsConfigurationTool,
8284+
tailscale_get_dns_preferences: tailscaleGetDnsPreferencesTool,
8285+
tailscale_get_dns_searchpaths: tailscaleGetDnsSearchpathsTool,
8286+
tailscale_get_split_dns: tailscaleGetSplitDnsTool,
8287+
tailscale_get_tailnet_settings: tailscaleGetTailnetSettingsTool,
8288+
tailscale_get_user: tailscaleGetUserTool,
8289+
tailscale_list_auth_keys: tailscaleListAuthKeysTool,
8290+
tailscale_list_devices: tailscaleListDevicesTool,
82638291
tailscale_list_dns_nameservers: tailscaleListDnsNameserversTool,
8292+
tailscale_list_users: tailscaleListUsersTool,
8293+
tailscale_restore_user: tailscaleRestoreUserTool,
8294+
tailscale_set_acl: tailscaleSetAclTool,
8295+
tailscale_set_device_attribute: tailscaleSetDeviceAttributeTool,
8296+
tailscale_set_device_name: tailscaleSetDeviceNameTool,
8297+
tailscale_set_device_routes: tailscaleSetDeviceRoutesTool,
8298+
tailscale_set_device_tags: tailscaleSetDeviceTagsTool,
8299+
tailscale_set_dns_configuration: tailscaleSetDnsConfigurationTool,
82648300
tailscale_set_dns_nameservers: tailscaleSetDnsNameserversTool,
8265-
tailscale_get_dns_preferences: tailscaleGetDnsPreferencesTool,
82668301
tailscale_set_dns_preferences: tailscaleSetDnsPreferencesTool,
8267-
tailscale_get_dns_searchpaths: tailscaleGetDnsSearchpathsTool,
82688302
tailscale_set_dns_searchpaths: tailscaleSetDnsSearchpathsTool,
8269-
tailscale_list_users: tailscaleListUsersTool,
8303+
tailscale_set_split_dns: tailscaleSetSplitDnsTool,
8304+
tailscale_set_user_role: tailscaleSetUserRoleTool,
82708305
tailscale_suspend_user: tailscaleSuspendUserTool,
8271-
tailscale_delete_user: tailscaleDeleteUserTool,
8272-
tailscale_create_auth_key: tailscaleCreateAuthKeyTool,
8273-
tailscale_list_auth_keys: tailscaleListAuthKeysTool,
8274-
tailscale_get_auth_key: tailscaleGetAuthKeyTool,
8275-
tailscale_delete_auth_key: tailscaleDeleteAuthKeyTool,
8276-
tailscale_get_acl: tailscaleGetAclTool,
8277-
tailscale_set_acl: tailscaleSetAclTool,
8306+
tailscale_update_device_key: tailscaleUpdateDeviceKeyTool,
8307+
tailscale_update_split_dns: tailscaleUpdateSplitDnsTool,
8308+
tailscale_update_tailnet_settings: tailscaleUpdateTailnetSettingsTool,
8309+
tailscale_validate_acl: tailscaleValidateAclTool,
82788310
calendly_get_current_user: calendlyGetCurrentUserTool,
82798311
calendly_get_user: calendlyGetUserTool,
82808312
calendly_list_event_types: calendlyListEventTypesTool,
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import type { TailscaleApproveUserResponse, TailscaleUserParams } from '@/tools/tailscale/types'
2+
import { assertTailscaleResponse } from '@/tools/tailscale/utils'
3+
import type { ToolConfig } from '@/tools/types'
4+
import { safeUrlPathSegment } from '@/tools/url-path'
5+
6+
export const tailscaleApproveUserTool: ToolConfig<
7+
TailscaleUserParams,
8+
TailscaleApproveUserResponse
9+
> = {
10+
id: 'tailscale_approve_user',
11+
name: 'Tailscale Approve User',
12+
description: 'Approve a pending user to join the tailnet',
13+
version: '1.0.0',
14+
params: {
15+
apiKey: {
16+
type: 'string',
17+
required: true,
18+
visibility: 'user-only',
19+
description:
20+
'Tailscale API access token or OAuth access token (not an auth key or OAuth client secret)',
21+
},
22+
userId: {
23+
type: 'string',
24+
required: true,
25+
visibility: 'user-or-llm',
26+
description: 'Tailscale user ID',
27+
},
28+
},
29+
request: {
30+
url: (params) =>
31+
`https://api.tailscale.com/api/v2/users/${safeUrlPathSegment(params.userId, 'userId')}/approve`,
32+
method: 'POST',
33+
headers: (params) => ({
34+
Authorization: `Bearer ${params.apiKey.trim()}`,
35+
'Content-Type': 'application/json',
36+
}),
37+
},
38+
transformResponse: async (response, params) => {
39+
await assertTailscaleResponse(response)
40+
return { success: true, output: { success: true, userId: params?.userId ?? '' } }
41+
},
42+
outputs: {
43+
success: {
44+
type: 'boolean',
45+
description: 'Whether the operation succeeded',
46+
},
47+
userId: {
48+
type: 'string',
49+
description: 'ID of the affected user',
50+
},
51+
},
52+
}
Lines changed: 27 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
1+
import type {
2+
TailscaleAuthorizeDeviceParams,
3+
TailscaleAuthorizeDeviceResponse,
4+
} from '@/tools/tailscale/types'
5+
import { assertTailscaleResponse } from '@/tools/tailscale/utils'
16
import type { ToolConfig } from '@/tools/types'
2-
import type { TailscaleAuthorizeDeviceParams, TailscaleAuthorizeDeviceResponse } from './types'
7+
import { safeUrlPathSegment } from '@/tools/url-path'
38

49
export const tailscaleAuthorizeDeviceTool: ToolConfig<
510
TailscaleAuthorizeDeviceParams,
@@ -9,70 +14,60 @@ export const tailscaleAuthorizeDeviceTool: ToolConfig<
914
name: 'Tailscale Authorize Device',
1015
description: 'Authorize or deauthorize a device on the tailnet',
1116
version: '1.0.0',
12-
1317
params: {
1418
apiKey: {
1519
type: 'string',
1620
required: true,
1721
visibility: 'user-only',
18-
description: 'Tailscale API key',
19-
},
20-
tailnet: {
21-
type: 'string',
22-
required: true,
23-
visibility: 'user-or-llm',
24-
description: 'Tailnet name (e.g., example.com) or "-" for default',
22+
description:
23+
'Tailscale API access token or OAuth access token (not an auth key or OAuth client secret)',
2524
},
2625
deviceId: {
2726
type: 'string',
2827
required: true,
2928
visibility: 'user-or-llm',
30-
description: 'Device ID to authorize',
29+
description: 'Device nodeId (preferred) or legacy device ID',
3130
},
3231
authorized: {
3332
type: 'boolean',
3433
required: true,
3534
visibility: 'user-or-llm',
36-
description: 'Whether to authorize (true) or deauthorize (false) the device',
35+
description: 'Whether to authorize or deauthorize the device',
3736
},
3837
},
39-
4038
request: {
4139
url: (params) =>
42-
`https://api.tailscale.com/api/v2/device/${encodeURIComponent(params.deviceId.trim())}/authorized`,
40+
`https://api.tailscale.com/api/v2/device/${safeUrlPathSegment(params.deviceId, 'deviceId')}/authorized`,
4341
method: 'POST',
4442
headers: (params) => ({
4543
Authorization: `Bearer ${params.apiKey.trim()}`,
4644
'Content-Type': 'application/json',
4745
}),
48-
body: (params) => ({
49-
authorized: params.authorized,
50-
}),
46+
body: (params) => ({ authorized: params.authorized }),
5147
},
52-
53-
transformResponse: async (response: Response, params?: TailscaleAuthorizeDeviceParams) => {
54-
if (!response.ok) {
55-
const data = await response.json().catch(() => ({}))
56-
return {
57-
success: false,
58-
output: { success: false, deviceId: '', authorized: false },
59-
error: (data as Record<string, string>).message ?? 'Failed to authorize device',
60-
}
61-
}
62-
48+
transformResponse: async (response, params) => {
49+
await assertTailscaleResponse(response)
6350
return {
6451
success: true,
6552
output: {
6653
success: true,
6754
deviceId: params?.deviceId ?? '',
68-
authorized: params?.authorized ?? true,
55+
authorized: params?.authorized ?? false,
6956
},
7057
}
7158
},
72-
7359
outputs: {
74-
success: { type: 'boolean', description: 'Whether the operation succeeded' },
75-
deviceId: { type: 'string', description: 'Device ID' },
76-
authorized: { type: 'boolean', description: 'Authorization status after the operation' },
60+
success: {
61+
type: 'boolean',
62+
description: 'Whether the operation succeeded',
63+
},
64+
deviceId: {
65+
type: 'string',
66+
description: 'ID of the affected device',
67+
},
68+
authorized: {
69+
type: 'boolean',
70+
description: 'Requested device authorization state',
71+
},
7772
},
7873
}

0 commit comments

Comments
 (0)