tailscale-mcp 2026.3.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/.env.example +17 -0
  2. package/ARCHITECTURE.md +220 -0
  3. package/CHANGELOG.md +93 -0
  4. package/CLAUDE.md +180 -0
  5. package/COMMERCIAL_LICENSE.md +44 -0
  6. package/CONTRIBUTING.md +54 -0
  7. package/LICENSE +661 -0
  8. package/PRODUCT_PACKAGING.md +138 -0
  9. package/README.md +276 -0
  10. package/ROADMAP.md +67 -0
  11. package/SECURITY.md +24 -0
  12. package/dist/client/client-factory.d.ts +12 -0
  13. package/dist/client/client-factory.d.ts.map +1 -0
  14. package/dist/client/client-factory.js +31 -0
  15. package/dist/client/client-factory.js.map +1 -0
  16. package/dist/client/tailscale-client.d.ts +18 -0
  17. package/dist/client/tailscale-client.d.ts.map +1 -0
  18. package/dist/client/tailscale-client.js +101 -0
  19. package/dist/client/tailscale-client.js.map +1 -0
  20. package/dist/client/tailscale-oauth-client.d.ts +19 -0
  21. package/dist/client/tailscale-oauth-client.d.ts.map +1 -0
  22. package/dist/client/tailscale-oauth-client.js +119 -0
  23. package/dist/client/tailscale-oauth-client.js.map +1 -0
  24. package/dist/client/types.d.ts +281 -0
  25. package/dist/client/types.d.ts.map +1 -0
  26. package/dist/client/types.js +3 -0
  27. package/dist/client/types.js.map +1 -0
  28. package/dist/index.d.ts +2 -0
  29. package/dist/index.d.ts.map +1 -0
  30. package/dist/index.js +100 -0
  31. package/dist/index.js.map +1 -0
  32. package/dist/tools/acl.d.ts +80 -0
  33. package/dist/tools/acl.d.ts.map +1 -0
  34. package/dist/tools/acl.js +180 -0
  35. package/dist/tools/acl.js.map +1 -0
  36. package/dist/tools/devices.d.ts +162 -0
  37. package/dist/tools/devices.d.ts.map +1 -0
  38. package/dist/tools/devices.js +347 -0
  39. package/dist/tools/devices.js.map +1 -0
  40. package/dist/tools/diagnostics.d.ts +65 -0
  41. package/dist/tools/diagnostics.d.ts.map +1 -0
  42. package/dist/tools/diagnostics.js +178 -0
  43. package/dist/tools/diagnostics.js.map +1 -0
  44. package/dist/tools/dns.d.ts +98 -0
  45. package/dist/tools/dns.d.ts.map +1 -0
  46. package/dist/tools/dns.js +179 -0
  47. package/dist/tools/dns.js.map +1 -0
  48. package/dist/tools/keys.d.ts +107 -0
  49. package/dist/tools/keys.d.ts.map +1 -0
  50. package/dist/tools/keys.js +167 -0
  51. package/dist/tools/keys.js.map +1 -0
  52. package/dist/tools/posture.d.ts +98 -0
  53. package/dist/tools/posture.d.ts.map +1 -0
  54. package/dist/tools/posture.js +155 -0
  55. package/dist/tools/posture.js.map +1 -0
  56. package/dist/tools/tailnet.d.ts +132 -0
  57. package/dist/tools/tailnet.d.ts.map +1 -0
  58. package/dist/tools/tailnet.js +222 -0
  59. package/dist/tools/tailnet.js.map +1 -0
  60. package/dist/tools/users.d.ts +44 -0
  61. package/dist/tools/users.d.ts.map +1 -0
  62. package/dist/tools/users.js +90 -0
  63. package/dist/tools/users.js.map +1 -0
  64. package/dist/tools/webhooks.d.ts +88 -0
  65. package/dist/tools/webhooks.d.ts.map +1 -0
  66. package/dist/tools/webhooks.js +168 -0
  67. package/dist/tools/webhooks.js.map +1 -0
  68. package/dist/transport.d.ts +13 -0
  69. package/dist/transport.d.ts.map +1 -0
  70. package/dist/transport.js +42 -0
  71. package/dist/transport.js.map +1 -0
  72. package/dist/utils/errors.d.ts +8 -0
  73. package/dist/utils/errors.d.ts.map +1 -0
  74. package/dist/utils/errors.js +42 -0
  75. package/dist/utils/errors.js.map +1 -0
  76. package/dist/utils/validation.d.ts +18 -0
  77. package/dist/utils/validation.d.ts.map +1 -0
  78. package/dist/utils/validation.js +35 -0
  79. package/dist/utils/validation.js.map +1 -0
  80. package/package.json +55 -0
  81. package/vitest.config.ts +8 -0
@@ -0,0 +1,347 @@
1
+ import { z } from "zod";
2
+ import { DeviceIdSchema } from "../utils/validation.js";
3
+ // ---------------------------------------------------------------------------
4
+ // Zod schemas for input validation
5
+ // ---------------------------------------------------------------------------
6
+ const DeviceListSchema = z.object({});
7
+ const DeviceGetSchema = z.object({
8
+ deviceId: DeviceIdSchema,
9
+ });
10
+ const DeviceDeleteSchema = z.object({
11
+ deviceId: DeviceIdSchema,
12
+ confirm: z.literal(true, {
13
+ errorMap: () => ({ message: "confirm must be true to delete a device" }),
14
+ }),
15
+ });
16
+ const DeviceAuthorizeSchema = z.object({
17
+ deviceId: DeviceIdSchema,
18
+ });
19
+ const DeviceRoutesGetSchema = z.object({
20
+ deviceId: DeviceIdSchema,
21
+ });
22
+ const DeviceRoutesSetSchema = z.object({
23
+ deviceId: DeviceIdSchema,
24
+ routes: z.array(z.string()).min(1, "At least one route is required"),
25
+ });
26
+ const DeviceTagsSetSchema = z.object({
27
+ deviceId: DeviceIdSchema,
28
+ tags: z.array(z.string()),
29
+ });
30
+ const DevicePostureGetSchema = z.object({
31
+ deviceId: DeviceIdSchema,
32
+ });
33
+ const DeviceExpireSchema = z.object({
34
+ deviceId: DeviceIdSchema,
35
+ confirm: z.literal(true, {
36
+ errorMap: () => ({ message: "confirm must be true to expire a device key" }),
37
+ }),
38
+ });
39
+ const DeviceRenameSchema = z.object({
40
+ deviceId: DeviceIdSchema,
41
+ name: z.string().min(1, "Device name is required").max(255, "Device name too long"),
42
+ });
43
+ const DevicePostureSetSchema = z.object({
44
+ deviceId: DeviceIdSchema,
45
+ attributeKey: z.string().min(1, "Attribute key is required"),
46
+ value: z.union([z.string(), z.boolean(), z.number()]),
47
+ });
48
+ // ---------------------------------------------------------------------------
49
+ // Tool definitions (for ListTools)
50
+ // ---------------------------------------------------------------------------
51
+ export const deviceToolDefinitions = [
52
+ {
53
+ name: "tailscale_device_list",
54
+ description: "List all devices in the tailnet. Returns all registered devices with their IP addresses, hostname, OS, and connection status.",
55
+ inputSchema: {
56
+ type: "object",
57
+ properties: {},
58
+ },
59
+ },
60
+ {
61
+ name: "tailscale_device_get",
62
+ description: "Get details of a specific device by its ID.",
63
+ inputSchema: {
64
+ type: "object",
65
+ properties: {
66
+ deviceId: {
67
+ type: "string",
68
+ description: "Tailscale device ID (numeric string)",
69
+ },
70
+ },
71
+ required: ["deviceId"],
72
+ },
73
+ },
74
+ {
75
+ name: "tailscale_device_delete",
76
+ description: "Delete a device from the tailnet. This removes the device and revokes its access. Requires confirm: true.",
77
+ inputSchema: {
78
+ type: "object",
79
+ properties: {
80
+ deviceId: {
81
+ type: "string",
82
+ description: "Tailscale device ID to delete",
83
+ },
84
+ confirm: {
85
+ type: "boolean",
86
+ description: "Must be true to confirm device deletion",
87
+ },
88
+ },
89
+ required: ["deviceId", "confirm"],
90
+ },
91
+ },
92
+ {
93
+ name: "tailscale_device_authorize",
94
+ description: "Authorize a device that is pending approval. Sets the device's authorized status to true.",
95
+ inputSchema: {
96
+ type: "object",
97
+ properties: {
98
+ deviceId: {
99
+ type: "string",
100
+ description: "Tailscale device ID to authorize",
101
+ },
102
+ },
103
+ required: ["deviceId"],
104
+ },
105
+ },
106
+ {
107
+ name: "tailscale_device_routes_get",
108
+ description: "Get the advertised and enabled subnet routes for a device.",
109
+ inputSchema: {
110
+ type: "object",
111
+ properties: {
112
+ deviceId: {
113
+ type: "string",
114
+ description: "Tailscale device ID",
115
+ },
116
+ },
117
+ required: ["deviceId"],
118
+ },
119
+ },
120
+ {
121
+ name: "tailscale_device_routes_set",
122
+ description: "Set the enabled subnet routes for a device. Replaces the current set of enabled routes.",
123
+ inputSchema: {
124
+ type: "object",
125
+ properties: {
126
+ deviceId: {
127
+ type: "string",
128
+ description: "Tailscale device ID",
129
+ },
130
+ routes: {
131
+ type: "array",
132
+ items: { type: "string" },
133
+ description: "List of CIDR routes to enable (e.g., ['10.0.0.0/8', '192.168.1.0/24'])",
134
+ },
135
+ },
136
+ required: ["deviceId", "routes"],
137
+ },
138
+ },
139
+ {
140
+ name: "tailscale_device_tags_set",
141
+ description: "Set ACL tags on a device. Replaces all existing tags. Use an empty array to remove all tags.",
142
+ inputSchema: {
143
+ type: "object",
144
+ properties: {
145
+ deviceId: {
146
+ type: "string",
147
+ description: "Tailscale device ID",
148
+ },
149
+ tags: {
150
+ type: "array",
151
+ items: { type: "string" },
152
+ description: "List of ACL tags to set (e.g., ['tag:server', 'tag:prod']). Use empty array to clear tags.",
153
+ },
154
+ },
155
+ required: ["deviceId", "tags"],
156
+ },
157
+ },
158
+ {
159
+ name: "tailscale_device_posture_get",
160
+ description: "Get custom posture attributes for a device. Returns all key-value posture attributes.",
161
+ inputSchema: {
162
+ type: "object",
163
+ properties: {
164
+ deviceId: {
165
+ type: "string",
166
+ description: "Tailscale device ID",
167
+ },
168
+ },
169
+ required: ["deviceId"],
170
+ },
171
+ },
172
+ {
173
+ name: "tailscale_device_posture_set",
174
+ description: "Set a custom posture attribute on a device. Creates or updates a single attribute key-value pair.",
175
+ inputSchema: {
176
+ type: "object",
177
+ properties: {
178
+ deviceId: {
179
+ type: "string",
180
+ description: "Tailscale device ID",
181
+ },
182
+ attributeKey: {
183
+ type: "string",
184
+ description: "Posture attribute key (e.g., 'custom:compliance-status')",
185
+ },
186
+ value: {
187
+ description: "Attribute value (string, boolean, or number)",
188
+ },
189
+ },
190
+ required: ["deviceId", "attributeKey", "value"],
191
+ },
192
+ },
193
+ {
194
+ name: "tailscale_device_expire",
195
+ description: "Expire a device's key, forcing it to re-authenticate. The device remains in the tailnet but loses connectivity until re-authenticated. This is one-directional — once expired, the device must re-auth. Requires confirm: true.",
196
+ inputSchema: {
197
+ type: "object",
198
+ properties: {
199
+ deviceId: {
200
+ type: "string",
201
+ description: "Tailscale device ID",
202
+ },
203
+ confirm: {
204
+ type: "boolean",
205
+ description: "Must be true to confirm key expiry",
206
+ },
207
+ },
208
+ required: ["deviceId", "confirm"],
209
+ },
210
+ },
211
+ {
212
+ name: "tailscale_device_rename",
213
+ description: "Set a custom display name for a device. This changes the device's 'given name' in Tailscale, not the machine hostname.",
214
+ inputSchema: {
215
+ type: "object",
216
+ properties: {
217
+ deviceId: {
218
+ type: "string",
219
+ description: "Tailscale device ID",
220
+ },
221
+ name: {
222
+ type: "string",
223
+ description: "New display name for the device",
224
+ },
225
+ },
226
+ required: ["deviceId", "name"],
227
+ },
228
+ },
229
+ ];
230
+ // ---------------------------------------------------------------------------
231
+ // Tool handler
232
+ // ---------------------------------------------------------------------------
233
+ export async function handleDeviceTool(name, args, client) {
234
+ try {
235
+ switch (name) {
236
+ case "tailscale_device_list": {
237
+ DeviceListSchema.parse(args);
238
+ const result = await client.get(`/tailnet/${client.tailnet}/devices`);
239
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
240
+ }
241
+ case "tailscale_device_get": {
242
+ const parsed = DeviceGetSchema.parse(args);
243
+ const result = await client.get(`/device/${parsed.deviceId}`);
244
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
245
+ }
246
+ case "tailscale_device_delete": {
247
+ const parsed = DeviceDeleteSchema.parse(args);
248
+ await client.deleteVoid(`/device/${parsed.deviceId}`);
249
+ return {
250
+ content: [
251
+ {
252
+ type: "text",
253
+ text: JSON.stringify({ deleted: true, deviceId: parsed.deviceId }, null, 2),
254
+ },
255
+ ],
256
+ };
257
+ }
258
+ case "tailscale_device_authorize": {
259
+ const parsed = DeviceAuthorizeSchema.parse(args);
260
+ await client.postVoid(`/device/${parsed.deviceId}/authorized`, {
261
+ authorized: true,
262
+ });
263
+ return {
264
+ content: [
265
+ {
266
+ type: "text",
267
+ text: JSON.stringify({ authorized: true, deviceId: parsed.deviceId }, null, 2),
268
+ },
269
+ ],
270
+ };
271
+ }
272
+ case "tailscale_device_routes_get": {
273
+ const parsed = DeviceRoutesGetSchema.parse(args);
274
+ const result = await client.get(`/device/${parsed.deviceId}/routes`);
275
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
276
+ }
277
+ case "tailscale_device_routes_set": {
278
+ const parsed = DeviceRoutesSetSchema.parse(args);
279
+ const result = await client.post(`/device/${parsed.deviceId}/routes`, { routes: parsed.routes });
280
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
281
+ }
282
+ case "tailscale_device_tags_set": {
283
+ const parsed = DeviceTagsSetSchema.parse(args);
284
+ await client.postVoid(`/device/${parsed.deviceId}/tags`, {
285
+ tags: parsed.tags,
286
+ });
287
+ return {
288
+ content: [
289
+ {
290
+ type: "text",
291
+ text: JSON.stringify({ tags: parsed.tags, deviceId: parsed.deviceId }, null, 2),
292
+ },
293
+ ],
294
+ };
295
+ }
296
+ case "tailscale_device_posture_get": {
297
+ const parsed = DevicePostureGetSchema.parse(args);
298
+ const result = await client.get(`/device/${parsed.deviceId}/attributes`);
299
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
300
+ }
301
+ case "tailscale_device_posture_set": {
302
+ const parsed = DevicePostureSetSchema.parse(args);
303
+ const result = await client.post(`/device/${parsed.deviceId}/attributes/${parsed.attributeKey}`, { value: parsed.value });
304
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
305
+ }
306
+ case "tailscale_device_expire": {
307
+ const parsed = DeviceExpireSchema.parse(args);
308
+ await client.postVoid(`/device/${parsed.deviceId}/key`, {
309
+ keyExpiryDisabled: false,
310
+ });
311
+ return {
312
+ content: [
313
+ {
314
+ type: "text",
315
+ text: JSON.stringify({ expired: true, deviceId: parsed.deviceId }, null, 2),
316
+ },
317
+ ],
318
+ };
319
+ }
320
+ case "tailscale_device_rename": {
321
+ const parsed = DeviceRenameSchema.parse(args);
322
+ await client.postVoid(`/device/${parsed.deviceId}/name`, {
323
+ name: parsed.name,
324
+ });
325
+ return {
326
+ content: [
327
+ {
328
+ type: "text",
329
+ text: JSON.stringify({ renamed: true, deviceId: parsed.deviceId, name: parsed.name }, null, 2),
330
+ },
331
+ ],
332
+ };
333
+ }
334
+ default:
335
+ return {
336
+ content: [{ type: "text", text: `Unknown device tool: ${name}` }],
337
+ };
338
+ }
339
+ }
340
+ catch (error) {
341
+ const message = error instanceof Error ? error.message : "Unknown error";
342
+ return {
343
+ content: [{ type: "text", text: `Error executing ${name}: ${message}` }],
344
+ };
345
+ }
346
+ }
347
+ //# sourceMappingURL=devices.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"devices.js","sourceRoot":"","sources":["../../src/tools/devices.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,65 @@
1
+ import type { ITailscaleClient } from "../client/types.js";
2
+ export declare const diagnosticsToolDefinitions: ({
3
+ name: string;
4
+ description: string;
5
+ inputSchema: {
6
+ type: "object";
7
+ properties: {
8
+ logType?: undefined;
9
+ destinationType?: undefined;
10
+ url?: undefined;
11
+ confirm?: undefined;
12
+ };
13
+ required?: undefined;
14
+ };
15
+ } | {
16
+ name: string;
17
+ description: string;
18
+ inputSchema: {
19
+ type: "object";
20
+ properties: {
21
+ logType: {
22
+ type: string;
23
+ enum: string[];
24
+ description: string;
25
+ };
26
+ destinationType?: undefined;
27
+ url?: undefined;
28
+ confirm?: undefined;
29
+ };
30
+ required: string[];
31
+ };
32
+ } | {
33
+ name: string;
34
+ description: string;
35
+ inputSchema: {
36
+ type: "object";
37
+ properties: {
38
+ logType: {
39
+ type: string;
40
+ enum: string[];
41
+ description: string;
42
+ };
43
+ destinationType: {
44
+ type: string;
45
+ description: string;
46
+ };
47
+ url: {
48
+ type: string;
49
+ description: string;
50
+ };
51
+ confirm: {
52
+ type: string;
53
+ description: string;
54
+ };
55
+ };
56
+ required: string[];
57
+ };
58
+ })[];
59
+ export declare function handleDiagnosticsTool(name: string, args: Record<string, unknown>, client: ITailscaleClient): Promise<{
60
+ content: Array<{
61
+ type: "text";
62
+ text: string;
63
+ }>;
64
+ }>;
65
+ //# sourceMappingURL=diagnostics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostics.d.ts","sourceRoot":"","sources":["../../src/tools/diagnostics.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAkC3D,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAwEtC,CAAC;AAMF,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,MAAM,EAAE,gBAAgB,GACvB,OAAO,CAAC;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,CAAC,CAsG7D"}
@@ -0,0 +1,178 @@
1
+ import { z } from "zod";
2
+ // ---------------------------------------------------------------------------
3
+ // Zod schemas for input validation
4
+ // ---------------------------------------------------------------------------
5
+ const StatusSchema = z.object({});
6
+ const ApiVerifySchema = z.object({});
7
+ const LogStreamGetSchema = z.object({
8
+ logType: z.enum(["configuration", "network"], {
9
+ errorMap: () => ({ message: "logType must be 'configuration' or 'network'" }),
10
+ }),
11
+ });
12
+ const LogStreamSetSchema = z.object({
13
+ logType: z.enum(["configuration", "network"], {
14
+ errorMap: () => ({ message: "logType must be 'configuration' or 'network'" }),
15
+ }),
16
+ destinationType: z.string().min(1, "destinationType is required"),
17
+ url: z.string().url("Invalid log stream URL"),
18
+ confirm: z.literal(true, {
19
+ errorMap: () => ({ message: "confirm must be true to set a log stream configuration" }),
20
+ }),
21
+ });
22
+ const DerpMapSchema = z.object({});
23
+ // ---------------------------------------------------------------------------
24
+ // Tool definitions (for ListTools)
25
+ // ---------------------------------------------------------------------------
26
+ export const diagnosticsToolDefinitions = [
27
+ {
28
+ name: "tailscale_status",
29
+ description: "Get a summary of the tailnet status including total device count, online/offline counts, and last-seen timestamps.",
30
+ inputSchema: {
31
+ type: "object",
32
+ properties: {},
33
+ },
34
+ },
35
+ {
36
+ name: "tailscale_api_verify",
37
+ description: "Verify API connectivity and authentication by making a lightweight request to the Tailscale API.",
38
+ inputSchema: {
39
+ type: "object",
40
+ properties: {},
41
+ },
42
+ },
43
+ {
44
+ name: "tailscale_log_stream_get",
45
+ description: "Get the current log streaming configuration for the tailnet. Log types: 'configuration' or 'network'.",
46
+ inputSchema: {
47
+ type: "object",
48
+ properties: {
49
+ logType: {
50
+ type: "string",
51
+ enum: ["configuration", "network"],
52
+ description: "Type of logs to retrieve the streaming config for",
53
+ },
54
+ },
55
+ required: ["logType"],
56
+ },
57
+ },
58
+ {
59
+ name: "tailscale_log_stream_set",
60
+ description: "Configure log streaming for the tailnet. Requires confirm: true. Streams logs to a specified URL endpoint.",
61
+ inputSchema: {
62
+ type: "object",
63
+ properties: {
64
+ logType: {
65
+ type: "string",
66
+ enum: ["configuration", "network"],
67
+ description: "Type of logs to stream",
68
+ },
69
+ destinationType: {
70
+ type: "string",
71
+ description: "Destination type for log streaming (e.g., 'panther')",
72
+ },
73
+ url: {
74
+ type: "string",
75
+ description: "URL endpoint to stream logs to",
76
+ },
77
+ confirm: {
78
+ type: "boolean",
79
+ description: "Must be true to confirm log stream configuration change",
80
+ },
81
+ },
82
+ required: ["logType", "destinationType", "url", "confirm"],
83
+ },
84
+ },
85
+ {
86
+ name: "tailscale_derp_map",
87
+ description: "Get the DERP relay map for the tailnet. Shows all DERP regions and their relay nodes used for traffic routing.",
88
+ inputSchema: {
89
+ type: "object",
90
+ properties: {},
91
+ },
92
+ },
93
+ ];
94
+ // ---------------------------------------------------------------------------
95
+ // Tool handler
96
+ // ---------------------------------------------------------------------------
97
+ export async function handleDiagnosticsTool(name, args, client) {
98
+ try {
99
+ switch (name) {
100
+ case "tailscale_status": {
101
+ StatusSchema.parse(args);
102
+ const result = await client.get(`/tailnet/${client.tailnet}/devices`);
103
+ const devices = result.devices ?? [];
104
+ const now = new Date();
105
+ const onlineThresholdMs = 5 * 60 * 1000; // 5 minutes
106
+ const onlineDevices = devices.filter((d) => {
107
+ if (!d.lastSeen)
108
+ return false;
109
+ const lastSeenMs = new Date(d.lastSeen).getTime();
110
+ return now.getTime() - lastSeenMs < onlineThresholdMs;
111
+ });
112
+ const status = {
113
+ tailnet: client.tailnet,
114
+ deviceCount: devices.length,
115
+ onlineDevices: onlineDevices.length,
116
+ offlineDevices: devices.length - onlineDevices.length,
117
+ devices: devices.map((d) => ({
118
+ id: d.id,
119
+ name: d.name,
120
+ hostname: d.hostname,
121
+ os: d.os,
122
+ addresses: d.addresses,
123
+ lastSeen: d.lastSeen,
124
+ authorized: d.authorized,
125
+ })),
126
+ };
127
+ return { content: [{ type: "text", text: JSON.stringify(status, null, 2) }] };
128
+ }
129
+ case "tailscale_api_verify": {
130
+ ApiVerifySchema.parse(args);
131
+ const result = await client.get(`/tailnet/${client.tailnet}/devices`, { per_page: 1 });
132
+ const deviceCount = (result.devices ?? []).length;
133
+ return {
134
+ content: [
135
+ {
136
+ type: "text",
137
+ text: JSON.stringify({
138
+ connected: true,
139
+ tailnet: client.tailnet,
140
+ deviceCount,
141
+ message: "Tailscale API connection verified successfully",
142
+ }, null, 2),
143
+ },
144
+ ],
145
+ };
146
+ }
147
+ case "tailscale_log_stream_get": {
148
+ const parsed = LogStreamGetSchema.parse(args);
149
+ const result = await client.get(`/tailnet/${client.tailnet}/logging/${parsed.logType}/stream`);
150
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
151
+ }
152
+ case "tailscale_log_stream_set": {
153
+ const parsed = LogStreamSetSchema.parse(args);
154
+ const result = await client.put(`/tailnet/${client.tailnet}/logging/${parsed.logType}/stream`, {
155
+ destinationType: parsed.destinationType,
156
+ url: parsed.url,
157
+ });
158
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
159
+ }
160
+ case "tailscale_derp_map": {
161
+ DerpMapSchema.parse(args);
162
+ const result = await client.get(`/tailnet/${client.tailnet}/derp-map`);
163
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
164
+ }
165
+ default:
166
+ return {
167
+ content: [{ type: "text", text: `Unknown diagnostics tool: ${name}` }],
168
+ };
169
+ }
170
+ }
171
+ catch (error) {
172
+ const message = error instanceof Error ? error.message : "Unknown error";
173
+ return {
174
+ content: [{ type: "text", text: `Error executing ${name}: ${message}` }],
175
+ };
176
+ }
177
+ }
178
+ //# sourceMappingURL=diagnostics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostics.js","sourceRoot":"","sources":["../../src/tools/diagnostics.ts"],"names":[],"mappings":"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"}