helipod-mcp 0.5.16 → 0.5.18

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/dist/http.js CHANGED
@@ -35854,7 +35854,7 @@ var containerTools = [
35854
35854
  name: "list_services",
35855
35855
  title: "List services",
35856
35856
  kind: "read",
35857
- description: "Services (containers) in an environment: status, source, resources, domains, latest deployment and daily cost.",
35857
+ description: "Services (containers) in an environment: status, source, resources, domains, latest deployment and daily cost. Status awaiting_payment = a deploy was refused because the wallet could not pay: top up or buy a bundle (get_bundle), then deploy_service again; nothing is lost.",
35858
35858
  input: { environmentId: id("Environment") },
35859
35859
  run: (a, api2) => api2.api("GET", `${C}/environments/${a.environmentId}/services`)
35860
35860
  }),
@@ -35951,7 +35951,7 @@ var containerTools = [
35951
35951
  title: "Update / rename service",
35952
35952
  kind: "write",
35953
35953
  idempotent: true,
35954
- 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.",
35954
+ description: "Rename a service or change its start command, root directory, health check or startup dependencies. Settings apply on the next deploy (needsRedeploy). Renaming rewrites references like ${{oldName.KEY}} in the environment's service variables to the new name (applied on their next deploy); project shared variables are not rewritten and are listed in warnings.",
35955
35955
  input: {
35956
35956
  serviceId: id("Service"),
35957
35957
  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)"),
@@ -37285,7 +37285,7 @@ var emailTools = [
37285
37285
  name: "list_email_keys",
37286
37286
  title: "List email keys",
37287
37287
  kind: "read",
37288
- description: "Email API keys of a project (name, prefix, last used, expiry; never the key itself). Needs a Helipod API key with the Email API: an email key or a sign-in token answers 403 KEY_NOT_ALLOWED.",
37288
+ description: "Email API keys of a project (name, prefix, access full or send, last used, expiry; never the key itself). Needs a Helipod API key with the Email API: an email key or a sign-in token answers 403 KEY_NOT_ALLOWED.",
37289
37289
  input: { projectId },
37290
37290
  run: (a, api2) => api2.emailWithAccountKey("GET", "/keys", { project: a.projectId })
37291
37291
  }),
@@ -37293,9 +37293,14 @@ var emailTools = [
37293
37293
  name: "create_email_key",
37294
37294
  title: "Create email key",
37295
37295
  kind: "write",
37296
- description: "Make an email API key for a project, e.g. one per customer of a reseller. The key works on the Email API and as the SMTP password (smtp.helipod.io, username apikey) for that project only, and cannot make keys itself. The full key is in the answer ONCE: give it to the user to store; it cannot be shown again. Needs a Helipod API key with the Email API (an email key or a sign-in token answers 403 KEY_NOT_ALLOWED). Per project: 5 active keys on Free/Starter, 10 on Pro, 50 on Business.",
37297
- input: { projectId, name: exports_external.string().min(1).max(100).describe("To tell keys apart, e.g. the customer's name"), expiresInDays: exports_external.number().int().min(1).max(3650).optional() },
37298
- run: (a, api2) => api2.emailWithAccountKey("POST", "/keys", { project: a.projectId, body: { name: a.name, expiresInDays: a.expiresInDays } })
37296
+ description: 'Make an email API key for a project, e.g. one per customer of a reseller. The key works on the Email API and as the SMTP password (smtp.helipod.io, username apikey) for that project only, and cannot make keys itself. The full key is in the answer ONCE: give it to the user to store; it cannot be shown again. Needs a Helipod API key with the Email API (an email key or a sign-in token answers 403 KEY_NOT_ALLOWED). Per project: 5 active keys on Free/Starter, 10 on Pro, 50 on Business. access="send" makes a send-only key (POST /send, /send/batch, SMTP and reading sent mail; everything else, plans included, answers 403 KEY_SEND_ONLY): give that one to a customer who only needs SMTP, so it can never buy or renew plans from the wallet.',
37297
+ input: {
37298
+ projectId,
37299
+ name: exports_external.string().min(1).max(100).describe("To tell keys apart, e.g. the customer's name"),
37300
+ expiresInDays: exports_external.number().int().min(1).max(3650).optional(),
37301
+ access: exports_external.enum(["full", "send"]).optional().describe("full (default): everything the project allows. send: only sending and reading sent mail")
37302
+ },
37303
+ run: (a, api2) => api2.emailWithAccountKey("POST", "/keys", { project: a.projectId, body: { name: a.name, expiresInDays: a.expiresInDays, ...a.access ? { access: a.access } : {} } })
37299
37304
  }),
37300
37305
  defineTool({
37301
37306
  name: "revoke_email_key",
@@ -38558,7 +38563,7 @@ var generalTools = [
38558
38563
  ];
38559
38564
 
38560
38565
  // src/server.ts
38561
- var VERSION = "0.5.16";
38566
+ var VERSION = "0.5.18";
38562
38567
  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.
38563
38568
  - 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, generate_ai_image) cover the AI gateway.
38564
38569
  - 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, generating images): 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.
@@ -38567,7 +38572,7 @@ var INSTRUCTIONS = `Helipod is a cloud platform (Indonesia): containers, managed
38567
38572
  - Deploying an app, step by step: list_projects (pick the project and its production environmentId) -> get_bundle (is it covered?) -> if it needs Postgres: create_database, then get_database_connection and store DATABASE_URL with set_variables (secrets) after the service exists, or pass it in create_service variables -> create_service with dryRun=true (repo or image, port, variables) -> tell the user the cost (included in the bundle, or walletDailyCost per day) and wait for their OK -> create_service for real -> poll get_deployment until it settles, read get_deployment_logs if it failed -> give the user the *.helipod.app URL from get_service. Ask the user for secrets (API keys) only when the app needs them; never invent values.
38568
38573
  - Destructive tools (delete, terminate, reinstall, rollback, restore a backup or an import, copy a backup onto another VPS, 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.
38569
38574
  - 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.
38570
- - Email keys: create_email_key gives an app or a customer its own key (also its SMTP password: smtp.helipod.io, username apikey); the full key is shown once, so hand it over and never print it again. Domain on Helipod: add_domain_email_records puts the sending domain's DNS records in place in one call.
38575
+ - Email keys: create_email_key gives an app or a customer its own key (also its SMTP password: smtp.helipod.io, username apikey); the full key is shown once, so hand it over and never print it again. A customer who only sends gets access "send": that key cannot touch plans or anything that costs money. Domain on Helipod: add_domain_email_records puts the sending domain's DNS records in place in one call.
38571
38576
  - Domains for someone else (resellers): register_domain and transfer_domain take registrant (.id only; a transfer gets the owner when it completes), set_domain_owner changes it later. Use only details the user gave.
38572
38577
  - 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.
38573
38578
  - Databases: get_database_connection returns a password; put it in a secret variable (DATABASE_URL) instead of code or chat.
package/dist/index.js CHANGED
@@ -34999,7 +34999,7 @@ var containerTools = [
34999
34999
  name: "list_services",
35000
35000
  title: "List services",
35001
35001
  kind: "read",
35002
- description: "Services (containers) in an environment: status, source, resources, domains, latest deployment and daily cost.",
35002
+ description: "Services (containers) in an environment: status, source, resources, domains, latest deployment and daily cost. Status awaiting_payment = a deploy was refused because the wallet could not pay: top up or buy a bundle (get_bundle), then deploy_service again; nothing is lost.",
35003
35003
  input: { environmentId: id("Environment") },
35004
35004
  run: (a, api2) => api2.api("GET", `${C}/environments/${a.environmentId}/services`)
35005
35005
  }),
@@ -35096,7 +35096,7 @@ var containerTools = [
35096
35096
  title: "Update / rename service",
35097
35097
  kind: "write",
35098
35098
  idempotent: true,
35099
- 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.",
35099
+ description: "Rename a service or change its start command, root directory, health check or startup dependencies. Settings apply on the next deploy (needsRedeploy). Renaming rewrites references like ${{oldName.KEY}} in the environment's service variables to the new name (applied on their next deploy); project shared variables are not rewritten and are listed in warnings.",
35100
35100
  input: {
35101
35101
  serviceId: id("Service"),
35102
35102
  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)"),
@@ -36430,7 +36430,7 @@ var emailTools = [
36430
36430
  name: "list_email_keys",
36431
36431
  title: "List email keys",
36432
36432
  kind: "read",
36433
- description: "Email API keys of a project (name, prefix, last used, expiry; never the key itself). Needs a Helipod API key with the Email API: an email key or a sign-in token answers 403 KEY_NOT_ALLOWED.",
36433
+ description: "Email API keys of a project (name, prefix, access full or send, last used, expiry; never the key itself). Needs a Helipod API key with the Email API: an email key or a sign-in token answers 403 KEY_NOT_ALLOWED.",
36434
36434
  input: { projectId },
36435
36435
  run: (a, api2) => api2.emailWithAccountKey("GET", "/keys", { project: a.projectId })
36436
36436
  }),
@@ -36438,9 +36438,14 @@ var emailTools = [
36438
36438
  name: "create_email_key",
36439
36439
  title: "Create email key",
36440
36440
  kind: "write",
36441
- description: "Make an email API key for a project, e.g. one per customer of a reseller. The key works on the Email API and as the SMTP password (smtp.helipod.io, username apikey) for that project only, and cannot make keys itself. The full key is in the answer ONCE: give it to the user to store; it cannot be shown again. Needs a Helipod API key with the Email API (an email key or a sign-in token answers 403 KEY_NOT_ALLOWED). Per project: 5 active keys on Free/Starter, 10 on Pro, 50 on Business.",
36442
- input: { projectId, name: exports_external.string().min(1).max(100).describe("To tell keys apart, e.g. the customer's name"), expiresInDays: exports_external.number().int().min(1).max(3650).optional() },
36443
- run: (a, api2) => api2.emailWithAccountKey("POST", "/keys", { project: a.projectId, body: { name: a.name, expiresInDays: a.expiresInDays } })
36441
+ description: 'Make an email API key for a project, e.g. one per customer of a reseller. The key works on the Email API and as the SMTP password (smtp.helipod.io, username apikey) for that project only, and cannot make keys itself. The full key is in the answer ONCE: give it to the user to store; it cannot be shown again. Needs a Helipod API key with the Email API (an email key or a sign-in token answers 403 KEY_NOT_ALLOWED). Per project: 5 active keys on Free/Starter, 10 on Pro, 50 on Business. access="send" makes a send-only key (POST /send, /send/batch, SMTP and reading sent mail; everything else, plans included, answers 403 KEY_SEND_ONLY): give that one to a customer who only needs SMTP, so it can never buy or renew plans from the wallet.',
36442
+ input: {
36443
+ projectId,
36444
+ name: exports_external.string().min(1).max(100).describe("To tell keys apart, e.g. the customer's name"),
36445
+ expiresInDays: exports_external.number().int().min(1).max(3650).optional(),
36446
+ access: exports_external.enum(["full", "send"]).optional().describe("full (default): everything the project allows. send: only sending and reading sent mail")
36447
+ },
36448
+ run: (a, api2) => api2.emailWithAccountKey("POST", "/keys", { project: a.projectId, body: { name: a.name, expiresInDays: a.expiresInDays, ...a.access ? { access: a.access } : {} } })
36444
36449
  }),
36445
36450
  defineTool({
36446
36451
  name: "revoke_email_key",
@@ -37703,7 +37708,7 @@ var generalTools = [
37703
37708
  ];
37704
37709
 
37705
37710
  // src/server.ts
37706
- var VERSION = "0.5.16";
37711
+ var VERSION = "0.5.18";
37707
37712
  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.
37708
37713
  - 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, generate_ai_image) cover the AI gateway.
37709
37714
  - 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, generating images): 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.
@@ -37712,7 +37717,7 @@ var INSTRUCTIONS = `Helipod is a cloud platform (Indonesia): containers, managed
37712
37717
  - Deploying an app, step by step: list_projects (pick the project and its production environmentId) -> get_bundle (is it covered?) -> if it needs Postgres: create_database, then get_database_connection and store DATABASE_URL with set_variables (secrets) after the service exists, or pass it in create_service variables -> create_service with dryRun=true (repo or image, port, variables) -> tell the user the cost (included in the bundle, or walletDailyCost per day) and wait for their OK -> create_service for real -> poll get_deployment until it settles, read get_deployment_logs if it failed -> give the user the *.helipod.app URL from get_service. Ask the user for secrets (API keys) only when the app needs them; never invent values.
37713
37718
  - Destructive tools (delete, terminate, reinstall, rollback, restore a backup or an import, copy a backup onto another VPS, 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.
37714
37719
  - 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.
37715
- - Email keys: create_email_key gives an app or a customer its own key (also its SMTP password: smtp.helipod.io, username apikey); the full key is shown once, so hand it over and never print it again. Domain on Helipod: add_domain_email_records puts the sending domain's DNS records in place in one call.
37720
+ - Email keys: create_email_key gives an app or a customer its own key (also its SMTP password: smtp.helipod.io, username apikey); the full key is shown once, so hand it over and never print it again. A customer who only sends gets access "send": that key cannot touch plans or anything that costs money. Domain on Helipod: add_domain_email_records puts the sending domain's DNS records in place in one call.
37716
37721
  - Domains for someone else (resellers): register_domain and transfer_domain take registrant (.id only; a transfer gets the owner when it completes), set_domain_owner changes it later. Use only details the user gave.
37717
37722
  - 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.
37718
37723
  - Databases: get_database_connection returns a password; put it in a secret variable (DATABASE_URL) instead of code or chat.
package/dist/stdio.js CHANGED
@@ -35106,7 +35106,7 @@ var containerTools = [
35106
35106
  name: "list_services",
35107
35107
  title: "List services",
35108
35108
  kind: "read",
35109
- description: "Services (containers) in an environment: status, source, resources, domains, latest deployment and daily cost.",
35109
+ description: "Services (containers) in an environment: status, source, resources, domains, latest deployment and daily cost. Status awaiting_payment = a deploy was refused because the wallet could not pay: top up or buy a bundle (get_bundle), then deploy_service again; nothing is lost.",
35110
35110
  input: { environmentId: id("Environment") },
35111
35111
  run: (a, api2) => api2.api("GET", `${C}/environments/${a.environmentId}/services`)
35112
35112
  }),
@@ -35203,7 +35203,7 @@ var containerTools = [
35203
35203
  title: "Update / rename service",
35204
35204
  kind: "write",
35205
35205
  idempotent: true,
35206
- 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.",
35206
+ description: "Rename a service or change its start command, root directory, health check or startup dependencies. Settings apply on the next deploy (needsRedeploy). Renaming rewrites references like ${{oldName.KEY}} in the environment's service variables to the new name (applied on their next deploy); project shared variables are not rewritten and are listed in warnings.",
35207
35207
  input: {
35208
35208
  serviceId: id("Service"),
35209
35209
  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)"),
@@ -36537,7 +36537,7 @@ var emailTools = [
36537
36537
  name: "list_email_keys",
36538
36538
  title: "List email keys",
36539
36539
  kind: "read",
36540
- description: "Email API keys of a project (name, prefix, last used, expiry; never the key itself). Needs a Helipod API key with the Email API: an email key or a sign-in token answers 403 KEY_NOT_ALLOWED.",
36540
+ description: "Email API keys of a project (name, prefix, access full or send, last used, expiry; never the key itself). Needs a Helipod API key with the Email API: an email key or a sign-in token answers 403 KEY_NOT_ALLOWED.",
36541
36541
  input: { projectId },
36542
36542
  run: (a, api2) => api2.emailWithAccountKey("GET", "/keys", { project: a.projectId })
36543
36543
  }),
@@ -36545,9 +36545,14 @@ var emailTools = [
36545
36545
  name: "create_email_key",
36546
36546
  title: "Create email key",
36547
36547
  kind: "write",
36548
- description: "Make an email API key for a project, e.g. one per customer of a reseller. The key works on the Email API and as the SMTP password (smtp.helipod.io, username apikey) for that project only, and cannot make keys itself. The full key is in the answer ONCE: give it to the user to store; it cannot be shown again. Needs a Helipod API key with the Email API (an email key or a sign-in token answers 403 KEY_NOT_ALLOWED). Per project: 5 active keys on Free/Starter, 10 on Pro, 50 on Business.",
36549
- input: { projectId, name: exports_external.string().min(1).max(100).describe("To tell keys apart, e.g. the customer's name"), expiresInDays: exports_external.number().int().min(1).max(3650).optional() },
36550
- run: (a, api2) => api2.emailWithAccountKey("POST", "/keys", { project: a.projectId, body: { name: a.name, expiresInDays: a.expiresInDays } })
36548
+ description: 'Make an email API key for a project, e.g. one per customer of a reseller. The key works on the Email API and as the SMTP password (smtp.helipod.io, username apikey) for that project only, and cannot make keys itself. The full key is in the answer ONCE: give it to the user to store; it cannot be shown again. Needs a Helipod API key with the Email API (an email key or a sign-in token answers 403 KEY_NOT_ALLOWED). Per project: 5 active keys on Free/Starter, 10 on Pro, 50 on Business. access="send" makes a send-only key (POST /send, /send/batch, SMTP and reading sent mail; everything else, plans included, answers 403 KEY_SEND_ONLY): give that one to a customer who only needs SMTP, so it can never buy or renew plans from the wallet.',
36549
+ input: {
36550
+ projectId,
36551
+ name: exports_external.string().min(1).max(100).describe("To tell keys apart, e.g. the customer's name"),
36552
+ expiresInDays: exports_external.number().int().min(1).max(3650).optional(),
36553
+ access: exports_external.enum(["full", "send"]).optional().describe("full (default): everything the project allows. send: only sending and reading sent mail")
36554
+ },
36555
+ run: (a, api2) => api2.emailWithAccountKey("POST", "/keys", { project: a.projectId, body: { name: a.name, expiresInDays: a.expiresInDays, ...a.access ? { access: a.access } : {} } })
36551
36556
  }),
36552
36557
  defineTool({
36553
36558
  name: "revoke_email_key",
@@ -37810,7 +37815,7 @@ var generalTools = [
37810
37815
  ];
37811
37816
 
37812
37817
  // src/server.ts
37813
- var VERSION = "0.5.16";
37818
+ var VERSION = "0.5.18";
37814
37819
  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.
37815
37820
  - 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, generate_ai_image) cover the AI gateway.
37816
37821
  - 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, generating images): 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.
@@ -37819,7 +37824,7 @@ var INSTRUCTIONS = `Helipod is a cloud platform (Indonesia): containers, managed
37819
37824
  - Deploying an app, step by step: list_projects (pick the project and its production environmentId) -> get_bundle (is it covered?) -> if it needs Postgres: create_database, then get_database_connection and store DATABASE_URL with set_variables (secrets) after the service exists, or pass it in create_service variables -> create_service with dryRun=true (repo or image, port, variables) -> tell the user the cost (included in the bundle, or walletDailyCost per day) and wait for their OK -> create_service for real -> poll get_deployment until it settles, read get_deployment_logs if it failed -> give the user the *.helipod.app URL from get_service. Ask the user for secrets (API keys) only when the app needs them; never invent values.
37820
37825
  - Destructive tools (delete, terminate, reinstall, rollback, restore a backup or an import, copy a backup onto another VPS, 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.
37821
37826
  - 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.
37822
- - Email keys: create_email_key gives an app or a customer its own key (also its SMTP password: smtp.helipod.io, username apikey); the full key is shown once, so hand it over and never print it again. Domain on Helipod: add_domain_email_records puts the sending domain's DNS records in place in one call.
37827
+ - Email keys: create_email_key gives an app or a customer its own key (also its SMTP password: smtp.helipod.io, username apikey); the full key is shown once, so hand it over and never print it again. A customer who only sends gets access "send": that key cannot touch plans or anything that costs money. Domain on Helipod: add_domain_email_records puts the sending domain's DNS records in place in one call.
37823
37828
  - Domains for someone else (resellers): register_domain and transfer_domain take registrant (.id only; a transfer gets the owner when it completes), set_domain_owner changes it later. Use only details the user gave.
37824
37829
  - 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.
37825
37830
  - Databases: get_database_connection returns a password; put it in a secret variable (DATABASE_URL) instead of code or chat.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "helipod-mcp",
3
3
  "mcpName": "io.helipod/helipod",
4
- "version": "0.5.16",
4
+ "version": "0.5.18",
5
5
  "description": "MCP server for Helipod: containers, databases, VPS, domains and email from Claude Code, Codex, Cursor and other AI tools.",
6
6
  "type": "module",
7
7
  "bin": {
@@ -15,7 +15,7 @@ Uses the Helipod API key `HELIPOD_API_KEY` with **Email API** enabled (Settings
15
15
 
16
16
  ## Email keys and SMTP
17
17
 
18
- - An app or a customer gets its own key: `create_email_key` (name it after the app or customer). The full key is in the answer once; store it as a secret. It works for that project only, and cannot make keys.
18
+ - An app or a customer gets its own key: `create_email_key` (name it after the app or customer). The full key is in the answer once; store it as a secret. It works for that project only, and cannot make keys. `access: "send"` makes a send-only key (send, SMTP and reading sent mail only), the right choice for an SMTP password handed to someone else.
19
19
  - `list_email_keys`, `revoke_email_key` (stops it at once, also open SMTP sessions). Managing keys needs the Helipod API key (`HELIPOD_API_KEY`); an email key or an AI-tool sign-in answers `403 KEY_NOT_ALLOWED`.
20
20
  - SMTP for apps that only speak SMTP (WordPress, Laravel, PHPMailer): host `smtp.helipod.io`, port 587 (STARTTLS) or 465 (SSL), username `apikey`, password = an email key (not the Helipod API key). From = an address on a verified domain.
21
21
 
@@ -15,7 +15,7 @@ Follow the `helipod` skill rules. The reseller's wallet pays for everything; set
15
15
  ## Email per customer
16
16
 
17
17
  1. `buy_email_plan` for the customer's project (FREE first, `dryRun`), `add_email_domain` with the customer's domain, the DNS records (`add_domain_email_records` when the domain is on Helipod, else give them to the customer), `verify_email_domain`.
18
- 2. `create_email_key` with the customer's name → the key is shown ONCE: hand it to the customer (or store it encrypted on your side). It works for that project only, on the Email API and as the SMTP password (`smtp.helipod.io`, port 587 STARTTLS or 465, username `apikey`). It cannot make other keys.
18
+ 2. `create_email_key` with the customer's name → the key is shown ONCE: hand it to the customer (or store it encrypted on your side). It works for that project only, on the Email API and as the SMTP password (`smtp.helipod.io`, port 587 STARTTLS or 465, username `apikey`). It cannot make other keys. Pass `access: "send"` for a customer who only needs SMTP / sending: that key answers 403 KEY_SEND_ONLY on everything else (plans, renewals, domains, contacts), so it can never spend your wallet.
19
19
  3. `list_email_keys`, `revoke_email_key` when a customer leaves or a key leaks. Allowance per project: 5 keys (Free/Starter), 10 (Pro), 50 (Business).
20
20
  4. Managing keys needs the Helipod API key itself: an email key or an AI-tool sign-in answers `403 KEY_NOT_ALLOWED`.
21
21