@yawlabs/tailscale-mcp 0.1.3 → 0.1.5

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.
package/README.md CHANGED
@@ -4,7 +4,7 @@
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
6
 
7
- **Manage your Tailscale tailnet from Claude Code, Cursor, and any MCP client.** 44 tools. One env var. Works on first try.
7
+ **Manage your Tailscale tailnet from Claude Code, Cursor, and any MCP client.** 52 tools. One env var. Works on first try.
8
8
 
9
9
  Built and maintained by [YawLabs](https://yaw.sh).
10
10
 
@@ -72,7 +72,7 @@ The server checks for an API key first, then falls back to OAuth. If neither is
72
72
 
73
73
  **Tailnet:** Uses your default tailnet automatically. Set `TAILSCALE_TAILNET` to specify one explicitly.
74
74
 
75
- ## Tools (44)
75
+ ## Tools (52)
76
76
 
77
77
  ### Status
78
78
 
@@ -81,7 +81,7 @@ The server checks for an API key first, then falls back to OAuth. If neither is
81
81
  | `tailscale_status` | Verify API connection, see tailnet info and device count |
82
82
 
83
83
  <details>
84
- <summary><strong>Devices</strong> (10 tools)</summary>
84
+ <summary><strong>Devices</strong> (13 tools)</summary>
85
85
 
86
86
  | Tool | Description |
87
87
  |------|-------------|
@@ -94,6 +94,9 @@ The server checks for an API key first, then falls back to OAuth. If neither is
94
94
  | `tailscale_expire_device` | Expire a device's key, forcing re-authentication |
95
95
  | `tailscale_get_device_routes` | Get advertised and enabled subnet routes |
96
96
  | `tailscale_set_device_routes` | Enable or disable subnet routes |
97
+ | `tailscale_get_device_posture_attributes` | Get all posture attributes for a device |
98
+ | `tailscale_set_device_posture_attribute` | Set a custom posture attribute (with optional expiry) |
99
+ | `tailscale_delete_device_posture_attribute` | Delete a custom posture attribute |
97
100
  | `tailscale_set_device_tags` | Set ACL tags on a device |
98
101
 
99
102
  </details>
@@ -139,12 +142,16 @@ The server checks for an API key first, then falls back to OAuth. If neither is
139
142
  </details>
140
143
 
141
144
  <details>
142
- <summary><strong>Users</strong> (2 tools)</summary>
145
+ <summary><strong>Users</strong> (6 tools)</summary>
143
146
 
144
147
  | Tool | Description |
145
148
  |------|-------------|
146
149
  | `tailscale_list_users` | List all users in the tailnet |
147
150
  | `tailscale_get_user` | Get details for a specific user |
151
+ | `tailscale_approve_user` | Approve a pending user |
152
+ | `tailscale_suspend_user` | Suspend a user, revoking access |
153
+ | `tailscale_restore_user` | Restore a suspended user |
154
+ | `tailscale_update_user_role` | Update a user's role (owner, admin, member, etc.) |
148
155
 
149
156
  </details>
150
157
 
@@ -177,7 +184,7 @@ The server checks for an API key first, then falls back to OAuth. If neither is
177
184
  | `tailscale_list_webhooks` | List webhooks |
178
185
  | `tailscale_get_webhook` | Get a specific webhook |
179
186
  | `tailscale_create_webhook` | Create a webhook |
180
- | `tailscale_update_webhook` | Update a webhook's subscriptions |
187
+ | `tailscale_update_webhook` | Update a webhook's endpoint URL and/or subscriptions |
181
188
  | `tailscale_delete_webhook` | Delete a webhook |
182
189
 
183
190
  </details>
@@ -195,14 +202,19 @@ The server checks for an API key first, then falls back to OAuth. If neither is
195
202
  </details>
196
203
 
197
204
  <details>
198
- <summary><strong>Audit Log</strong> (1 tool)</summary>
205
+ <summary><strong>Logging</strong> (2 tools)</summary>
199
206
 
200
207
  | Tool | Description |
201
208
  |------|-------------|
202
209
  | `tailscale_get_audit_log` | Get configuration audit log (who changed what, when) |
210
+ | `tailscale_get_network_flow_logs` | Get network traffic flow logs between devices |
203
211
 
204
212
  </details>
205
213
 
214
+ ## Requirements
215
+
216
+ - Node.js 18 or higher
217
+
206
218
  ## Contributing
207
219
 
208
220
  Contributions are welcome. Please [open an issue](https://github.com/YawLabs/tailscale-mcp/issues) to discuss what you'd like to change before submitting a PR.
@@ -214,6 +226,7 @@ git clone https://github.com/YawLabs/tailscale-mcp.git
214
226
  cd tailscale-mcp
215
227
  npm install
216
228
  npm run build
229
+ npm test
217
230
  ```
218
231
 
219
232
  Test against your own tailnet by setting `TAILSCALE_API_KEY` and running:
package/dist/api.d.ts CHANGED
@@ -2,6 +2,8 @@
2
2
  * Tailscale API client with API key and OAuth authentication.
3
3
  */
4
4
  export declare function getTailnet(): string;
5
+ /** URL-encode a path segment to prevent path traversal. */
6
+ export declare function encPath(segment: string): string;
5
7
  export interface ApiResponse<T = unknown> {
6
8
  ok: boolean;
7
9
  status: number;
package/dist/api.js CHANGED
@@ -12,7 +12,10 @@ function getConfig() {
12
12
  const tailnet = process.env.TAILSCALE_TAILNET || "-";
13
13
  if (!apiKey && !(oauthClientId && oauthClientSecret)) {
14
14
  throw new Error("No Tailscale credentials configured. " +
15
- "Set TAILSCALE_API_KEY, or set TAILSCALE_OAUTH_CLIENT_ID and TAILSCALE_OAUTH_CLIENT_SECRET.");
15
+ "Set TAILSCALE_API_KEY, or set both TAILSCALE_OAUTH_CLIENT_ID and TAILSCALE_OAUTH_CLIENT_SECRET.");
16
+ }
17
+ if (apiKey && apiKey.trim() === "") {
18
+ throw new Error("TAILSCALE_API_KEY is set but empty. Provide a valid API key.");
16
19
  }
17
20
  return { apiKey, oauthClientId, oauthClientSecret, tailnet };
18
21
  }
@@ -64,6 +67,10 @@ async function getAuthHeader() {
64
67
  export function getTailnet() {
65
68
  return process.env.TAILSCALE_TAILNET || "-";
66
69
  }
70
+ /** URL-encode a path segment to prevent path traversal. */
71
+ export function encPath(segment) {
72
+ return encodeURIComponent(segment);
73
+ }
67
74
  export async function apiRequest(method, path, body, options) {
68
75
  const auth = await getAuthHeader();
69
76
  const headers = {
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
@@ -27,7 +27,7 @@ const allTools = [
27
27
  ];
28
28
  const server = new McpServer({
29
29
  name: "@yawlabs/tailscale-mcp",
30
- version: "0.1.3",
30
+ version: "0.1.5",
31
31
  });
32
32
  for (const tool of allTools) {
33
33
  server.tool(tool.name, tool.description, tool.inputSchema.shape, async (input) => {
@@ -16,4 +16,21 @@ export declare const auditTools: readonly [{
16
16
  start: string;
17
17
  end?: string;
18
18
  }) => Promise<import("../api.js").ApiResponse<unknown>>;
19
+ }, {
20
+ readonly name: "tailscale_get_network_flow_logs";
21
+ 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.";
22
+ readonly inputSchema: z.ZodObject<{
23
+ start: z.ZodString;
24
+ end: z.ZodOptional<z.ZodString>;
25
+ }, "strip", z.ZodTypeAny, {
26
+ start: string;
27
+ end?: string | undefined;
28
+ }, {
29
+ start: string;
30
+ end?: string | undefined;
31
+ }>;
32
+ readonly handler: (input: {
33
+ start: string;
34
+ end?: string;
35
+ }) => Promise<import("../api.js").ApiResponse<unknown>>;
19
36
  }];
@@ -20,5 +20,24 @@ export const auditTools = [
20
20
  return apiGet(`/tailnet/${getTailnet()}/logging/configuration?${params}`);
21
21
  },
22
22
  },
23
+ {
24
+ name: "tailscale_get_network_flow_logs",
25
+ 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.",
26
+ inputSchema: z.object({
27
+ start: z
28
+ .string()
29
+ .describe("Start time in RFC3339 format (e.g. '2026-04-01T00:00:00Z'). Required."),
30
+ end: z
31
+ .string()
32
+ .optional()
33
+ .describe("End time in RFC3339 format. Defaults to now."),
34
+ }),
35
+ handler: async (input) => {
36
+ const params = new URLSearchParams({ start: input.start });
37
+ if (input.end)
38
+ params.set("end", input.end);
39
+ return apiGet(`/tailnet/${getTailnet()}/logging/network?${params}`);
40
+ },
41
+ },
23
42
  ];
24
43
  //# sourceMappingURL=audit.js.map
@@ -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,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,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;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,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,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,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"}
@@ -109,7 +109,7 @@ export declare const deviceTools: readonly [{
109
109
  }) => Promise<import("../api.js").ApiResponse<unknown>>;
110
110
  }, {
111
111
  readonly name: "tailscale_set_device_routes";
112
- readonly description: "Enable or disable subnet routes for a device.";
112
+ readonly description: "Set the enabled subnet routes for a device. Replaces all currently enabled routes — pass the full list of routes you want enabled.";
113
113
  readonly inputSchema: z.ZodObject<{
114
114
  deviceId: z.ZodString;
115
115
  routes: z.ZodArray<z.ZodString, "many">;
@@ -124,9 +124,64 @@ export declare const deviceTools: readonly [{
124
124
  deviceId: string;
125
125
  routes: string[];
126
126
  }) => Promise<import("../api.js").ApiResponse<unknown>>;
127
+ }, {
128
+ readonly name: "tailscale_get_device_posture_attributes";
129
+ readonly description: "Get all posture attributes for a device, including custom and system-managed attributes.";
130
+ readonly inputSchema: z.ZodObject<{
131
+ deviceId: z.ZodString;
132
+ }, "strip", z.ZodTypeAny, {
133
+ deviceId: string;
134
+ }, {
135
+ deviceId: string;
136
+ }>;
137
+ readonly handler: (input: {
138
+ deviceId: string;
139
+ }) => Promise<import("../api.js").ApiResponse<unknown>>;
140
+ }, {
141
+ readonly name: "tailscale_set_device_posture_attribute";
142
+ readonly description: "Set a custom posture attribute on a device. Creates or updates the attribute. Attribute keys must start with 'custom:'. Useful for compliance tracking, JIT access, and custom security policies.";
143
+ readonly inputSchema: z.ZodObject<{
144
+ deviceId: z.ZodString;
145
+ attributeKey: z.ZodString;
146
+ value: z.ZodString;
147
+ expiry: z.ZodOptional<z.ZodString>;
148
+ }, "strip", z.ZodTypeAny, {
149
+ value: string;
150
+ deviceId: string;
151
+ attributeKey: string;
152
+ expiry?: string | undefined;
153
+ }, {
154
+ value: string;
155
+ deviceId: string;
156
+ attributeKey: string;
157
+ expiry?: string | undefined;
158
+ }>;
159
+ readonly handler: (input: {
160
+ deviceId: string;
161
+ attributeKey: string;
162
+ value: string;
163
+ expiry?: string;
164
+ }) => Promise<import("../api.js").ApiResponse<unknown>>;
165
+ }, {
166
+ readonly name: "tailscale_delete_device_posture_attribute";
167
+ readonly description: "Delete a custom posture attribute from a device. This is irreversible.";
168
+ readonly inputSchema: z.ZodObject<{
169
+ deviceId: z.ZodString;
170
+ attributeKey: z.ZodString;
171
+ }, "strip", z.ZodTypeAny, {
172
+ deviceId: string;
173
+ attributeKey: string;
174
+ }, {
175
+ deviceId: string;
176
+ attributeKey: string;
177
+ }>;
178
+ readonly handler: (input: {
179
+ deviceId: string;
180
+ attributeKey: string;
181
+ }) => Promise<import("../api.js").ApiResponse<unknown>>;
127
182
  }, {
128
183
  readonly name: "tailscale_set_device_tags";
129
- readonly description: "Set ACL tags on a device. Replaces all existing tags.";
184
+ readonly description: "Set ACL tags on a device. Replaces all existing tags — pass the full list of tags you want applied.";
130
185
  readonly inputSchema: z.ZodObject<{
131
186
  deviceId: z.ZodString;
132
187
  tags: z.ZodArray<z.ZodString, "many">;
@@ -1,5 +1,5 @@
1
1
  import { z } from "zod";
2
- import { apiGet, apiPost, apiDelete, getTailnet } from "../api.js";
2
+ import { apiGet, apiPost, apiDelete, getTailnet, encPath } from "../api.js";
3
3
  export const deviceTools = [
4
4
  {
5
5
  name: "tailscale_list_devices",
@@ -22,7 +22,7 @@ export const deviceTools = [
22
22
  deviceId: z.string().describe("The device ID (numeric or nodekey format)"),
23
23
  }),
24
24
  handler: async (input) => {
25
- return apiGet(`/device/${input.deviceId}`);
25
+ return apiGet(`/device/${encPath(input.deviceId)}`);
26
26
  },
27
27
  },
28
28
  {
@@ -32,7 +32,7 @@ export const deviceTools = [
32
32
  deviceId: z.string().describe("The device ID to authorize"),
33
33
  }),
34
34
  handler: async (input) => {
35
- return apiPost(`/device/${input.deviceId}/authorized`, { authorized: true });
35
+ return apiPost(`/device/${encPath(input.deviceId)}/authorized`, { authorized: true });
36
36
  },
37
37
  },
38
38
  {
@@ -42,7 +42,7 @@ export const deviceTools = [
42
42
  deviceId: z.string().describe("The device ID to deauthorize"),
43
43
  }),
44
44
  handler: async (input) => {
45
- return apiPost(`/device/${input.deviceId}/authorized`, { authorized: false });
45
+ return apiPost(`/device/${encPath(input.deviceId)}/authorized`, { authorized: false });
46
46
  },
47
47
  },
48
48
  {
@@ -52,7 +52,7 @@ export const deviceTools = [
52
52
  deviceId: z.string().describe("The device ID to delete"),
53
53
  }),
54
54
  handler: async (input) => {
55
- return apiDelete(`/device/${input.deviceId}`);
55
+ return apiDelete(`/device/${encPath(input.deviceId)}`);
56
56
  },
57
57
  },
58
58
  {
@@ -63,7 +63,7 @@ export const deviceTools = [
63
63
  name: z.string().describe("The new name for the device (FQDN within your tailnet)"),
64
64
  }),
65
65
  handler: async (input) => {
66
- return apiPost(`/device/${input.deviceId}/name`, { name: input.name });
66
+ return apiPost(`/device/${encPath(input.deviceId)}/name`, { name: input.name });
67
67
  },
68
68
  },
69
69
  {
@@ -73,7 +73,7 @@ export const deviceTools = [
73
73
  deviceId: z.string().describe("The device ID to expire"),
74
74
  }),
75
75
  handler: async (input) => {
76
- return apiPost(`/device/${input.deviceId}/expire`);
76
+ return apiPost(`/device/${encPath(input.deviceId)}/expire`);
77
77
  },
78
78
  },
79
79
  {
@@ -83,29 +83,66 @@ export const deviceTools = [
83
83
  deviceId: z.string().describe("The device ID"),
84
84
  }),
85
85
  handler: async (input) => {
86
- return apiGet(`/device/${input.deviceId}/routes`);
86
+ return apiGet(`/device/${encPath(input.deviceId)}/routes`);
87
87
  },
88
88
  },
89
89
  {
90
90
  name: "tailscale_set_device_routes",
91
- description: "Enable or disable subnet routes for a device.",
91
+ description: "Set the enabled subnet routes for a device. Replaces all currently enabled routes — pass the full list of routes you want enabled.",
92
92
  inputSchema: z.object({
93
93
  deviceId: z.string().describe("The device ID"),
94
- routes: z.array(z.string()).describe("List of CIDR routes to enable (e.g. ['10.0.0.0/24', '192.168.1.0/24'])"),
94
+ routes: z.array(z.string()).describe("Full list of CIDR routes to enable (e.g. ['10.0.0.0/24', '192.168.1.0/24']). Replaces existing enabled routes."),
95
95
  }),
96
96
  handler: async (input) => {
97
- return apiPost(`/device/${input.deviceId}/routes`, { routes: input.routes });
97
+ return apiPost(`/device/${encPath(input.deviceId)}/routes`, { routes: input.routes });
98
+ },
99
+ },
100
+ {
101
+ name: "tailscale_get_device_posture_attributes",
102
+ description: "Get all posture attributes for a device, including custom and system-managed attributes.",
103
+ inputSchema: z.object({
104
+ deviceId: z.string().describe("The device ID"),
105
+ }),
106
+ handler: async (input) => {
107
+ return apiGet(`/device/${encPath(input.deviceId)}/attributes`);
108
+ },
109
+ },
110
+ {
111
+ name: "tailscale_set_device_posture_attribute",
112
+ description: "Set a custom posture attribute on a device. Creates or updates the attribute. Attribute keys must start with 'custom:'. Useful for compliance tracking, JIT access, and custom security policies.",
113
+ inputSchema: z.object({
114
+ deviceId: z.string().describe("The device ID"),
115
+ attributeKey: z.string().describe("The attribute key (must start with 'custom:', e.g. 'custom:lastAuditDate')"),
116
+ value: z.string().describe("The attribute value"),
117
+ expiry: z.string().optional().describe("Optional expiry time in RFC3339 format (e.g. '2026-12-01T00:00:00Z'). Attribute is automatically removed after expiry."),
118
+ }),
119
+ handler: async (input) => {
120
+ const body = { value: input.value };
121
+ if (input.expiry !== undefined)
122
+ body.expiry = input.expiry;
123
+ return apiPost(`/device/${encPath(input.deviceId)}/attributes/${encPath(input.attributeKey)}`, body);
124
+ },
125
+ },
126
+ {
127
+ name: "tailscale_delete_device_posture_attribute",
128
+ description: "Delete a custom posture attribute from a device. This is irreversible.",
129
+ inputSchema: z.object({
130
+ deviceId: z.string().describe("The device ID"),
131
+ attributeKey: z.string().describe("The attribute key to delete (e.g. 'custom:lastAuditDate')"),
132
+ }),
133
+ handler: async (input) => {
134
+ return apiDelete(`/device/${encPath(input.deviceId)}/attributes/${encPath(input.attributeKey)}`);
98
135
  },
99
136
  },
100
137
  {
101
138
  name: "tailscale_set_device_tags",
102
- description: "Set ACL tags on a device. Replaces all existing tags.",
139
+ description: "Set ACL tags on a device. Replaces all existing tags — pass the full list of tags you want applied.",
103
140
  inputSchema: z.object({
104
141
  deviceId: z.string().describe("The device ID"),
105
- tags: z.array(z.string()).describe("List of ACL tags (e.g. ['tag:server', 'tag:production'])"),
142
+ tags: z.array(z.string()).describe("Full list of ACL tags (e.g. ['tag:server', 'tag:production']). Replaces all existing tags."),
106
143
  }),
107
144
  handler: async (input) => {
108
- return apiPost(`/device/${input.deviceId}/tags`, { tags: input.tags });
145
+ return apiPost(`/device/${encPath(input.deviceId)}/tags`, { tags: input.tags });
109
146
  },
110
147
  },
111
148
  ];
@@ -1 +1 @@
1
- {"version":3,"file":"devices.js","sourceRoot":"","sources":["../../src/tools/devices.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"devices.js","sourceRoot":"","sources":["../../src/tools/devices.ts"],"names":[],"mappings":"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"}
@@ -6,7 +6,7 @@ export declare const dnsTools: readonly [{
6
6
  readonly handler: () => Promise<import("../api.js").ApiResponse<unknown>>;
7
7
  }, {
8
8
  readonly name: "tailscale_set_nameservers";
9
- readonly description: "Set the DNS nameservers for your tailnet.";
9
+ readonly description: "Set the DNS nameservers for your tailnet. Replaces all existing nameservers.";
10
10
  readonly inputSchema: z.ZodObject<{
11
11
  dns: z.ZodArray<z.ZodString, "many">;
12
12
  }, "strip", z.ZodTypeAny, {
@@ -24,7 +24,7 @@ export declare const dnsTools: readonly [{
24
24
  readonly handler: () => Promise<import("../api.js").ApiResponse<unknown>>;
25
25
  }, {
26
26
  readonly name: "tailscale_set_search_paths";
27
- readonly description: "Set the DNS search paths for your tailnet.";
27
+ readonly description: "Set the DNS search paths for your tailnet. Replaces all existing search paths.";
28
28
  readonly inputSchema: z.ZodObject<{
29
29
  searchPaths: z.ZodArray<z.ZodString, "many">;
30
30
  }, "strip", z.ZodTypeAny, {
@@ -42,7 +42,7 @@ export declare const dnsTools: readonly [{
42
42
  readonly handler: () => Promise<import("../api.js").ApiResponse<unknown>>;
43
43
  }, {
44
44
  readonly name: "tailscale_set_split_dns";
45
- readonly description: "Set split DNS configuration. Maps domains to specific nameservers.";
45
+ readonly description: "Set split DNS configuration. Maps domains to specific nameservers. Replaces the entire split DNS configuration.";
46
46
  readonly inputSchema: z.ZodObject<{
47
47
  splitDns: z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString, "many">>;
48
48
  }, "strip", z.ZodTypeAny, {
package/dist/tools/dns.js CHANGED
@@ -11,7 +11,7 @@ export const dnsTools = [
11
11
  },
12
12
  {
13
13
  name: "tailscale_set_nameservers",
14
- description: "Set the DNS nameservers for your tailnet.",
14
+ description: "Set the DNS nameservers for your tailnet. Replaces all existing nameservers.",
15
15
  inputSchema: z.object({
16
16
  dns: z.array(z.string()).describe("List of DNS server IP addresses (e.g. ['8.8.8.8', '1.1.1.1'])"),
17
17
  }),
@@ -29,7 +29,7 @@ export const dnsTools = [
29
29
  },
30
30
  {
31
31
  name: "tailscale_set_search_paths",
32
- description: "Set the DNS search paths for your tailnet.",
32
+ description: "Set the DNS search paths for your tailnet. Replaces all existing search paths.",
33
33
  inputSchema: z.object({
34
34
  searchPaths: z.array(z.string()).describe("List of DNS search domains (e.g. ['example.com', 'internal.corp'])"),
35
35
  }),
@@ -49,7 +49,7 @@ export const dnsTools = [
49
49
  },
50
50
  {
51
51
  name: "tailscale_set_split_dns",
52
- description: "Set split DNS configuration. Maps domains to specific nameservers.",
52
+ description: "Set split DNS configuration. Maps domains to specific nameservers. Replaces the entire split DNS configuration.",
53
53
  inputSchema: z.object({
54
54
  splitDns: z
55
55
  .record(z.string(), z.array(z.string()))
@@ -1 +1 @@
1
- {"version":3,"file":"dns.js","sourceRoot":"","sources":["../../src/tools/dns.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"dns.js","sourceRoot":"","sources":["../../src/tools/dns.ts"],"names":[],"mappings":"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"}
@@ -19,7 +19,7 @@ export declare const keyTools: readonly [{
19
19
  }) => Promise<import("../api.js").ApiResponse<unknown>>;
20
20
  }, {
21
21
  readonly name: "tailscale_create_key";
22
- readonly description: "Create a new auth key for adding devices to your tailnet.";
22
+ readonly description: "Create a new auth key for adding devices to your tailnet. Returns the key value — save it immediately, as it cannot be retrieved again.";
23
23
  readonly inputSchema: z.ZodObject<{
24
24
  reusable: z.ZodOptional<z.ZodBoolean>;
25
25
  ephemeral: z.ZodOptional<z.ZodBoolean>;
@@ -52,7 +52,7 @@ export declare const keyTools: readonly [{
52
52
  }) => Promise<import("../api.js").ApiResponse<unknown>>;
53
53
  }, {
54
54
  readonly name: "tailscale_delete_key";
55
- readonly description: "Delete an auth key.";
55
+ readonly description: "Delete an auth key. This is irreversible — devices already authenticated with this key are unaffected, but no new devices can use it.";
56
56
  readonly inputSchema: z.ZodObject<{
57
57
  keyId: z.ZodString;
58
58
  }, "strip", z.ZodTypeAny, {
@@ -1,5 +1,5 @@
1
1
  import { z } from "zod";
2
- import { apiGet, apiPost, apiDelete, getTailnet } from "../api.js";
2
+ import { apiGet, apiPost, apiDelete, getTailnet, encPath } from "../api.js";
3
3
  export const keyTools = [
4
4
  {
5
5
  name: "tailscale_list_keys",
@@ -16,12 +16,12 @@ export const keyTools = [
16
16
  keyId: z.string().describe("The auth key ID"),
17
17
  }),
18
18
  handler: async (input) => {
19
- return apiGet(`/tailnet/${getTailnet()}/keys/${input.keyId}`);
19
+ return apiGet(`/tailnet/${getTailnet()}/keys/${encPath(input.keyId)}`);
20
20
  },
21
21
  },
22
22
  {
23
23
  name: "tailscale_create_key",
24
- description: "Create a new auth key for adding devices to your tailnet.",
24
+ description: "Create a new auth key for adding devices to your tailnet. Returns the key value — save it immediately, as it cannot be retrieved again.",
25
25
  inputSchema: z.object({
26
26
  reusable: z.boolean().optional().describe("Whether the key can be used more than once (default: false)"),
27
27
  ephemeral: z.boolean().optional().describe("Whether devices using this key are ephemeral (default: false)"),
@@ -52,12 +52,12 @@ export const keyTools = [
52
52
  },
53
53
  {
54
54
  name: "tailscale_delete_key",
55
- description: "Delete an auth key.",
55
+ description: "Delete an auth key. This is irreversible — devices already authenticated with this key are unaffected, but no new devices can use it.",
56
56
  inputSchema: z.object({
57
57
  keyId: z.string().describe("The auth key ID to delete"),
58
58
  }),
59
59
  handler: async (input) => {
60
- return apiDelete(`/tailnet/${getTailnet()}/keys/${input.keyId}`);
60
+ return apiDelete(`/tailnet/${getTailnet()}/keys/${encPath(input.keyId)}`);
61
61
  },
62
62
  },
63
63
  ];
@@ -1 +1 @@
1
- {"version":3,"file":"keys.js","sourceRoot":"","sources":["../../src/tools/keys.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"keys.js","sourceRoot":"","sources":["../../src/tools/keys.ts"],"names":[],"mappings":"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"}
@@ -6,7 +6,7 @@ export declare const postureTools: readonly [{
6
6
  readonly handler: () => Promise<import("../api.js").ApiResponse<unknown>>;
7
7
  }, {
8
8
  readonly name: "tailscale_get_posture_integration";
9
- readonly description: "Get details for a specific posture integration.";
9
+ readonly description: "Get details for a specific device posture integration.";
10
10
  readonly inputSchema: z.ZodObject<{
11
11
  integrationId: z.ZodString;
12
12
  }, "strip", z.ZodTypeAny, {
@@ -48,7 +48,7 @@ export declare const postureTools: readonly [{
48
48
  }) => Promise<import("../api.js").ApiResponse<unknown>>;
49
49
  }, {
50
50
  readonly name: "tailscale_delete_posture_integration";
51
- readonly description: "Delete a posture integration.";
51
+ readonly description: "Delete a posture integration. This is irreversible.";
52
52
  readonly inputSchema: z.ZodObject<{
53
53
  integrationId: z.ZodString;
54
54
  }, "strip", z.ZodTypeAny, {
@@ -1,5 +1,5 @@
1
1
  import { z } from "zod";
2
- import { apiGet, apiPost, apiDelete, getTailnet } from "../api.js";
2
+ import { apiGet, apiPost, apiDelete, getTailnet, encPath } from "../api.js";
3
3
  export const postureTools = [
4
4
  {
5
5
  name: "tailscale_list_posture_integrations",
@@ -11,12 +11,12 @@ export const postureTools = [
11
11
  },
12
12
  {
13
13
  name: "tailscale_get_posture_integration",
14
- description: "Get details for a specific posture integration.",
14
+ description: "Get details for a specific device posture integration.",
15
15
  inputSchema: z.object({
16
16
  integrationId: z.string().describe("The posture integration ID"),
17
17
  }),
18
18
  handler: async (input) => {
19
- return apiGet(`/tailnet/${getTailnet()}/posture/integrations/${input.integrationId}`);
19
+ return apiGet(`/tailnet/${getTailnet()}/posture/integrations/${encPath(input.integrationId)}`);
20
20
  },
21
21
  },
22
22
  {
@@ -35,12 +35,12 @@ export const postureTools = [
35
35
  },
36
36
  {
37
37
  name: "tailscale_delete_posture_integration",
38
- description: "Delete a posture integration.",
38
+ description: "Delete a posture integration. This is irreversible.",
39
39
  inputSchema: z.object({
40
40
  integrationId: z.string().describe("The posture integration ID to delete"),
41
41
  }),
42
42
  handler: async (input) => {
43
- return apiDelete(`/tailnet/${getTailnet()}/posture/integrations/${input.integrationId}`);
43
+ return apiDelete(`/tailnet/${getTailnet()}/posture/integrations/${encPath(input.integrationId)}`);
44
44
  },
45
45
  },
46
46
  ];
@@ -1 +1 @@
1
- {"version":3,"file":"posture.js","sourceRoot":"","sources":["../../src/tools/posture.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAEnE,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B;QACE,IAAI,EAAE,qCAAqC;QAC3C,WAAW,EAAE,mEAAmE;QAChF,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC;QACzB,OAAO,EAAE,KAAK,IAAI,EAAE;YAClB,OAAO,MAAM,CAAC,YAAY,UAAU,EAAE,uBAAuB,CAAC,CAAC;QACjE,CAAC;KACF;IACD;QACE,IAAI,EAAE,mCAAmC;QACzC,WAAW,EAAE,iDAAiD;QAC9D,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,4BAA4B,CAAC;SACjE,CAAC;QACF,OAAO,EAAE,KAAK,EAAE,KAAgC,EAAE,EAAE;YAClD,OAAO,MAAM,CACX,YAAY,UAAU,EAAE,yBAAyB,KAAK,CAAC,aAAa,EAAE,CACvE,CAAC;QACJ,CAAC;KACF;IACD;QACE,IAAI,EAAE,sCAAsC;QAC5C,WAAW,EAAE,0CAA0C;QACvD,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,oEAAoE,CAAC;YACnG,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,sCAAsC,CAAC;YACrE,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,0CAA0C,CAAC;YAC7E,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,6CAA6C,CAAC;YACvF,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,yCAAyC,CAAC;SAC5F,CAAC;QACF,OAAO,EAAE,KAAK,EAAE,KAMf,EAAE,EAAE;YACH,OAAO,OAAO,CACZ,YAAY,UAAU,EAAE,uBAAuB,EAC/C,KAAK,CACN,CAAC;QACJ,CAAC;KACF;IACD;QACE,IAAI,EAAE,sCAAsC;QAC5C,WAAW,EAAE,+BAA+B;QAC5C,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,sCAAsC,CAAC;SAC3E,CAAC;QACF,OAAO,EAAE,KAAK,EAAE,KAAgC,EAAE,EAAE;YAClD,OAAO,SAAS,CACd,YAAY,UAAU,EAAE,yBAAyB,KAAK,CAAC,aAAa,EAAE,CACvE,CAAC;QACJ,CAAC;KACF;CACO,CAAC"}
1
+ {"version":3,"file":"posture.js","sourceRoot":"","sources":["../../src/tools/posture.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAE5E,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B;QACE,IAAI,EAAE,qCAAqC;QAC3C,WAAW,EAAE,mEAAmE;QAChF,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC;QACzB,OAAO,EAAE,KAAK,IAAI,EAAE;YAClB,OAAO,MAAM,CAAC,YAAY,UAAU,EAAE,uBAAuB,CAAC,CAAC;QACjE,CAAC;KACF;IACD;QACE,IAAI,EAAE,mCAAmC;QACzC,WAAW,EAAE,wDAAwD;QACrE,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,4BAA4B,CAAC;SACjE,CAAC;QACF,OAAO,EAAE,KAAK,EAAE,KAAgC,EAAE,EAAE;YAClD,OAAO,MAAM,CACX,YAAY,UAAU,EAAE,yBAAyB,OAAO,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE,CAChF,CAAC;QACJ,CAAC;KACF;IACD;QACE,IAAI,EAAE,sCAAsC;QAC5C,WAAW,EAAE,0CAA0C;QACvD,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,oEAAoE,CAAC;YACnG,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,sCAAsC,CAAC;YACrE,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,0CAA0C,CAAC;YAC7E,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,6CAA6C,CAAC;YACvF,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,yCAAyC,CAAC;SAC5F,CAAC;QACF,OAAO,EAAE,KAAK,EAAE,KAMf,EAAE,EAAE;YACH,OAAO,OAAO,CACZ,YAAY,UAAU,EAAE,uBAAuB,EAC/C,KAAK,CACN,CAAC;QACJ,CAAC;KACF;IACD;QACE,IAAI,EAAE,sCAAsC;QAC5C,WAAW,EAAE,qDAAqD;QAClE,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,sCAAsC,CAAC;SAC3E,CAAC;QACF,OAAO,EAAE,KAAK,EAAE,KAAgC,EAAE,EAAE;YAClD,OAAO,SAAS,CACd,YAAY,UAAU,EAAE,yBAAyB,OAAO,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE,CAChF,CAAC;QACJ,CAAC;KACF;CACO,CAAC"}
@@ -9,6 +9,7 @@ export declare const statusTools: readonly [{
9
9
  ok: boolean;
10
10
  status: number;
11
11
  data: {
12
+ settingsError?: string | undefined;
12
13
  connected: boolean;
13
14
  tailnet: string;
14
15
  deviceCount: number;
@@ -22,6 +22,7 @@ export const statusTools = [
22
22
  tailnet: getTailnet(),
23
23
  deviceCount,
24
24
  settings: settingsRes.ok ? settingsRes.data : undefined,
25
+ ...(settingsRes.ok ? {} : { settingsError: settingsRes.error || "Failed to fetch tailnet settings" }),
25
26
  },
26
27
  };
27
28
  },
@@ -1 +1 @@
1
- {"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/tools/status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAE/C,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB;QACE,IAAI,EAAE,kBAAkB;QACxB,WAAW,EACT,8JAA8J;QAChK,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC;QACzB,OAAO,EAAE,KAAK,IAAI,EAAE;YAClB,MAAM,CAAC,UAAU,EAAE,WAAW,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;gBAClD,MAAM,CAAyB,YAAY,UAAU,EAAE,oBAAoB,CAAC;gBAC5E,MAAM,CAA0B,YAAY,UAAU,EAAE,WAAW,CAAC;aACrE,CAAC,CAAC;YAEH,IAAI,CAAC,UAAU,CAAC,EAAE,EAAE,CAAC;gBACnB,OAAO,UAAU,CAAC;YACpB,CAAC;YACD,MAAM,WAAW,GAAG,UAAU,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC,CAAC;YAE1D,OAAO;gBACL,EAAE,EAAE,IAAI;gBACR,MAAM,EAAE,GAAG;gBACX,IAAI,EAAE;oBACJ,SAAS,EAAE,IAAI;oBACf,OAAO,EAAE,UAAU,EAAE;oBACrB,WAAW;oBACX,QAAQ,EAAE,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;iBACxD;aACF,CAAC;QACJ,CAAC;KACF;CACO,CAAC"}
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/tools/status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAE/C,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB;QACE,IAAI,EAAE,kBAAkB;QACxB,WAAW,EACT,8JAA8J;QAChK,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC;QACzB,OAAO,EAAE,KAAK,IAAI,EAAE;YAClB,MAAM,CAAC,UAAU,EAAE,WAAW,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;gBAClD,MAAM,CAAyB,YAAY,UAAU,EAAE,oBAAoB,CAAC;gBAC5E,MAAM,CAA0B,YAAY,UAAU,EAAE,WAAW,CAAC;aACrE,CAAC,CAAC;YAEH,IAAI,CAAC,UAAU,CAAC,EAAE,EAAE,CAAC;gBACnB,OAAO,UAAU,CAAC;YACpB,CAAC;YACD,MAAM,WAAW,GAAG,UAAU,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC,CAAC;YAE1D,OAAO;gBACL,EAAE,EAAE,IAAI;gBACR,MAAM,EAAE,GAAG;gBACX,IAAI,EAAE;oBACJ,SAAS,EAAE,IAAI;oBACf,OAAO,EAAE,UAAU,EAAE;oBACrB,WAAW;oBACX,QAAQ,EAAE,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;oBACvD,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,WAAW,CAAC,KAAK,IAAI,kCAAkC,EAAE,CAAC;iBACtG;aACF,CAAC;QACJ,CAAC;KACF;CACO,CAAC"}
@@ -17,4 +17,60 @@ export declare const userTools: readonly [{
17
17
  readonly handler: (input: {
18
18
  userId: string;
19
19
  }) => Promise<import("../api.js").ApiResponse<unknown>>;
20
+ }, {
21
+ readonly name: "tailscale_approve_user";
22
+ readonly description: "Approve a pending user, granting them access to the tailnet.";
23
+ readonly inputSchema: z.ZodObject<{
24
+ userId: z.ZodString;
25
+ }, "strip", z.ZodTypeAny, {
26
+ userId: string;
27
+ }, {
28
+ userId: string;
29
+ }>;
30
+ readonly handler: (input: {
31
+ userId: string;
32
+ }) => Promise<import("../api.js").ApiResponse<unknown>>;
33
+ }, {
34
+ readonly name: "tailscale_suspend_user";
35
+ readonly description: "Suspend a user, immediately revoking their access to the tailnet. Their devices will be disconnected. Can be reversed with tailscale_restore_user.";
36
+ readonly inputSchema: z.ZodObject<{
37
+ userId: z.ZodString;
38
+ }, "strip", z.ZodTypeAny, {
39
+ userId: string;
40
+ }, {
41
+ userId: string;
42
+ }>;
43
+ readonly handler: (input: {
44
+ userId: string;
45
+ }) => Promise<import("../api.js").ApiResponse<unknown>>;
46
+ }, {
47
+ readonly name: "tailscale_restore_user";
48
+ readonly description: "Restore a previously suspended user, re-granting them access to the tailnet.";
49
+ readonly inputSchema: z.ZodObject<{
50
+ userId: z.ZodString;
51
+ }, "strip", z.ZodTypeAny, {
52
+ userId: string;
53
+ }, {
54
+ userId: string;
55
+ }>;
56
+ readonly handler: (input: {
57
+ userId: string;
58
+ }) => Promise<import("../api.js").ApiResponse<unknown>>;
59
+ }, {
60
+ readonly name: "tailscale_update_user_role";
61
+ readonly description: "Update a user's role in the tailnet.";
62
+ readonly inputSchema: z.ZodObject<{
63
+ userId: z.ZodString;
64
+ role: z.ZodEnum<["owner", "admin", "it-admin", "network-admin", "billing-admin", "auditor", "member"]>;
65
+ }, "strip", z.ZodTypeAny, {
66
+ userId: string;
67
+ role: "owner" | "admin" | "it-admin" | "network-admin" | "billing-admin" | "auditor" | "member";
68
+ }, {
69
+ userId: string;
70
+ role: "owner" | "admin" | "it-admin" | "network-admin" | "billing-admin" | "auditor" | "member";
71
+ }>;
72
+ readonly handler: (input: {
73
+ userId: string;
74
+ role: string;
75
+ }) => Promise<import("../api.js").ApiResponse<unknown>>;
20
76
  }];
@@ -1,5 +1,5 @@
1
1
  import { z } from "zod";
2
- import { apiGet, getTailnet } from "../api.js";
2
+ import { apiGet, apiPost, apiPatch, getTailnet, encPath } from "../api.js";
3
3
  export const userTools = [
4
4
  {
5
5
  name: "tailscale_list_users",
@@ -16,7 +16,49 @@ export const userTools = [
16
16
  userId: z.string().describe("The user ID"),
17
17
  }),
18
18
  handler: async (input) => {
19
- return apiGet(`/users/${input.userId}`);
19
+ return apiGet(`/users/${encPath(input.userId)}`);
20
+ },
21
+ },
22
+ {
23
+ name: "tailscale_approve_user",
24
+ description: "Approve a pending user, granting them access to the tailnet.",
25
+ inputSchema: z.object({
26
+ userId: z.string().describe("The user ID to approve"),
27
+ }),
28
+ handler: async (input) => {
29
+ return apiPost(`/users/${encPath(input.userId)}/approve`);
30
+ },
31
+ },
32
+ {
33
+ name: "tailscale_suspend_user",
34
+ description: "Suspend a user, immediately revoking their access to the tailnet. Their devices will be disconnected. Can be reversed with tailscale_restore_user.",
35
+ inputSchema: z.object({
36
+ userId: z.string().describe("The user ID to suspend"),
37
+ }),
38
+ handler: async (input) => {
39
+ return apiPost(`/users/${encPath(input.userId)}/suspend`);
40
+ },
41
+ },
42
+ {
43
+ name: "tailscale_restore_user",
44
+ description: "Restore a previously suspended user, re-granting them access to the tailnet.",
45
+ inputSchema: z.object({
46
+ userId: z.string().describe("The user ID to restore"),
47
+ }),
48
+ handler: async (input) => {
49
+ return apiPost(`/users/${encPath(input.userId)}/restore`);
50
+ },
51
+ },
52
+ {
53
+ name: "tailscale_update_user_role",
54
+ description: "Update a user's role in the tailnet.",
55
+ inputSchema: z.object({
56
+ userId: z.string().describe("The user ID"),
57
+ role: z.enum(["owner", "admin", "it-admin", "network-admin", "billing-admin", "auditor", "member"])
58
+ .describe("The new role to assign"),
59
+ }),
60
+ handler: async (input) => {
61
+ return apiPatch(`/users/${encPath(input.userId)}/role`, { role: input.role });
20
62
  },
21
63
  },
22
64
  ];
@@ -1 +1 @@
1
- {"version":3,"file":"users.js","sourceRoot":"","sources":["../../src/tools/users.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAE/C,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB;QACE,IAAI,EAAE,sBAAsB;QAC5B,WAAW,EAAE,iCAAiC;QAC9C,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC;QACzB,OAAO,EAAE,KAAK,IAAI,EAAE;YAClB,OAAO,MAAM,CAAC,YAAY,UAAU,EAAE,QAAQ,CAAC,CAAC;QAClD,CAAC;KACF;IACD;QACE,IAAI,EAAE,oBAAoB;QAC1B,WAAW,EAAE,kCAAkC;QAC/C,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,aAAa,CAAC;SAC3C,CAAC;QACF,OAAO,EAAE,KAAK,EAAE,KAAyB,EAAE,EAAE;YAC3C,OAAO,MAAM,CAAC,UAAU,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;QAC1C,CAAC;KACF;CACO,CAAC"}
1
+ {"version":3,"file":"users.js","sourceRoot":"","sources":["../../src/tools/users.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAE3E,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB;QACE,IAAI,EAAE,sBAAsB;QAC5B,WAAW,EAAE,iCAAiC;QAC9C,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC;QACzB,OAAO,EAAE,KAAK,IAAI,EAAE;YAClB,OAAO,MAAM,CAAC,YAAY,UAAU,EAAE,QAAQ,CAAC,CAAC;QAClD,CAAC;KACF;IACD;QACE,IAAI,EAAE,oBAAoB;QAC1B,WAAW,EAAE,kCAAkC;QAC/C,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,aAAa,CAAC;SAC3C,CAAC;QACF,OAAO,EAAE,KAAK,EAAE,KAAyB,EAAE,EAAE;YAC3C,OAAO,MAAM,CAAC,UAAU,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACnD,CAAC;KACF;IACD;QACE,IAAI,EAAE,wBAAwB;QAC9B,WAAW,EAAE,8DAA8D;QAC3E,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,wBAAwB,CAAC;SACtD,CAAC;QACF,OAAO,EAAE,KAAK,EAAE,KAAyB,EAAE,EAAE;YAC3C,OAAO,OAAO,CAAC,UAAU,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAC5D,CAAC;KACF;IACD;QACE,IAAI,EAAE,wBAAwB;QAC9B,WAAW,EAAE,oJAAoJ;QACjK,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,wBAAwB,CAAC;SACtD,CAAC;QACF,OAAO,EAAE,KAAK,EAAE,KAAyB,EAAE,EAAE;YAC3C,OAAO,OAAO,CAAC,UAAU,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAC5D,CAAC;KACF;IACD;QACE,IAAI,EAAE,wBAAwB;QAC9B,WAAW,EAAE,8EAA8E;QAC3F,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,wBAAwB,CAAC;SACtD,CAAC;QACF,OAAO,EAAE,KAAK,EAAE,KAAyB,EAAE,EAAE;YAC3C,OAAO,OAAO,CAAC,UAAU,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAC5D,CAAC;KACF;IACD;QACE,IAAI,EAAE,4BAA4B;QAClC,WAAW,EAAE,sCAAsC;QACnD,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,aAAa,CAAC;YAC1C,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,eAAe,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;iBAChG,QAAQ,CAAC,wBAAwB,CAAC;SACtC,CAAC;QACF,OAAO,EAAE,KAAK,EAAE,KAAuC,EAAE,EAAE;YACzD,OAAO,QAAQ,CAAC,UAAU,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;QAChF,CAAC;KACF;CACO,CAAC"}
@@ -36,20 +36,24 @@ export declare const webhookTools: readonly [{
36
36
  }) => Promise<import("../api.js").ApiResponse<unknown>>;
37
37
  }, {
38
38
  readonly name: "tailscale_update_webhook";
39
- readonly description: "Update an existing webhook's subscriptions.";
39
+ readonly description: "Update an existing webhook's endpoint URL and/or subscriptions.";
40
40
  readonly inputSchema: z.ZodObject<{
41
41
  webhookId: z.ZodString;
42
- subscriptions: z.ZodArray<z.ZodString, "many">;
42
+ endpointUrl: z.ZodOptional<z.ZodString>;
43
+ subscriptions: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
43
44
  }, "strip", z.ZodTypeAny, {
44
45
  webhookId: string;
45
- subscriptions: string[];
46
+ endpointUrl?: string | undefined;
47
+ subscriptions?: string[] | undefined;
46
48
  }, {
47
49
  webhookId: string;
48
- subscriptions: string[];
50
+ endpointUrl?: string | undefined;
51
+ subscriptions?: string[] | undefined;
49
52
  }>;
50
53
  readonly handler: (input: {
51
54
  webhookId: string;
52
- subscriptions: string[];
55
+ endpointUrl?: string;
56
+ subscriptions?: string[];
53
57
  }) => Promise<import("../api.js").ApiResponse<unknown>>;
54
58
  }, {
55
59
  readonly name: "tailscale_delete_webhook";
@@ -1,5 +1,5 @@
1
1
  import { z } from "zod";
2
- import { apiGet, apiPost, apiPatch, apiDelete, getTailnet } from "../api.js";
2
+ import { apiGet, apiPost, apiPatch, apiDelete, getTailnet, encPath } from "../api.js";
3
3
  export const webhookTools = [
4
4
  {
5
5
  name: "tailscale_list_webhooks",
@@ -16,7 +16,7 @@ export const webhookTools = [
16
16
  webhookId: z.string().describe("The webhook ID"),
17
17
  }),
18
18
  handler: async (input) => {
19
- return apiGet(`/webhooks/${input.webhookId}`);
19
+ return apiGet(`/webhooks/${encPath(input.webhookId)}`);
20
20
  },
21
21
  },
22
22
  {
@@ -37,17 +37,22 @@ export const webhookTools = [
37
37
  },
38
38
  {
39
39
  name: "tailscale_update_webhook",
40
- description: "Update an existing webhook's subscriptions.",
40
+ description: "Update an existing webhook's endpoint URL and/or subscriptions.",
41
41
  inputSchema: z.object({
42
42
  webhookId: z.string().describe("The webhook ID to update"),
43
+ endpointUrl: z.string().optional().describe("New URL to send webhook events to"),
43
44
  subscriptions: z
44
45
  .array(z.string())
46
+ .optional()
45
47
  .describe("Updated list of event types to subscribe to (e.g. ['nodeCreated', 'nodeDeleted', 'nodeApproved', 'policyUpdate', 'userCreated', 'userDeleted'])"),
46
48
  }),
47
49
  handler: async (input) => {
48
- return apiPatch(`/webhooks/${input.webhookId}`, {
49
- subscriptions: input.subscriptions,
50
- });
50
+ const body = {};
51
+ if (input.endpointUrl !== undefined)
52
+ body.endpointUrl = input.endpointUrl;
53
+ if (input.subscriptions !== undefined)
54
+ body.subscriptions = input.subscriptions;
55
+ return apiPatch(`/webhooks/${encPath(input.webhookId)}`, body);
51
56
  },
52
57
  },
53
58
  {
@@ -57,7 +62,7 @@ export const webhookTools = [
57
62
  webhookId: z.string().describe("The webhook ID to delete"),
58
63
  }),
59
64
  handler: async (input) => {
60
- return apiDelete(`/webhooks/${input.webhookId}`);
65
+ return apiDelete(`/webhooks/${encPath(input.webhookId)}`);
61
66
  },
62
67
  },
63
68
  ];
@@ -1 +1 @@
1
- {"version":3,"file":"webhooks.js","sourceRoot":"","sources":["../../src/tools/webhooks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAE7E,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B;QACE,IAAI,EAAE,yBAAyB;QAC/B,WAAW,EAAE,gDAAgD;QAC7D,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC;QACzB,OAAO,EAAE,KAAK,IAAI,EAAE;YAClB,OAAO,MAAM,CAAC,YAAY,UAAU,EAAE,WAAW,CAAC,CAAC;QACrD,CAAC;KACF;IACD;QACE,IAAI,EAAE,uBAAuB;QAC7B,WAAW,EAAE,qCAAqC;QAClD,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,gBAAgB,CAAC;SACjD,CAAC;QACF,OAAO,EAAE,KAAK,EAAE,KAA4B,EAAE,EAAE;YAC9C,OAAO,MAAM,CAAC,aAAa,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC;QAChD,CAAC;KACF;IACD;QACE,IAAI,EAAE,0BAA0B;QAChC,WAAW,EAAE,uBAAuB;QACpC,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,mCAAmC,CAAC;YACrE,aAAa,EAAE,CAAC;iBACb,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;iBACjB,QAAQ,CACP,iIAAiI,CAClI;SACJ,CAAC;QACF,OAAO,EAAE,KAAK,EAAE,KAAuD,EAAE,EAAE;YACzE,OAAO,OAAO,CAAC,YAAY,UAAU,EAAE,WAAW,EAAE;gBAClD,WAAW,EAAE,KAAK,CAAC,WAAW;gBAC9B,aAAa,EAAE,KAAK,CAAC,aAAa;aACnC,CAAC,CAAC;QACL,CAAC;KACF;IACD;QACE,IAAI,EAAE,0BAA0B;QAChC,WAAW,EAAE,6CAA6C;QAC1D,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,0BAA0B,CAAC;YAC1D,aAAa,EAAE,CAAC;iBACb,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;iBACjB,QAAQ,CACP,iJAAiJ,CAClJ;SACJ,CAAC;QACF,OAAO,EAAE,KAAK,EAAE,KAAqD,EAAE,EAAE;YACvE,OAAO,QAAQ,CAAC,aAAa,KAAK,CAAC,SAAS,EAAE,EAAE;gBAC9C,aAAa,EAAE,KAAK,CAAC,aAAa;aACnC,CAAC,CAAC;QACL,CAAC;KACF;IACD;QACE,IAAI,EAAE,0BAA0B;QAChC,WAAW,EAAE,kFAAkF;QAC/F,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,0BAA0B,CAAC;SAC3D,CAAC;QACF,OAAO,EAAE,KAAK,EAAE,KAA4B,EAAE,EAAE;YAC9C,OAAO,SAAS,CAAC,aAAa,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC;QACnD,CAAC;KACF;CACO,CAAC"}
1
+ {"version":3,"file":"webhooks.js","sourceRoot":"","sources":["../../src/tools/webhooks.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yawlabs/tailscale-mcp",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "description": "Tailscale MCP server for managing your tailnet from AI assistants",
5
5
  "license": "MIT",
6
6
  "author": "YawLabs <contact@yaw.sh>",