helipod-mcp 0.5.0 → 0.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -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 | `helipod_request` for any other documented endpoint |
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 === "destructive",
35676
+ destructiveHint: d.kind !== "read",
35677
35677
  idempotentHint: d.kind === "read" || !!d.idempotent,
35678
35678
  openWorldHint: true
35679
35679
  }
@@ -36861,7 +36861,7 @@ var emailTools = [
36861
36861
  name: "email_status",
36862
36862
  title: "Email status",
36863
36863
  kind: "read",
36864
- description: "Email service of the key's project: plan, usage today and this month, limits, counts.",
36864
+ description: "Email service of the key's project: plan, usage today and this month, limits, counts. activated false = email is not set up yet: start it with buy_email_plan.",
36865
36865
  input: { projectId },
36866
36866
  run: (a, api2) => api2.email("GET", "/status", { project: a.projectId })
36867
36867
  }),
@@ -36885,7 +36885,7 @@ var emailTools = [
36885
36885
  name: "buy_email_plan",
36886
36886
  title: "Buy email plan",
36887
36887
  kind: "write",
36888
- description: `Start an email plan for the project (a free plan activates without charge). ${MONEY} The dry run's mode says purchase, activate_free or already_active.`,
36888
+ description: `Start an email plan for the project (a free plan activates without charge). Works for a project with no email yet: the real call also sets email up (result.setup). ${MONEY} The dry run's mode says purchase, activate_free or already_active.`,
36889
36889
  input: { projectId, planCode, months: exports_external.union([exports_external.literal(1), exports_external.literal(3), exports_external.literal(6), exports_external.literal(12)]).optional().describe("Billing cycle, default 1"), dryRun: dryRun3, idempotencyKey: idem2 },
36890
36890
  run: (a, api2) => api2.email("POST", "/plan", {
36891
36891
  project: a.projectId,
@@ -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: "helipod_request",
37962
- title: "Call any Helipod API endpoint",
37963
- kind: "destructive",
37964
- description: "Call an endpoint that has no dedicated tool, as documented at https://docs.helipod.io. api=core for the Container, Database, VPS, Domain, Account and AI APIs (paths like /vps/{id}/backup, /account/wallet, /ai/usage), api=email for the Email API (paths like /broadcasts). Prefer the dedicated tools; ask the user before any call that costs money or deletes something.",
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
- method: exports_external.enum(["GET", "POST", "PUT", "PATCH", "DELETE"]),
37968
- path: exports_external.string().regex(/^\/[A-Za-z0-9/_.\-:]*$/).describe("Path after the base URL, e.g. /vps/abc/backup"),
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,23 +37973,24 @@ 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(a.method, a.path, { query: a.query, body: a.body });
37976
+ return api2.api("GET", a.path, { query: a.query });
37979
37977
  }
37980
- return api2.email(a.method, a.path, { query: a.query, body: a.body });
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.0";
37984
+ var VERSION = "0.5.2";
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.
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.
37991
37990
  - Databases: get_database_connection returns a password; put it in a secret variable (DATABASE_URL) instead of code or chat.
37992
37991
  - Deploys and VPS actions run in the background: poll get_deployment / get_vps until they settle; on a failed deploy read get_deployment_logs.
37993
37992
  - 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.
37994
- - Errors come back as { status, code, error }: 401/403 means the key lacks access (keys choose products and projects in Settings → API keys; wallet, invoices, tickets and AI money need a whole-account key), 402 means plan limit or low balance.
37993
+ - Errors come back as { status, code, error }: 401/403 means the key lacks access (keys choose products and projects in Settings → API keys; wallet, invoices, tickets and AI money need a whole-account key: with a sign-in, reconnect and choose Whole account), 402 means plan limit or low balance.
37995
37994
  Docs: https://docs.helipod.io`;
37996
37995
  var ALL_TOOLS = [...containerTools, ...databaseTools, ...vpsTools, ...domainTools, ...emailTools, ...accountTools, ...aiTools, ...generalTools];
37997
37996
  function createHelipodServer(config2) {
package/dist/index.js CHANGED
@@ -34818,7 +34818,7 @@ function register(server, api2, defs) {
34818
34818
  annotations: {
34819
34819
  title: d.title,
34820
34820
  readOnlyHint: d.kind === "read",
34821
- destructiveHint: d.kind === "destructive",
34821
+ destructiveHint: d.kind !== "read",
34822
34822
  idempotentHint: d.kind === "read" || !!d.idempotent,
34823
34823
  openWorldHint: true
34824
34824
  }
@@ -36006,7 +36006,7 @@ var emailTools = [
36006
36006
  name: "email_status",
36007
36007
  title: "Email status",
36008
36008
  kind: "read",
36009
- description: "Email service of the key's project: plan, usage today and this month, limits, counts.",
36009
+ description: "Email service of the key's project: plan, usage today and this month, limits, counts. activated false = email is not set up yet: start it with buy_email_plan.",
36010
36010
  input: { projectId },
36011
36011
  run: (a, api2) => api2.email("GET", "/status", { project: a.projectId })
36012
36012
  }),
@@ -36030,7 +36030,7 @@ var emailTools = [
36030
36030
  name: "buy_email_plan",
36031
36031
  title: "Buy email plan",
36032
36032
  kind: "write",
36033
- description: `Start an email plan for the project (a free plan activates without charge). ${MONEY} The dry run's mode says purchase, activate_free or already_active.`,
36033
+ description: `Start an email plan for the project (a free plan activates without charge). Works for a project with no email yet: the real call also sets email up (result.setup). ${MONEY} The dry run's mode says purchase, activate_free or already_active.`,
36034
36034
  input: { projectId, planCode, months: exports_external.union([exports_external.literal(1), exports_external.literal(3), exports_external.literal(6), exports_external.literal(12)]).optional().describe("Billing cycle, default 1"), dryRun: dryRun3, idempotencyKey: idem2 },
36035
36035
  run: (a, api2) => api2.email("POST", "/plan", {
36036
36036
  project: a.projectId,
@@ -37103,16 +37103,14 @@ var aiTools = [
37103
37103
  var API_PREFIXES = ["/containers/", "/databases", "/vps", "/backup/", "/domains", "/account/", "/ai/"];
37104
37104
  var generalTools = [
37105
37105
  defineTool({
37106
- name: "helipod_request",
37107
- title: "Call any Helipod API endpoint",
37108
- kind: "destructive",
37109
- description: "Call an endpoint that has no dedicated tool, as documented at https://docs.helipod.io. api=core for the Container, Database, VPS, Domain, Account and AI APIs (paths like /vps/{id}/backup, /account/wallet, /ai/usage), api=email for the Email API (paths like /broadcasts). Prefer the dedicated tools; ask the user before any call that costs money or deletes something.",
37106
+ name: "helipod_api_get",
37107
+ title: "Read any Helipod API endpoint",
37108
+ kind: "read",
37109
+ 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.",
37110
37110
  input: {
37111
37111
  api: exports_external.enum(["core", "email"]),
37112
- method: exports_external.enum(["GET", "POST", "PUT", "PATCH", "DELETE"]),
37113
- path: exports_external.string().regex(/^\/[A-Za-z0-9/_.\-:]*$/).describe("Path after the base URL, e.g. /vps/abc/backup"),
37114
- query: exports_external.record(exports_external.string(), exports_external.string()).optional(),
37115
- body: exports_external.record(exports_external.string(), exports_external.any()).optional()
37112
+ path: exports_external.string().regex(/^\/[A-Za-z0-9/_.\-:]*$/).describe("Path after the base URL, e.g. /vps/abc/backup/runs"),
37113
+ query: exports_external.record(exports_external.string(), exports_external.string()).optional()
37116
37114
  },
37117
37115
  run: (a, api2) => {
37118
37116
  if (a.path.includes(".."))
@@ -37120,23 +37118,24 @@ var generalTools = [
37120
37118
  if (a.api === "core") {
37121
37119
  if (!API_PREFIXES.some((p) => a.path.startsWith(p)))
37122
37120
  throw new Error(`Core API paths start with one of: ${API_PREFIXES.join(", ")}`);
37123
- return api2.api(a.method, a.path, { query: a.query, body: a.body });
37121
+ return api2.api("GET", a.path, { query: a.query });
37124
37122
  }
37125
- return api2.email(a.method, a.path, { query: a.query, body: a.body });
37123
+ return api2.email("GET", a.path, { query: a.query });
37126
37124
  }
37127
37125
  })
37128
37126
  ];
37129
37127
 
37130
37128
  // src/server.ts
37131
- var VERSION = "0.5.0";
37129
+ var VERSION = "0.5.2";
37132
37130
  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.
37133
37131
  - 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.
37134
37132
  - 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.
37135
37133
  - 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.
37134
+ - 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.
37136
37135
  - Databases: get_database_connection returns a password; put it in a secret variable (DATABASE_URL) instead of code or chat.
37137
37136
  - Deploys and VPS actions run in the background: poll get_deployment / get_vps until they settle; on a failed deploy read get_deployment_logs.
37138
37137
  - 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.
37139
- - Errors come back as { status, code, error }: 401/403 means the key lacks access (keys choose products and projects in Settings → API keys; wallet, invoices, tickets and AI money need a whole-account key), 402 means plan limit or low balance.
37138
+ - Errors come back as { status, code, error }: 401/403 means the key lacks access (keys choose products and projects in Settings → API keys; wallet, invoices, tickets and AI money need a whole-account key: with a sign-in, reconnect and choose Whole account), 402 means plan limit or low balance.
37140
37139
  Docs: https://docs.helipod.io`;
37141
37140
  var ALL_TOOLS = [...containerTools, ...databaseTools, ...vpsTools, ...domainTools, ...emailTools, ...accountTools, ...aiTools, ...generalTools];
37142
37141
  function createHelipodServer(config2) {
package/dist/stdio.js CHANGED
@@ -34925,7 +34925,7 @@ function register(server, api2, defs) {
34925
34925
  annotations: {
34926
34926
  title: d.title,
34927
34927
  readOnlyHint: d.kind === "read",
34928
- destructiveHint: d.kind === "destructive",
34928
+ destructiveHint: d.kind !== "read",
34929
34929
  idempotentHint: d.kind === "read" || !!d.idempotent,
34930
34930
  openWorldHint: true
34931
34931
  }
@@ -36113,7 +36113,7 @@ var emailTools = [
36113
36113
  name: "email_status",
36114
36114
  title: "Email status",
36115
36115
  kind: "read",
36116
- description: "Email service of the key's project: plan, usage today and this month, limits, counts.",
36116
+ description: "Email service of the key's project: plan, usage today and this month, limits, counts. activated false = email is not set up yet: start it with buy_email_plan.",
36117
36117
  input: { projectId },
36118
36118
  run: (a, api2) => api2.email("GET", "/status", { project: a.projectId })
36119
36119
  }),
@@ -36137,7 +36137,7 @@ var emailTools = [
36137
36137
  name: "buy_email_plan",
36138
36138
  title: "Buy email plan",
36139
36139
  kind: "write",
36140
- description: `Start an email plan for the project (a free plan activates without charge). ${MONEY} The dry run's mode says purchase, activate_free or already_active.`,
36140
+ description: `Start an email plan for the project (a free plan activates without charge). Works for a project with no email yet: the real call also sets email up (result.setup). ${MONEY} The dry run's mode says purchase, activate_free or already_active.`,
36141
36141
  input: { projectId, planCode, months: exports_external.union([exports_external.literal(1), exports_external.literal(3), exports_external.literal(6), exports_external.literal(12)]).optional().describe("Billing cycle, default 1"), dryRun: dryRun3, idempotencyKey: idem2 },
36142
36142
  run: (a, api2) => api2.email("POST", "/plan", {
36143
36143
  project: a.projectId,
@@ -37210,16 +37210,14 @@ var aiTools = [
37210
37210
  var API_PREFIXES = ["/containers/", "/databases", "/vps", "/backup/", "/domains", "/account/", "/ai/"];
37211
37211
  var generalTools = [
37212
37212
  defineTool({
37213
- name: "helipod_request",
37214
- title: "Call any Helipod API endpoint",
37215
- kind: "destructive",
37216
- description: "Call an endpoint that has no dedicated tool, as documented at https://docs.helipod.io. api=core for the Container, Database, VPS, Domain, Account and AI APIs (paths like /vps/{id}/backup, /account/wallet, /ai/usage), api=email for the Email API (paths like /broadcasts). Prefer the dedicated tools; ask the user before any call that costs money or deletes something.",
37213
+ name: "helipod_api_get",
37214
+ title: "Read any Helipod API endpoint",
37215
+ kind: "read",
37216
+ 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.",
37217
37217
  input: {
37218
37218
  api: exports_external.enum(["core", "email"]),
37219
- method: exports_external.enum(["GET", "POST", "PUT", "PATCH", "DELETE"]),
37220
- path: exports_external.string().regex(/^\/[A-Za-z0-9/_.\-:]*$/).describe("Path after the base URL, e.g. /vps/abc/backup"),
37221
- query: exports_external.record(exports_external.string(), exports_external.string()).optional(),
37222
- body: exports_external.record(exports_external.string(), exports_external.any()).optional()
37219
+ path: exports_external.string().regex(/^\/[A-Za-z0-9/_.\-:]*$/).describe("Path after the base URL, e.g. /vps/abc/backup/runs"),
37220
+ query: exports_external.record(exports_external.string(), exports_external.string()).optional()
37223
37221
  },
37224
37222
  run: (a, api2) => {
37225
37223
  if (a.path.includes(".."))
@@ -37227,23 +37225,24 @@ var generalTools = [
37227
37225
  if (a.api === "core") {
37228
37226
  if (!API_PREFIXES.some((p) => a.path.startsWith(p)))
37229
37227
  throw new Error(`Core API paths start with one of: ${API_PREFIXES.join(", ")}`);
37230
- return api2.api(a.method, a.path, { query: a.query, body: a.body });
37228
+ return api2.api("GET", a.path, { query: a.query });
37231
37229
  }
37232
- return api2.email(a.method, a.path, { query: a.query, body: a.body });
37230
+ return api2.email("GET", a.path, { query: a.query });
37233
37231
  }
37234
37232
  })
37235
37233
  ];
37236
37234
 
37237
37235
  // src/server.ts
37238
- var VERSION = "0.5.0";
37236
+ var VERSION = "0.5.2";
37239
37237
  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.
37240
37238
  - 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.
37241
37239
  - 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.
37242
37240
  - 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.
37241
+ - 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.
37243
37242
  - Databases: get_database_connection returns a password; put it in a secret variable (DATABASE_URL) instead of code or chat.
37244
37243
  - Deploys and VPS actions run in the background: poll get_deployment / get_vps until they settle; on a failed deploy read get_deployment_logs.
37245
37244
  - 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.
37246
- - Errors come back as { status, code, error }: 401/403 means the key lacks access (keys choose products and projects in Settings → API keys; wallet, invoices, tickets and AI money need a whole-account key), 402 means plan limit or low balance.
37245
+ - Errors come back as { status, code, error }: 401/403 means the key lacks access (keys choose products and projects in Settings → API keys; wallet, invoices, tickets and AI money need a whole-account key: with a sign-in, reconnect and choose Whole account), 402 means plan limit or low balance.
37247
37246
  Docs: https://docs.helipod.io`;
37248
37247
  var ALL_TOOLS = [...containerTools, ...databaseTools, ...vpsTools, ...domainTools, ...emailTools, ...accountTools, ...aiTools, ...generalTools];
37249
37248
  function createHelipodServer(config2) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "helipod-mcp",
3
- "version": "0.5.0",
3
+ "version": "0.5.2",
4
4
  "description": "MCP server for Helipod: containers, databases, VPS, domains and email from Claude Code, Codex, Cursor and other AI tools.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -25,4 +25,4 @@ Follow the `helipod` skill rules. A VPS is prepaid per period: creating one char
25
25
  - Billing: `get_vps_renewal_options` → `renew_vps`; `upgrade_vps` to a larger plan (charges the difference, restarts); `toggle_vps_auto_renew`.
26
26
  - Terminate: `terminate_vps` is permanent, no refund: confirm explicitly.
27
27
 
28
- Backups (paid add-on) and anything else: `helipod_request` with paths from https://docs.helipod.io/docs/vps-api
28
+ Backups (paid add-on) have dedicated tools; to read anything else use `helipod_api_get` with paths from https://docs.helipod.io/docs/vps-api