@dominusnode/flowise-tools 1.0.1 → 1.3.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.
- package/CHANGELOG.md +30 -0
- package/LICENSE +21 -0
- package/README.md +83 -0
- package/dist/toolkit.d.ts +37 -2
- package/dist/toolkit.d.ts.map +1 -1
- package/dist/toolkit.js +1265 -177
- package/dist/toolkit.js.map +1 -1
- package/package.json +3 -2
package/dist/toolkit.js
CHANGED
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* Dominus Node Flowise Toolkit
|
|
4
4
|
*
|
|
5
|
-
* Provides
|
|
5
|
+
* Provides 53 LangChain-compatible DynamicStructuredTool instances for use
|
|
6
6
|
* inside Flowise AI workflows. Covers proxied fetching, wallet management,
|
|
7
|
-
* agentic wallets, teams, PayPal top-up,
|
|
7
|
+
* agentic wallets, teams, Stripe/PayPal/crypto top-up, x402 micropayment info,
|
|
8
|
+
* account management, API key management, plans, sessions, and usage analytics.
|
|
8
9
|
*
|
|
9
10
|
* Security:
|
|
10
11
|
* - Full SSRF protection (private IP blocking, DNS rebinding, Teredo/6to4,
|
|
@@ -391,6 +392,7 @@ class DominusNodeToolkit {
|
|
|
391
392
|
const portVal = Number(options.proxyPort || process.env.DOMINUSNODE_PROXY_PORT || 8080);
|
|
392
393
|
this.proxyPort = isNaN(portVal) || portVal < 1 || portVal > 65535 ? 8080 : portVal;
|
|
393
394
|
this.timeout = options.timeout || 30000;
|
|
395
|
+
this.agentSecret = options.agentSecret || process.env.DOMINUSNODE_AGENT_SECRET;
|
|
394
396
|
}
|
|
395
397
|
// -----------------------------------------------------------------------
|
|
396
398
|
// Authentication
|
|
@@ -402,12 +404,17 @@ class DominusNodeToolkit {
|
|
|
402
404
|
if (!this.apiKey.startsWith("dn_live_") && !this.apiKey.startsWith("dn_test_")) {
|
|
403
405
|
throw new Error('DOMINUSNODE_API_KEY must start with "dn_live_" or "dn_test_".');
|
|
404
406
|
}
|
|
407
|
+
const authHeaders = {
|
|
408
|
+
"Content-Type": "application/json",
|
|
409
|
+
"User-Agent": "dominusnode-flowise/1.0.0",
|
|
410
|
+
};
|
|
411
|
+
if (this.agentSecret) {
|
|
412
|
+
authHeaders["X-DominusNode-Agent"] = "mcp";
|
|
413
|
+
authHeaders["X-DominusNode-Agent-Secret"] = this.agentSecret;
|
|
414
|
+
}
|
|
405
415
|
const res = await fetch(`${this.baseUrl}/api/auth/verify-key`, {
|
|
406
416
|
method: "POST",
|
|
407
|
-
headers:
|
|
408
|
-
"Content-Type": "application/json",
|
|
409
|
-
"User-Agent": "dominusnode-flowise/1.0.0",
|
|
410
|
-
},
|
|
417
|
+
headers: authHeaders,
|
|
411
418
|
body: JSON.stringify({ apiKey: this.apiKey }),
|
|
412
419
|
redirect: "error",
|
|
413
420
|
signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),
|
|
@@ -439,6 +446,10 @@ class DominusNodeToolkit {
|
|
|
439
446
|
Accept: "application/json",
|
|
440
447
|
"User-Agent": "dominusnode-flowise/1.0.0",
|
|
441
448
|
};
|
|
449
|
+
if (this.agentSecret) {
|
|
450
|
+
headers["X-DominusNode-Agent"] = "mcp";
|
|
451
|
+
headers["X-DominusNode-Agent-Secret"] = this.agentSecret;
|
|
452
|
+
}
|
|
442
453
|
const init = {
|
|
443
454
|
method,
|
|
444
455
|
headers,
|
|
@@ -511,6 +522,76 @@ class DominusNodeToolkit {
|
|
|
511
522
|
}
|
|
512
523
|
}
|
|
513
524
|
// -----------------------------------------------------------------------
|
|
525
|
+
// Unauthenticated request helper (register, login, verifyEmail)
|
|
526
|
+
// -----------------------------------------------------------------------
|
|
527
|
+
async _unauthenticatedRequest(method, path, body) {
|
|
528
|
+
const url = `${this.baseUrl}${path}`;
|
|
529
|
+
const headers = {
|
|
530
|
+
"Content-Type": "application/json",
|
|
531
|
+
"User-Agent": "dominusnode-flowise/1.0.0",
|
|
532
|
+
};
|
|
533
|
+
if (this.agentSecret) {
|
|
534
|
+
headers["X-DominusNode-Agent"] = "mcp";
|
|
535
|
+
headers["X-DominusNode-Agent-Secret"] = this.agentSecret;
|
|
536
|
+
}
|
|
537
|
+
const init = {
|
|
538
|
+
method,
|
|
539
|
+
headers,
|
|
540
|
+
signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),
|
|
541
|
+
redirect: "error",
|
|
542
|
+
};
|
|
543
|
+
if (body) {
|
|
544
|
+
init.body = JSON.stringify(body);
|
|
545
|
+
}
|
|
546
|
+
let res;
|
|
547
|
+
try {
|
|
548
|
+
res = await fetch(url, init);
|
|
549
|
+
}
|
|
550
|
+
catch (err) {
|
|
551
|
+
throw new Error(`Request failed: ${safeError(err)}`);
|
|
552
|
+
}
|
|
553
|
+
let rawText;
|
|
554
|
+
try {
|
|
555
|
+
rawText = await res.text();
|
|
556
|
+
}
|
|
557
|
+
catch {
|
|
558
|
+
rawText = "";
|
|
559
|
+
}
|
|
560
|
+
if (new TextEncoder().encode(rawText).length > MAX_RESPONSE_BYTES) {
|
|
561
|
+
throw new Error("Response too large");
|
|
562
|
+
}
|
|
563
|
+
if (!res.ok) {
|
|
564
|
+
let errorMsg = `Error ${res.status}`;
|
|
565
|
+
if (rawText) {
|
|
566
|
+
try {
|
|
567
|
+
const parsed = JSON.parse(rawText);
|
|
568
|
+
stripDangerousKeys(parsed);
|
|
569
|
+
if (parsed.error) {
|
|
570
|
+
errorMsg = `Error ${res.status}: ${scrubCredentials(String(parsed.error))}`;
|
|
571
|
+
}
|
|
572
|
+
else if (parsed.message) {
|
|
573
|
+
errorMsg = `Error ${res.status}: ${scrubCredentials(String(parsed.message))}`;
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
catch {
|
|
577
|
+
errorMsg = `Error ${res.status}: ${scrubCredentials(rawText.slice(0, 200))}`;
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
throw new Error(errorMsg);
|
|
581
|
+
}
|
|
582
|
+
if (!rawText || rawText.trim().length === 0) {
|
|
583
|
+
return {};
|
|
584
|
+
}
|
|
585
|
+
try {
|
|
586
|
+
const parsed = JSON.parse(rawText);
|
|
587
|
+
stripDangerousKeys(parsed);
|
|
588
|
+
return parsed;
|
|
589
|
+
}
|
|
590
|
+
catch {
|
|
591
|
+
throw new Error("Failed to parse response as JSON");
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
// -----------------------------------------------------------------------
|
|
514
595
|
// Tool 1: proxiedFetch
|
|
515
596
|
// -----------------------------------------------------------------------
|
|
516
597
|
async proxiedFetch(url, method = "GET", country, proxyType = "dc") {
|
|
@@ -1342,7 +1423,57 @@ class DominusNodeToolkit {
|
|
|
1342
1423
|
}
|
|
1343
1424
|
}
|
|
1344
1425
|
// -----------------------------------------------------------------------
|
|
1345
|
-
// Tool 23:
|
|
1426
|
+
// Tool 23: topupStripe
|
|
1427
|
+
// -----------------------------------------------------------------------
|
|
1428
|
+
async topupStripe(amountCents) {
|
|
1429
|
+
try {
|
|
1430
|
+
if (!Number.isInteger(amountCents) || amountCents < 500 || amountCents > 100000) {
|
|
1431
|
+
return "Error: amount_cents must be an integer between 500 ($5) and 100000 ($1,000).";
|
|
1432
|
+
}
|
|
1433
|
+
const data = await this._requestWithRetry("POST", "/api/wallet/topup/stripe", { amountCents });
|
|
1434
|
+
return [
|
|
1435
|
+
"Stripe Checkout Session Created",
|
|
1436
|
+
"",
|
|
1437
|
+
`Session ID: ${data.sessionId}`,
|
|
1438
|
+
`Amount: ${formatCents(amountCents)}`,
|
|
1439
|
+
`Checkout URL: ${data.url}`,
|
|
1440
|
+
"",
|
|
1441
|
+
"Open the checkout URL in a browser to complete payment.",
|
|
1442
|
+
"Once paid, the funds will be credited to your wallet automatically.",
|
|
1443
|
+
].join("\n");
|
|
1444
|
+
}
|
|
1445
|
+
catch (err) {
|
|
1446
|
+
return `Error: ${safeError(err)}`;
|
|
1447
|
+
}
|
|
1448
|
+
}
|
|
1449
|
+
async topupCrypto(amountUsd, currency) {
|
|
1450
|
+
try {
|
|
1451
|
+
if (typeof amountUsd !== "number" || !Number.isFinite(amountUsd) || amountUsd < 5 || amountUsd > 1000) {
|
|
1452
|
+
return "Error: amount_usd must be a number between 5 and 1,000.";
|
|
1453
|
+
}
|
|
1454
|
+
const cur = String(currency ?? "").toLowerCase();
|
|
1455
|
+
if (!DominusNodeToolkit.VALID_CRYPTO_CURRENCIES.has(cur)) {
|
|
1456
|
+
return `Error: currency must be one of: ${[...DominusNodeToolkit.VALID_CRYPTO_CURRENCIES].join(", ")}.`;
|
|
1457
|
+
}
|
|
1458
|
+
const data = await this._requestWithRetry("POST", "/api/wallet/topup/crypto", { amountUsd, currency: cur });
|
|
1459
|
+
return [
|
|
1460
|
+
"Crypto Payment Invoice Created",
|
|
1461
|
+
"",
|
|
1462
|
+
`Invoice ID: ${data.invoiceId}`,
|
|
1463
|
+
`Amount: $${amountUsd}`,
|
|
1464
|
+
`Pay: ${data.priceAmount} ${data.payCurrency?.toUpperCase() ?? cur.toUpperCase()}`,
|
|
1465
|
+
`Payment URL: ${data.invoiceUrl}`,
|
|
1466
|
+
"",
|
|
1467
|
+
"Open the payment URL to complete payment.",
|
|
1468
|
+
"Once confirmed on-chain, the funds will be credited to your wallet.",
|
|
1469
|
+
].join("\n");
|
|
1470
|
+
}
|
|
1471
|
+
catch (err) {
|
|
1472
|
+
return `Error: ${safeError(err)}`;
|
|
1473
|
+
}
|
|
1474
|
+
}
|
|
1475
|
+
// -----------------------------------------------------------------------
|
|
1476
|
+
// Tool 25: x402Info
|
|
1346
1477
|
// -----------------------------------------------------------------------
|
|
1347
1478
|
async x402Info() {
|
|
1348
1479
|
try {
|
|
@@ -1354,176 +1485,804 @@ class DominusNodeToolkit {
|
|
|
1354
1485
|
}
|
|
1355
1486
|
}
|
|
1356
1487
|
// -----------------------------------------------------------------------
|
|
1357
|
-
//
|
|
1488
|
+
// Tool 26: getProxyStatus
|
|
1358
1489
|
// -----------------------------------------------------------------------
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
})
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
}
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
}
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
}
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
})
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1490
|
+
async getProxyStatus() {
|
|
1491
|
+
try {
|
|
1492
|
+
const data = await this._requestWithRetry("GET", "/api/proxy/status");
|
|
1493
|
+
const lines = [
|
|
1494
|
+
"Proxy Status",
|
|
1495
|
+
"",
|
|
1496
|
+
];
|
|
1497
|
+
if (data.status)
|
|
1498
|
+
lines.push(`Status: ${data.status}`);
|
|
1499
|
+
if (data.uptime !== undefined)
|
|
1500
|
+
lines.push(`Uptime: ${data.uptime}`);
|
|
1501
|
+
if (data.activeConnections !== undefined)
|
|
1502
|
+
lines.push(`Active Connections: ${data.activeConnections}`);
|
|
1503
|
+
if (data.providerStatus)
|
|
1504
|
+
lines.push(`Provider Status: ${JSON.stringify(data.providerStatus)}`);
|
|
1505
|
+
if (Object.keys(data).length === 0) {
|
|
1506
|
+
lines.push("No status data available.");
|
|
1507
|
+
}
|
|
1508
|
+
return truncate(lines.join("\n"));
|
|
1509
|
+
}
|
|
1510
|
+
catch (err) {
|
|
1511
|
+
return `Error: ${safeError(err)}`;
|
|
1512
|
+
}
|
|
1513
|
+
}
|
|
1514
|
+
// -----------------------------------------------------------------------
|
|
1515
|
+
// Tool 27: getTransactions
|
|
1516
|
+
// -----------------------------------------------------------------------
|
|
1517
|
+
async getTransactions(limit = 20) {
|
|
1518
|
+
try {
|
|
1519
|
+
const lim = Math.min(Math.max(Math.floor(limit), 1), 100);
|
|
1520
|
+
const data = await this._requestWithRetry("GET", `/api/wallet/transactions?limit=${lim}`);
|
|
1521
|
+
const txs = data.transactions ?? [];
|
|
1522
|
+
if (txs.length === 0) {
|
|
1523
|
+
return "No wallet transactions found.";
|
|
1524
|
+
}
|
|
1525
|
+
const lines = [`Wallet Transactions (${txs.length})`, ""];
|
|
1526
|
+
for (const tx of txs) {
|
|
1527
|
+
const sign = tx.type === "topup" || tx.type === "fund" || tx.type === "refund" ? "+" : "-";
|
|
1528
|
+
lines.push(` ${sign}${formatCents(tx.amountCents)} [${tx.type}] ${tx.description}`);
|
|
1529
|
+
lines.push(` ${tx.createdAt}`);
|
|
1530
|
+
}
|
|
1531
|
+
return truncate(lines.join("\n"));
|
|
1532
|
+
}
|
|
1533
|
+
catch (err) {
|
|
1534
|
+
return `Error: ${safeError(err)}`;
|
|
1535
|
+
}
|
|
1536
|
+
}
|
|
1537
|
+
// -----------------------------------------------------------------------
|
|
1538
|
+
// Tool 28: getForecast
|
|
1539
|
+
// -----------------------------------------------------------------------
|
|
1540
|
+
async getForecast() {
|
|
1541
|
+
try {
|
|
1542
|
+
const data = await this._requestWithRetry("GET", "/api/wallet/forecast");
|
|
1543
|
+
const lines = [
|
|
1544
|
+
"Wallet Balance Forecast",
|
|
1545
|
+
"",
|
|
1546
|
+
`Current Balance: ${formatCents(data.balanceCents ?? 0)}`,
|
|
1547
|
+
`Average Daily Spend: ${formatCents(data.avgDailySpendCents ?? 0)}`,
|
|
1548
|
+
`Estimated Days Remaining: ${data.daysRemaining ?? "N/A"}`,
|
|
1549
|
+
];
|
|
1550
|
+
if (data.estimatedDepletionDate) {
|
|
1551
|
+
lines.push(`Estimated Depletion Date: ${data.estimatedDepletionDate}`);
|
|
1552
|
+
}
|
|
1553
|
+
return lines.join("\n");
|
|
1554
|
+
}
|
|
1555
|
+
catch (err) {
|
|
1556
|
+
return `Error: ${safeError(err)}`;
|
|
1557
|
+
}
|
|
1558
|
+
}
|
|
1559
|
+
// -----------------------------------------------------------------------
|
|
1560
|
+
// Tool 29: checkPayment
|
|
1561
|
+
// -----------------------------------------------------------------------
|
|
1562
|
+
async checkPayment(invoiceId) {
|
|
1563
|
+
try {
|
|
1564
|
+
if (!invoiceId || invoiceId.trim().length === 0) {
|
|
1565
|
+
return "Error: invoice_id is required.";
|
|
1566
|
+
}
|
|
1567
|
+
if (/[\x00-\x1f\x7f]/.test(invoiceId)) {
|
|
1568
|
+
return "Error: invoice_id contains invalid control characters.";
|
|
1569
|
+
}
|
|
1570
|
+
const data = await this._requestWithRetry("GET", `/api/wallet/topup/crypto/${encodeURIComponent(invoiceId.trim())}/status`);
|
|
1571
|
+
const lines = [
|
|
1572
|
+
"Crypto Payment Status",
|
|
1573
|
+
"",
|
|
1574
|
+
`Invoice ID: ${data.invoiceId ?? invoiceId}`,
|
|
1575
|
+
`Status: ${data.status ?? "unknown"}`,
|
|
1576
|
+
`Amount: $${data.amountUsd ?? "N/A"}`,
|
|
1577
|
+
`Currency: ${data.payCurrency?.toUpperCase() ?? "N/A"}`,
|
|
1578
|
+
];
|
|
1579
|
+
if (data.paidAt) {
|
|
1580
|
+
lines.push(`Paid At: ${data.paidAt}`);
|
|
1581
|
+
}
|
|
1582
|
+
return lines.join("\n");
|
|
1583
|
+
}
|
|
1584
|
+
catch (err) {
|
|
1585
|
+
return `Error: ${safeError(err)}`;
|
|
1586
|
+
}
|
|
1587
|
+
}
|
|
1588
|
+
// -----------------------------------------------------------------------
|
|
1589
|
+
// Tool 30: getDailyUsage
|
|
1590
|
+
// -----------------------------------------------------------------------
|
|
1591
|
+
async getDailyUsage(days = 7) {
|
|
1592
|
+
try {
|
|
1593
|
+
const d = Math.min(Math.max(Math.floor(days), 1), 365);
|
|
1594
|
+
const data = await this._requestWithRetry("GET", `/api/usage/daily?days=${d}`);
|
|
1595
|
+
const dayEntries = data.days ?? [];
|
|
1596
|
+
if (dayEntries.length === 0) {
|
|
1597
|
+
return "No daily usage data available.";
|
|
1598
|
+
}
|
|
1599
|
+
const lines = [`Daily Usage (last ${d} days)`, ""];
|
|
1600
|
+
for (const day of dayEntries) {
|
|
1601
|
+
lines.push(` ${day.date}: ${formatBytes(day.bytes)} | ${formatCents(day.costCents)} | ${day.requests} reqs`);
|
|
1602
|
+
}
|
|
1603
|
+
return truncate(lines.join("\n"));
|
|
1604
|
+
}
|
|
1605
|
+
catch (err) {
|
|
1606
|
+
return `Error: ${safeError(err)}`;
|
|
1607
|
+
}
|
|
1608
|
+
}
|
|
1609
|
+
// -----------------------------------------------------------------------
|
|
1610
|
+
// Tool 31: getTopHosts
|
|
1611
|
+
// -----------------------------------------------------------------------
|
|
1612
|
+
async getTopHosts(limit = 10) {
|
|
1613
|
+
try {
|
|
1614
|
+
const lim = Math.min(Math.max(Math.floor(limit), 1), 100);
|
|
1615
|
+
const data = await this._requestWithRetry("GET", `/api/usage/top-hosts?limit=${lim}`);
|
|
1616
|
+
const hosts = data.hosts ?? [];
|
|
1617
|
+
if (hosts.length === 0) {
|
|
1618
|
+
return "No top hosts data available.";
|
|
1619
|
+
}
|
|
1620
|
+
const lines = [`Top Hosts by Bandwidth (${hosts.length})`, ""];
|
|
1621
|
+
for (const h of hosts) {
|
|
1622
|
+
lines.push(` ${h.host}: ${formatBytes(h.bytes)} | ${formatCents(h.costCents)} | ${h.requests} reqs`);
|
|
1623
|
+
}
|
|
1624
|
+
return truncate(lines.join("\n"));
|
|
1625
|
+
}
|
|
1626
|
+
catch (err) {
|
|
1627
|
+
return `Error: ${safeError(err)}`;
|
|
1628
|
+
}
|
|
1629
|
+
}
|
|
1630
|
+
// -----------------------------------------------------------------------
|
|
1631
|
+
// Tool 32: register (unauthenticated)
|
|
1632
|
+
// -----------------------------------------------------------------------
|
|
1633
|
+
async register(email, password) {
|
|
1634
|
+
try {
|
|
1635
|
+
if (!email || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
|
|
1636
|
+
return "Error: a valid email address is required.";
|
|
1637
|
+
}
|
|
1638
|
+
if (!password || password.length < 8 || password.length > 128) {
|
|
1639
|
+
return "Error: password must be between 8 and 128 characters.";
|
|
1640
|
+
}
|
|
1641
|
+
const data = await this._unauthenticatedRequest("POST", "/api/auth/register", { email, password });
|
|
1642
|
+
return [
|
|
1643
|
+
"Account Created",
|
|
1644
|
+
"",
|
|
1645
|
+
`User ID: ${data.user?.id ?? "N/A"}`,
|
|
1646
|
+
`Email: ${data.user?.email ?? email}`,
|
|
1647
|
+
"",
|
|
1648
|
+
"Verify your email to unlock financial features.",
|
|
1649
|
+
"MCP agents are auto-verified via agent headers.",
|
|
1650
|
+
].join("\n");
|
|
1651
|
+
}
|
|
1652
|
+
catch (err) {
|
|
1653
|
+
return `Error: ${safeError(err)}`;
|
|
1654
|
+
}
|
|
1655
|
+
}
|
|
1656
|
+
// -----------------------------------------------------------------------
|
|
1657
|
+
// Tool 33: login (unauthenticated)
|
|
1658
|
+
// -----------------------------------------------------------------------
|
|
1659
|
+
async login(email, password) {
|
|
1660
|
+
try {
|
|
1661
|
+
if (!email || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
|
|
1662
|
+
return "Error: a valid email address is required.";
|
|
1663
|
+
}
|
|
1664
|
+
if (!password || password.length < 1) {
|
|
1665
|
+
return "Error: password is required.";
|
|
1666
|
+
}
|
|
1667
|
+
const data = await this._unauthenticatedRequest("POST", "/api/auth/login", { email, password });
|
|
1668
|
+
if (data.mfaRequired) {
|
|
1669
|
+
return [
|
|
1670
|
+
"MFA Required",
|
|
1671
|
+
"",
|
|
1672
|
+
`Challenge Token: ${data.challengeToken ?? "N/A"}`,
|
|
1673
|
+
"",
|
|
1674
|
+
"Multi-factor authentication is required. Complete the MFA challenge to proceed.",
|
|
1675
|
+
].join("\n");
|
|
1676
|
+
}
|
|
1677
|
+
return [
|
|
1678
|
+
"Login Successful",
|
|
1679
|
+
"",
|
|
1680
|
+
"Access and refresh tokens have been issued.",
|
|
1681
|
+
"Use get_account_info to view your account details.",
|
|
1682
|
+
].join("\n");
|
|
1683
|
+
}
|
|
1684
|
+
catch (err) {
|
|
1685
|
+
return `Error: ${safeError(err)}`;
|
|
1686
|
+
}
|
|
1687
|
+
}
|
|
1688
|
+
// -----------------------------------------------------------------------
|
|
1689
|
+
// Tool 34: getAccountInfo
|
|
1690
|
+
// -----------------------------------------------------------------------
|
|
1691
|
+
async getAccountInfo() {
|
|
1692
|
+
try {
|
|
1693
|
+
const data = await this._requestWithRetry("GET", "/api/auth/me");
|
|
1694
|
+
const user = data.user;
|
|
1695
|
+
return [
|
|
1696
|
+
"Account Information",
|
|
1697
|
+
"",
|
|
1698
|
+
`User ID: ${user?.id ?? "N/A"}`,
|
|
1699
|
+
`Email: ${user?.email ?? "N/A"}`,
|
|
1700
|
+
`Plan: ${user?.plan ?? "N/A"}`,
|
|
1701
|
+
`Email Verified: ${user?.emailVerified ?? false}`,
|
|
1702
|
+
`Status: ${user?.status ?? "N/A"}`,
|
|
1703
|
+
`Created: ${user?.createdAt ?? "N/A"}`,
|
|
1704
|
+
].join("\n");
|
|
1705
|
+
}
|
|
1706
|
+
catch (err) {
|
|
1707
|
+
return `Error: ${safeError(err)}`;
|
|
1708
|
+
}
|
|
1709
|
+
}
|
|
1710
|
+
// -----------------------------------------------------------------------
|
|
1711
|
+
// Tool 35: verifyEmail (unauthenticated)
|
|
1712
|
+
// -----------------------------------------------------------------------
|
|
1713
|
+
async verifyEmail(token) {
|
|
1714
|
+
try {
|
|
1715
|
+
if (!token || token.trim().length === 0) {
|
|
1716
|
+
return "Error: verification token is required.";
|
|
1717
|
+
}
|
|
1718
|
+
if (/[\x00-\x1f\x7f]/.test(token)) {
|
|
1719
|
+
return "Error: token contains invalid control characters.";
|
|
1720
|
+
}
|
|
1721
|
+
await this._unauthenticatedRequest("POST", "/api/auth/verify-email", {
|
|
1722
|
+
token: token.trim(),
|
|
1723
|
+
});
|
|
1724
|
+
return "Email verified successfully. Financial features are now unlocked.";
|
|
1725
|
+
}
|
|
1726
|
+
catch (err) {
|
|
1727
|
+
return `Error: ${safeError(err)}`;
|
|
1728
|
+
}
|
|
1729
|
+
}
|
|
1730
|
+
// -----------------------------------------------------------------------
|
|
1731
|
+
// Tool 36: resendVerification
|
|
1732
|
+
// -----------------------------------------------------------------------
|
|
1733
|
+
async resendVerification() {
|
|
1734
|
+
try {
|
|
1735
|
+
await this._requestWithRetry("POST", "/api/auth/resend-verification");
|
|
1736
|
+
return "Verification email sent. Check your inbox for the verification link.";
|
|
1737
|
+
}
|
|
1738
|
+
catch (err) {
|
|
1739
|
+
return `Error: ${safeError(err)}`;
|
|
1740
|
+
}
|
|
1741
|
+
}
|
|
1742
|
+
// -----------------------------------------------------------------------
|
|
1743
|
+
// Tool 37: updatePassword
|
|
1744
|
+
// -----------------------------------------------------------------------
|
|
1745
|
+
async updatePassword(currentPassword, newPassword) {
|
|
1746
|
+
try {
|
|
1747
|
+
if (!currentPassword || currentPassword.length < 1) {
|
|
1748
|
+
return "Error: current password is required.";
|
|
1749
|
+
}
|
|
1750
|
+
if (!newPassword || newPassword.length < 8 || newPassword.length > 128) {
|
|
1751
|
+
return "Error: new password must be between 8 and 128 characters.";
|
|
1752
|
+
}
|
|
1753
|
+
await this._requestWithRetry("POST", "/api/auth/change-password", {
|
|
1754
|
+
currentPassword,
|
|
1755
|
+
newPassword,
|
|
1756
|
+
});
|
|
1757
|
+
return "Password updated successfully.";
|
|
1758
|
+
}
|
|
1759
|
+
catch (err) {
|
|
1760
|
+
return `Error: ${safeError(err)}`;
|
|
1761
|
+
}
|
|
1762
|
+
}
|
|
1763
|
+
// -----------------------------------------------------------------------
|
|
1764
|
+
// Tool 38: listKeys
|
|
1765
|
+
// -----------------------------------------------------------------------
|
|
1766
|
+
async listKeys() {
|
|
1767
|
+
try {
|
|
1768
|
+
const data = await this._requestWithRetry("GET", "/api/keys");
|
|
1769
|
+
const keys = data.keys ?? [];
|
|
1770
|
+
if (keys.length === 0) {
|
|
1771
|
+
return "No API keys found. Use create_key to create one.";
|
|
1772
|
+
}
|
|
1773
|
+
const lines = [`API Keys (${keys.length})`, ""];
|
|
1774
|
+
for (const k of keys) {
|
|
1775
|
+
lines.push(` ${k.label ?? "unlabeled"} (${k.id.slice(0, 8)}...)`);
|
|
1776
|
+
lines.push(` Prefix: ${k.prefix} | Created: ${k.createdAt}`);
|
|
1777
|
+
}
|
|
1778
|
+
return truncate(lines.join("\n"));
|
|
1779
|
+
}
|
|
1780
|
+
catch (err) {
|
|
1781
|
+
return `Error: ${safeError(err)}`;
|
|
1782
|
+
}
|
|
1783
|
+
}
|
|
1784
|
+
// -----------------------------------------------------------------------
|
|
1785
|
+
// Tool 39: createKey
|
|
1786
|
+
// -----------------------------------------------------------------------
|
|
1787
|
+
async createKey(label) {
|
|
1788
|
+
try {
|
|
1789
|
+
if (label !== undefined) {
|
|
1790
|
+
if (label.length === 0 || label.length > 100) {
|
|
1791
|
+
return "Error: label must be 1-100 characters.";
|
|
1792
|
+
}
|
|
1793
|
+
if (/[\x00-\x1f\x7f]/.test(label)) {
|
|
1794
|
+
return "Error: label contains invalid control characters.";
|
|
1795
|
+
}
|
|
1796
|
+
}
|
|
1797
|
+
const body = {};
|
|
1798
|
+
if (label)
|
|
1799
|
+
body.label = label.trim();
|
|
1800
|
+
const data = await this._requestWithRetry("POST", "/api/keys", body);
|
|
1801
|
+
return [
|
|
1802
|
+
"API Key Created",
|
|
1803
|
+
"",
|
|
1804
|
+
`Key ID: ${data.id}`,
|
|
1805
|
+
`API Key: ${data.key}`,
|
|
1806
|
+
`Prefix: ${data.prefix}`,
|
|
1807
|
+
`Label: ${data.label ?? ""}`,
|
|
1808
|
+
`Created: ${data.createdAt}`,
|
|
1809
|
+
"",
|
|
1810
|
+
"IMPORTANT: Save this API key now -- it will not be shown again.",
|
|
1811
|
+
].join("\n");
|
|
1812
|
+
}
|
|
1813
|
+
catch (err) {
|
|
1814
|
+
return `Error: ${safeError(err)}`;
|
|
1815
|
+
}
|
|
1816
|
+
}
|
|
1817
|
+
// -----------------------------------------------------------------------
|
|
1818
|
+
// Tool 40: revokeKey
|
|
1819
|
+
// -----------------------------------------------------------------------
|
|
1820
|
+
async revokeKey(keyId) {
|
|
1821
|
+
try {
|
|
1822
|
+
const kid = validateUuid(keyId, "key_id");
|
|
1823
|
+
await this._requestWithRetry("DELETE", `/api/keys/${encodeURIComponent(kid)}`);
|
|
1824
|
+
return [
|
|
1825
|
+
"API Key Revoked",
|
|
1826
|
+
"",
|
|
1827
|
+
`Key ID: ${kid}`,
|
|
1828
|
+
"",
|
|
1829
|
+
"The key is now permanently deactivated and cannot be used.",
|
|
1830
|
+
].join("\n");
|
|
1831
|
+
}
|
|
1832
|
+
catch (err) {
|
|
1833
|
+
return `Error: ${safeError(err)}`;
|
|
1834
|
+
}
|
|
1835
|
+
}
|
|
1836
|
+
// -----------------------------------------------------------------------
|
|
1837
|
+
// Tool 41: getPlan
|
|
1838
|
+
// -----------------------------------------------------------------------
|
|
1839
|
+
async getPlan() {
|
|
1840
|
+
try {
|
|
1841
|
+
const data = await this._requestWithRetry("GET", "/api/plans/user/plan");
|
|
1842
|
+
const lines = [
|
|
1843
|
+
"Current Plan",
|
|
1844
|
+
"",
|
|
1845
|
+
`Plan ID: ${data.id ?? "N/A"}`,
|
|
1846
|
+
`Name: ${data.name ?? "N/A"}`,
|
|
1847
|
+
];
|
|
1848
|
+
if (data.bandwidthLimitBytes !== undefined) {
|
|
1849
|
+
lines.push(`Bandwidth Limit: ${formatBytes(data.bandwidthLimitBytes)}`);
|
|
1850
|
+
}
|
|
1851
|
+
if (data.pricePerGbCents !== undefined) {
|
|
1852
|
+
lines.push(`Price Per GB: ${formatCents(data.pricePerGbCents)}`);
|
|
1853
|
+
}
|
|
1854
|
+
if (data.features && data.features.length > 0) {
|
|
1855
|
+
lines.push(`Features: ${data.features.join(", ")}`);
|
|
1856
|
+
}
|
|
1857
|
+
return lines.join("\n");
|
|
1858
|
+
}
|
|
1859
|
+
catch (err) {
|
|
1860
|
+
return `Error: ${safeError(err)}`;
|
|
1861
|
+
}
|
|
1862
|
+
}
|
|
1863
|
+
// -----------------------------------------------------------------------
|
|
1864
|
+
// Tool 42: listPlans
|
|
1865
|
+
// -----------------------------------------------------------------------
|
|
1866
|
+
async listPlans() {
|
|
1867
|
+
try {
|
|
1868
|
+
const data = await this._requestWithRetry("GET", "/api/plans");
|
|
1869
|
+
const plans = data.plans ?? [];
|
|
1870
|
+
if (plans.length === 0) {
|
|
1871
|
+
return "No plans available.";
|
|
1872
|
+
}
|
|
1873
|
+
const lines = [`Available Plans (${plans.length})`, ""];
|
|
1874
|
+
for (const p of plans) {
|
|
1875
|
+
lines.push(` ${p.name} (${p.id})`);
|
|
1876
|
+
if (p.bandwidthLimitBytes !== undefined) {
|
|
1877
|
+
lines.push(` Bandwidth: ${formatBytes(p.bandwidthLimitBytes)} | Price: ${formatCents(p.pricePerGbCents)}/GB`);
|
|
1878
|
+
}
|
|
1879
|
+
if (p.features && p.features.length > 0) {
|
|
1880
|
+
lines.push(` Features: ${p.features.join(", ")}`);
|
|
1881
|
+
}
|
|
1882
|
+
lines.push("");
|
|
1883
|
+
}
|
|
1884
|
+
return truncate(lines.join("\n"));
|
|
1885
|
+
}
|
|
1886
|
+
catch (err) {
|
|
1887
|
+
return `Error: ${safeError(err)}`;
|
|
1888
|
+
}
|
|
1889
|
+
}
|
|
1890
|
+
// -----------------------------------------------------------------------
|
|
1891
|
+
// Tool 43: changePlan
|
|
1892
|
+
// -----------------------------------------------------------------------
|
|
1893
|
+
async changePlan(planId) {
|
|
1894
|
+
try {
|
|
1895
|
+
if (!planId || planId.trim().length === 0) {
|
|
1896
|
+
return "Error: plan_id is required.";
|
|
1897
|
+
}
|
|
1898
|
+
if (/[\x00-\x1f\x7f]/.test(planId)) {
|
|
1899
|
+
return "Error: plan_id contains invalid control characters.";
|
|
1900
|
+
}
|
|
1901
|
+
const data = await this._requestWithRetry("PUT", "/api/plans/user/plan", { planId: planId.trim() });
|
|
1902
|
+
return [
|
|
1903
|
+
"Plan Changed",
|
|
1904
|
+
"",
|
|
1905
|
+
`New Plan: ${data.name ?? data.id ?? planId}`,
|
|
1906
|
+
data.message ? `Message: ${data.message}` : "",
|
|
1907
|
+
].filter(Boolean).join("\n");
|
|
1908
|
+
}
|
|
1909
|
+
catch (err) {
|
|
1910
|
+
return `Error: ${safeError(err)}`;
|
|
1911
|
+
}
|
|
1912
|
+
}
|
|
1913
|
+
// -----------------------------------------------------------------------
|
|
1914
|
+
// Tool 44: teamDelete
|
|
1915
|
+
// -----------------------------------------------------------------------
|
|
1916
|
+
async teamDelete(teamId) {
|
|
1917
|
+
try {
|
|
1918
|
+
const tid = validateUuid(teamId, "team_id");
|
|
1919
|
+
await this._requestWithRetry("DELETE", `/api/teams/${encodeURIComponent(tid)}`);
|
|
1920
|
+
return [
|
|
1921
|
+
"Team Deleted",
|
|
1922
|
+
"",
|
|
1923
|
+
`Team ID: ${tid}`,
|
|
1924
|
+
"",
|
|
1925
|
+
"The team has been permanently deleted.",
|
|
1926
|
+
].join("\n");
|
|
1927
|
+
}
|
|
1928
|
+
catch (err) {
|
|
1929
|
+
return `Error: ${safeError(err)}`;
|
|
1930
|
+
}
|
|
1931
|
+
}
|
|
1932
|
+
// -----------------------------------------------------------------------
|
|
1933
|
+
// Tool 45: teamRevokeKey
|
|
1934
|
+
// -----------------------------------------------------------------------
|
|
1935
|
+
async teamRevokeKey(teamId, keyId) {
|
|
1936
|
+
try {
|
|
1937
|
+
const tid = validateUuid(teamId, "team_id");
|
|
1938
|
+
const kid = validateUuid(keyId, "key_id");
|
|
1939
|
+
await this._requestWithRetry("DELETE", `/api/teams/${encodeURIComponent(tid)}/keys/${encodeURIComponent(kid)}`);
|
|
1940
|
+
return [
|
|
1941
|
+
"Team API Key Revoked",
|
|
1942
|
+
"",
|
|
1943
|
+
`Team ID: ${tid}`,
|
|
1944
|
+
`Key ID: ${kid}`,
|
|
1945
|
+
"",
|
|
1946
|
+
"The team key is now permanently deactivated.",
|
|
1947
|
+
].join("\n");
|
|
1948
|
+
}
|
|
1949
|
+
catch (err) {
|
|
1950
|
+
return `Error: ${safeError(err)}`;
|
|
1951
|
+
}
|
|
1952
|
+
}
|
|
1953
|
+
// -----------------------------------------------------------------------
|
|
1954
|
+
// Tool 46: teamListKeys
|
|
1955
|
+
// -----------------------------------------------------------------------
|
|
1956
|
+
async teamListKeys(teamId) {
|
|
1957
|
+
try {
|
|
1958
|
+
const tid = validateUuid(teamId, "team_id");
|
|
1959
|
+
const data = await this._requestWithRetry("GET", `/api/teams/${encodeURIComponent(tid)}/keys`);
|
|
1960
|
+
const keys = data.keys ?? [];
|
|
1961
|
+
if (keys.length === 0) {
|
|
1962
|
+
return "No API keys found for this team. Use team_create_key to create one.";
|
|
1963
|
+
}
|
|
1964
|
+
const lines = [`Team API Keys (${keys.length})`, ""];
|
|
1965
|
+
for (const k of keys) {
|
|
1966
|
+
lines.push(` ${k.label ?? "unlabeled"} (${k.id.slice(0, 8)}...)`);
|
|
1967
|
+
lines.push(` Prefix: ${k.prefix} | Created: ${k.createdAt}`);
|
|
1968
|
+
}
|
|
1969
|
+
return truncate(lines.join("\n"));
|
|
1970
|
+
}
|
|
1971
|
+
catch (err) {
|
|
1972
|
+
return `Error: ${safeError(err)}`;
|
|
1973
|
+
}
|
|
1974
|
+
}
|
|
1975
|
+
// -----------------------------------------------------------------------
|
|
1976
|
+
// Tool 47: teamListMembers
|
|
1977
|
+
// -----------------------------------------------------------------------
|
|
1978
|
+
async teamListMembers(teamId) {
|
|
1979
|
+
try {
|
|
1980
|
+
const tid = validateUuid(teamId, "team_id");
|
|
1981
|
+
const data = await this._requestWithRetry("GET", `/api/teams/${encodeURIComponent(tid)}/members`);
|
|
1982
|
+
const members = data.members ?? [];
|
|
1983
|
+
if (members.length === 0) {
|
|
1984
|
+
return "No members found for this team.";
|
|
1985
|
+
}
|
|
1986
|
+
const lines = [`Team Members (${members.length})`, ""];
|
|
1987
|
+
for (const m of members) {
|
|
1988
|
+
lines.push(` ${m.email} -- ${m.role}`);
|
|
1989
|
+
lines.push(` User ID: ${m.userId} | Joined: ${m.joinedAt}`);
|
|
1990
|
+
}
|
|
1991
|
+
return truncate(lines.join("\n"));
|
|
1992
|
+
}
|
|
1993
|
+
catch (err) {
|
|
1994
|
+
return `Error: ${safeError(err)}`;
|
|
1995
|
+
}
|
|
1996
|
+
}
|
|
1997
|
+
// -----------------------------------------------------------------------
|
|
1998
|
+
// Tool 48: teamAddMember
|
|
1999
|
+
// -----------------------------------------------------------------------
|
|
2000
|
+
async teamAddMember(teamId, email, role) {
|
|
2001
|
+
try {
|
|
2002
|
+
const tid = validateUuid(teamId, "team_id");
|
|
2003
|
+
if (!email || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
|
|
2004
|
+
return "Error: a valid email address is required.";
|
|
2005
|
+
}
|
|
2006
|
+
if (role !== undefined && role !== "member" && role !== "admin") {
|
|
2007
|
+
return "Error: role must be 'member' or 'admin'.";
|
|
2008
|
+
}
|
|
2009
|
+
const body = { email };
|
|
2010
|
+
if (role)
|
|
2011
|
+
body.role = role;
|
|
2012
|
+
const data = await this._requestWithRetry("POST", `/api/teams/${encodeURIComponent(tid)}/members`, body);
|
|
2013
|
+
return [
|
|
2014
|
+
"Team Member Added",
|
|
2015
|
+
"",
|
|
2016
|
+
`Team ID: ${tid}`,
|
|
2017
|
+
`Email: ${data.email ?? email}`,
|
|
2018
|
+
`Role: ${data.role ?? role ?? "member"}`,
|
|
2019
|
+
].join("\n");
|
|
2020
|
+
}
|
|
2021
|
+
catch (err) {
|
|
2022
|
+
return `Error: ${safeError(err)}`;
|
|
2023
|
+
}
|
|
2024
|
+
}
|
|
2025
|
+
// -----------------------------------------------------------------------
|
|
2026
|
+
// Tool 49: teamRemoveMember
|
|
2027
|
+
// -----------------------------------------------------------------------
|
|
2028
|
+
async teamRemoveMember(teamId, userId) {
|
|
2029
|
+
try {
|
|
2030
|
+
const tid = validateUuid(teamId, "team_id");
|
|
2031
|
+
const uid = validateUuid(userId, "user_id");
|
|
2032
|
+
await this._requestWithRetry("DELETE", `/api/teams/${encodeURIComponent(tid)}/members/${encodeURIComponent(uid)}`);
|
|
2033
|
+
return [
|
|
2034
|
+
"Team Member Removed",
|
|
2035
|
+
"",
|
|
2036
|
+
`Team ID: ${tid}`,
|
|
2037
|
+
`User ID: ${uid}`,
|
|
2038
|
+
].join("\n");
|
|
2039
|
+
}
|
|
2040
|
+
catch (err) {
|
|
2041
|
+
return `Error: ${safeError(err)}`;
|
|
2042
|
+
}
|
|
2043
|
+
}
|
|
2044
|
+
// -----------------------------------------------------------------------
|
|
2045
|
+
// Tool 50: teamInviteMember
|
|
2046
|
+
// -----------------------------------------------------------------------
|
|
2047
|
+
async teamInviteMember(teamId, email, role) {
|
|
2048
|
+
try {
|
|
2049
|
+
const tid = validateUuid(teamId, "team_id");
|
|
2050
|
+
if (!email || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
|
|
2051
|
+
return "Error: a valid email address is required.";
|
|
2052
|
+
}
|
|
2053
|
+
if (role !== undefined && role !== "member" && role !== "admin") {
|
|
2054
|
+
return "Error: role must be 'member' or 'admin'.";
|
|
2055
|
+
}
|
|
2056
|
+
const body = { email };
|
|
2057
|
+
if (role)
|
|
2058
|
+
body.role = role;
|
|
2059
|
+
const data = await this._requestWithRetry("POST", `/api/teams/${encodeURIComponent(tid)}/invites`, body);
|
|
2060
|
+
return [
|
|
2061
|
+
"Team Invitation Sent",
|
|
2062
|
+
"",
|
|
2063
|
+
`Invite ID: ${data.id ?? "N/A"}`,
|
|
2064
|
+
`Team ID: ${tid}`,
|
|
2065
|
+
`Email: ${data.email ?? email}`,
|
|
2066
|
+
`Role: ${data.role ?? role ?? "member"}`,
|
|
2067
|
+
data.expiresAt ? `Expires: ${data.expiresAt}` : "",
|
|
2068
|
+
].filter(Boolean).join("\n");
|
|
2069
|
+
}
|
|
2070
|
+
catch (err) {
|
|
2071
|
+
return `Error: ${safeError(err)}`;
|
|
2072
|
+
}
|
|
2073
|
+
}
|
|
2074
|
+
// -----------------------------------------------------------------------
|
|
2075
|
+
// Tool 51: teamListInvites
|
|
2076
|
+
// -----------------------------------------------------------------------
|
|
2077
|
+
async teamListInvites(teamId) {
|
|
2078
|
+
try {
|
|
2079
|
+
const tid = validateUuid(teamId, "team_id");
|
|
2080
|
+
const data = await this._requestWithRetry("GET", `/api/teams/${encodeURIComponent(tid)}/invites`);
|
|
2081
|
+
const invites = data.invites ?? [];
|
|
2082
|
+
if (invites.length === 0) {
|
|
2083
|
+
return "No pending invitations for this team.";
|
|
2084
|
+
}
|
|
2085
|
+
const lines = [`Team Invitations (${invites.length})`, ""];
|
|
2086
|
+
for (const inv of invites) {
|
|
2087
|
+
lines.push(` ${inv.email} -- ${inv.role} [${inv.status}]`);
|
|
2088
|
+
lines.push(` Invite ID: ${inv.id.slice(0, 8)}... | Created: ${inv.createdAt}`);
|
|
2089
|
+
}
|
|
2090
|
+
return truncate(lines.join("\n"));
|
|
2091
|
+
}
|
|
2092
|
+
catch (err) {
|
|
2093
|
+
return `Error: ${safeError(err)}`;
|
|
2094
|
+
}
|
|
2095
|
+
}
|
|
2096
|
+
// -----------------------------------------------------------------------
|
|
2097
|
+
// Tool 52: teamCancelInvite
|
|
2098
|
+
// -----------------------------------------------------------------------
|
|
2099
|
+
async teamCancelInvite(teamId, inviteId) {
|
|
2100
|
+
try {
|
|
2101
|
+
const tid = validateUuid(teamId, "team_id");
|
|
2102
|
+
const iid = validateUuid(inviteId, "invite_id");
|
|
2103
|
+
await this._requestWithRetry("DELETE", `/api/teams/${encodeURIComponent(tid)}/invites/${encodeURIComponent(iid)}`);
|
|
2104
|
+
return [
|
|
2105
|
+
"Team Invitation Cancelled",
|
|
2106
|
+
"",
|
|
2107
|
+
`Team ID: ${tid}`,
|
|
2108
|
+
`Invite ID: ${iid}`,
|
|
2109
|
+
].join("\n");
|
|
2110
|
+
}
|
|
2111
|
+
catch (err) {
|
|
2112
|
+
return `Error: ${safeError(err)}`;
|
|
2113
|
+
}
|
|
2114
|
+
}
|
|
2115
|
+
// -----------------------------------------------------------------------
|
|
2116
|
+
// getTools() -- returns LangChain DynamicStructuredTool[] for Flowise
|
|
2117
|
+
// -----------------------------------------------------------------------
|
|
2118
|
+
getTools() {
|
|
2119
|
+
return [
|
|
2120
|
+
// 1. proxied_fetch
|
|
2121
|
+
new tools_1.DynamicStructuredTool({
|
|
2122
|
+
name: "dominusnode_proxied_fetch",
|
|
2123
|
+
description: "Fetch a URL through Dominus Node's rotating proxy network. Supports geo-targeting " +
|
|
2124
|
+
"by country. Returns status code, headers, and response body (truncated).",
|
|
2125
|
+
schema: zod_1.z.object({
|
|
2126
|
+
url: zod_1.z.string().describe("The target URL to fetch (http or https)"),
|
|
2127
|
+
method: zod_1.z.enum(["GET", "HEAD", "OPTIONS"]).default("GET").describe("HTTP method"),
|
|
2128
|
+
country: zod_1.z.string().optional().describe("ISO 3166-1 alpha-2 country code for geo-targeting (e.g., US, GB, DE)"),
|
|
2129
|
+
proxyType: zod_1.z.enum(["dc", "residential"]).default("dc").describe("Proxy pool: dc ($3/GB) or residential ($5/GB)"),
|
|
2130
|
+
}),
|
|
2131
|
+
func: async ({ url, method, country, proxyType }) => {
|
|
2132
|
+
return this.proxiedFetch(url, method, country, proxyType);
|
|
2133
|
+
},
|
|
2134
|
+
}),
|
|
2135
|
+
// 2. check_balance
|
|
2136
|
+
new tools_1.DynamicStructuredTool({
|
|
2137
|
+
name: "dominusnode_check_balance",
|
|
2138
|
+
description: "Check your Dominus Node wallet balance and estimated remaining bandwidth at current pricing.",
|
|
2139
|
+
schema: zod_1.z.object({}),
|
|
2140
|
+
func: async () => {
|
|
2141
|
+
return this.checkBalance();
|
|
2142
|
+
},
|
|
2143
|
+
}),
|
|
2144
|
+
// 3. check_usage
|
|
2145
|
+
new tools_1.DynamicStructuredTool({
|
|
2146
|
+
name: "dominusnode_check_usage",
|
|
2147
|
+
description: "View bandwidth usage statistics for a specified time period. Shows total bytes, cost, and request count.",
|
|
2148
|
+
schema: zod_1.z.object({
|
|
2149
|
+
days: zod_1.z.number().min(1).max(365).default(30).describe("Number of days to look back (1-365)"),
|
|
2150
|
+
}),
|
|
2151
|
+
func: async ({ days }) => {
|
|
2152
|
+
return this.checkUsage(days);
|
|
2153
|
+
},
|
|
2154
|
+
}),
|
|
2155
|
+
// 4. get_proxy_config
|
|
2156
|
+
new tools_1.DynamicStructuredTool({
|
|
2157
|
+
name: "dominusnode_get_proxy_config",
|
|
2158
|
+
description: "Get available proxy pools, pricing, supported countries, and endpoint configuration.",
|
|
2159
|
+
schema: zod_1.z.object({}),
|
|
2160
|
+
func: async () => {
|
|
2161
|
+
return this.getProxyConfig();
|
|
2162
|
+
},
|
|
2163
|
+
}),
|
|
2164
|
+
// 5. list_sessions
|
|
2165
|
+
new tools_1.DynamicStructuredTool({
|
|
2166
|
+
name: "dominusnode_list_sessions",
|
|
2167
|
+
description: "List all active proxy sessions showing target hosts, bandwidth used, and status.",
|
|
2168
|
+
schema: zod_1.z.object({}),
|
|
2169
|
+
func: async () => {
|
|
2170
|
+
return this.listSessions();
|
|
2171
|
+
},
|
|
2172
|
+
}),
|
|
2173
|
+
// 6. create_agentic_wallet
|
|
2174
|
+
new tools_1.DynamicStructuredTool({
|
|
2175
|
+
name: "dominusnode_create_agentic_wallet",
|
|
2176
|
+
description: "Create a server-side custodial agentic wallet for autonomous proxy billing. " +
|
|
2177
|
+
"Set a spending limit per transaction for safety. Optionally set a daily budget cap and domain allowlist.",
|
|
2178
|
+
schema: zod_1.z.object({
|
|
2179
|
+
label: zod_1.z.string().min(1).max(100).describe('Label for this wallet (e.g., "scraper-bot")'),
|
|
2180
|
+
spendingLimitCents: zod_1.z
|
|
2181
|
+
.number()
|
|
2182
|
+
.int()
|
|
2183
|
+
.min(0)
|
|
2184
|
+
.max(1000000)
|
|
2185
|
+
.default(10000)
|
|
2186
|
+
.describe("Max spend per transaction in cents (0 = no limit, default $100)"),
|
|
2187
|
+
dailyLimitCents: zod_1.z
|
|
2188
|
+
.number()
|
|
2189
|
+
.int()
|
|
2190
|
+
.positive()
|
|
2191
|
+
.max(1000000)
|
|
2192
|
+
.optional()
|
|
2193
|
+
.describe("Optional daily budget cap in cents (max 1,000,000 = $10,000)"),
|
|
2194
|
+
allowedDomains: zod_1.z
|
|
2195
|
+
.array(zod_1.z.string().max(253))
|
|
2196
|
+
.max(100)
|
|
2197
|
+
.optional()
|
|
2198
|
+
.describe("Optional list of allowed domains for proxy access (max 100 entries)"),
|
|
2199
|
+
}),
|
|
2200
|
+
func: async ({ label, spendingLimitCents, dailyLimitCents, allowedDomains }) => {
|
|
2201
|
+
return this.createAgenticWallet(label, spendingLimitCents, dailyLimitCents, allowedDomains);
|
|
2202
|
+
},
|
|
2203
|
+
}),
|
|
2204
|
+
// 7. fund_agentic_wallet
|
|
2205
|
+
new tools_1.DynamicStructuredTool({
|
|
2206
|
+
name: "dominusnode_fund_agentic_wallet",
|
|
2207
|
+
description: "Transfer funds from your main wallet to an agentic wallet. Min $1, max $10,000.",
|
|
2208
|
+
schema: zod_1.z.object({
|
|
2209
|
+
walletId: zod_1.z.string().uuid().describe("Agentic wallet ID (UUID)"),
|
|
2210
|
+
amountCents: zod_1.z.number().int().min(100).max(1000000).describe("Amount in cents to transfer"),
|
|
2211
|
+
}),
|
|
2212
|
+
func: async ({ walletId, amountCents }) => {
|
|
2213
|
+
return this.fundAgenticWallet(walletId, amountCents);
|
|
2214
|
+
},
|
|
2215
|
+
}),
|
|
2216
|
+
// 8. agentic_wallet_balance
|
|
2217
|
+
new tools_1.DynamicStructuredTool({
|
|
2218
|
+
name: "dominusnode_agentic_wallet_balance",
|
|
2219
|
+
description: "Check the balance and details of an agentic wallet.",
|
|
2220
|
+
schema: zod_1.z.object({
|
|
2221
|
+
walletId: zod_1.z.string().uuid().describe("Agentic wallet ID (UUID)"),
|
|
2222
|
+
}),
|
|
2223
|
+
func: async ({ walletId }) => {
|
|
2224
|
+
return this.agenticWalletBalance(walletId);
|
|
2225
|
+
},
|
|
2226
|
+
}),
|
|
2227
|
+
// 9. list_agentic_wallets
|
|
2228
|
+
new tools_1.DynamicStructuredTool({
|
|
2229
|
+
name: "dominusnode_list_agentic_wallets",
|
|
2230
|
+
description: "List all your agentic wallets with balances and status.",
|
|
2231
|
+
schema: zod_1.z.object({}),
|
|
2232
|
+
func: async () => {
|
|
2233
|
+
return this.listAgenticWallets();
|
|
2234
|
+
},
|
|
2235
|
+
}),
|
|
2236
|
+
// 10. agentic_transactions
|
|
2237
|
+
new tools_1.DynamicStructuredTool({
|
|
2238
|
+
name: "dominusnode_agentic_transactions",
|
|
2239
|
+
description: "Get transaction history for an agentic wallet.",
|
|
2240
|
+
schema: zod_1.z.object({
|
|
2241
|
+
walletId: zod_1.z.string().uuid().describe("Agentic wallet ID (UUID)"),
|
|
2242
|
+
limit: zod_1.z.number().int().min(1).max(100).default(20).describe("Number of transactions to return"),
|
|
2243
|
+
}),
|
|
2244
|
+
func: async ({ walletId, limit }) => {
|
|
2245
|
+
return this.agenticTransactions(walletId, limit);
|
|
2246
|
+
},
|
|
2247
|
+
}),
|
|
2248
|
+
// 11. freeze_agentic_wallet
|
|
2249
|
+
new tools_1.DynamicStructuredTool({
|
|
2250
|
+
name: "dominusnode_freeze_agentic_wallet",
|
|
2251
|
+
description: "Freeze an agentic wallet to prevent spending. Balance is preserved until unfrozen.",
|
|
2252
|
+
schema: zod_1.z.object({
|
|
2253
|
+
walletId: zod_1.z.string().uuid().describe("Agentic wallet ID (UUID)"),
|
|
2254
|
+
}),
|
|
2255
|
+
func: async ({ walletId }) => {
|
|
2256
|
+
return this.freezeAgenticWallet(walletId);
|
|
2257
|
+
},
|
|
2258
|
+
}),
|
|
2259
|
+
// 12. unfreeze_agentic_wallet
|
|
2260
|
+
new tools_1.DynamicStructuredTool({
|
|
2261
|
+
name: "dominusnode_unfreeze_agentic_wallet",
|
|
2262
|
+
description: "Unfreeze a previously frozen agentic wallet to re-enable spending.",
|
|
2263
|
+
schema: zod_1.z.object({
|
|
2264
|
+
walletId: zod_1.z.string().uuid().describe("Agentic wallet ID (UUID)"),
|
|
2265
|
+
}),
|
|
2266
|
+
func: async ({ walletId }) => {
|
|
2267
|
+
return this.unfreezeAgenticWallet(walletId);
|
|
2268
|
+
},
|
|
2269
|
+
}),
|
|
2270
|
+
// 13. delete_agentic_wallet
|
|
2271
|
+
new tools_1.DynamicStructuredTool({
|
|
2272
|
+
name: "dominusnode_delete_agentic_wallet",
|
|
2273
|
+
description: "Delete an agentic wallet. Must be unfrozen first. Remaining balance refunded to main wallet.",
|
|
2274
|
+
schema: zod_1.z.object({
|
|
2275
|
+
walletId: zod_1.z.string().uuid().describe("Agentic wallet ID (UUID)"),
|
|
2276
|
+
}),
|
|
2277
|
+
func: async ({ walletId }) => {
|
|
2278
|
+
return this.deleteAgenticWallet(walletId);
|
|
2279
|
+
},
|
|
2280
|
+
}),
|
|
2281
|
+
// 13b. update_wallet_policy
|
|
2282
|
+
new tools_1.DynamicStructuredTool({
|
|
2283
|
+
name: "dominusnode_update_wallet_policy",
|
|
2284
|
+
description: "Update spending policy for an agentic wallet. Set or remove daily budget caps and domain restrictions.",
|
|
2285
|
+
schema: zod_1.z.object({
|
|
1527
2286
|
walletId: zod_1.z.string().uuid().describe("Agentic wallet ID (UUID)"),
|
|
1528
2287
|
dailyLimitCents: zod_1.z
|
|
1529
2288
|
.number()
|
|
@@ -1651,7 +2410,34 @@ class DominusNodeToolkit {
|
|
|
1651
2410
|
return this.topupPaypal(amountCents);
|
|
1652
2411
|
},
|
|
1653
2412
|
}),
|
|
1654
|
-
//
|
|
2413
|
+
// 23. topup_stripe
|
|
2414
|
+
new tools_1.DynamicStructuredTool({
|
|
2415
|
+
name: "dominusnode_topup_stripe",
|
|
2416
|
+
description: "Top up your Dominus Node wallet via Stripe. Creates a Stripe checkout session and returns " +
|
|
2417
|
+
"a checkout URL. Minimum $5 (500 cents), maximum $1,000 (100000 cents).",
|
|
2418
|
+
schema: zod_1.z.object({
|
|
2419
|
+
amountCents: zod_1.z.number().int().min(500).max(100000).describe("Amount in cents to top up (min 500 = $5)"),
|
|
2420
|
+
}),
|
|
2421
|
+
func: async ({ amountCents }) => {
|
|
2422
|
+
return this.topupStripe(amountCents);
|
|
2423
|
+
},
|
|
2424
|
+
}),
|
|
2425
|
+
// 24. topup_crypto
|
|
2426
|
+
new tools_1.DynamicStructuredTool({
|
|
2427
|
+
name: "dominusnode_topup_crypto",
|
|
2428
|
+
description: "Top up your Dominus Node wallet via cryptocurrency. Creates a crypto payment invoice. " +
|
|
2429
|
+
"Supports BTC, ETH, LTC, XMR, ZEC, USDC, SOL, USDT, DAI, BNB, LINK. " +
|
|
2430
|
+
"Minimum $5, maximum $1,000.",
|
|
2431
|
+
schema: zod_1.z.object({
|
|
2432
|
+
amountUsd: zod_1.z.number().min(5).max(1000).describe("Amount in USD to top up (5-1000)"),
|
|
2433
|
+
currency: zod_1.z.enum(["btc", "eth", "ltc", "xmr", "zec", "usdc", "sol", "usdt", "dai", "bnb", "link"])
|
|
2434
|
+
.describe("Cryptocurrency to pay with"),
|
|
2435
|
+
}),
|
|
2436
|
+
func: async ({ amountUsd, currency }) => {
|
|
2437
|
+
return this.topupCrypto(amountUsd, currency);
|
|
2438
|
+
},
|
|
2439
|
+
}),
|
|
2440
|
+
// 25. x402_info
|
|
1655
2441
|
new tools_1.DynamicStructuredTool({
|
|
1656
2442
|
name: "dominusnode_x402_info",
|
|
1657
2443
|
description: "Get x402 micropayment protocol information including supported facilitators, " +
|
|
@@ -1661,8 +2447,310 @@ class DominusNodeToolkit {
|
|
|
1661
2447
|
return this.x402Info();
|
|
1662
2448
|
},
|
|
1663
2449
|
}),
|
|
2450
|
+
// 26. get_proxy_status
|
|
2451
|
+
new tools_1.DynamicStructuredTool({
|
|
2452
|
+
name: "dominusnode_get_proxy_status",
|
|
2453
|
+
description: "Get proxy health and status information including uptime, active connections, and provider status.",
|
|
2454
|
+
schema: zod_1.z.object({}),
|
|
2455
|
+
func: async () => {
|
|
2456
|
+
return this.getProxyStatus();
|
|
2457
|
+
},
|
|
2458
|
+
}),
|
|
2459
|
+
// 27. get_transactions
|
|
2460
|
+
new tools_1.DynamicStructuredTool({
|
|
2461
|
+
name: "dominusnode_get_transactions",
|
|
2462
|
+
description: "Get wallet transaction history including top-ups, usage charges, and refunds.",
|
|
2463
|
+
schema: zod_1.z.object({
|
|
2464
|
+
limit: zod_1.z.number().int().min(1).max(100).default(20).describe("Number of transactions to return (1-100)"),
|
|
2465
|
+
}),
|
|
2466
|
+
func: async ({ limit }) => {
|
|
2467
|
+
return this.getTransactions(limit);
|
|
2468
|
+
},
|
|
2469
|
+
}),
|
|
2470
|
+
// 28. get_forecast
|
|
2471
|
+
new tools_1.DynamicStructuredTool({
|
|
2472
|
+
name: "dominusnode_get_forecast",
|
|
2473
|
+
description: "Get a wallet balance forecast based on recent usage patterns. Shows estimated days until balance depletion.",
|
|
2474
|
+
schema: zod_1.z.object({}),
|
|
2475
|
+
func: async () => {
|
|
2476
|
+
return this.getForecast();
|
|
2477
|
+
},
|
|
2478
|
+
}),
|
|
2479
|
+
// 29. check_payment
|
|
2480
|
+
new tools_1.DynamicStructuredTool({
|
|
2481
|
+
name: "dominusnode_check_payment",
|
|
2482
|
+
description: "Check the status of a cryptocurrency payment invoice. Use after creating a crypto top-up.",
|
|
2483
|
+
schema: zod_1.z.object({
|
|
2484
|
+
invoiceId: zod_1.z.string().min(1).describe("The invoice ID from the crypto top-up creation"),
|
|
2485
|
+
}),
|
|
2486
|
+
func: async ({ invoiceId }) => {
|
|
2487
|
+
return this.checkPayment(invoiceId);
|
|
2488
|
+
},
|
|
2489
|
+
}),
|
|
2490
|
+
// 30. get_daily_usage
|
|
2491
|
+
new tools_1.DynamicStructuredTool({
|
|
2492
|
+
name: "dominusnode_get_daily_usage",
|
|
2493
|
+
description: "Get daily usage breakdown showing bandwidth, cost, and request count per day.",
|
|
2494
|
+
schema: zod_1.z.object({
|
|
2495
|
+
days: zod_1.z.number().int().min(1).max(365).default(7).describe("Number of days to look back (1-365)"),
|
|
2496
|
+
}),
|
|
2497
|
+
func: async ({ days }) => {
|
|
2498
|
+
return this.getDailyUsage(days);
|
|
2499
|
+
},
|
|
2500
|
+
}),
|
|
2501
|
+
// 31. get_top_hosts
|
|
2502
|
+
new tools_1.DynamicStructuredTool({
|
|
2503
|
+
name: "dominusnode_get_top_hosts",
|
|
2504
|
+
description: "Get the top accessed hosts ranked by bandwidth usage. Useful for understanding proxy usage patterns.",
|
|
2505
|
+
schema: zod_1.z.object({
|
|
2506
|
+
limit: zod_1.z.number().int().min(1).max(100).default(10).describe("Number of top hosts to return (1-100)"),
|
|
2507
|
+
}),
|
|
2508
|
+
func: async ({ limit }) => {
|
|
2509
|
+
return this.getTopHosts(limit);
|
|
2510
|
+
},
|
|
2511
|
+
}),
|
|
2512
|
+
// 32. register
|
|
2513
|
+
new tools_1.DynamicStructuredTool({
|
|
2514
|
+
name: "dominusnode_register",
|
|
2515
|
+
description: "Register a new Dominus Node account. Returns user info. " +
|
|
2516
|
+
"After registering, verify email or rely on MCP agent auto-verification.",
|
|
2517
|
+
schema: zod_1.z.object({
|
|
2518
|
+
email: zod_1.z.string().email().describe("Email address for the new account"),
|
|
2519
|
+
password: zod_1.z.string().min(8).max(128).describe("Password (min 8, max 128 characters)"),
|
|
2520
|
+
}),
|
|
2521
|
+
func: async ({ email, password }) => {
|
|
2522
|
+
return this.register(email, password);
|
|
2523
|
+
},
|
|
2524
|
+
}),
|
|
2525
|
+
// 33. login
|
|
2526
|
+
new tools_1.DynamicStructuredTool({
|
|
2527
|
+
name: "dominusnode_login",
|
|
2528
|
+
description: "Log into an existing Dominus Node account. Returns login status. " +
|
|
2529
|
+
"Detects MFA requirements and surfaces challenge tokens.",
|
|
2530
|
+
schema: zod_1.z.object({
|
|
2531
|
+
email: zod_1.z.string().email().describe("Account email address"),
|
|
2532
|
+
password: zod_1.z.string().min(1).describe("Account password"),
|
|
2533
|
+
}),
|
|
2534
|
+
func: async ({ email, password }) => {
|
|
2535
|
+
return this.login(email, password);
|
|
2536
|
+
},
|
|
2537
|
+
}),
|
|
2538
|
+
// 34. get_account_info
|
|
2539
|
+
new tools_1.DynamicStructuredTool({
|
|
2540
|
+
name: "dominusnode_get_account_info",
|
|
2541
|
+
description: "Get the current authenticated account information including email, plan, verification status, and creation date.",
|
|
2542
|
+
schema: zod_1.z.object({}),
|
|
2543
|
+
func: async () => {
|
|
2544
|
+
return this.getAccountInfo();
|
|
2545
|
+
},
|
|
2546
|
+
}),
|
|
2547
|
+
// 35. verify_email
|
|
2548
|
+
new tools_1.DynamicStructuredTool({
|
|
2549
|
+
name: "dominusnode_verify_email",
|
|
2550
|
+
description: "Verify email address using the verification token sent to email. " +
|
|
2551
|
+
"MCP agents are auto-verified via agent headers.",
|
|
2552
|
+
schema: zod_1.z.object({
|
|
2553
|
+
token: zod_1.z.string().min(1).describe("Email verification token from the verification email"),
|
|
2554
|
+
}),
|
|
2555
|
+
func: async ({ token }) => {
|
|
2556
|
+
return this.verifyEmail(token);
|
|
2557
|
+
},
|
|
2558
|
+
}),
|
|
2559
|
+
// 36. resend_verification
|
|
2560
|
+
new tools_1.DynamicStructuredTool({
|
|
2561
|
+
name: "dominusnode_resend_verification",
|
|
2562
|
+
description: "Resend the email verification token to the account's email address.",
|
|
2563
|
+
schema: zod_1.z.object({}),
|
|
2564
|
+
func: async () => {
|
|
2565
|
+
return this.resendVerification();
|
|
2566
|
+
},
|
|
2567
|
+
}),
|
|
2568
|
+
// 37. update_password
|
|
2569
|
+
new tools_1.DynamicStructuredTool({
|
|
2570
|
+
name: "dominusnode_update_password",
|
|
2571
|
+
description: "Change the password for the current Dominus Node account. Requires the current password.",
|
|
2572
|
+
schema: zod_1.z.object({
|
|
2573
|
+
currentPassword: zod_1.z.string().min(1).describe("Current account password"),
|
|
2574
|
+
newPassword: zod_1.z.string().min(8).max(128).describe("New password (min 8, max 128 characters)"),
|
|
2575
|
+
}),
|
|
2576
|
+
func: async ({ currentPassword, newPassword }) => {
|
|
2577
|
+
return this.updatePassword(currentPassword, newPassword);
|
|
2578
|
+
},
|
|
2579
|
+
}),
|
|
2580
|
+
// 38. list_keys
|
|
2581
|
+
new tools_1.DynamicStructuredTool({
|
|
2582
|
+
name: "dominusnode_list_keys",
|
|
2583
|
+
description: "List all API keys for the current account. Shows key ID, label, prefix, and creation date.",
|
|
2584
|
+
schema: zod_1.z.object({}),
|
|
2585
|
+
func: async () => {
|
|
2586
|
+
return this.listKeys();
|
|
2587
|
+
},
|
|
2588
|
+
}),
|
|
2589
|
+
// 39. create_key
|
|
2590
|
+
new tools_1.DynamicStructuredTool({
|
|
2591
|
+
name: "dominusnode_create_key",
|
|
2592
|
+
description: "Create a new API key for the current account. The key is shown only once on creation.",
|
|
2593
|
+
schema: zod_1.z.object({
|
|
2594
|
+
label: zod_1.z.string().min(1).max(100).optional().describe('Optional label for the API key (e.g., "production")'),
|
|
2595
|
+
}),
|
|
2596
|
+
func: async ({ label }) => {
|
|
2597
|
+
return this.createKey(label);
|
|
2598
|
+
},
|
|
2599
|
+
}),
|
|
2600
|
+
// 40. revoke_key
|
|
2601
|
+
new tools_1.DynamicStructuredTool({
|
|
2602
|
+
name: "dominusnode_revoke_key",
|
|
2603
|
+
description: "Revoke (permanently delete) an API key. The key will immediately stop working.",
|
|
2604
|
+
schema: zod_1.z.object({
|
|
2605
|
+
keyId: zod_1.z.string().uuid().describe("UUID of the API key to revoke"),
|
|
2606
|
+
}),
|
|
2607
|
+
func: async ({ keyId }) => {
|
|
2608
|
+
return this.revokeKey(keyId);
|
|
2609
|
+
},
|
|
2610
|
+
}),
|
|
2611
|
+
// 41. get_plan
|
|
2612
|
+
new tools_1.DynamicStructuredTool({
|
|
2613
|
+
name: "dominusnode_get_plan",
|
|
2614
|
+
description: "Get the current user's plan details including bandwidth limits, pricing tier, and features.",
|
|
2615
|
+
schema: zod_1.z.object({}),
|
|
2616
|
+
func: async () => {
|
|
2617
|
+
return this.getPlan();
|
|
2618
|
+
},
|
|
2619
|
+
}),
|
|
2620
|
+
// 42. list_plans
|
|
2621
|
+
new tools_1.DynamicStructuredTool({
|
|
2622
|
+
name: "dominusnode_list_plans",
|
|
2623
|
+
description: "List all available Dominus Node plans with pricing, bandwidth limits, and features.",
|
|
2624
|
+
schema: zod_1.z.object({}),
|
|
2625
|
+
func: async () => {
|
|
2626
|
+
return this.listPlans();
|
|
2627
|
+
},
|
|
2628
|
+
}),
|
|
2629
|
+
// 43. change_plan
|
|
2630
|
+
new tools_1.DynamicStructuredTool({
|
|
2631
|
+
name: "dominusnode_change_plan",
|
|
2632
|
+
description: "Change the current user's plan. Provide the plan ID of the desired plan from list_plans.",
|
|
2633
|
+
schema: zod_1.z.object({
|
|
2634
|
+
planId: zod_1.z.string().min(1).describe("ID of the plan to switch to"),
|
|
2635
|
+
}),
|
|
2636
|
+
func: async ({ planId }) => {
|
|
2637
|
+
return this.changePlan(planId);
|
|
2638
|
+
},
|
|
2639
|
+
}),
|
|
2640
|
+
// 44. team_delete
|
|
2641
|
+
new tools_1.DynamicStructuredTool({
|
|
2642
|
+
name: "dominusnode_team_delete",
|
|
2643
|
+
description: "Delete a team permanently. Requires owner role. All team keys are revoked and members removed.",
|
|
2644
|
+
schema: zod_1.z.object({
|
|
2645
|
+
teamId: zod_1.z.string().uuid().describe("Team ID (UUID) to delete"),
|
|
2646
|
+
}),
|
|
2647
|
+
func: async ({ teamId }) => {
|
|
2648
|
+
return this.teamDelete(teamId);
|
|
2649
|
+
},
|
|
2650
|
+
}),
|
|
2651
|
+
// 45. team_revoke_key
|
|
2652
|
+
new tools_1.DynamicStructuredTool({
|
|
2653
|
+
name: "dominusnode_team_revoke_key",
|
|
2654
|
+
description: "Revoke (delete) a team API key. Requires owner or admin role.",
|
|
2655
|
+
schema: zod_1.z.object({
|
|
2656
|
+
teamId: zod_1.z.string().uuid().describe("Team ID (UUID)"),
|
|
2657
|
+
keyId: zod_1.z.string().uuid().describe("UUID of the team key to revoke"),
|
|
2658
|
+
}),
|
|
2659
|
+
func: async ({ teamId, keyId }) => {
|
|
2660
|
+
return this.teamRevokeKey(teamId, keyId);
|
|
2661
|
+
},
|
|
2662
|
+
}),
|
|
2663
|
+
// 46. team_list_keys
|
|
2664
|
+
new tools_1.DynamicStructuredTool({
|
|
2665
|
+
name: "dominusnode_team_list_keys",
|
|
2666
|
+
description: "List all API keys for a team. Shows key ID, label, prefix, and creation date.",
|
|
2667
|
+
schema: zod_1.z.object({
|
|
2668
|
+
teamId: zod_1.z.string().uuid().describe("Team ID (UUID)"),
|
|
2669
|
+
}),
|
|
2670
|
+
func: async ({ teamId }) => {
|
|
2671
|
+
return this.teamListKeys(teamId);
|
|
2672
|
+
},
|
|
2673
|
+
}),
|
|
2674
|
+
// 47. team_list_members
|
|
2675
|
+
new tools_1.DynamicStructuredTool({
|
|
2676
|
+
name: "dominusnode_team_list_members",
|
|
2677
|
+
description: "List all members of a team with their roles and join dates.",
|
|
2678
|
+
schema: zod_1.z.object({
|
|
2679
|
+
teamId: zod_1.z.string().uuid().describe("Team ID (UUID)"),
|
|
2680
|
+
}),
|
|
2681
|
+
func: async ({ teamId }) => {
|
|
2682
|
+
return this.teamListMembers(teamId);
|
|
2683
|
+
},
|
|
2684
|
+
}),
|
|
2685
|
+
// 48. team_add_member
|
|
2686
|
+
new tools_1.DynamicStructuredTool({
|
|
2687
|
+
name: "dominusnode_team_add_member",
|
|
2688
|
+
description: "Add a member to a team by email address. Optionally specify their role (member or admin).",
|
|
2689
|
+
schema: zod_1.z.object({
|
|
2690
|
+
teamId: zod_1.z.string().uuid().describe("Team ID (UUID)"),
|
|
2691
|
+
email: zod_1.z.string().email().describe("Email address of the user to add"),
|
|
2692
|
+
role: zod_1.z.enum(["member", "admin"]).optional().describe("Role for the new member (default: member)"),
|
|
2693
|
+
}),
|
|
2694
|
+
func: async ({ teamId, email, role }) => {
|
|
2695
|
+
return this.teamAddMember(teamId, email, role);
|
|
2696
|
+
},
|
|
2697
|
+
}),
|
|
2698
|
+
// 49. team_remove_member
|
|
2699
|
+
new tools_1.DynamicStructuredTool({
|
|
2700
|
+
name: "dominusnode_team_remove_member",
|
|
2701
|
+
description: "Remove a member from a team. Requires owner or admin role. Cannot remove the owner.",
|
|
2702
|
+
schema: zod_1.z.object({
|
|
2703
|
+
teamId: zod_1.z.string().uuid().describe("Team ID (UUID)"),
|
|
2704
|
+
userId: zod_1.z.string().uuid().describe("User ID (UUID) of the member to remove"),
|
|
2705
|
+
}),
|
|
2706
|
+
func: async ({ teamId, userId }) => {
|
|
2707
|
+
return this.teamRemoveMember(teamId, userId);
|
|
2708
|
+
},
|
|
2709
|
+
}),
|
|
2710
|
+
// 50. team_invite_member
|
|
2711
|
+
new tools_1.DynamicStructuredTool({
|
|
2712
|
+
name: "dominusnode_team_invite_member",
|
|
2713
|
+
description: "Send a team invitation to an email address. Invited users can accept to join the team.",
|
|
2714
|
+
schema: zod_1.z.object({
|
|
2715
|
+
teamId: zod_1.z.string().uuid().describe("Team ID (UUID)"),
|
|
2716
|
+
email: zod_1.z.string().email().describe("Email address to invite"),
|
|
2717
|
+
role: zod_1.z.enum(["member", "admin"]).optional().describe("Role for the invited member (default: member)"),
|
|
2718
|
+
}),
|
|
2719
|
+
func: async ({ teamId, email, role }) => {
|
|
2720
|
+
return this.teamInviteMember(teamId, email, role);
|
|
2721
|
+
},
|
|
2722
|
+
}),
|
|
2723
|
+
// 51. team_list_invites
|
|
2724
|
+
new tools_1.DynamicStructuredTool({
|
|
2725
|
+
name: "dominusnode_team_list_invites",
|
|
2726
|
+
description: "List all pending invitations for a team. Shows invite ID, email, role, and status.",
|
|
2727
|
+
schema: zod_1.z.object({
|
|
2728
|
+
teamId: zod_1.z.string().uuid().describe("Team ID (UUID)"),
|
|
2729
|
+
}),
|
|
2730
|
+
func: async ({ teamId }) => {
|
|
2731
|
+
return this.teamListInvites(teamId);
|
|
2732
|
+
},
|
|
2733
|
+
}),
|
|
2734
|
+
// 52. team_cancel_invite
|
|
2735
|
+
new tools_1.DynamicStructuredTool({
|
|
2736
|
+
name: "dominusnode_team_cancel_invite",
|
|
2737
|
+
description: "Cancel a pending team invitation. Requires owner or admin role.",
|
|
2738
|
+
schema: zod_1.z.object({
|
|
2739
|
+
teamId: zod_1.z.string().uuid().describe("Team ID (UUID)"),
|
|
2740
|
+
inviteId: zod_1.z.string().uuid().describe("UUID of the invitation to cancel"),
|
|
2741
|
+
}),
|
|
2742
|
+
func: async ({ teamId, inviteId }) => {
|
|
2743
|
+
return this.teamCancelInvite(teamId, inviteId);
|
|
2744
|
+
},
|
|
2745
|
+
}),
|
|
1664
2746
|
];
|
|
1665
2747
|
}
|
|
1666
2748
|
}
|
|
1667
2749
|
exports.DominusNodeToolkit = DominusNodeToolkit;
|
|
2750
|
+
// -----------------------------------------------------------------------
|
|
2751
|
+
// Tool 24: topupCrypto
|
|
2752
|
+
// -----------------------------------------------------------------------
|
|
2753
|
+
DominusNodeToolkit.VALID_CRYPTO_CURRENCIES = new Set([
|
|
2754
|
+
"btc", "eth", "ltc", "xmr", "zec", "usdc", "sol", "usdt", "dai", "bnb", "link",
|
|
2755
|
+
]);
|
|
1668
2756
|
//# sourceMappingURL=toolkit.js.map
|