@yawlabs/tailscale-mcp 0.1.6 → 0.2.0

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 (54) hide show
  1. package/README.md +73 -7
  2. package/dist/api.js +2 -2
  3. package/dist/api.js.map +1 -1
  4. package/dist/index.js +59 -8
  5. package/dist/index.js.map +1 -1
  6. package/dist/tools/acl.d.ts +28 -0
  7. package/dist/tools/acl.js +33 -4
  8. package/dist/tools/acl.js.map +1 -1
  9. package/dist/tools/audit.d.ts +14 -0
  10. package/dist/tools/audit.js +19 -15
  11. package/dist/tools/audit.js.map +1 -1
  12. package/dist/tools/devices.d.ts +91 -0
  13. package/dist/tools/devices.js +102 -4
  14. package/dist/tools/devices.js.map +1 -1
  15. package/dist/tools/dns.d.ts +56 -0
  16. package/dist/tools/dns.js +57 -1
  17. package/dist/tools/dns.js.map +1 -1
  18. package/dist/tools/invites.d.ts +56 -0
  19. package/dist/tools/invites.js +59 -9
  20. package/dist/tools/invites.js.map +1 -1
  21. package/dist/tools/keys.d.ts +28 -0
  22. package/dist/tools/keys.js +29 -1
  23. package/dist/tools/keys.js.map +1 -1
  24. package/dist/tools/log-streaming.d.ts +90 -0
  25. package/dist/tools/log-streaming.js +89 -0
  26. package/dist/tools/log-streaming.js.map +1 -0
  27. package/dist/tools/network-lock.d.ts +7 -0
  28. package/dist/tools/network-lock.js +7 -0
  29. package/dist/tools/network-lock.js.map +1 -1
  30. package/dist/tools/oauth-clients.d.ts +118 -0
  31. package/dist/tools/oauth-clients.js +102 -0
  32. package/dist/tools/oauth-clients.js.map +1 -0
  33. package/dist/tools/posture.d.ts +35 -0
  34. package/dist/tools/posture.js +36 -1
  35. package/dist/tools/posture.js.map +1 -1
  36. package/dist/tools/services.d.ts +124 -0
  37. package/dist/tools/services.js +106 -0
  38. package/dist/tools/services.js.map +1 -0
  39. package/dist/tools/status.d.ts +7 -0
  40. package/dist/tools/status.js +7 -0
  41. package/dist/tools/status.js.map +1 -1
  42. package/dist/tools/tailnet.d.ts +28 -0
  43. package/dist/tools/tailnet.js +28 -0
  44. package/dist/tools/tailnet.js.map +1 -1
  45. package/dist/tools/users.d.ts +42 -0
  46. package/dist/tools/users.js +45 -2
  47. package/dist/tools/users.js.map +1 -1
  48. package/dist/tools/webhooks.d.ts +42 -0
  49. package/dist/tools/webhooks.js +43 -1
  50. package/dist/tools/webhooks.js.map +1 -1
  51. package/dist/tools/workload-identity.d.ts +118 -0
  52. package/dist/tools/workload-identity.js +105 -0
  53. package/dist/tools/workload-identity.js.map +1 -0
  54. package/package.json +6 -2
package/README.md CHANGED
@@ -3,8 +3,9 @@
3
3
  [![npm version](https://img.shields.io/npm/v/@yawlabs/tailscale-mcp)](https://www.npmjs.com/package/@yawlabs/tailscale-mcp)
4
4
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
5
5
  [![GitHub stars](https://img.shields.io/github/stars/YawLabs/tailscale-mcp)](https://github.com/YawLabs/tailscale-mcp/stargazers)
6
+ [![CI](https://github.com/YawLabs/tailscale-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/YawLabs/tailscale-mcp/actions/workflows/ci.yml)
6
7
 
7
- **Manage your Tailscale tailnet from Claude Code, Cursor, and any MCP client.** 62 tools. One env var. Works on first try.
8
+ **Manage your Tailscale tailnet from Claude Code, Cursor, and any MCP client.** 81 tools + 4 resources. One env var. Works on first try.
8
9
 
9
10
  Built and maintained by [YawLabs](https://yaw.sh).
10
11
 
@@ -14,6 +15,8 @@ Other Tailscale MCP servers were vibe-coded in a weekend and abandoned. This one
14
15
 
15
16
  - **Preserves ACL formatting** — reads and writes HuJSON (comments, trailing commas, indentation). Others compact your carefully formatted policy into a single line.
16
17
  - **Safe ACL updates** — uses ETags to prevent overwriting concurrent changes. No silent data loss.
18
+ - **Tool annotations** — every tool declares `readOnlyHint`, `destructiveHint`, and `idempotentHint`, so MCP clients skip confirmation dialogs for safe operations.
19
+ - **MCP Resources** — exposes tailnet status, device list, ACL policy, and DNS config as browsable resources.
17
20
  - **Zero restarts** — the server always starts, even with missing credentials. Auth errors surface as clear tool-call errors, not silent crashes that force you to restart your AI assistant.
18
21
  - **One env var setup** — no config files, no setup wizards, no multi-step flows.
19
22
  - **Every tool verified** — no placeholder endpoints that 404. If it's in the tool list, it works.
@@ -45,13 +48,13 @@ That's it. Now ask your AI assistant:
45
48
  ```
46
49
  ┌────────────┬─────────┬────────────────┬──────────────────────┐
47
50
  │ Hostname │ OS │ Tailscale IP │ Last Seen │
48
- ├────────────┼─────────┼────────────────┼──────────────────────┤
51
+ ���────────────┼─────────┼────────────────┼──────────────────────┤
49
52
  │ web-prod │ Linux │ 100.x.x.1 │ 2026-04-03 21:09 UTC │
50
- ├────────────┼─────────┼────────────────┼──────────────────────┤
51
- │ db-staging │ Linux │ 100.x.x.2 │ 2026-04-03 21:09 UTC
52
- ├────────────┼─────────┼────────────────┼──────────────────────┤
53
+ ├────────────┼─────────┼���───────────────┼──────────────────────┤
54
+ │ db-staging │ Linux │ 100.x.x.2 │ 2026-04-03 21:09 UTC ��
55
+ ���────────────┼──────���──┼────────────────┼──────────────────────┤
53
56
  │ dev-laptop │ macOS │ 100.x.x.3 │ 2026-04-03 21:09 UTC │
54
- └────────────┴─────────┴────────────────┴──────────────────────┘
57
+ └────────────┴─────────┴──���─────────────┴──────────────────────┘
55
58
  ```
56
59
 
57
60
  > "Show me the ACL policy"
@@ -72,7 +75,18 @@ The server checks for an API key first, then falls back to OAuth. If neither is
72
75
 
73
76
  **Tailnet:** Uses your default tailnet automatically. Set `TAILSCALE_TAILNET` to specify one explicitly.
74
77
 
75
- ## Tools (62)
78
+ ## Resources (4)
79
+
80
+ MCP Resources expose read-only data that clients can browse without tool calls.
81
+
82
+ | Resource | URI | Description |
83
+ |----------|-----|-------------|
84
+ | Tailnet Status | `tailscale://tailnet/status` | Device count and tailnet settings |
85
+ | Devices | `tailscale://tailnet/devices` | All devices with status and IPs |
86
+ | ACL Policy | `tailscale://tailnet/acl` | Full ACL policy (HuJSON preserved) |
87
+ | DNS Config | `tailscale://tailnet/dns` | Nameservers, search paths, split DNS, MagicDNS |
88
+
89
+ ## Tools (81)
76
90
 
77
91
  <details>
78
92
  <summary><strong>Status</strong> (1 tool)</summary>
@@ -206,6 +220,57 @@ The server checks for an API key first, then falls back to OAuth. If neither is
206
220
 
207
221
  </details>
208
222
 
223
+ <details>
224
+ <summary><strong>Tailscale Services</strong> (5 tools)</summary>
225
+
226
+ | Tool | Description |
227
+ |------|-------------|
228
+ | `tailscale_list_services` | List all Tailscale Services in your tailnet |
229
+ | `tailscale_get_service` | Get details for a specific service |
230
+ | `tailscale_update_service` | Update a service's configuration |
231
+ | `tailscale_delete_service` | Delete a service |
232
+ | `tailscale_list_service_hosts` | List devices hosting a service |
233
+
234
+ </details>
235
+
236
+ <details>
237
+ <summary><strong>Log Streaming</strong> (4 tools)</summary>
238
+
239
+ | Tool | Description |
240
+ |------|-------------|
241
+ | `tailscale_list_log_stream_configs` | List log streaming configurations |
242
+ | `tailscale_get_log_stream_config` | Get log streaming config for a log type |
243
+ | `tailscale_set_log_stream_config` | Set where logs are sent (Axiom, Datadog, Splunk, etc.) |
244
+ | `tailscale_delete_log_stream_config` | Delete a log streaming configuration |
245
+
246
+ </details>
247
+
248
+ <details>
249
+ <summary><strong>Workload Identity</strong> (5 tools)</summary>
250
+
251
+ | Tool | Description |
252
+ |------|-------------|
253
+ | `tailscale_list_workload_identities` | List federated workload identity providers |
254
+ | `tailscale_get_workload_identity` | Get a workload identity provider |
255
+ | `tailscale_create_workload_identity` | Create an OIDC federation provider (GitHub Actions, GitLab CI, etc.) |
256
+ | `tailscale_update_workload_identity` | Update a workload identity provider |
257
+ | `tailscale_delete_workload_identity` | Delete a workload identity provider |
258
+
259
+ </details>
260
+
261
+ <details>
262
+ <summary><strong>OAuth Clients</strong> (5 tools)</summary>
263
+
264
+ | Tool | Description |
265
+ |------|-------------|
266
+ | `tailscale_list_oauth_clients` | List OAuth clients |
267
+ | `tailscale_get_oauth_client` | Get an OAuth client |
268
+ | `tailscale_create_oauth_client` | Create an OAuth client for programmatic API access |
269
+ | `tailscale_update_oauth_client` | Update an OAuth client |
270
+ | `tailscale_delete_oauth_client` | Delete an OAuth client |
271
+
272
+ </details>
273
+
209
274
  <details>
210
275
  <summary><strong>Device Invites</strong> (4 tools)</summary>
211
276
 
@@ -255,6 +320,7 @@ git clone https://github.com/YawLabs/tailscale-mcp.git
255
320
  cd tailscale-mcp
256
321
  npm install
257
322
  npm run build
323
+ npm run lint
258
324
  npm test
259
325
  ```
260
326
 
package/dist/api.js CHANGED
@@ -59,7 +59,7 @@ async function getOAuthAccessToken(clientId, clientSecret) {
59
59
  async function getAuthHeader() {
60
60
  const config = getConfig();
61
61
  if (config.apiKey) {
62
- return `Basic ${Buffer.from(config.apiKey + ":").toString("base64")}`;
62
+ return `Basic ${Buffer.from(`${config.apiKey}:`).toString("base64")}`;
63
63
  }
64
64
  const token = await getOAuthAccessToken(config.oauthClientId, config.oauthClientSecret);
65
65
  return `Bearer ${token}`;
@@ -77,7 +77,7 @@ export async function apiRequest(method, path, body, options) {
77
77
  Authorization: auth,
78
78
  };
79
79
  if (options?.accept) {
80
- headers["Accept"] = options.accept;
80
+ headers.Accept = options.accept;
81
81
  }
82
82
  if (options?.ifMatch) {
83
83
  headers["If-Match"] = options.ifMatch;
package/dist/api.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,19 +1,24 @@
1
1
  #!/usr/bin/env node
2
+ import { createRequire } from "node:module";
2
3
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
4
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
- import { createRequire } from "node:module";
5
- import { deviceTools } from "./tools/devices.js";
5
+ import { apiGet, getTailnet } from "./api.js";
6
6
  import { aclTools } from "./tools/acl.js";
7
+ import { auditTools } from "./tools/audit.js";
8
+ import { deviceTools } from "./tools/devices.js";
7
9
  import { dnsTools } from "./tools/dns.js";
10
+ import { inviteTools } from "./tools/invites.js";
8
11
  import { keyTools } from "./tools/keys.js";
9
- import { userTools } from "./tools/users.js";
10
- import { tailnetTools } from "./tools/tailnet.js";
11
- import { webhookTools } from "./tools/webhooks.js";
12
+ import { logStreamingTools } from "./tools/log-streaming.js";
12
13
  import { networkLockTools } from "./tools/network-lock.js";
14
+ import { oauthClientTools } from "./tools/oauth-clients.js";
13
15
  import { postureTools } from "./tools/posture.js";
14
- import { auditTools } from "./tools/audit.js";
16
+ import { serviceTools } from "./tools/services.js";
15
17
  import { statusTools } from "./tools/status.js";
16
- import { inviteTools } from "./tools/invites.js";
18
+ import { tailnetTools } from "./tools/tailnet.js";
19
+ import { userTools } from "./tools/users.js";
20
+ import { webhookTools } from "./tools/webhooks.js";
21
+ import { workloadIdentityTools } from "./tools/workload-identity.js";
17
22
  const require = createRequire(import.meta.url);
18
23
  const { version } = require("../package.json");
19
24
  const allTools = [
@@ -29,13 +34,18 @@ const allTools = [
29
34
  ...postureTools,
30
35
  ...auditTools,
31
36
  ...inviteTools,
37
+ ...serviceTools,
38
+ ...logStreamingTools,
39
+ ...workloadIdentityTools,
40
+ ...oauthClientTools,
32
41
  ];
33
42
  const server = new McpServer({
34
43
  name: "@yawlabs/tailscale-mcp",
35
44
  version,
36
45
  });
46
+ // Register all tools with annotations
37
47
  for (const tool of allTools) {
38
- server.tool(tool.name, tool.description, tool.inputSchema.shape, async (input) => {
48
+ server.tool(tool.name, tool.description, tool.inputSchema.shape, tool.annotations, async (input) => {
39
49
  try {
40
50
  const result = await tool.handler(input);
41
51
  const response = result;
@@ -64,6 +74,47 @@ for (const tool of allTools) {
64
74
  }
65
75
  });
66
76
  }
77
+ // Register MCP Resources
78
+ server.resource("tailnet-status", "tailscale://tailnet/status", { description: "Current tailnet status including device count and settings", mimeType: "application/json" }, async (uri) => {
79
+ const [devicesRes, settingsRes] = await Promise.all([
80
+ apiGet(`/tailnet/${getTailnet()}/devices?fields=id`),
81
+ apiGet(`/tailnet/${getTailnet()}/settings`),
82
+ ]);
83
+ const data = {
84
+ tailnet: getTailnet(),
85
+ deviceCount: devicesRes.ok ? (devicesRes.data?.devices?.length ?? 0) : "error",
86
+ settings: settingsRes.ok ? settingsRes.data : undefined,
87
+ };
88
+ return { contents: [{ uri: uri.href, text: JSON.stringify(data, null, 2), mimeType: "application/json" }] };
89
+ });
90
+ server.resource("tailnet-devices", "tailscale://tailnet/devices", { description: "List of all devices in the tailnet with their status", mimeType: "application/json" }, async (uri) => {
91
+ const res = await apiGet(`/tailnet/${getTailnet()}/devices`);
92
+ const text = res.ok ? JSON.stringify(res.data, null, 2) : JSON.stringify({ error: res.error });
93
+ return { contents: [{ uri: uri.href, text, mimeType: "application/json" }] };
94
+ });
95
+ server.resource("tailnet-acl", "tailscale://tailnet/acl", { description: "Current ACL policy (HuJSON with comments preserved)", mimeType: "application/hujson" }, async (uri) => {
96
+ const res = await apiGet(`/tailnet/${getTailnet()}/acl`, { acceptRaw: true, accept: "application/hujson" });
97
+ const text = res.ok ? (res.rawBody ?? "") : `Error: ${res.error}`;
98
+ return { contents: [{ uri: uri.href, text, mimeType: "application/hujson" }] };
99
+ });
100
+ server.resource("tailnet-dns", "tailscale://tailnet/dns", {
101
+ description: "DNS configuration including nameservers, search paths, split DNS, and MagicDNS status",
102
+ mimeType: "application/json",
103
+ }, async (uri) => {
104
+ const [nameservers, searchPaths, splitDns, preferences] = await Promise.all([
105
+ apiGet(`/tailnet/${getTailnet()}/dns/nameservers`),
106
+ apiGet(`/tailnet/${getTailnet()}/dns/searchpaths`),
107
+ apiGet(`/tailnet/${getTailnet()}/dns/split-dns`),
108
+ apiGet(`/tailnet/${getTailnet()}/dns/preferences`),
109
+ ]);
110
+ const data = {
111
+ nameservers: nameservers.ok ? nameservers.data : undefined,
112
+ searchPaths: searchPaths.ok ? searchPaths.data : undefined,
113
+ splitDns: splitDns.ok ? splitDns.data : undefined,
114
+ preferences: preferences.ok ? preferences.data : undefined,
115
+ };
116
+ return { contents: [{ uri: uri.href, text: JSON.stringify(data, null, 2), mimeType: "application/json" }] };
117
+ });
67
118
  async function main() {
68
119
  const transport = new StdioServerTransport();
69
120
  await server.connect(transport);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -2,11 +2,25 @@ import { z } from "zod";
2
2
  export declare const aclTools: readonly [{
3
3
  readonly name: "tailscale_get_acl";
4
4
  readonly description: "Get the current ACL policy for your tailnet. Returns the raw policy text with original formatting preserved, including comments and trailing commas (HuJSON). Also returns an ETag — you must pass it to tailscale_update_acl to safely update the policy.";
5
+ readonly annotations: {
6
+ readonly title: "Get ACL policy";
7
+ readonly readOnlyHint: true;
8
+ readonly destructiveHint: false;
9
+ readonly idempotentHint: true;
10
+ readonly openWorldHint: true;
11
+ };
5
12
  readonly inputSchema: z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>;
6
13
  readonly handler: () => Promise<import("../api.js").ApiResponse<unknown>>;
7
14
  }, {
8
15
  readonly name: "tailscale_update_acl";
9
16
  readonly description: "Update the ACL policy for your tailnet. Accepts the full policy as a string to preserve formatting, comments, and trailing commas (HuJSON). You MUST pass the ETag from tailscale_get_acl to prevent overwriting concurrent changes. Always get the current ACL first, make targeted edits to the text, and pass the full modified text back.";
17
+ readonly annotations: {
18
+ readonly title: "Update ACL policy";
19
+ readonly readOnlyHint: false;
20
+ readonly destructiveHint: false;
21
+ readonly idempotentHint: true;
22
+ readonly openWorldHint: true;
23
+ };
10
24
  readonly inputSchema: z.ZodObject<{
11
25
  policy: z.ZodString;
12
26
  etag: z.ZodString;
@@ -24,6 +38,13 @@ export declare const aclTools: readonly [{
24
38
  }, {
25
39
  readonly name: "tailscale_validate_acl";
26
40
  readonly description: "Validate an ACL policy without applying it. Returns any errors found, or confirms the policy is valid.";
41
+ readonly annotations: {
42
+ readonly title: "Validate ACL policy";
43
+ readonly readOnlyHint: true;
44
+ readonly destructiveHint: false;
45
+ readonly idempotentHint: true;
46
+ readonly openWorldHint: true;
47
+ };
27
48
  readonly inputSchema: z.ZodObject<{
28
49
  policy: z.ZodString;
29
50
  }, "strip", z.ZodTypeAny, {
@@ -37,6 +58,13 @@ export declare const aclTools: readonly [{
37
58
  }, {
38
59
  readonly name: "tailscale_preview_acl";
39
60
  readonly description: "Preview the ACL rules that would apply to a specific user or IP address if a proposed policy were applied.";
61
+ readonly annotations: {
62
+ readonly title: "Preview ACL rules";
63
+ readonly readOnlyHint: true;
64
+ readonly destructiveHint: false;
65
+ readonly idempotentHint: true;
66
+ readonly openWorldHint: true;
67
+ };
40
68
  readonly inputSchema: z.ZodObject<{
41
69
  policy: z.ZodString;
42
70
  type: z.ZodEnum<["user", "ipport"]>;
package/dist/tools/acl.js CHANGED
@@ -4,6 +4,13 @@ export const aclTools = [
4
4
  {
5
5
  name: "tailscale_get_acl",
6
6
  description: "Get the current ACL policy for your tailnet. Returns the raw policy text with original formatting preserved, including comments and trailing commas (HuJSON). Also returns an ETag — you must pass it to tailscale_update_acl to safely update the policy.",
7
+ annotations: {
8
+ title: "Get ACL policy",
9
+ readOnlyHint: true,
10
+ destructiveHint: false,
11
+ idempotentHint: true,
12
+ openWorldHint: true,
13
+ },
7
14
  inputSchema: z.object({}),
8
15
  handler: async () => {
9
16
  const res = await apiGet(`/tailnet/${getTailnet()}/acl`, {
@@ -22,13 +29,18 @@ export const aclTools = [
22
29
  {
23
30
  name: "tailscale_update_acl",
24
31
  description: "Update the ACL policy for your tailnet. Accepts the full policy as a string to preserve formatting, comments, and trailing commas (HuJSON). You MUST pass the ETag from tailscale_get_acl to prevent overwriting concurrent changes. Always get the current ACL first, make targeted edits to the text, and pass the full modified text back.",
32
+ annotations: {
33
+ title: "Update ACL policy",
34
+ readOnlyHint: false,
35
+ destructiveHint: false,
36
+ idempotentHint: true,
37
+ openWorldHint: true,
38
+ },
25
39
  inputSchema: z.object({
26
40
  policy: z
27
41
  .string()
28
42
  .describe("The full ACL policy text. Preserve existing formatting, comments, and structure. Only modify the specific parts that need to change."),
29
- etag: z
30
- .string()
31
- .describe("The ETag from tailscale_get_acl. Required to prevent concurrent edit conflicts."),
43
+ etag: z.string().describe("The ETag from tailscale_get_acl. Required to prevent concurrent edit conflicts."),
32
44
  }),
33
45
  handler: async (input) => {
34
46
  return apiPost(`/tailnet/${getTailnet()}/acl`, undefined, {
@@ -41,6 +53,13 @@ export const aclTools = [
41
53
  {
42
54
  name: "tailscale_validate_acl",
43
55
  description: "Validate an ACL policy without applying it. Returns any errors found, or confirms the policy is valid.",
56
+ annotations: {
57
+ title: "Validate ACL policy",
58
+ readOnlyHint: true,
59
+ destructiveHint: false,
60
+ idempotentHint: true,
61
+ openWorldHint: true,
62
+ },
44
63
  inputSchema: z.object({
45
64
  policy: z.string().describe("The full ACL policy text to validate"),
46
65
  }),
@@ -58,6 +77,13 @@ export const aclTools = [
58
77
  {
59
78
  name: "tailscale_preview_acl",
60
79
  description: "Preview the ACL rules that would apply to a specific user or IP address if a proposed policy were applied.",
80
+ annotations: {
81
+ title: "Preview ACL rules",
82
+ readOnlyHint: true,
83
+ destructiveHint: false,
84
+ idempotentHint: true,
85
+ openWorldHint: true,
86
+ },
61
87
  inputSchema: z.object({
62
88
  policy: z.string().describe("The proposed ACL policy text to preview"),
63
89
  type: z
@@ -69,7 +95,10 @@ export const aclTools = [
69
95
  }),
70
96
  handler: async (input) => {
71
97
  const params = new URLSearchParams({ type: input.type, previewFor: input.previewFor });
72
- return apiPost(`/tailnet/${getTailnet()}/acl/preview?${params}`, undefined, { rawBody: input.policy, contentType: "application/hujson" });
98
+ return apiPost(`/tailnet/${getTailnet()}/acl/preview?${params}`, undefined, {
99
+ rawBody: input.policy,
100
+ contentType: "application/hujson",
101
+ });
73
102
  },
74
103
  },
75
104
  ];
@@ -1 +1 @@
1
- {"version":3,"file":"acl.js","sourceRoot":"","sources":["../../src/tools/acl.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"acl.js","sourceRoot":"","sources":["../../src/tools/acl.ts"],"names":[],"mappings":"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"}
@@ -2,6 +2,13 @@ import { z } from "zod";
2
2
  export declare const auditTools: readonly [{
3
3
  readonly name: "tailscale_get_audit_log";
4
4
  readonly description: "Get the tailnet audit/configuration log. Shows who changed what and when — useful for troubleshooting and compliance.";
5
+ readonly annotations: {
6
+ readonly title: "Get audit log";
7
+ readonly readOnlyHint: true;
8
+ readonly destructiveHint: false;
9
+ readonly idempotentHint: true;
10
+ readonly openWorldHint: true;
11
+ };
5
12
  readonly inputSchema: z.ZodObject<{
6
13
  start: z.ZodString;
7
14
  end: z.ZodOptional<z.ZodString>;
@@ -19,6 +26,13 @@ export declare const auditTools: readonly [{
19
26
  }, {
20
27
  readonly name: "tailscale_get_network_flow_logs";
21
28
  readonly description: "Get network traffic flow logs showing connections between devices. Shows source/destination nodes, timestamps, and traffic metadata — useful for security monitoring and debugging connectivity.";
29
+ readonly annotations: {
30
+ readonly title: "Get network flow logs";
31
+ readonly readOnlyHint: true;
32
+ readonly destructiveHint: false;
33
+ readonly idempotentHint: true;
34
+ readonly openWorldHint: true;
35
+ };
22
36
  readonly inputSchema: z.ZodObject<{
23
37
  start: z.ZodString;
24
38
  end: z.ZodOptional<z.ZodString>;
@@ -3,7 +3,7 @@ import { apiGet, getTailnet } from "../api.js";
3
3
  /** Validate that a string is a valid RFC3339 date-time. */
4
4
  function assertRFC3339(value, label) {
5
5
  const d = new Date(value);
6
- if (isNaN(d.getTime())) {
6
+ if (Number.isNaN(d.getTime())) {
7
7
  throw new Error(`${label} must be a valid RFC3339 date-time (e.g. '2026-04-01T00:00:00Z'), got: '${value}'`);
8
8
  }
9
9
  }
@@ -11,14 +11,16 @@ export const auditTools = [
11
11
  {
12
12
  name: "tailscale_get_audit_log",
13
13
  description: "Get the tailnet audit/configuration log. Shows who changed what and when — useful for troubleshooting and compliance.",
14
+ annotations: {
15
+ title: "Get audit log",
16
+ readOnlyHint: true,
17
+ destructiveHint: false,
18
+ idempotentHint: true,
19
+ openWorldHint: true,
20
+ },
14
21
  inputSchema: z.object({
15
- start: z
16
- .string()
17
- .describe("Start time in RFC3339 format (e.g. '2026-04-01T00:00:00Z'). Required."),
18
- end: z
19
- .string()
20
- .optional()
21
- .describe("End time in RFC3339 format. Defaults to now."),
22
+ start: z.string().describe("Start time in RFC3339 format (e.g. '2026-04-01T00:00:00Z'). Required."),
23
+ end: z.string().optional().describe("End time in RFC3339 format. Defaults to now."),
22
24
  }),
23
25
  handler: async (input) => {
24
26
  assertRFC3339(input.start, "start");
@@ -33,14 +35,16 @@ export const auditTools = [
33
35
  {
34
36
  name: "tailscale_get_network_flow_logs",
35
37
  description: "Get network traffic flow logs showing connections between devices. Shows source/destination nodes, timestamps, and traffic metadata — useful for security monitoring and debugging connectivity.",
38
+ annotations: {
39
+ title: "Get network flow logs",
40
+ readOnlyHint: true,
41
+ destructiveHint: false,
42
+ idempotentHint: true,
43
+ openWorldHint: true,
44
+ },
36
45
  inputSchema: z.object({
37
- start: z
38
- .string()
39
- .describe("Start time in RFC3339 format (e.g. '2026-04-01T00:00:00Z'). Required."),
40
- end: z
41
- .string()
42
- .optional()
43
- .describe("End time in RFC3339 format. Defaults to now."),
46
+ start: z.string().describe("Start time in RFC3339 format (e.g. '2026-04-01T00:00:00Z'). Required."),
47
+ end: z.string().optional().describe("End time in RFC3339 format. Defaults to now."),
44
48
  }),
45
49
  handler: async (input) => {
46
50
  assertRFC3339(input.start, "start");
@@ -1 +1 @@
1
- {"version":3,"file":"audit.js","sourceRoot":"","sources":["../../src/tools/audit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAE/C,2DAA2D;AAC3D,SAAS,aAAa,CAAC,KAAa,EAAE,KAAa;IACjD,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC;IAC1B,IAAI,KAAK,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,2EAA2E,KAAK,GAAG,CAAC,CAAC;IAC/G,CAAC;AACH,CAAC;AAED,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB;QACE,IAAI,EAAE,yBAAyB;QAC/B,WAAW,EACT,uHAAuH;QACzH,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,KAAK,EAAE,CAAC;iBACL,MAAM,EAAE;iBACR,QAAQ,CAAC,uEAAuE,CAAC;YACpF,GAAG,EAAE,CAAC;iBACH,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CAAC,8CAA8C,CAAC;SAC5D,CAAC;QACF,OAAO,EAAE,KAAK,EAAE,KAAsC,EAAE,EAAE;YACxD,aAAa,CAAC,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;YACpC,IAAI,KAAK,CAAC,GAAG;gBAAE,aAAa,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YAC/C,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;YAC3D,IAAI,KAAK,CAAC,GAAG;gBAAE,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;YAC5C,OAAO,MAAM,CACX,YAAY,UAAU,EAAE,0BAA0B,MAAM,EAAE,CAC3D,CAAC;QACJ,CAAC;KACF;IACD;QACE,IAAI,EAAE,iCAAiC;QACvC,WAAW,EACT,kMAAkM;QACpM,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,KAAK,EAAE,CAAC;iBACL,MAAM,EAAE;iBACR,QAAQ,CAAC,uEAAuE,CAAC;YACpF,GAAG,EAAE,CAAC;iBACH,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CAAC,8CAA8C,CAAC;SAC5D,CAAC;QACF,OAAO,EAAE,KAAK,EAAE,KAAsC,EAAE,EAAE;YACxD,aAAa,CAAC,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;YACpC,IAAI,KAAK,CAAC,GAAG;gBAAE,aAAa,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YAC/C,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;YAC3D,IAAI,KAAK,CAAC,GAAG;gBAAE,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;YAC5C,OAAO,MAAM,CACX,YAAY,UAAU,EAAE,oBAAoB,MAAM,EAAE,CACrD,CAAC;QACJ,CAAC;KACF;CACO,CAAC"}
1
+ {"version":3,"file":"audit.js","sourceRoot":"","sources":["../../src/tools/audit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAE/C,2DAA2D;AAC3D,SAAS,aAAa,CAAC,KAAa,EAAE,KAAa;IACjD,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC;IAC1B,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,2EAA2E,KAAK,GAAG,CAAC,CAAC;IAC/G,CAAC;AACH,CAAC;AAED,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB;QACE,IAAI,EAAE,yBAAyB;QAC/B,WAAW,EACT,uHAAuH;QACzH,WAAW,EAAE;YACX,KAAK,EAAE,eAAe;YACtB,YAAY,EAAE,IAAI;YAClB,eAAe,EAAE,KAAK;YACtB,cAAc,EAAE,IAAI;YACpB,aAAa,EAAE,IAAI;SACpB;QACD,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,uEAAuE,CAAC;YACnG,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,8CAA8C,CAAC;SACpF,CAAC;QACF,OAAO,EAAE,KAAK,EAAE,KAAsC,EAAE,EAAE;YACxD,aAAa,CAAC,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;YACpC,IAAI,KAAK,CAAC,GAAG;gBAAE,aAAa,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YAC/C,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;YAC3D,IAAI,KAAK,CAAC,GAAG;gBAAE,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;YAC5C,OAAO,MAAM,CAAC,YAAY,UAAU,EAAE,0BAA0B,MAAM,EAAE,CAAC,CAAC;QAC5E,CAAC;KACF;IACD;QACE,IAAI,EAAE,iCAAiC;QACvC,WAAW,EACT,kMAAkM;QACpM,WAAW,EAAE;YACX,KAAK,EAAE,uBAAuB;YAC9B,YAAY,EAAE,IAAI;YAClB,eAAe,EAAE,KAAK;YACtB,cAAc,EAAE,IAAI;YACpB,aAAa,EAAE,IAAI;SACpB;QACD,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,uEAAuE,CAAC;YACnG,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,8CAA8C,CAAC;SACpF,CAAC;QACF,OAAO,EAAE,KAAK,EAAE,KAAsC,EAAE,EAAE;YACxD,aAAa,CAAC,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;YACpC,IAAI,KAAK,CAAC,GAAG;gBAAE,aAAa,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YAC/C,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;YAC3D,IAAI,KAAK,CAAC,GAAG;gBAAE,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;YAC5C,OAAO,MAAM,CAAC,YAAY,UAAU,EAAE,oBAAoB,MAAM,EAAE,CAAC,CAAC;QACtE,CAAC;KACF;CACO,CAAC"}