@yawlabs/tailscale-mcp 0.10.7 → 0.10.8
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 +1 -1
- package/dist/index.js +28 -9
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -210,7 +210,7 @@ MCP Resources expose read-only data clients can browse without a tool call.
|
|
|
210
210
|
| ACL Policy | `tailscale://tailnet/acl` | Full ACL policy (HuJSON preserved) |
|
|
211
211
|
| DNS Config | `tailscale://tailnet/dns` | Nameservers, search paths, split DNS, MagicDNS |
|
|
212
212
|
|
|
213
|
-
## Tools (
|
|
213
|
+
## Tools (89)
|
|
214
214
|
|
|
215
215
|
<details>
|
|
216
216
|
<summary><strong>Status</strong> (1 tool)</summary>
|
package/dist/index.js
CHANGED
|
@@ -31141,19 +31141,16 @@ function compute429DelayMs(retryAfter, attempt) {
|
|
|
31141
31141
|
const base = Math.min(DEFAULT_429_DELAY_MS * 2 ** attempt, MAX_429_DELAY_MS);
|
|
31142
31142
|
return base + Math.floor(Math.random() * 250);
|
|
31143
31143
|
}
|
|
31144
|
-
async function executeFetch(method, url2, headers, body) {
|
|
31144
|
+
async function executeFetch(method, url2, headers, body, timeoutMs) {
|
|
31145
31145
|
return fetch(url2, {
|
|
31146
31146
|
method,
|
|
31147
31147
|
headers,
|
|
31148
31148
|
body,
|
|
31149
|
-
signal: AbortSignal.timeout(
|
|
31149
|
+
signal: AbortSignal.timeout(timeoutMs)
|
|
31150
31150
|
});
|
|
31151
31151
|
}
|
|
31152
31152
|
async function apiRequest(method, path, body, options) {
|
|
31153
|
-
const
|
|
31154
|
-
const headers = {
|
|
31155
|
-
Authorization: auth
|
|
31156
|
-
};
|
|
31153
|
+
const headers = {};
|
|
31157
31154
|
if (options?.accept) {
|
|
31158
31155
|
headers.Accept = options.accept;
|
|
31159
31156
|
}
|
|
@@ -31174,9 +31171,19 @@ async function apiRequest(method, path, body, options) {
|
|
|
31174
31171
|
const isRetryable = RETRYABLE_METHODS.has(method.toUpperCase());
|
|
31175
31172
|
const requestBudgetMs = getRequestBudgetMs();
|
|
31176
31173
|
return withConcurrencyLimit(async () => {
|
|
31174
|
+
headers.Authorization = await getAuthHeader();
|
|
31177
31175
|
let res;
|
|
31178
31176
|
for (let attempt = 0; attempt <= MAX_429_RETRIES; attempt++) {
|
|
31179
|
-
|
|
31177
|
+
const remaining = requestBudgetMs - (Date.now() - startedAt);
|
|
31178
|
+
if (remaining <= 0) {
|
|
31179
|
+
return {
|
|
31180
|
+
ok: false,
|
|
31181
|
+
status: 0,
|
|
31182
|
+
error: `Request budget of ${requestBudgetMs}ms exhausted before attempt could begin.`
|
|
31183
|
+
};
|
|
31184
|
+
}
|
|
31185
|
+
const attemptTimeoutMs = Math.min(REQUEST_TIMEOUT_MS, remaining);
|
|
31186
|
+
res = await executeFetch(method, url2, headers, fetchBody, attemptTimeoutMs);
|
|
31180
31187
|
if (res.status !== 429 || attempt === MAX_429_RETRIES || !isRetryable) break;
|
|
31181
31188
|
const delay = compute429DelayMs(res.headers.get("retry-after"), attempt);
|
|
31182
31189
|
const elapsed2 = Date.now() - startedAt;
|
|
@@ -31363,7 +31370,11 @@ async function tailnetDevicesResource(uri) {
|
|
|
31363
31370
|
}
|
|
31364
31371
|
async function tailnetAclResource(uri) {
|
|
31365
31372
|
const res = await apiGet(`/tailnet/${getTailnet()}/acl`, { acceptRaw: true, accept: "application/hujson" });
|
|
31366
|
-
|
|
31373
|
+
if (res.ok) {
|
|
31374
|
+
return { contents: [{ uri: uri.href, text: res.rawBody ?? "", mimeType: "application/hujson" }] };
|
|
31375
|
+
}
|
|
31376
|
+
const lines = `Error: ${res.error ?? `HTTP ${res.status}`}`.split("\n");
|
|
31377
|
+
const text = `${lines.map((l) => `// ${l}`).join("\n")}
|
|
31367
31378
|
`;
|
|
31368
31379
|
return { contents: [{ uri: uri.href, text, mimeType: "application/hujson" }] };
|
|
31369
31380
|
}
|
|
@@ -32451,6 +32462,14 @@ var keyTools = [
|
|
|
32451
32462
|
if (wrongFields.length > 0) {
|
|
32452
32463
|
throw new Error(`${wrongFields.join(", ")} can only be used with keyType 'auth', not '${keyType}'`);
|
|
32453
32464
|
}
|
|
32465
|
+
} else {
|
|
32466
|
+
const nonAuthFields = ["scopes", "issuer", "subject", "audience", "customClaimRules"];
|
|
32467
|
+
const wrongFields = nonAuthFields.filter((f) => input[f] !== void 0);
|
|
32468
|
+
if (wrongFields.length > 0) {
|
|
32469
|
+
throw new Error(
|
|
32470
|
+
`${wrongFields.join(", ")} cannot be used with keyType 'auth'. Set keyType to 'client' or 'federated'.`
|
|
32471
|
+
);
|
|
32472
|
+
}
|
|
32454
32473
|
}
|
|
32455
32474
|
const body = {};
|
|
32456
32475
|
if (keyType !== "auth") body.keyType = keyType;
|
|
@@ -33448,7 +33467,7 @@ var webhookTools = [
|
|
|
33448
33467
|
];
|
|
33449
33468
|
|
|
33450
33469
|
// src/index.ts
|
|
33451
|
-
var version2 = true ? "0.10.
|
|
33470
|
+
var version2 = true ? "0.10.8" : (await null).createRequire(import.meta.url)("../package.json").version;
|
|
33452
33471
|
var subcommand = process.argv[2];
|
|
33453
33472
|
if (subcommand === "deploy-acl") {
|
|
33454
33473
|
const filePath = process.argv[3];
|