helipod-mcp 0.5.1 → 0.5.3
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/http.js +69 -70
- package/dist/index.js +69 -70
- package/dist/stdio.js +69 -70
- package/package.json +1 -1
- package/skills/helipod-vps/SKILL.md +1 -1
package/README.md
CHANGED
|
@@ -198,7 +198,7 @@ Pick your agents when asked (or pass `-a codex cursor gemini-cli opencode -y`).
|
|
|
198
198
|
| Email | status, plan (buy, renew, change, inbox add-ons, with dry runs), send, sent log, sending domains, templates, contacts, segments, topics, broadcasts, suppressions, webhooks, inbox |
|
|
199
199
|
| Account | wallet and transactions, invoices, monthly statements, notifications, project activity, support tickets |
|
|
200
200
|
| AI | models and prices, balance, usage, metrics, AI keys (list, revoke), top-up and auto top-up |
|
|
201
|
-
| Other | `
|
|
201
|
+
| Other | `helipod_api_get` to read any other documented endpoint (read only) |
|
|
202
202
|
|
|
203
203
|
Each tool is marked read-only, write or destructive, so clients can ask before running the risky ones. Calls that cost money support a dry run, and the server tells the agent to show the price and wait for your OK.
|
|
204
204
|
|
package/dist/http.js
CHANGED
|
@@ -35673,7 +35673,7 @@ function register(server, api2, defs) {
|
|
|
35673
35673
|
annotations: {
|
|
35674
35674
|
title: d.title,
|
|
35675
35675
|
readOnlyHint: d.kind === "read",
|
|
35676
|
-
destructiveHint: d.kind
|
|
35676
|
+
destructiveHint: d.kind !== "read",
|
|
35677
35677
|
idempotentHint: d.kind === "read" || !!d.idempotent,
|
|
35678
35678
|
openWorldHint: true
|
|
35679
35679
|
}
|
|
@@ -35873,7 +35873,7 @@ var containerTools = [
|
|
|
35873
35873
|
title: "Update / rename service",
|
|
35874
35874
|
kind: "write",
|
|
35875
35875
|
idempotent: true,
|
|
35876
|
-
description: "Rename a service or change its start command, root directory, health check or startup dependencies. Settings apply on the next deploy (needsRedeploy). Renaming breaks references like ${{oldName.KEY}} in other services' variables:
|
|
35876
|
+
description: "Rename a service or change its start command, root directory, health check or startup dependencies. Settings apply on the next deploy (needsRedeploy). Renaming breaks references like ${{oldName.KEY}} in other services' variables: the response lists them in warnings.",
|
|
35877
35877
|
input: {
|
|
35878
35878
|
serviceId: id("Service"),
|
|
35879
35879
|
name: exports_external.string().regex(/^[A-Za-z][A-Za-z0-9_-]{0,39}$/).optional().describe("New service name (letters, digits, _ -; starts with a letter; unique in the environment)"),
|
|
@@ -35897,7 +35897,7 @@ var containerTools = [
|
|
|
35897
35897
|
name: "delete_service",
|
|
35898
35898
|
title: "Delete service",
|
|
35899
35899
|
kind: "destructive",
|
|
35900
|
-
description: "Stop and delete a service with its domains and volumes. Volume data is lost.
|
|
35900
|
+
description: "Stop and delete a service with its domains and volumes. Volume data is lost.",
|
|
35901
35901
|
input: { serviceId: id("Service") },
|
|
35902
35902
|
run: (a, api2) => api2.api("DELETE", `${C}/services/${a.serviceId}`)
|
|
35903
35903
|
}),
|
|
@@ -35905,7 +35905,7 @@ var containerTools = [
|
|
|
35905
35905
|
name: "deploy_service",
|
|
35906
35906
|
title: "Deploy service",
|
|
35907
35907
|
kind: "write",
|
|
35908
|
-
description: "Start a new deployment (Git services build the latest commit). COSTS MONEY: charges today's cost when the build starts, refunded if it fails. dryRun=true returns the cost only.
|
|
35908
|
+
description: "Start a new deployment (Git services build the latest commit). COSTS MONEY: charges today's cost when the build starts, refunded if it fails. dryRun=true returns the cost only. The deployment runs in the background; get_deployment returns its status.",
|
|
35909
35909
|
input: { serviceId: id("Service"), dryRun, idempotencyKey: idem },
|
|
35910
35910
|
run: (a, api2) => api2.api("POST", `${C}/services/${a.serviceId}/deployments`, { query: { dryRun: a.dryRun ? "true" : undefined }, idempotencyKey: a.idempotencyKey })
|
|
35911
35911
|
}),
|
|
@@ -35982,7 +35982,7 @@ var containerTools = [
|
|
|
35982
35982
|
name: "add_service_domain",
|
|
35983
35983
|
title: "Add domain to service",
|
|
35984
35984
|
kind: "write",
|
|
35985
|
-
description: "Add a free *.helipod.app domain (kind=helipod) or your own domain (kind=custom) to a port. For custom domains,
|
|
35985
|
+
description: "Add a free *.helipod.app domain (kind=helipod) or your own domain (kind=custom) to a port. For custom domains, the response's dns field is the DNS record the domain needs.",
|
|
35986
35986
|
input: {
|
|
35987
35987
|
serviceId: id("Service"),
|
|
35988
35988
|
kind: exports_external.enum(["helipod", "custom"]),
|
|
@@ -36053,7 +36053,7 @@ var containerTools = [
|
|
|
36053
36053
|
name: "delete_volume",
|
|
36054
36054
|
title: "Delete volume",
|
|
36055
36055
|
kind: "destructive",
|
|
36056
|
-
description: "Remove a volume; its data is lost on the next deploy.
|
|
36056
|
+
description: "Remove a volume; its data is lost on the next deploy.",
|
|
36057
36057
|
input: { serviceId: id("Service"), volumeId: id("Volume") },
|
|
36058
36058
|
run: (a, api2) => api2.api("DELETE", `${C}/services/${a.serviceId}/volumes/${a.volumeId}`)
|
|
36059
36059
|
}),
|
|
@@ -36061,7 +36061,7 @@ var containerTools = [
|
|
|
36061
36061
|
name: "resize_volume",
|
|
36062
36062
|
title: "Resize volume",
|
|
36063
36063
|
kind: "write",
|
|
36064
|
-
description: "Change a volume's size (1-50 GB; never below the space already used). A larger volume COSTS MONEY: it raises the daily cost, charged pro rata when the service is redeployed and in full from the next renewal.
|
|
36064
|
+
description: "Change a volume's size (1-50 GB; never below the space already used). A larger volume COSTS MONEY: it raises the daily cost, charged pro rata when the service is redeployed and in full from the next renewal. dryRun=true returns currentDailyCost and newDailyCost (IDR) without changing anything. Applies on the next deploy.",
|
|
36065
36065
|
input: {
|
|
36066
36066
|
serviceId: id("Service"),
|
|
36067
36067
|
volumeId: id("Volume"),
|
|
@@ -36100,7 +36100,7 @@ var containerTools = [
|
|
|
36100
36100
|
title: "Save function source",
|
|
36101
36101
|
kind: "write",
|
|
36102
36102
|
idempotent: true,
|
|
36103
|
-
description: "Replace the whole source code of a function service (up to 512 KB). The previous code is overwritten
|
|
36103
|
+
description: "Replace the whole source code of a function service (up to 512 KB). The previous code is overwritten (get_function_code returns the current code). Runs after the next deploy (deploy_service).",
|
|
36104
36104
|
input: { serviceId: id("Service"), code: exports_external.string().min(1).max(512 * 1024) },
|
|
36105
36105
|
run: (a, api2) => api2.api("PUT", `${C}/services/${a.serviceId}/function`, { body: { code: a.code } })
|
|
36106
36106
|
}),
|
|
@@ -36116,7 +36116,7 @@ var containerTools = [
|
|
|
36116
36116
|
name: "add_secret_file",
|
|
36117
36117
|
title: "Add secret file",
|
|
36118
36118
|
kind: "write",
|
|
36119
|
-
description: "Upload a file (certificate, key, credentials JSON, config) that is mounted read-only into the service at mountPath. Content is base64 of the file's bytes, at most 10 MB; it is stored as a secret and can never be read back. Applies on the next deploy.
|
|
36119
|
+
description: "Upload a file (certificate, key, credentials JSON, config) that is mounted read-only into the service at mountPath. Content is base64 of the file's bytes, at most 10 MB; it is stored as a secret and can never be read back. Applies on the next deploy.",
|
|
36120
36120
|
input: {
|
|
36121
36121
|
serviceId: id("Service"),
|
|
36122
36122
|
fileName: exports_external.string().min(1).max(200).describe("e.g. service-account.json"),
|
|
@@ -36146,7 +36146,7 @@ var containerTools = [
|
|
|
36146
36146
|
name: "delete_secret_file",
|
|
36147
36147
|
title: "Delete secret file",
|
|
36148
36148
|
kind: "destructive",
|
|
36149
|
-
description: "Delete a secret file; it is gone from the service after the next deploy and cannot be recovered (contents are never readable).
|
|
36149
|
+
description: "Delete a secret file; it is gone from the service after the next deploy and cannot be recovered (contents are never readable).",
|
|
36150
36150
|
input: { serviceId: id("Service"), fileId: id("File") },
|
|
36151
36151
|
run: (a, api2) => api2.api("DELETE", `${C}/services/${a.serviceId}/files/${a.fileId}`)
|
|
36152
36152
|
}),
|
|
@@ -36183,7 +36183,7 @@ var containerTools = [
|
|
|
36183
36183
|
name: "deploy_template",
|
|
36184
36184
|
title: "Deploy template",
|
|
36185
36185
|
kind: "write",
|
|
36186
|
-
description: "Create every service of a template in an environment and deploy them. COSTS MONEY (each service is billed daily).
|
|
36186
|
+
description: "Create every service of a template in an environment and deploy them. COSTS MONEY (each service is billed daily).",
|
|
36187
36187
|
input: {
|
|
36188
36188
|
environmentId: id("Environment"),
|
|
36189
36189
|
slug: exports_external.string().regex(/^[a-z0-9][a-z0-9-]{0,79}$/),
|
|
@@ -36264,7 +36264,7 @@ var vpsTools = [
|
|
|
36264
36264
|
name: "vps_power",
|
|
36265
36265
|
title: "Start / stop / restart VPS",
|
|
36266
36266
|
kind: "destructive",
|
|
36267
|
-
description: "Power action on a server. stop and restart interrupt whatever runs on it
|
|
36267
|
+
description: "Power action on a server. stop and restart interrupt whatever runs on it.",
|
|
36268
36268
|
input: { vpsId, action: exports_external.enum(["start", "stop", "restart"]) },
|
|
36269
36269
|
run: (a, api2) => api2.api("POST", `/vps/${a.vpsId}/${a.action}`)
|
|
36270
36270
|
}),
|
|
@@ -36272,7 +36272,7 @@ var vpsTools = [
|
|
|
36272
36272
|
name: "reinstall_vps",
|
|
36273
36273
|
title: "Reinstall VPS",
|
|
36274
36274
|
kind: "destructive",
|
|
36275
|
-
description: "Wipe the disk and install an operating system. ALL DATA ON THE SERVER IS LOST.
|
|
36275
|
+
description: "Wipe the disk and install an operating system. ALL DATA ON THE SERVER IS LOST.",
|
|
36276
36276
|
input: { vpsId, osType: exports_external.string(), osVersion: exports_external.string(), rootPassword: password },
|
|
36277
36277
|
run: (a, api2) => api2.api("POST", `/vps/${a.vpsId}/reinstall`, { body: { osType: a.osType, osVersion: a.osVersion, rootPassword: a.rootPassword } })
|
|
36278
36278
|
}),
|
|
@@ -36288,7 +36288,7 @@ var vpsTools = [
|
|
|
36288
36288
|
name: "get_vps_credentials",
|
|
36289
36289
|
title: "Get VPS login",
|
|
36290
36290
|
kind: "read",
|
|
36291
|
-
description: "Login details: host, user (root, or Administrator on Windows), port, protocol (ssh or rdp) and password.
|
|
36291
|
+
description: "Login details: host, user (root, or Administrator on Windows), port, protocol (ssh or rdp) and password. The response contains the root password.",
|
|
36292
36292
|
input: { vpsId },
|
|
36293
36293
|
run: (a, api2) => api2.api("GET", `/vps/${a.vpsId}/credentials`)
|
|
36294
36294
|
}),
|
|
@@ -36296,7 +36296,7 @@ var vpsTools = [
|
|
|
36296
36296
|
name: "terminate_vps",
|
|
36297
36297
|
title: "Terminate VPS",
|
|
36298
36298
|
kind: "destructive",
|
|
36299
|
-
description: "Delete a server permanently. ALL DATA IS LOST and there is no refund for the remaining period.
|
|
36299
|
+
description: "Delete a server permanently. ALL DATA IS LOST and there is no refund for the remaining period.",
|
|
36300
36300
|
input: { vpsId },
|
|
36301
36301
|
run: (a, api2) => api2.api("DELETE", `/vps/${a.vpsId}`)
|
|
36302
36302
|
}),
|
|
@@ -36320,7 +36320,7 @@ var vpsTools = [
|
|
|
36320
36320
|
name: "upgrade_vps",
|
|
36321
36321
|
title: "Upgrade VPS plan",
|
|
36322
36322
|
kind: "write",
|
|
36323
|
-
description: "Move a server to a larger plan in the same family and region. COSTS MONEY (the difference for the days left) and restarts the server.
|
|
36323
|
+
description: "Move a server to a larger plan in the same family and region. COSTS MONEY (the difference for the days left) and restarts the server. planId must be one listed by get_vps_upgrade_options, which also gives the price in IDR; the server restarts during the upgrade.",
|
|
36324
36324
|
input: { vpsId, planId: exports_external.string() },
|
|
36325
36325
|
run: (a, api2) => api2.api("POST", `/vps/${a.vpsId}/upgrade`, { body: { planId: a.planId } })
|
|
36326
36326
|
}),
|
|
@@ -36328,7 +36328,7 @@ var vpsTools = [
|
|
|
36328
36328
|
name: "get_vps_upgrade_options",
|
|
36329
36329
|
title: "VPS upgrade options",
|
|
36330
36330
|
kind: "read",
|
|
36331
|
-
description: "Plans this server can move to (same family and region) with the price to pay now for the days left (IDR).
|
|
36331
|
+
description: "Plans this server can move to (same family and region) with the price to pay now for the days left (IDR). upgrade_vps accepts only a planId from this list.",
|
|
36332
36332
|
input: { vpsId },
|
|
36333
36333
|
run: (a, api2) => api2.api("GET", `/vps/${a.vpsId}/upgrade-options`)
|
|
36334
36334
|
}),
|
|
@@ -36417,7 +36417,7 @@ var vpsTools = [
|
|
|
36417
36417
|
name: "remove_vps_port",
|
|
36418
36418
|
title: "Remove port forward",
|
|
36419
36419
|
kind: "destructive",
|
|
36420
|
-
description: "Remove a port forward (id from list_vps_ports). Whatever reaches the server through it stops working
|
|
36420
|
+
description: "Remove a port forward (id from list_vps_ports). Whatever reaches the server through it stops working.",
|
|
36421
36421
|
input: { vpsId, allocationId: exports_external.string().uuid().describe("Port forward id from list_vps_ports") },
|
|
36422
36422
|
run: (a, api2) => api2.api("DELETE", `/vps/${a.vpsId}/ports/${a.allocationId}`)
|
|
36423
36423
|
}),
|
|
@@ -36441,7 +36441,7 @@ var vpsTools = [
|
|
|
36441
36441
|
name: "remove_vps_ssh_key",
|
|
36442
36442
|
title: "Remove SSH key",
|
|
36443
36443
|
kind: "destructive",
|
|
36444
|
-
description: "Remove an SSH key by fingerprint (from list_vps_ssh_keys). Whoever logs in with it loses access
|
|
36444
|
+
description: "Remove an SSH key by fingerprint (from list_vps_ssh_keys). Whoever logs in with it loses access (another key or the root password still works).",
|
|
36445
36445
|
input: { vpsId, fingerprint: exports_external.string().min(8).max(100).describe("e.g. SHA256:abc…+/= as listed") },
|
|
36446
36446
|
run: (a, api2) => api2.api("DELETE", `/vps/${a.vpsId}/ssh-keys/${a.fingerprint.trim().replace(/^SHA256:/, "").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "")}`)
|
|
36447
36447
|
}),
|
|
@@ -36450,7 +36450,7 @@ var vpsTools = [
|
|
|
36450
36450
|
title: "Turn SSH on / off",
|
|
36451
36451
|
kind: "write",
|
|
36452
36452
|
idempotent: true,
|
|
36453
|
-
description: "Turn SSH access to the server on or off (no change when it is already in that state). Turning it off locks out every SSH session and key
|
|
36453
|
+
description: "Turn SSH access to the server on or off (no change when it is already in that state). Turning it off locks out every SSH session and key. The server must be running.",
|
|
36454
36454
|
input: { vpsId, enabled: exports_external.boolean() },
|
|
36455
36455
|
run: (a, api2) => api2.api("POST", `/vps/${a.vpsId}/ssh`, { body: { enabled: a.enabled } })
|
|
36456
36456
|
}),
|
|
@@ -36474,7 +36474,7 @@ var vpsTools = [
|
|
|
36474
36474
|
name: "apply_snapshot",
|
|
36475
36475
|
title: "Roll back to snapshot",
|
|
36476
36476
|
kind: "destructive",
|
|
36477
|
-
description: "Roll the server's disk back to a snapshot. Everything written since is lost.
|
|
36477
|
+
description: "Roll the server's disk back to a snapshot. Everything written since is lost.",
|
|
36478
36478
|
input: { vpsId, snapshotId: exports_external.string() },
|
|
36479
36479
|
run: (a, api2) => api2.api("POST", `/vps/${a.vpsId}/snapshots/${a.snapshotId}/apply`)
|
|
36480
36480
|
}),
|
|
@@ -36506,7 +36506,7 @@ var vpsTools = [
|
|
|
36506
36506
|
name: "activate_vps_backup",
|
|
36507
36507
|
title: "Turn on VPS backups",
|
|
36508
36508
|
kind: "write",
|
|
36509
|
-
description: "Turn on daily backups for a running Linux server. COSTS MONEY right away: the whole period (1 or 12 months) is charged from the wallet and there is no dry run.
|
|
36509
|
+
description: "Turn on daily backups for a running Linux server. COSTS MONEY right away: the whole period (1 or 12 months) is charged from the wallet and there is no dry run. Prices (priceMonthly / priceYearly, IDR) are in list_backup_plans. The server must be running.",
|
|
36510
36510
|
input: {
|
|
36511
36511
|
vpsId,
|
|
36512
36512
|
planCode: exports_external.string().max(30).describe("Plan code from list_backup_plans"),
|
|
@@ -36533,7 +36533,7 @@ var vpsTools = [
|
|
|
36533
36533
|
name: "cancel_vps_backup",
|
|
36534
36534
|
title: "Cancel VPS backups",
|
|
36535
36535
|
kind: "destructive",
|
|
36536
|
-
description: "Stop renewing the server's backups. Backups keep running until the paid period ends; after that and a grace period the backups are DELETED and can no longer be restored.
|
|
36536
|
+
description: "Stop renewing the server's backups. Backups keep running until the paid period ends; after that and a grace period the backups are DELETED and can no longer be restored. (update_vps_backup autoRenew=true undoes it before the end.)",
|
|
36537
36537
|
input: { vpsId },
|
|
36538
36538
|
run: (a, api2) => api2.api("DELETE", `/vps/${a.vpsId}/backup`)
|
|
36539
36539
|
}),
|
|
@@ -36573,7 +36573,7 @@ var vpsTools = [
|
|
|
36573
36573
|
name: "restore_vps_backup",
|
|
36574
36574
|
title: "Restore VPS from backup",
|
|
36575
36575
|
kind: "destructive",
|
|
36576
|
-
description: "Restore from a restore point. mode=full puts the WHOLE disk back to that moment: everything written since is LOST and the server is offline while it restores. mode=files restores 1-50 paths: target=folder (default) puts them in a separate folder on the server, target=inplace OVERWRITES the current files.
|
|
36576
|
+
description: "Restore from a restore point. mode=full puts the WHOLE disk back to that moment: everything written since is LOST and the server is offline while it restores. mode=files restores 1-50 paths: target=folder (default) puts them in a separate folder on the server, target=inplace OVERWRITES the current files. Files at those paths are overwritten. Runs in the background: follow it with list_vps_backup_runs.",
|
|
36577
36577
|
input: {
|
|
36578
36578
|
vpsId,
|
|
36579
36579
|
pointId,
|
|
@@ -36595,7 +36595,7 @@ var vpsTools = [
|
|
|
36595
36595
|
name: "get_vps_backup_download",
|
|
36596
36596
|
title: "Get backup download link",
|
|
36597
36597
|
kind: "read",
|
|
36598
|
-
description: "Status of a prepared backup download; when ready, a short-lived url for the user to open (it expires at expiresAt).
|
|
36598
|
+
description: "Status of a prepared backup download; when ready, a short-lived url for the user to open (it expires at expiresAt). The link is for the user to download in a browser.",
|
|
36599
36599
|
input: { vpsId, downloadId: exports_external.string() },
|
|
36600
36600
|
run: (a, api2) => api2.api("GET", `/vps/${a.vpsId}/backup/downloads/${a.downloadId}`)
|
|
36601
36601
|
})
|
|
@@ -36605,7 +36605,7 @@ var vpsTools = [
|
|
|
36605
36605
|
var domainId = exports_external.number().int().positive().describe("Domain id (number, from list_my_domains)");
|
|
36606
36606
|
var hostId = exports_external.number().int().positive().describe("Child nameserver id (from list_child_nameservers)");
|
|
36607
36607
|
var dryRun2 = exports_external.boolean().optional().describe("true = return the exact price (IDR, VAT included) and the wallet balance after it; nothing is charged or registered");
|
|
36608
|
-
var DRY = "
|
|
36608
|
+
var DRY = "dryRun=true returns the price and walletBalanceAfter without charging or changing anything.";
|
|
36609
36609
|
var record3 = exports_external.object({
|
|
36610
36610
|
name: exports_external.string().describe('"@" for the domain itself, or a label like "www"'),
|
|
36611
36611
|
type: exports_external.enum(["A", "AAAA", "MX", "MXE", "CNAME", "SPF", "TXT"]),
|
|
@@ -36658,7 +36658,7 @@ var domainTools = [
|
|
|
36658
36658
|
title: "Update owner details",
|
|
36659
36659
|
kind: "write",
|
|
36660
36660
|
idempotent: true,
|
|
36661
|
-
description: "Set the account's domain owner (registrant) details the registrar needs: name, phone, addressLine1, city, state, countryCode and postalCode are required for a complete profile (organization, addressLine2 and fax are optional). Send only fields to change.
|
|
36661
|
+
description: "Set the account's domain owner (registrant) details the registrar needs: name, phone, addressLine1, city, state, countryCode and postalCode are required for a complete profile (organization, addressLine2 and fax are optional). Send only fields to change. These are personal details of the domain owner, stored as given. The answer says whether the details are now complete and which fields are still missing (it never echoes them).",
|
|
36662
36662
|
input: {
|
|
36663
36663
|
name: exports_external.string().min(1).max(255).optional().describe("Owner's full name"),
|
|
36664
36664
|
organization: exports_external.string().max(255).optional().describe("Company / organization (optional)"),
|
|
@@ -36718,7 +36718,7 @@ var domainTools = [
|
|
|
36718
36718
|
name: "set_dns_records",
|
|
36719
36719
|
title: "Replace DNS records",
|
|
36720
36720
|
kind: "destructive",
|
|
36721
|
-
description: "Replace ALL DNS records of the domain with this list.
|
|
36721
|
+
description: "Replace ALL DNS records of the domain with this list. Records not included are deleted (list_dns_records returns the current ones).",
|
|
36722
36722
|
input: { domainId, records: exports_external.array(record3).min(1) },
|
|
36723
36723
|
run: (a, api2) => api2.api("POST", `/domains/${a.domainId}/dns`, { body: { records: a.records } })
|
|
36724
36724
|
}),
|
|
@@ -36743,7 +36743,7 @@ var domainTools = [
|
|
|
36743
36743
|
name: "enable_whois_privacy",
|
|
36744
36744
|
title: "Enable WHOIS privacy",
|
|
36745
36745
|
kind: "write",
|
|
36746
|
-
description: "Hide the owner's details in WHOIS. COSTS MONEY (the whois_protection price per year).
|
|
36746
|
+
description: "Hide the owner's details in WHOIS. COSTS MONEY (the whois_protection price per year).",
|
|
36747
36747
|
input: { domainId },
|
|
36748
36748
|
run: (a, api2) => api2.api("POST", `/domains/${a.domainId}/whois-protection`)
|
|
36749
36749
|
}),
|
|
@@ -36759,7 +36759,7 @@ var domainTools = [
|
|
|
36759
36759
|
name: "whois_lookup",
|
|
36760
36760
|
title: "WHOIS lookup",
|
|
36761
36761
|
kind: "read",
|
|
36762
|
-
description: "Public WHOIS record of any domain name: registrar, dates, status, nameservers.
|
|
36762
|
+
description: "Public WHOIS record of any domain name: registrar, dates, status, nameservers. Availability is checked by search_domain.",
|
|
36763
36763
|
input: { domain: exports_external.string().describe("e.g. example.com") },
|
|
36764
36764
|
run: (a, api2) => api2.api("GET", "/domains/whois", { query: { domain: a.domain } })
|
|
36765
36765
|
}),
|
|
@@ -36768,7 +36768,7 @@ var domainTools = [
|
|
|
36768
36768
|
title: "Update one DNS record",
|
|
36769
36769
|
kind: "write",
|
|
36770
36770
|
idempotent: true,
|
|
36771
|
-
description: "Set one DNS record (by name and type) to new content, leaving the other records as they are.
|
|
36771
|
+
description: "Set one DNS record (by name and type) to new content, leaving the other records as they are. Changes one record and leaves the others as they are (list_dns_records returns record ids).",
|
|
36772
36772
|
input: { domainId, ...record3.shape },
|
|
36773
36773
|
run: (a, api2) => api2.api("PUT", `/domains/${a.domainId}/dns`, { body: { name: a.name, type: a.type, content: a.content, ttl: a.ttl } })
|
|
36774
36774
|
}),
|
|
@@ -36817,7 +36817,7 @@ var domainTools = [
|
|
|
36817
36817
|
name: "disable_whois_privacy",
|
|
36818
36818
|
title: "Disable WHOIS privacy",
|
|
36819
36819
|
kind: "destructive",
|
|
36820
|
-
description: "Turn WHOIS privacy off: the owner's name, address, email and phone become PUBLIC in WHOIS (no refund; turning it back on with enable_whois_privacy costs money).
|
|
36820
|
+
description: "Turn WHOIS privacy off: the owner's name, address, email and phone become PUBLIC in WHOIS (no refund; turning it back on with enable_whois_privacy costs money).",
|
|
36821
36821
|
input: { domainId },
|
|
36822
36822
|
run: (a, api2) => api2.api("DELETE", `/domains/${a.domainId}/whois-protection`)
|
|
36823
36823
|
})
|
|
@@ -36852,10 +36852,10 @@ var message = exports_external.object({
|
|
|
36852
36852
|
});
|
|
36853
36853
|
var dryRun3 = exports_external.boolean().optional().describe("true = return the price (IDR) and the wallet balance after it; nothing is charged or changed");
|
|
36854
36854
|
var idem2 = exports_external.string().regex(/^[A-Za-z0-9_.:-]{8,128}$/).optional().describe("Idempotency-Key for the real purchase. Generated when omitted; pass the same value when retrying so it is never charged twice");
|
|
36855
|
-
var MONEY = "COSTS MONEY from the wallet.
|
|
36855
|
+
var MONEY = "COSTS MONEY from the wallet. dryRun=true returns the charge (IDR) and walletBalanceAfter without charging or changing anything.";
|
|
36856
36856
|
var planCode = exports_external.string().min(1).max(50).describe("Plan code from list_email_plans");
|
|
36857
36857
|
var folder = exports_external.enum(["inbox", "spam", "archive", "trash"]);
|
|
36858
|
-
var AUDIENCE = "
|
|
36858
|
+
var AUDIENCE = "It goes to every contact in the broadcast's segment or topic (unsubscribed and suppressed addresses are skipped); the audience size is the segment's contactCount in list_email_segments, or preview_email_segment with no rules for all contacts.";
|
|
36859
36859
|
var emailTools = [
|
|
36860
36860
|
defineTool({
|
|
36861
36861
|
name: "email_status",
|
|
@@ -36924,7 +36924,7 @@ var emailTools = [
|
|
|
36924
36924
|
name: "buy_email_inbox_addon",
|
|
36925
36925
|
title: "Set inbox add-ons",
|
|
36926
36926
|
kind: "write",
|
|
36927
|
-
description: `Set the TOTAL extra mailboxes and extra inbox storage on the active paid plan (absolute numbers, not additions
|
|
36927
|
+
description: `Set the TOTAL extra mailboxes and extra inbox storage on the active paid plan (absolute numbers, not additions; get_email_plan returns the current values). Increases are charged now, prorated to the plan's end date, then renew with the plan; decreases must still fit what is in use. ${MONEY}`,
|
|
36928
36928
|
input: {
|
|
36929
36929
|
projectId,
|
|
36930
36930
|
extraMailboxes: exports_external.number().int().min(0).max(50).describe("Total extra mailboxes wanted (0-50)"),
|
|
@@ -36989,7 +36989,7 @@ var emailTools = [
|
|
|
36989
36989
|
name: "add_email_domain",
|
|
36990
36990
|
title: "Add sending domain",
|
|
36991
36991
|
kind: "write",
|
|
36992
|
-
description: "Add a sending domain; the response lists the DNS records the
|
|
36992
|
+
description: "Add a sending domain; the response lists the DNS records the domain needs; verify_email_domain checks them.",
|
|
36993
36993
|
input: { projectId, domain: exports_external.string() },
|
|
36994
36994
|
run: (a, api2) => api2.email("POST", "/domains", { body: { domain: a.domain }, project: a.projectId })
|
|
36995
36995
|
}),
|
|
@@ -37053,7 +37053,7 @@ var emailTools = [
|
|
|
37053
37053
|
name: "delete_email_domain",
|
|
37054
37054
|
title: "Delete sending domain",
|
|
37055
37055
|
kind: "destructive",
|
|
37056
|
-
description: "Remove a sending domain: email can no longer be sent from its addresses.
|
|
37056
|
+
description: "Remove a sending domain: email can no longer be sent from its addresses.",
|
|
37057
37057
|
input: { projectId, domainId: exports_external.string() },
|
|
37058
37058
|
run: (a, api2) => api2.email("DELETE", `/domains/${a.domainId}`, { project: a.projectId })
|
|
37059
37059
|
}),
|
|
@@ -37099,7 +37099,7 @@ var emailTools = [
|
|
|
37099
37099
|
name: "delete_email_template",
|
|
37100
37100
|
title: "Delete email template",
|
|
37101
37101
|
kind: "destructive",
|
|
37102
|
-
description: "Delete a template. Code that still sends with its templateId will fail.
|
|
37102
|
+
description: "Delete a template. Code that still sends with its templateId will fail.",
|
|
37103
37103
|
input: { projectId, templateId: exports_external.string() },
|
|
37104
37104
|
run: (a, api2) => api2.email("DELETE", `/templates/${a.templateId}`, { project: a.projectId })
|
|
37105
37105
|
}),
|
|
@@ -37155,7 +37155,7 @@ var emailTools = [
|
|
|
37155
37155
|
name: "delete_email_contact",
|
|
37156
37156
|
title: "Delete email contact",
|
|
37157
37157
|
kind: "destructive",
|
|
37158
|
-
description: "Delete a contact and its history.
|
|
37158
|
+
description: "Delete a contact and its history. unsubscribe_email_contact stops emails and keeps the opt-out on record; this deletes the contact.",
|
|
37159
37159
|
input: { projectId, contactId: uid("Contact") },
|
|
37160
37160
|
run: (a, api2) => api2.email("DELETE", `/contacts/${a.contactId}`, { project: a.projectId })
|
|
37161
37161
|
}),
|
|
@@ -37212,7 +37212,7 @@ var emailTools = [
|
|
|
37212
37212
|
name: "delete_email_segment",
|
|
37213
37213
|
title: "Delete segment",
|
|
37214
37214
|
kind: "destructive",
|
|
37215
|
-
description: "Delete a segment (its contacts are kept).
|
|
37215
|
+
description: "Delete a segment (its contacts are kept).",
|
|
37216
37216
|
input: { projectId, segmentId: uid("Segment") },
|
|
37217
37217
|
run: (a, api2) => api2.email("DELETE", `/segments/${a.segmentId}`, { project: a.projectId })
|
|
37218
37218
|
}),
|
|
@@ -37252,7 +37252,7 @@ var emailTools = [
|
|
|
37252
37252
|
name: "delete_email_topic",
|
|
37253
37253
|
title: "Delete topic",
|
|
37254
37254
|
kind: "destructive",
|
|
37255
|
-
description: "Delete a topic and every contact's subscription to it.
|
|
37255
|
+
description: "Delete a topic and every contact's subscription to it.",
|
|
37256
37256
|
input: { projectId, topicId: uid("Topic") },
|
|
37257
37257
|
run: (a, api2) => api2.email("DELETE", `/topics/${a.topicId}`, { project: a.projectId })
|
|
37258
37258
|
}),
|
|
@@ -37362,7 +37362,7 @@ var emailTools = [
|
|
|
37362
37362
|
name: "delete_email_suppression",
|
|
37363
37363
|
title: "Remove suppression",
|
|
37364
37364
|
kind: "destructive",
|
|
37365
|
-
description: "Allow an address to be emailed again. Only when the person asked for it or the bounce was fixed: emailing addresses that bounced or complained hurts the project's sending reputation.
|
|
37365
|
+
description: "Allow an address to be emailed again. Only when the person asked for it or the bounce was fixed: emailing addresses that bounced or complained hurts the project's sending reputation.",
|
|
37366
37366
|
input: { projectId, suppressionId: exports_external.string() },
|
|
37367
37367
|
run: (a, api2) => api2.email("DELETE", `/suppressions/${a.suppressionId}`, { project: a.projectId })
|
|
37368
37368
|
}),
|
|
@@ -37378,7 +37378,7 @@ var emailTools = [
|
|
|
37378
37378
|
name: "create_email_webhook",
|
|
37379
37379
|
title: "Create email webhook",
|
|
37380
37380
|
kind: "write",
|
|
37381
|
-
description: "POST email events to an HTTPS URL. The response holds the signing secret ONCE:
|
|
37381
|
+
description: "POST email events to an HTTPS URL. The response holds the signing secret ONCE: it is not shown again.",
|
|
37382
37382
|
input: {
|
|
37383
37383
|
projectId,
|
|
37384
37384
|
url: exports_external.string().min(8).max(2000),
|
|
@@ -37390,7 +37390,7 @@ var emailTools = [
|
|
|
37390
37390
|
name: "delete_email_webhook",
|
|
37391
37391
|
title: "Delete email webhook",
|
|
37392
37392
|
kind: "destructive",
|
|
37393
|
-
description: "Stop sending events to a webhook URL.
|
|
37393
|
+
description: "Stop sending events to a webhook URL.",
|
|
37394
37394
|
input: { projectId, webhookId: uid("Webhook") },
|
|
37395
37395
|
run: (a, api2) => api2.email("DELETE", `/webhooks/${a.webhookId}`, { project: a.projectId })
|
|
37396
37396
|
}),
|
|
@@ -37439,7 +37439,7 @@ var emailTools = [
|
|
|
37439
37439
|
name: "delete_inbox_address",
|
|
37440
37440
|
title: "Delete inbox address",
|
|
37441
37441
|
kind: "destructive",
|
|
37442
|
-
description: "Delete a receiving address: mail to it is no longer accepted (messages already received are kept).
|
|
37442
|
+
description: "Delete a receiving address: mail to it is no longer accepted (messages already received are kept).",
|
|
37443
37443
|
input: { projectId, addressId: uid("Address") },
|
|
37444
37444
|
run: (a, api2) => api2.email("DELETE", `/inbound/addresses/${a.addressId}`, { project: a.projectId })
|
|
37445
37445
|
}),
|
|
@@ -37475,7 +37475,7 @@ var emailTools = [
|
|
|
37475
37475
|
name: "reply_inbox_message",
|
|
37476
37476
|
title: "Reply to inbox message",
|
|
37477
37477
|
kind: "write",
|
|
37478
|
-
description: "Send a threaded reply to a received message (counts against the sending quota).
|
|
37478
|
+
description: "Send a threaded reply to a received message (counts against the sending quota). The reply is sent from the inbox address.",
|
|
37479
37479
|
input: {
|
|
37480
37480
|
projectId,
|
|
37481
37481
|
messageId: uid("Message"),
|
|
@@ -37490,7 +37490,7 @@ var emailTools = [
|
|
|
37490
37490
|
name: "delete_inbox_message",
|
|
37491
37491
|
title: "Delete inbox message",
|
|
37492
37492
|
kind: "destructive",
|
|
37493
|
-
description: "Delete a received message permanently.
|
|
37493
|
+
description: "Delete a received message permanently.",
|
|
37494
37494
|
input: { projectId, messageId: uid("Message") },
|
|
37495
37495
|
run: (a, api2) => api2.email("DELETE", `/inbound/messages/${a.messageId}`, { project: a.projectId })
|
|
37496
37496
|
})
|
|
@@ -37571,7 +37571,7 @@ var databaseTools = [
|
|
|
37571
37571
|
name: "delete_database_branch",
|
|
37572
37572
|
title: "Delete database branch",
|
|
37573
37573
|
kind: "destructive",
|
|
37574
|
-
description: "Delete an environment's branch and its data. The primary (production) branch cannot be deleted.
|
|
37574
|
+
description: "Delete an environment's branch and its data. The primary (production) branch cannot be deleted.",
|
|
37575
37575
|
input: { databaseId, environmentId: exports_external.string().uuid() },
|
|
37576
37576
|
run: (a, api2) => api2.api("DELETE", `/databases/${a.databaseId}/branches/${a.environmentId}`)
|
|
37577
37577
|
}),
|
|
@@ -37612,7 +37612,7 @@ var databaseTools = [
|
|
|
37612
37612
|
name: "suspend_database",
|
|
37613
37613
|
title: "Suspend database",
|
|
37614
37614
|
kind: "destructive",
|
|
37615
|
-
description: "Stop the database's compute (connections fail until resumed).
|
|
37615
|
+
description: "Stop the database's compute (connections fail until resumed).",
|
|
37616
37616
|
input: { databaseId },
|
|
37617
37617
|
run: (a, api2) => api2.api("POST", `/databases/${a.databaseId}/suspend`)
|
|
37618
37618
|
}),
|
|
@@ -37673,7 +37673,7 @@ var databaseTools = [
|
|
|
37673
37673
|
name: "browse_database_table",
|
|
37674
37674
|
title: "Browse table rows",
|
|
37675
37675
|
kind: "read",
|
|
37676
|
-
description: "Rows of a table, a page at a time (limit up to 200, offset to page). Read-only. Rows are
|
|
37676
|
+
description: "Rows of a table, a page at a time (limit up to 200, offset to page). Read-only. Rows are returned as stored, including any sensitive columns.",
|
|
37677
37677
|
input: {
|
|
37678
37678
|
databaseId,
|
|
37679
37679
|
table: exports_external.string().min(1).max(63),
|
|
@@ -37687,7 +37687,7 @@ var databaseTools = [
|
|
|
37687
37687
|
name: "query_database",
|
|
37688
37688
|
title: "Query database (read-only)",
|
|
37689
37689
|
kind: "read",
|
|
37690
|
-
description: "Run a read-only SQL statement (SELECT, EXPLAIN, SHOW…) in a read-only transaction; up to 200 rows. Use $1, $2… placeholders with params. Statements that change data are refused
|
|
37690
|
+
description: "Run a read-only SQL statement (SELECT, EXPLAIN, SHOW…) in a read-only transaction; up to 200 rows. Use $1, $2… placeholders with params. Statements that change data are refused (execute_database_sql runs those).",
|
|
37691
37691
|
input: { databaseId, sql: exports_external.string().min(1).max(1e4), params: exports_external.array(exports_external.any()).max(100).optional(), environmentId: environmentId.optional() },
|
|
37692
37692
|
run: (a, api2) => api2.api("POST", `/databases/${a.databaseId}/query`, { body: { sql: a.sql, params: a.params, environmentId: a.environmentId } })
|
|
37693
37693
|
}),
|
|
@@ -37695,7 +37695,7 @@ var databaseTools = [
|
|
|
37695
37695
|
name: "classify_database_sql",
|
|
37696
37696
|
title: "Classify SQL (no run)",
|
|
37697
37697
|
kind: "read",
|
|
37698
|
-
description: "What a SQL statement is (command, e.g. select / update / drop) and whether it writes, WITHOUT running it.
|
|
37698
|
+
description: "What a SQL statement is (command, e.g. select / update / drop) and whether it writes, WITHOUT running it. It reports what a statement would change before execute_database_sql runs it; readOnly statements can run with query_database.",
|
|
37699
37699
|
input: { databaseId, sql: exports_external.string().min(1).max(1e4) },
|
|
37700
37700
|
run: (a, api2) => api2.api("POST", `/databases/${a.databaseId}/query/classify`, { body: { sql: a.sql } })
|
|
37701
37701
|
}),
|
|
@@ -37703,7 +37703,7 @@ var databaseTools = [
|
|
|
37703
37703
|
name: "execute_database_sql",
|
|
37704
37704
|
title: "Execute SQL (writes)",
|
|
37705
37705
|
kind: "destructive",
|
|
37706
|
-
description: "Run a statement that changes data or schema (INSERT, UPDATE, DELETE, CREATE, ALTER, DROP…).
|
|
37706
|
+
description: "Run a statement that changes data or schema (INSERT, UPDATE, DELETE, CREATE, ALTER, DROP…). classify_database_sql reports what a statement does without running it. It runs on the chosen environment's branch.",
|
|
37707
37707
|
input: { databaseId, sql: exports_external.string().min(1).max(1e4), params: exports_external.array(exports_external.any()).max(100).optional(), environmentId: environmentId.optional() },
|
|
37708
37708
|
run: (a, api2) => api2.api("POST", `/databases/${a.databaseId}/query`, { body: { sql: a.sql, params: a.params, environmentId: a.environmentId, allowWrite: true } })
|
|
37709
37709
|
})
|
|
@@ -37793,7 +37793,7 @@ var accountTools = [
|
|
|
37793
37793
|
title: "Mark all notifications read",
|
|
37794
37794
|
kind: "write",
|
|
37795
37795
|
idempotent: true,
|
|
37796
|
-
description: "Mark every unread notification as read (a project key: its project's only).
|
|
37796
|
+
description: "Mark every unread notification as read (a project key: its project's only). Marks every notification as read.",
|
|
37797
37797
|
input: {},
|
|
37798
37798
|
run: (_a3, api2) => api2.api("POST", "/account/notifications/read-all")
|
|
37799
37799
|
}),
|
|
@@ -37831,7 +37831,7 @@ var accountTools = [
|
|
|
37831
37831
|
name: "create_support_ticket",
|
|
37832
37832
|
title: "Open support ticket",
|
|
37833
37833
|
kind: "write",
|
|
37834
|
-
description: `Open a ticket with Helipod support (at most 5 an hour;
|
|
37834
|
+
description: `Open a ticket with Helipod support (at most 5 an hour; replies go to an open ticket with reply_support_ticket). The subject and message are sent to Helipod support as written. ${ACCOUNT_KEY}`,
|
|
37835
37835
|
input: {
|
|
37836
37836
|
subject: exports_external.string().min(3).max(255),
|
|
37837
37837
|
category: exports_external.enum(["billing", "technical", "feature_request", "other"]),
|
|
@@ -37853,7 +37853,7 @@ var accountTools = [
|
|
|
37853
37853
|
title: "Close support ticket",
|
|
37854
37854
|
kind: "write",
|
|
37855
37855
|
idempotent: true,
|
|
37856
|
-
description: `Close a support ticket once the issue is solved (a closed ticket takes no more replies).
|
|
37856
|
+
description: `Close a support ticket once the issue is solved (a closed ticket takes no more replies). ${ACCOUNT_KEY}`,
|
|
37857
37857
|
input: { ticketId: uid2("Ticket") },
|
|
37858
37858
|
run: (a, api2) => api2.api("POST", `/account/tickets/${a.ticketId}/close`)
|
|
37859
37859
|
})
|
|
@@ -37910,7 +37910,7 @@ var aiTools = [
|
|
|
37910
37910
|
name: "revoke_ai_key",
|
|
37911
37911
|
title: "Revoke AI key",
|
|
37912
37912
|
kind: "destructive",
|
|
37913
|
-
description: "Revoke an AI key permanently: every app using it stops working at once and it cannot be restored (a new key must be made in the dashboard and deployed).
|
|
37913
|
+
description: "Revoke an AI key permanently: every app using it stops working at once and it cannot be restored (a new key must be made in the dashboard and deployed).",
|
|
37914
37914
|
input: { keyId: exports_external.string().uuid().describe("AI key id from list_ai_keys") },
|
|
37915
37915
|
run: (a, api2) => api2.api("DELETE", `/ai/keys/${a.keyId}`)
|
|
37916
37916
|
}),
|
|
@@ -37918,7 +37918,7 @@ var aiTools = [
|
|
|
37918
37918
|
name: "topup_ai_balance",
|
|
37919
37919
|
title: "Top up AI balance",
|
|
37920
37920
|
kind: "write",
|
|
37921
|
-
description: `Move money from the wallet to the AI balance, by pack (packId from get_ai_overview, may include a bonus) or by amount (IDR, at least minTopup). COSTS MONEY from the wallet.
|
|
37921
|
+
description: `Move money from the wallet to the AI balance, by pack (packId from get_ai_overview, may include a bonus) or by amount (IDR, at least minTopup). COSTS MONEY from the wallet. dryRun=true returns the amount, bonus and balances after without charging. ${ACCOUNT_KEY2}`,
|
|
37922
37922
|
input: {
|
|
37923
37923
|
packId: exports_external.string().min(1).max(64).optional(),
|
|
37924
37924
|
amount: exports_external.number().min(1).max(1e9).optional().describe("IDR"),
|
|
@@ -37940,7 +37940,7 @@ var aiTools = [
|
|
|
37940
37940
|
title: "Set AI auto top-up",
|
|
37941
37941
|
kind: "write",
|
|
37942
37942
|
idempotent: true,
|
|
37943
|
-
description: `Automatic top-up: when the AI balance falls below threshold (IDR), amount (IDR) is moved from the wallet. Enabling it COSTS MONEY later
|
|
37943
|
+
description: `Automatic top-up: when the AI balance falls below threshold (IDR), amount (IDR) is moved from the wallet. Enabling it COSTS MONEY later: top-ups then run automatically. dryRun=true returns the current and new settings without changing them. enabled=false turns it off. ${ACCOUNT_KEY2}`,
|
|
37944
37944
|
input: {
|
|
37945
37945
|
enabled: exports_external.boolean(),
|
|
37946
37946
|
threshold: exports_external.number().min(1).optional().describe("Top up when the AI balance is below this (IDR)"),
|
|
@@ -37958,16 +37958,14 @@ var aiTools = [
|
|
|
37958
37958
|
var API_PREFIXES = ["/containers/", "/databases", "/vps", "/backup/", "/domains", "/account/", "/ai/"];
|
|
37959
37959
|
var generalTools = [
|
|
37960
37960
|
defineTool({
|
|
37961
|
-
name: "
|
|
37962
|
-
title: "
|
|
37963
|
-
kind: "
|
|
37964
|
-
description: "
|
|
37961
|
+
name: "helipod_api_get",
|
|
37962
|
+
title: "Read any Helipod API endpoint",
|
|
37963
|
+
kind: "read",
|
|
37964
|
+
description: "GET an endpoint of the Helipod public API that has no dedicated read tool (Helipod API reference: https://docs.helipod.io/docs/helipod). api=core for the Container, Database, VPS, Domain, Account and AI APIs (paths like /vps/{id}/backup/runs, /account/wallet, /ai/usage), api=email for the Email API (paths like /broadcasts). Read only: it never changes anything.",
|
|
37965
37965
|
input: {
|
|
37966
37966
|
api: exports_external.enum(["core", "email"]),
|
|
37967
|
-
|
|
37968
|
-
|
|
37969
|
-
query: exports_external.record(exports_external.string(), exports_external.string()).optional(),
|
|
37970
|
-
body: exports_external.record(exports_external.string(), exports_external.any()).optional()
|
|
37967
|
+
path: exports_external.string().regex(/^\/[A-Za-z0-9/_.\-:]*$/).describe("Path after the base URL, e.g. /vps/abc/backup/runs"),
|
|
37968
|
+
query: exports_external.record(exports_external.string(), exports_external.string()).optional()
|
|
37971
37969
|
},
|
|
37972
37970
|
run: (a, api2) => {
|
|
37973
37971
|
if (a.path.includes(".."))
|
|
@@ -37975,20 +37973,21 @@ var generalTools = [
|
|
|
37975
37973
|
if (a.api === "core") {
|
|
37976
37974
|
if (!API_PREFIXES.some((p) => a.path.startsWith(p)))
|
|
37977
37975
|
throw new Error(`Core API paths start with one of: ${API_PREFIXES.join(", ")}`);
|
|
37978
|
-
return api2.api(
|
|
37976
|
+
return api2.api("GET", a.path, { query: a.query });
|
|
37979
37977
|
}
|
|
37980
|
-
return api2.email(
|
|
37978
|
+
return api2.email("GET", a.path, { query: a.query });
|
|
37981
37979
|
}
|
|
37982
37980
|
})
|
|
37983
37981
|
];
|
|
37984
37982
|
|
|
37985
37983
|
// src/server.ts
|
|
37986
|
-
var VERSION = "0.5.
|
|
37984
|
+
var VERSION = "0.5.3";
|
|
37987
37985
|
var INSTRUCTIONS = `Helipod is a cloud platform (Indonesia): containers, managed Postgres databases, VPS, domains, email and an AI gateway, billed from a prepaid wallet in Rupiah.
|
|
37988
37986
|
- Start with list_projects to find projects and environment ids. Account tools (get_wallet, invoices, statements, notifications, get_project_activity, support tickets) cover the account; AI tools (list_ai_models, get_ai_overview, get_ai_usage, AI keys, top-ups) cover the AI gateway.
|
|
37989
37987
|
- Anything that costs money (create/deploy/scale services, resize volumes, upgrade a database plan, create/renew/upgrade VPS, VPS backups, register/renew/transfer domains, email plans and inbox add-ons, AI top-ups and auto top-up): call it with dryRun=true first (or the price lookup when it has no dry run), tell the user the cost in IDR and the wallet balance after, and wait for an explicit yes before the real call. Never treat silence or an earlier general OK as a yes.
|
|
37990
37988
|
- Destructive tools (delete, terminate, reinstall, rollback, restore a backup, replace DNS, revoke a key, remove an SSH key or port forward, send a broadcast, execute_database_sql): confirm with the user and name what will be lost. Before execute_database_sql, run classify_database_sql.
|
|
37991
37989
|
- Email: when a project has no email yet (email_status shows activated false) or its plan ended, start it with buy_email_plan (dryRun first; the FREE plan costs nothing, still confirm). That also sets email up for the project; then add and verify a sending domain.
|
|
37990
|
+
- Before replacing all DNS records (set_dns_records), read list_dns_records and keep every record the user still needs. Before sending or scheduling a broadcast, tell the user how many contacts it reaches. Before deleting or replacing code, files or variables, read the current value. After renaming a service, fix the variable references listed in warnings.
|
|
37992
37991
|
- Databases: get_database_connection returns a password; put it in a secret variable (DATABASE_URL) instead of code or chat.
|
|
37993
37992
|
- Deploys and VPS actions run in the background: poll get_deployment / get_vps until they settle; on a failed deploy read get_deployment_logs.
|
|
37994
37993
|
- Never print secrets (passwords, secret variable values, secret files) unless the user asks for them. Domain owner details are personal data: use only what the user gave.
|