@sakupa/mcp 0.7.51 → 0.7.53

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.
Files changed (3) hide show
  1. package/dist/bin.js +28 -13
  2. package/dist/index.js +28 -13
  3. package/package.json +1 -1
package/dist/bin.js CHANGED
@@ -266,6 +266,8 @@ var PAID_SITE_MAX_TOTAL_BYTES = 2 * 1024 * 1024 * 1024;
266
266
  var MAX_FILE_COUNT = 5e3;
267
267
  var MAX_SINGLE_FILE_BYTES = 25 * 1024 * 1024;
268
268
  var FREE_REQUESTS_PER_MINUTE = 240;
269
+ var FREE_TRANSFER_BYTES_PER_DAY = 1024 * 1024 * 1024;
270
+ var USAGE_ROLLUP_MAX_DELAY_SECONDS = 5 * 60;
269
271
  var LOAD_BUDGET_ADVISORY = {
270
272
  maxFiles: 50,
271
273
  maxTotalBytes: 5 * 1024 * 1024,
@@ -400,7 +402,7 @@ function isFreeSiteAllowanceNetworkReference(value) {
400
402
  }
401
403
 
402
404
  // ../core/dist/domain/version.js
403
- var SAKUPA_MCP_VERSION = "0.7.51";
405
+ var SAKUPA_MCP_VERSION = "0.7.53";
404
406
 
405
407
  // ../core/dist/domain/errors.js
406
408
  var HTTP_STATUS = {
@@ -2756,8 +2758,6 @@ async function diagnoseBinding(input) {
2756
2758
  const layers = `Pipeline: [1] public DNS (checked LIVE above) -> [2] Sakupa ownership verification: ${input.verificationStatus} -> [3] HTTPS certificate & serving: ` + (input.provisioning ? "provisioning (Sakupa's certificate service validates and issues within minutes once the required www record above is OK; run bind status again in about 5 minutes to re-check the provider and advance activation)." : "starts after verification.");
2757
2759
  return { checks, apexResolves, allOk, checklist, layers };
2758
2760
  }
2759
- var DNS_RETRY_AFTER_SECONDS = 300;
2760
- var DNS_MAX_ATTEMPTS = 10;
2761
2761
  function toDnsChecklist(checks) {
2762
2762
  return checks.map((c) => ({
2763
2763
  name: c.record.name,
@@ -2768,13 +2768,12 @@ function toDnsChecklist(checks) {
2768
2768
  }));
2769
2769
  }
2770
2770
  function renderChecklistBlock(diag, fixTail) {
2771
- const cadence = `Re-check every ${DNS_RETRY_AFTER_SECONDS / 60} minutes, up to ${DNS_MAX_ATTEMPTS} times.`;
2772
2771
  return `Live DNS checklist (host values are the SHORT panel form):
2773
2772
  ${diag.checklist}
2774
2773
 
2775
2774
  ${diag.layers}
2776
2775
 
2777
- ` + (diag.allOk ? "All required records are live; certificate issuance completes automatically \u2014 re-check in a few minutes until the binding is active." : `${fixTail} ${cadence}`);
2776
+ ` + (diag.allOk ? "All required records are live. Cloudflare continues certificate issuance; wait about one minute, then run bind status once when the user asks. Do not poll automatically." : `${fixTail} After the user reports the DNS change is complete, run bind status once. Do not poll automatically.`);
2778
2777
  }
2779
2778
 
2780
2779
  // src/version.ts
@@ -4852,7 +4851,7 @@ Once Stripe confirms payment and Sakupa synchronizes the subscription, the curre
4852
4851
  });
4853
4852
  const { apexResolves, allOk } = diag;
4854
4853
  return text(
4855
- res2.bindingStatus === "active" ? "domain_binding_active" : res2.status === "verified" ? "domain_verification_succeeded" : "domain_verification_pending",
4854
+ res2.bindingStatus === "active" ? "domain_binding_active" : res2.bindingStatus === "provisioning" ? "domain_binding_provisioning" : "domain_verification_pending",
4856
4855
  `Domain binding status for ${apex2}: ${res2.status}
4857
4856
  ${res2.message}
4858
4857
 
@@ -4864,6 +4863,7 @@ ${res2.message}
4864
4863
  verificationId: res2.verificationId,
4865
4864
  status: res2.status,
4866
4865
  bindingStatus: res2.bindingStatus,
4866
+ provisioningPhase: res2.provisioningPhase,
4867
4867
  apexDomain: apex2,
4868
4868
  provisioningJobId: res2.provisioningJobId,
4869
4869
  servingTarget: res2.servingTarget,
@@ -4872,11 +4872,23 @@ ${res2.message}
4872
4872
  apexRequired: false,
4873
4873
  requiredServingHostname: `www.${apex2}`,
4874
4874
  optionalApexHostname: apex2,
4875
- retryAfterSeconds: DNS_RETRY_AFTER_SECONDS,
4876
- maxAttempts: DNS_MAX_ATTEMPTS,
4875
+ automaticRetries: 0,
4876
+ manualRecheckOnly: true,
4877
+ backgroundRetry: false,
4878
+ manualStatusCheckRequired: res2.bindingStatus === "provisioning" && res2.provisioningPhase !== "waiting_dns",
4879
+ suggestedRecheckAfterSeconds: res2.bindingStatus === "provisioning" && res2.provisioningPhase !== "waiting_dns" ? 60 : void 0,
4880
+ customerLiveConfirmed: res2.bindingStatus === "active",
4877
4881
  message: res2.message
4878
4882
  },
4879
- res2.bindingStatus === "active" ? "completed" : res2.status === "verified" ? "pending_provider" : "waiting_user"
4883
+ res2.bindingStatus === "active" ? "completed" : res2.provisioningPhase === "waiting_dns" || res2.status !== "verified" ? "waiting_user" : res2.bindingStatus === "provisioning" ? "pending_provider" : "waiting_user",
4884
+ res2.bindingStatus === "provisioning" ? [
4885
+ {
4886
+ tool: "bind",
4887
+ arguments: { action: "status" },
4888
+ allowed: true,
4889
+ reasonCode: res2.provisioningPhase === "waiting_dns" ? "after_user_fixes_dns" : "manual_recheck_after_provider_wait"
4890
+ }
4891
+ ] : []
4880
4892
  );
4881
4893
  }
4882
4894
  if (!args.hostname) {
@@ -4923,8 +4935,8 @@ When the user says the TXT is set, run bind "status". It verifies ownership and
4923
4935
  value: res.verificationRecord.value
4924
4936
  }
4925
4937
  ],
4926
- retryAfterSeconds: DNS_RETRY_AFTER_SECONDS,
4927
- maxAttempts: DNS_MAX_ATTEMPTS
4938
+ automaticRetries: 0,
4939
+ manualRecheckOnly: true
4928
4940
  },
4929
4941
  "waiting_user"
4930
4942
  );
@@ -4936,7 +4948,7 @@ When the user says the TXT is set, run bind "status". It verifies ownership and
4936
4948
  server.registerTool(
4937
4949
  "billing",
4938
4950
  {
4939
- description: "Return the sole authoritative source for this site's hosting subscription: current plan, next renewal plan or cancellation, effective time, payment state, current paid entitlement, reconciled usage, estimated usage tier, bound custom domains and risks. Owner-only (uses the credential in .sakupa/site.json).",
4951
+ description: "Return the sole authoritative source for this site's hosting subscription: current plan, next renewal plan or cancellation, effective time, payment state, current paid entitlement, reconciled paid usage or current free-site fair-use telemetry, estimated usage tier, bound custom domains and risks. Owner-only (uses the credential in .sakupa/site.json).",
4940
4952
  outputSchema: STRUCTURED_TOOL_OUTPUT_SCHEMA,
4941
4953
  annotations: { readOnlyHint: true, destructiveHint: false, openWorldHint: true },
4942
4954
  inputSchema: {}
@@ -4955,7 +4967,10 @@ When the user says the TXT is set, run bind "status". It verifies ownership and
4955
4967
  res.cancelAtPeriodEnd === true ? `Renewal: CANCELED \u2014 the site reverts to free at ${res.cancellationEffectiveAt ? timestampForAgent(res.cancellationEffectiveAt) : res.currentPeriodEnd ? timestampForAgent(res.currentPeriodEnd) : "the end of the already-paid month"}` : res.renewalPlan ? `Next renewal plan: ${res.renewalPlan} (JPY ${res.renewalMonthlyPriceJpy ?? tierPriceJpy(res.renewalPlan)}/month)` + (res.renewalEffectiveAt ? `, effective ${timestampForAgent(res.renewalEffectiveAt)}` : " (unchanged)") : res.cancelAtPeriodEnd === false ? "Renewal cancellation: no" : void 0,
4956
4968
  res.periodEntitlementPlan ? `Current paid entitlement: ${res.periodEntitlementPlan}` : void 0,
4957
4969
  res.currentPeriodStart ? `Current paid period: ${timestampForAgent(res.currentPeriodStart)} -> ${res.currentPeriodEnd ? timestampForAgent(res.currentPeriodEnd) : "?"}` : void 0,
4958
- `Usage state: ${res.usageState}`,
4970
+ res.mode === "free" ? `Usage state: ${res.usageState} \u2014 this describes free-site telemetry availability, not unlimited or unmeasured traffic. Free previews are measured and fair-use limited.` : `Usage state: ${res.usageState}`,
4971
+ res.freeUsage ? `Current free-site recorded usage for UTC day ${timestampForAgent(res.freeUsage.windowStart)} -> ${timestampForAgent(res.freeUsage.windowEnd)}: storage ${res.freeUsage.recordedUsage.storageBytes} bytes; transfer ${res.freeUsage.recordedUsage.transferBytes} bytes; requests ${res.freeUsage.recordedUsage.requests}.` : void 0,
4972
+ res.freeUsage ? `Free-site fair-use limits: transfer ${res.freeUsage.limits.transferBytesPerDay} bytes per UTC day; requests ${res.freeUsage.limits.requestsPerMinute} per minute per site.` : void 0,
4973
+ res.freeUsage ? `Free-site measurement delay: up to ${res.freeUsage.measurementDelaySecondsMax} seconds; ` + (res.freeUsage.recordedThrough ? `latest flushed counter ${timestampForAgent(res.freeUsage.recordedThrough)}.` : "no flushed request counter yet.") : void 0,
4959
4974
  res.currentPeriodUsage ? `Current usage: storage ${res.currentPeriodUsage.storageBytes} bytes; transfer ${res.currentPeriodUsage.transferBytes} bytes; requests ${res.currentPeriodUsage.requests}` : void 0,
4960
4975
  res.currentPeriodCountedTransferBytes !== void 0 ? `Transfer counted against current plan: ${res.currentPeriodCountedTransferBytes} bytes` : void 0,
4961
4976
  res.currentPlanLimits ? `Current plan limits: storage ${res.currentPlanLimits.storageBytes} bytes; transfer ${res.currentPlanLimits.transferBytes} bytes; requests ${res.currentPlanLimits.requests}` : void 0,
package/dist/index.js CHANGED
@@ -11,6 +11,8 @@ var PAID_SITE_MAX_TOTAL_BYTES = 2 * 1024 * 1024 * 1024;
11
11
  var MAX_FILE_COUNT = 5e3;
12
12
  var MAX_SINGLE_FILE_BYTES = 25 * 1024 * 1024;
13
13
  var FREE_REQUESTS_PER_MINUTE = 240;
14
+ var FREE_TRANSFER_BYTES_PER_DAY = 1024 * 1024 * 1024;
15
+ var USAGE_ROLLUP_MAX_DELAY_SECONDS = 5 * 60;
14
16
  var LOAD_BUDGET_ADVISORY = {
15
17
  maxFiles: 50,
16
18
  maxTotalBytes: 5 * 1024 * 1024,
@@ -145,7 +147,7 @@ function isFreeSiteAllowanceNetworkReference(value) {
145
147
  }
146
148
 
147
149
  // ../core/dist/domain/version.js
148
- var SAKUPA_MCP_VERSION = "0.7.51";
150
+ var SAKUPA_MCP_VERSION = "0.7.53";
149
151
 
150
152
  // ../core/dist/domain/errors.js
151
153
  var HTTP_STATUS = {
@@ -3506,8 +3508,6 @@ async function diagnoseBinding(input) {
3506
3508
  const layers = `Pipeline: [1] public DNS (checked LIVE above) -> [2] Sakupa ownership verification: ${input.verificationStatus} -> [3] HTTPS certificate & serving: ` + (input.provisioning ? "provisioning (Sakupa's certificate service validates and issues within minutes once the required www record above is OK; run bind status again in about 5 minutes to re-check the provider and advance activation)." : "starts after verification.");
3507
3509
  return { checks, apexResolves, allOk, checklist, layers };
3508
3510
  }
3509
- var DNS_RETRY_AFTER_SECONDS = 300;
3510
- var DNS_MAX_ATTEMPTS = 10;
3511
3511
  function toDnsChecklist(checks) {
3512
3512
  return checks.map((c) => ({
3513
3513
  name: c.record.name,
@@ -3518,13 +3518,12 @@ function toDnsChecklist(checks) {
3518
3518
  }));
3519
3519
  }
3520
3520
  function renderChecklistBlock(diag, fixTail) {
3521
- const cadence = `Re-check every ${DNS_RETRY_AFTER_SECONDS / 60} minutes, up to ${DNS_MAX_ATTEMPTS} times.`;
3522
3521
  return `Live DNS checklist (host values are the SHORT panel form):
3523
3522
  ${diag.checklist}
3524
3523
 
3525
3524
  ${diag.layers}
3526
3525
 
3527
- ` + (diag.allOk ? "All required records are live; certificate issuance completes automatically \u2014 re-check in a few minutes until the binding is active." : `${fixTail} ${cadence}`);
3526
+ ` + (diag.allOk ? "All required records are live. Cloudflare continues certificate issuance; wait about one minute, then run bind status once when the user asks. Do not poll automatically." : `${fixTail} After the user reports the DNS change is complete, run bind status once. Do not poll automatically.`);
3528
3527
  }
3529
3528
 
3530
3529
  // src/credential-rotation.ts
@@ -4968,7 +4967,7 @@ Once Stripe confirms payment and Sakupa synchronizes the subscription, the curre
4968
4967
  });
4969
4968
  const { apexResolves, allOk } = diag;
4970
4969
  return text(
4971
- res2.bindingStatus === "active" ? "domain_binding_active" : res2.status === "verified" ? "domain_verification_succeeded" : "domain_verification_pending",
4970
+ res2.bindingStatus === "active" ? "domain_binding_active" : res2.bindingStatus === "provisioning" ? "domain_binding_provisioning" : "domain_verification_pending",
4972
4971
  `Domain binding status for ${apex2}: ${res2.status}
4973
4972
  ${res2.message}
4974
4973
 
@@ -4980,6 +4979,7 @@ ${res2.message}
4980
4979
  verificationId: res2.verificationId,
4981
4980
  status: res2.status,
4982
4981
  bindingStatus: res2.bindingStatus,
4982
+ provisioningPhase: res2.provisioningPhase,
4983
4983
  apexDomain: apex2,
4984
4984
  provisioningJobId: res2.provisioningJobId,
4985
4985
  servingTarget: res2.servingTarget,
@@ -4988,11 +4988,23 @@ ${res2.message}
4988
4988
  apexRequired: false,
4989
4989
  requiredServingHostname: `www.${apex2}`,
4990
4990
  optionalApexHostname: apex2,
4991
- retryAfterSeconds: DNS_RETRY_AFTER_SECONDS,
4992
- maxAttempts: DNS_MAX_ATTEMPTS,
4991
+ automaticRetries: 0,
4992
+ manualRecheckOnly: true,
4993
+ backgroundRetry: false,
4994
+ manualStatusCheckRequired: res2.bindingStatus === "provisioning" && res2.provisioningPhase !== "waiting_dns",
4995
+ suggestedRecheckAfterSeconds: res2.bindingStatus === "provisioning" && res2.provisioningPhase !== "waiting_dns" ? 60 : void 0,
4996
+ customerLiveConfirmed: res2.bindingStatus === "active",
4993
4997
  message: res2.message
4994
4998
  },
4995
- res2.bindingStatus === "active" ? "completed" : res2.status === "verified" ? "pending_provider" : "waiting_user"
4999
+ res2.bindingStatus === "active" ? "completed" : res2.provisioningPhase === "waiting_dns" || res2.status !== "verified" ? "waiting_user" : res2.bindingStatus === "provisioning" ? "pending_provider" : "waiting_user",
5000
+ res2.bindingStatus === "provisioning" ? [
5001
+ {
5002
+ tool: "bind",
5003
+ arguments: { action: "status" },
5004
+ allowed: true,
5005
+ reasonCode: res2.provisioningPhase === "waiting_dns" ? "after_user_fixes_dns" : "manual_recheck_after_provider_wait"
5006
+ }
5007
+ ] : []
4996
5008
  );
4997
5009
  }
4998
5010
  if (!args.hostname) {
@@ -5039,8 +5051,8 @@ When the user says the TXT is set, run bind "status". It verifies ownership and
5039
5051
  value: res.verificationRecord.value
5040
5052
  }
5041
5053
  ],
5042
- retryAfterSeconds: DNS_RETRY_AFTER_SECONDS,
5043
- maxAttempts: DNS_MAX_ATTEMPTS
5054
+ automaticRetries: 0,
5055
+ manualRecheckOnly: true
5044
5056
  },
5045
5057
  "waiting_user"
5046
5058
  );
@@ -5052,7 +5064,7 @@ When the user says the TXT is set, run bind "status". It verifies ownership and
5052
5064
  server.registerTool(
5053
5065
  "billing",
5054
5066
  {
5055
- description: "Return the sole authoritative source for this site's hosting subscription: current plan, next renewal plan or cancellation, effective time, payment state, current paid entitlement, reconciled usage, estimated usage tier, bound custom domains and risks. Owner-only (uses the credential in .sakupa/site.json).",
5067
+ description: "Return the sole authoritative source for this site's hosting subscription: current plan, next renewal plan or cancellation, effective time, payment state, current paid entitlement, reconciled paid usage or current free-site fair-use telemetry, estimated usage tier, bound custom domains and risks. Owner-only (uses the credential in .sakupa/site.json).",
5056
5068
  outputSchema: STRUCTURED_TOOL_OUTPUT_SCHEMA,
5057
5069
  annotations: { readOnlyHint: true, destructiveHint: false, openWorldHint: true },
5058
5070
  inputSchema: {}
@@ -5071,7 +5083,10 @@ When the user says the TXT is set, run bind "status". It verifies ownership and
5071
5083
  res.cancelAtPeriodEnd === true ? `Renewal: CANCELED \u2014 the site reverts to free at ${res.cancellationEffectiveAt ? timestampForAgent(res.cancellationEffectiveAt) : res.currentPeriodEnd ? timestampForAgent(res.currentPeriodEnd) : "the end of the already-paid month"}` : res.renewalPlan ? `Next renewal plan: ${res.renewalPlan} (JPY ${res.renewalMonthlyPriceJpy ?? tierPriceJpy(res.renewalPlan)}/month)` + (res.renewalEffectiveAt ? `, effective ${timestampForAgent(res.renewalEffectiveAt)}` : " (unchanged)") : res.cancelAtPeriodEnd === false ? "Renewal cancellation: no" : void 0,
5072
5084
  res.periodEntitlementPlan ? `Current paid entitlement: ${res.periodEntitlementPlan}` : void 0,
5073
5085
  res.currentPeriodStart ? `Current paid period: ${timestampForAgent(res.currentPeriodStart)} -> ${res.currentPeriodEnd ? timestampForAgent(res.currentPeriodEnd) : "?"}` : void 0,
5074
- `Usage state: ${res.usageState}`,
5086
+ res.mode === "free" ? `Usage state: ${res.usageState} \u2014 this describes free-site telemetry availability, not unlimited or unmeasured traffic. Free previews are measured and fair-use limited.` : `Usage state: ${res.usageState}`,
5087
+ res.freeUsage ? `Current free-site recorded usage for UTC day ${timestampForAgent(res.freeUsage.windowStart)} -> ${timestampForAgent(res.freeUsage.windowEnd)}: storage ${res.freeUsage.recordedUsage.storageBytes} bytes; transfer ${res.freeUsage.recordedUsage.transferBytes} bytes; requests ${res.freeUsage.recordedUsage.requests}.` : void 0,
5088
+ res.freeUsage ? `Free-site fair-use limits: transfer ${res.freeUsage.limits.transferBytesPerDay} bytes per UTC day; requests ${res.freeUsage.limits.requestsPerMinute} per minute per site.` : void 0,
5089
+ res.freeUsage ? `Free-site measurement delay: up to ${res.freeUsage.measurementDelaySecondsMax} seconds; ` + (res.freeUsage.recordedThrough ? `latest flushed counter ${timestampForAgent(res.freeUsage.recordedThrough)}.` : "no flushed request counter yet.") : void 0,
5075
5090
  res.currentPeriodUsage ? `Current usage: storage ${res.currentPeriodUsage.storageBytes} bytes; transfer ${res.currentPeriodUsage.transferBytes} bytes; requests ${res.currentPeriodUsage.requests}` : void 0,
5076
5091
  res.currentPeriodCountedTransferBytes !== void 0 ? `Transfer counted against current plan: ${res.currentPeriodCountedTransferBytes} bytes` : void 0,
5077
5092
  res.currentPlanLimits ? `Current plan limits: storage ${res.currentPlanLimits.storageBytes} bytes; transfer ${res.currentPlanLimits.transferBytes} bytes; requests ${res.currentPlanLimits.requests}` : void 0,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sakupa/mcp",
3
- "version": "0.7.51",
3
+ "version": "0.7.53",
4
4
  "description": "Sakupa MCP server: publish AI-made static sites from your AI tool. AI-made pages, live in seconds.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",