@selfhost.dev/mcp-server 0.7.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -14,17 +14,48 @@ import { session } from "../session.js";
14
14
  * - PATCH /api/v1/platform/projects/:pid
15
15
  * - DELETE /api/v1/platform/projects/:pid (202 - async tear-down)
16
16
  * - GET /api/v1/platform/projects/:pid/metrics
17
+ * - GET /api/v1/platform/server_types (public reference data)
17
18
  *
18
19
  * `organization_id` is required on every call and is auto-injected from the
19
20
  * active org by the HTTP client (query for GET, body for POST/PATCH/DELETE).
21
+ *
22
+ * The project server is what the bill is for: each `server_type` resolves to a
23
+ * `hetzner_<type>` SKU and creation runs through the wallet gate, so pick the size
24
+ * deliberately rather than inheriting the default.
20
25
  */
21
26
  const PROJECTS_BASE = "/api/v1/platform/projects";
27
+ const SERVER_TYPES_URL = "/api/v1/platform/server_types";
22
28
  const DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
29
+ /** Sizes the backend will provision (`ReferenceDataService::SUPPORTED_SERVER_TYPES`). */
30
+ const SERVER_TYPES = ["cx23", "cx33", "cx43", "cx53"];
31
+ /** Backend default when `project[server_type]` is omitted (`coolify_projects_controller`). */
32
+ const DEFAULT_SERVER_TYPE = "cx23";
33
+ /** Static specs, so the model can size a project without a second call. Prices come from the API. */
34
+ const SERVER_TYPE_SPECS = {
35
+ cx23: "2 vCPU, 4 GB RAM, 40 GB disk",
36
+ cx33: "4 vCPU, 8 GB RAM, 80 GB disk",
37
+ cx43: "8 vCPU, 16 GB RAM, 160 GB disk",
38
+ cx53: "16 vCPU, 32 GB RAM, 320 GB disk",
39
+ };
23
40
  function requireOrg() {
24
41
  return session.getActiveOrgId();
25
42
  }
26
43
  const NO_ORG = "No active organization. Call `list_organizations` then `select_organization` first.";
27
44
  export function registerProjectTools(server) {
45
+ server.tool("list_server_types", `List the server sizes a PaaS project can be provisioned on, per location, with live availability and pricing. Public reference data - no org needed, and it does not count against the rate limit.
46
+
47
+ Returns locations (${"`"}fsn1${"`"} Falkenstein DE, ${"`"}nbg1${"`"} Nuremberg DE, ${"`"}hel1${"`"} Helsinki FI), each with the sizes: code, cores, memory_gb, disk_gb, ${"`"}available${"`"}, ${"`"}hourly_price_cents${"`"} and a formatted ${"`"}display_price${"`"}. Prices are all-in (platform margin already folded in) and billed hourly against wallet credit.
48
+
49
+ Call this before ${"`"}create_project${"`"} and show the user the options - the project server is the main cost of a project, and ${"`"}create_project${"`"} silently defaults to the smallest (${DEFAULT_SERVER_TYPE}) if you don't choose. A size showing ${"`"}available: false${"`"} is out of stock in that location and will fail at create.`, {}, async () => {
50
+ const result = await apiRequest(SERVER_TYPES_URL, {
51
+ toolName: "list_server_types",
52
+ skipOrgInjection: true,
53
+ });
54
+ if (!result.success) {
55
+ return { content: [{ type: "text", text: `Failed to list server types (${result.statusCode}): ${result.message}` }] };
56
+ }
57
+ return { content: [{ type: "text", text: JSON.stringify(result.data, null, 2) }] };
58
+ });
28
59
  server.tool("list_projects", "List PaaS projects (app containers) in the active organization. Each project is a provisioned server + Coolify install that deployments and project databases attach to. Returns pid, name, status (pending | provisioning | active | failed - note `deleting`/`terminated` are filtered out server-side), public_ip, instance_domain, and timestamps. A project must reach status `active` before you can create a deployment in it.", {}, async () => {
29
60
  if (!requireOrg())
30
61
  return { content: [{ type: "text", text: NO_ORG }] };
@@ -49,15 +80,23 @@ export function registerProjectTools(server) {
49
80
  }
50
81
  return { content: [{ type: "text", text: JSON.stringify(result.data, null, 2) }] };
51
82
  });
52
- server.tool("create_project", "Create a new PaaS project and start async server provisioning. Returns immediately (HTTP 202) with the project in status `pending` - actual provisioning (server → Coolify → DNS) takes ~2-5 minutes. Poll `get_project` until status is `active` before creating a deployment in it. Name must be unique within the org (excluding failed/terminated projects). May return 422 if the platform is at capacity for new servers - retry later.", {
83
+ server.tool("create_project", `Create a new PaaS project and start async server provisioning. Returns immediately (HTTP 202) with the project in status \`pending\` - actual provisioning (server → Coolify → DNS) takes ~2-5 minutes. Poll \`get_project\` until status is \`active\` before creating a deployment in it. Name must be unique within the org (excluding failed/terminated projects). May return 422 if the platform is at capacity for new servers - retry later.
84
+
85
+ SIZE IT DELIBERATELY: \`server_type\` decides what the project costs, and omitting it silently provisions the smallest size (${DEFAULT_SERVER_TYPE}, ${SERVER_TYPE_SPECS[DEFAULT_SERVER_TYPE]}). Call \`list_server_types\` for live prices/availability and confirm the choice with the user first. Sizes: ${SERVER_TYPES.map((t) => `${t} (${SERVER_TYPE_SPECS[t]})`).join("; ")}.
86
+
87
+ COSTS MONEY: the server bills hourly against wallet credit from the moment provisioning starts. A 402 means the wallet is empty or no payment method is linked (\`create_topup\` / \`link_billing_payment_method\`).`, {
53
88
  name: z.string().min(1).max(255).describe("Project name; unique per org, <=255 chars"),
54
89
  description: z.string().optional().describe("Optional free-text description"),
55
- }, async ({ name, description }) => {
90
+ server_type: z.enum(SERVER_TYPES).optional()
91
+ .describe(`Server size to provision. Defaults to ${DEFAULT_SERVER_TYPE} (${SERVER_TYPE_SPECS[DEFAULT_SERVER_TYPE]}) - ask the user rather than accepting the default silently.`),
92
+ }, async ({ name, description, server_type }) => {
56
93
  if (!requireOrg())
57
94
  return { content: [{ type: "text", text: NO_ORG }] };
58
95
  const project = { name };
59
96
  if (description !== undefined && description !== "")
60
97
  project.description = description;
98
+ if (server_type)
99
+ project.server_type = server_type;
61
100
  const result = await apiRequest(PROJECTS_BASE, {
62
101
  method: "POST",
63
102
  body: { project },
@@ -66,9 +105,13 @@ export function registerProjectTools(server) {
66
105
  if (!result.success) {
67
106
  return { content: [{ type: "text", text: `Failed to create project (${result.statusCode}): ${result.message}` }] };
68
107
  }
108
+ const size = server_type ?? DEFAULT_SERVER_TYPE;
69
109
  return {
70
110
  content: [
71
- { type: "text", text: `Project \`${name}\` created and provisioning started (status: pending). This takes ~2-5 min - poll \`get_project\` until status is \`active\` before deploying.` },
111
+ {
112
+ type: "text",
113
+ text: `Project \`${name}\` created on ${size} (${SERVER_TYPE_SPECS[size]})${server_type ? "" : " - the default size, because none was chosen"} and provisioning started (status: pending). Billing starts now. This takes ~2-5 min - poll \`get_project\` until status is \`active\` before deploying.`,
114
+ },
72
115
  { type: "text", text: JSON.stringify(result.data, null, 2) },
73
116
  ],
74
117
  };
@@ -1 +1 @@
1
- {"version":3,"file":"projects.js","sourceRoot":"","sources":["../../src/tools/projects.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"projects.js","sourceRoot":"","sources":["../../src/tools/projects.ts"],"names":[],"mappings":"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"}
@@ -18,6 +18,20 @@ import { session } from "../session.js";
18
18
  *
19
19
  * The body of POST/PATCH must be wrapped: `{ scaling_policy: { ... } }`. The
20
20
  * outer `organization_pid` is required by the backend.
21
+ *
22
+ * CLUSTER-CASCADE CONTRACT (backend, Jul 2026). Storage auto-scale is no longer
23
+ * an absolute target:
24
+ * - `expand_storage` grows by DOUBLING on each fire, clamped to
25
+ * `details.cluster_max_storage_gb` and the volume type's own max. The old
26
+ * `details.new_size_gb` / `growth_step_gb` are rejected outright (422).
27
+ * - The threshold must sit in the 40-85 band and the operator may not be `<`;
28
+ * a rule can only attach to a data, non-replica node.
29
+ * - When a data node commits a new size the platform expands every live data
30
+ * peer to match (StorageCascadeFanoutService) - storage is billed per node.
31
+ * - Multi-instance targets (`cloud_instance_pids`) are start/stop only.
32
+ * - The backend requires the reactive fields on EVERY non-start/stop policy
33
+ * even when the trigger is a cron schedule, so scheduled rules get neutral
34
+ * defaults injected here; ScheduledScalingJob fires on cron alone.
21
35
  */
22
36
  function resolveOrgId(organization_id) {
23
37
  return organization_id || session.getActiveOrgId();
@@ -37,11 +51,96 @@ const METRIC_NAMES = [
37
51
  "cpu_usage_percent",
38
52
  "memory_usage_percent",
39
53
  "disk_usage_percent",
54
+ "disk_used_percent",
40
55
  "manual_trigger",
41
56
  ];
42
57
  const COMPARISON_OPERATORS = [">", "<", ">=", "<="];
58
+ /** Actions that skip the reactive-trigger fields entirely and may target many instances. */
59
+ const START_STOP_ACTIONS = new Set(["start_instance", "stop_instance"]);
60
+ /** Actions the backend refuses to attach to more than one instance. */
61
+ const SINGLE_TARGET_ACTIONS = new Set(["expand_storage", "resize_instance", "add_replica"]);
62
+ /** Backend threshold band for storage auto-scale (`validate_expand_threshold_band`). */
63
+ const EXPAND_THRESHOLD_MIN = 40;
64
+ const EXPAND_THRESHOLD_MAX = 85;
65
+ /**
66
+ * Neutral reactive fields injected into scheduled (cron-triggered) non-start/stop
67
+ * policies. The backend validates them on every such policy regardless of
68
+ * `schedule_type`; the scheduled job ignores them and fires on cron alone.
69
+ */
70
+ const SCHEDULED_REACTIVE_DEFAULTS = {
71
+ metric_name: "manual_trigger",
72
+ threshold: EXPAND_THRESHOLD_MAX,
73
+ comparison_operator: ">",
74
+ duration_minutes: 1,
75
+ cooldown_minutes: 0,
76
+ };
77
+ /**
78
+ * Action-specific `details` validation, mirroring `ScalingPolicy#validate_details_based_on_scaling_action`
79
+ * so a doomed policy fails here with an explanation instead of as a bare 422.
80
+ */
81
+ function validateActionDetails(scalingAction, details) {
82
+ if (START_STOP_ACTIONS.has(scalingAction))
83
+ return null;
84
+ if (!details || Object.keys(details).length === 0) {
85
+ return `details is required for ${scalingAction} - the backend rejects a policy with empty details.`;
86
+ }
87
+ switch (scalingAction) {
88
+ case "expand_storage": {
89
+ if (details.new_size_gb !== undefined) {
90
+ return "details.new_size_gb is no longer accepted on expand_storage policies. Storage auto-scale now DOUBLES the volume on each fire, clamped to details.cluster_max_storage_gb - pass that ceiling instead. (One-off absolute resizes still go through `scale_instance`.)";
91
+ }
92
+ if (details.growth_step_gb !== undefined) {
93
+ return "details.growth_step_gb is not supported - growth is always a doubling until details.cluster_max_storage_gb is reached.";
94
+ }
95
+ const max = details.cluster_max_storage_gb;
96
+ if (max === undefined) {
97
+ return "details.cluster_max_storage_gb is required for expand_storage: the GiB ceiling the doubling stops at. It must exceed the volume's current size (and stay within the volume type's max).";
98
+ }
99
+ if (typeof max !== "number" || !Number.isInteger(max) || max <= 0) {
100
+ return "details.cluster_max_storage_gb must be a positive integer number of GiB.";
101
+ }
102
+ return null;
103
+ }
104
+ case "resize_instance":
105
+ if (!details.target_instance_type) {
106
+ return 'details.target_instance_type is required for resize_instance, e.g. details: { "target_instance_type": "t3.large" }.';
107
+ }
108
+ return null;
109
+ case "add_replica":
110
+ if (details.max_replicas === undefined) {
111
+ return 'details.max_replicas is required for add_replica, e.g. details: { "max_replicas": 2 }.';
112
+ }
113
+ return null;
114
+ default:
115
+ return null;
116
+ }
117
+ }
118
+ /** Threshold band + operator rules the backend enforces on storage auto-scale. */
119
+ function validateExpandTrigger(scalingAction, threshold, comparisonOperator) {
120
+ if (scalingAction !== "expand_storage")
121
+ return null;
122
+ if (comparisonOperator === "<" || comparisonOperator === "<=") {
123
+ return `comparison_operator '${comparisonOperator}' is invalid for expand_storage - a disk-fill trigger only makes sense as '>' or '>='. (The backend rejects '<' outright.)`;
124
+ }
125
+ if (threshold !== undefined && (threshold < EXPAND_THRESHOLD_MIN || threshold > EXPAND_THRESHOLD_MAX)) {
126
+ return `threshold ${threshold} is outside the ${EXPAND_THRESHOLD_MIN}-${EXPAND_THRESHOLD_MAX} band the backend enforces for storage auto-scale.`;
127
+ }
128
+ return null;
129
+ }
130
+ /**
131
+ * Scaling-policy writes still sit behind the backend's payment-channel gate
132
+ * (`require_paid_plan!` -> `chargeable_payment_channel?`), whose error copy
133
+ * predates the wallet migration and talks about "plans". Translate it.
134
+ */
135
+ function explainPolicyError(action, statusCode, message) {
136
+ const base = `Failed to ${action} scaling policy (${statusCode}): ${message}`;
137
+ if (/free plan|upgrade to a paid plan/i.test(message)) {
138
+ return `${base}\n\nThis is the payment-method gate, not a plan: auto-scaling policies need a linked card on the org. Call \`link_billing_payment_method\` and open the returned URL, then retry. (SelfHost has no plans or tiers - the backend's wording is stale.)`;
139
+ }
140
+ return base;
141
+ }
43
142
  export function registerScalingTools(server) {
44
- server.tool("scale_instance", "Manual one-off resize of an instance - change instance type, volume type, size, IOPS, throughput. Only fields you pass are sent (PATCH-style). Response includes `scaling_event_id` you can poll on the instance status (`resizing` / `modifying_storage` → terminal state). Storage must grow, not shrink.", {
143
+ server.tool("scale_instance", "Manual one-off resize of an instance - change instance type, volume type, size, IOPS, throughput. Only fields you pass are sent (PATCH-style). Response includes `scaling_event_id` you can poll on the instance status (`resizing` / `modifying_storage` → terminal state). Storage must grow, not shrink.\n\nSTORAGE CASCADES: growing a data node's volume also expands every live data peer in its cluster to match, and storage bills per node - so on a multi-node cluster the cost of `new_size_gb` is multiplied by the number of data nodes. Tell the user before scaling a clustered instance. (Unlike an auto-scale rule, a manual scale takes an absolute size and ignores any cluster_max_storage_gb ceiling.)", {
45
144
  instance_id: z.string().min(1),
46
145
  target_instance_type: z.string().optional()
47
146
  .describe("e.g. t3.medium, m6i.xlarge, r7g.4xlarge"),
@@ -93,7 +192,7 @@ export function registerScalingTools(server) {
93
192
  ],
94
193
  };
95
194
  });
96
- server.tool("list_scaling_policies", "List scaling policies, optionally filtered to one instance. Covers both start/stop schedules and auto-scaling rules.", {
195
+ server.tool("list_scaling_policies", "List scaling policies, optionally filtered to one instance. Covers both start/stop schedules and auto-scaling rules; each row carries `cloud_instance_pid` so you can tell which instance it belongs to.\n\nAn `expand_storage` policy whose `details` still has `new_size_gb` (instead of `cluster_max_storage_gb`) predates the cluster-cascade contract: it is outdated, cannot be edited or disabled (every save 422s), and must be deleted and recreated. Flag those to the user rather than trying to patch them.", {
97
196
  organization_id: z.string().optional()
98
197
  .describe("Org PID; defaults to active org. Used as `organization_pid` on the wire."),
99
198
  cloud_instance_pid: z.string().optional()
@@ -123,19 +222,38 @@ export function registerScalingTools(server) {
123
222
  }
124
223
  return { content: [{ type: "text", text: JSON.stringify(result.data, null, 2) }] };
125
224
  });
126
- server.tool("create_scaling_policy", "Create a scaling policy. Use this for both auto-start/stop schedules and reactive/scheduled auto-scaling rules. Shape depends on action + trigger:\n\n• start/stop schedules → schedule_type=scheduled + scheduled_start_time OR scheduled_stop_time (HH:MM UTC) + days_of_week\n• reactive auto-scale → schedule_type=reactive + metric_name + comparison_operator + threshold + duration_minutes + cooldown_minutes\n• scheduled auto-scale → schedule_type=scheduled + cron_expression (5-field) + optional start_time/end_time (ISO 8601)\n\nAction-specific `details`:\n• resize_instance → { target_instance_type }\n• expand_storage → { new_size_gb }\n• add_replica → { max_replicas }", {
225
+ server.tool("create_scaling_policy", `Create a scaling policy. Use this for both auto-start/stop schedules and reactive/scheduled auto-scaling rules. Shape depends on action + trigger:
226
+
227
+ • start/stop schedules → schedule_type=scheduled + scheduled_start_time OR scheduled_stop_time (HH:MM UTC) + days_of_week. These are the only policies that may target MANY instances (cloud_instance_pids).
228
+ • reactive auto-scale → schedule_type=reactive + metric_name + comparison_operator + threshold + duration_minutes + cooldown_minutes
229
+ • scheduled auto-scale → schedule_type=scheduled + cron_expression (5-field) + optional start_time/end_time (ISO 8601). The reactive fields are still required by the backend; neutral defaults are injected for you (manual_trigger / ${SCHEDULED_REACTIVE_DEFAULTS.threshold} / '>' / ${SCHEDULED_REACTIVE_DEFAULTS.duration_minutes}m / ${SCHEDULED_REACTIVE_DEFAULTS.cooldown_minutes} cooldown) and ignored at fire time.
230
+
231
+ Action-specific \`details\` (required on every non-start/stop policy):
232
+ • resize_instance → { target_instance_type }
233
+ • add_replica → { max_replicas }
234
+ • expand_storage → { cluster_max_storage_gb }
235
+
236
+ STORAGE AUTO-SCALE (expand_storage) - read before writing one:
237
+ - Growth is a DOUBLING on each fire, clamped to cluster_max_storage_gb and the volume type's own max: target = min(current x 2, cluster_max, type_max). There is no absolute-size or step option; details.new_size_gb and details.growth_step_gb are rejected (422). For a one-off absolute resize use \`scale_instance\`.
238
+ - cluster_max_storage_gb must EXCEED the volume's current size.
239
+ - threshold must be between ${EXPAND_THRESHOLD_MIN} and ${EXPAND_THRESHOLD_MAX}, and the operator must be '>' or '>=' (disk metrics: disk_used_percent / disk_usage_percent).
240
+ - The rule may only attach to a DATA, non-replica node (ClickHouse keeper-only nodes are not data nodes).
241
+ - Expansion CASCADES: when the volume commits, every live data peer in the cluster is expanded to match, and storage bills per node. Warn the user about the multiplied cost on a multi-node cluster.`, {
127
242
  organization_id: z.string().optional()
128
243
  .describe("Org PID; defaults to active org. Wire field: organization_pid"),
129
- cloud_instance_pid: z.string().min(1)
130
- .describe("Target instance PID"),
244
+ cloud_instance_pid: z.string().min(1).optional()
245
+ .describe("Target instance PID. Required for every action except bulk start/stop schedules, which may use cloud_instance_pids instead."),
246
+ cloud_instance_pids: z.array(z.string().min(1)).min(1).optional()
247
+ .describe("Multiple target instances - ONLY valid for start_instance / stop_instance schedules. The backend rejects it for expand_storage / resize_instance / add_replica."),
131
248
  scaling_action: z.enum(SCALING_ACTIONS),
132
249
  schedule_type: z.enum(SCHEDULE_TYPES),
133
250
  enabled: z.boolean().default(true),
134
251
  // Reactive trigger
135
- metric_name: z.enum(METRIC_NAMES).optional(),
252
+ metric_name: z.enum(METRIC_NAMES).optional()
253
+ .describe("Metric to watch. Disk fill reports as disk_used_percent (also accepted: disk_usage_percent)."),
136
254
  comparison_operator: z.enum(COMPARISON_OPERATORS).optional(),
137
255
  threshold: z.number().optional()
138
- .describe("0-100 for percentage metrics"),
256
+ .describe(`0-100 for percentage metrics. expand_storage is restricted to ${EXPAND_THRESHOLD_MIN}-${EXPAND_THRESHOLD_MAX}.`),
139
257
  duration_minutes: z.number().int().min(1).optional(),
140
258
  cooldown_minutes: z.number().int().min(0).optional(),
141
259
  // Scheduled / start-stop trigger
@@ -153,29 +271,112 @@ export function registerScalingTools(server) {
153
271
  timezone: z.string().optional().describe("Default UTC; BE supports UTC | EST | PST | GMT | CET"),
154
272
  // Action-specific details
155
273
  details: z.record(z.unknown()).optional()
156
- .describe("Action-specific payload: { target_instance_type } | { new_size_gb } | { max_replicas }"),
274
+ .describe("Action-specific payload: { target_instance_type } | { cluster_max_storage_gb } | { max_replicas }. Required for every action except start_instance / stop_instance."),
157
275
  }, async (params) => {
158
276
  const orgId = resolveOrgId(params.organization_id);
159
277
  if (!orgId) {
160
278
  return { content: [{ type: "text", text: noOrgMessage }] };
161
279
  }
280
+ const action = params.scaling_action;
281
+ const isStartStop = START_STOP_ACTIONS.has(action);
282
+ const targets = params.cloud_instance_pids ?? [];
283
+ // Target shape. Only start/stop fan out; everything else is single-instance
284
+ // (the backend enforces this for expand/resize/add_replica in
285
+ // `validate_multi_target_restrictions`).
286
+ if (targets.length > 0 && !isStartStop) {
287
+ const why = SINGLE_TARGET_ACTIONS.has(action)
288
+ ? `the backend rejects multi-instance targets for ${action}`
289
+ : "only start_instance / stop_instance schedules fan out";
290
+ return {
291
+ content: [{
292
+ type: "text",
293
+ text: `cloud_instance_pids is not allowed here - ${why}. Pass a single cloud_instance_pid instead.`,
294
+ }],
295
+ };
296
+ }
297
+ if (!params.cloud_instance_pid && targets.length === 0) {
298
+ return {
299
+ content: [{
300
+ type: "text",
301
+ text: "No target instance. Pass cloud_instance_pid (any action), or cloud_instance_pids for a bulk start/stop schedule.",
302
+ }],
303
+ };
304
+ }
305
+ if (new Set(targets).size !== targets.length) {
306
+ return { content: [{ type: "text", text: "cloud_instance_pids contains duplicates - the backend rejects those." }] };
307
+ }
308
+ const detailsError = validateActionDetails(action, params.details);
309
+ if (detailsError) {
310
+ return { content: [{ type: "text", text: detailsError }] };
311
+ }
312
+ // Scheduled non-start/stop rules still need the reactive fields on the wire.
313
+ const scheduledNonStartStop = params.schedule_type === "scheduled" && !isStartStop;
314
+ const trigger = {
315
+ metric_name: params.metric_name ?? (scheduledNonStartStop ? SCHEDULED_REACTIVE_DEFAULTS.metric_name : undefined),
316
+ comparison_operator: params.comparison_operator ?? (scheduledNonStartStop ? SCHEDULED_REACTIVE_DEFAULTS.comparison_operator : undefined),
317
+ threshold: params.threshold ?? (scheduledNonStartStop ? SCHEDULED_REACTIVE_DEFAULTS.threshold : undefined),
318
+ duration_minutes: params.duration_minutes ?? (scheduledNonStartStop ? SCHEDULED_REACTIVE_DEFAULTS.duration_minutes : undefined),
319
+ cooldown_minutes: params.cooldown_minutes ?? (scheduledNonStartStop ? SCHEDULED_REACTIVE_DEFAULTS.cooldown_minutes : undefined),
320
+ };
321
+ // `manual_scale` skips the numeric trigger but the backend still demands a metric name.
322
+ if (action === "manual_scale") {
323
+ trigger.metric_name ??= SCHEDULED_REACTIVE_DEFAULTS.metric_name;
324
+ }
325
+ else if (!isStartStop) {
326
+ // Everything else needs the whole reactive trigger, whatever the schedule type.
327
+ const missing = Object.entries({
328
+ metric_name: trigger.metric_name,
329
+ comparison_operator: trigger.comparison_operator,
330
+ threshold: trigger.threshold,
331
+ duration_minutes: trigger.duration_minutes,
332
+ cooldown_minutes: trigger.cooldown_minutes,
333
+ })
334
+ .filter(([, v]) => v === undefined)
335
+ .map(([k]) => k);
336
+ if (missing.length > 0) {
337
+ return {
338
+ content: [{
339
+ type: "text",
340
+ text: `Missing required trigger field(s) for ${action}: ${missing.join(", ")}. The backend validates the reactive trigger on every non-start/stop policy.`,
341
+ }],
342
+ };
343
+ }
344
+ }
345
+ // Start/stop schedules carry their own required shape.
346
+ if (isStartStop) {
347
+ const timeField = action === "start_instance" ? "scheduled_start_time" : "scheduled_stop_time";
348
+ const timeValue = action === "start_instance" ? params.scheduled_start_time : params.scheduled_stop_time;
349
+ if (!timeValue) {
350
+ return { content: [{ type: "text", text: `${timeField} (HH:MM UTC) is required for ${action}.` }] };
351
+ }
352
+ if (!params.days_of_week?.length) {
353
+ return { content: [{ type: "text", text: `days_of_week must list at least one day for ${action}.` }] };
354
+ }
355
+ }
356
+ const expandError = validateExpandTrigger(action, trigger.threshold, trigger.comparison_operator);
357
+ if (expandError) {
358
+ return { content: [{ type: "text", text: expandError }] };
359
+ }
162
360
  const fields = {
163
361
  organization_pid: orgId,
164
- cloud_instance_pid: params.cloud_instance_pid,
165
- scaling_action: params.scaling_action,
362
+ scaling_action: action,
166
363
  schedule_type: params.schedule_type,
167
364
  enabled: params.enabled,
168
365
  };
169
- if (params.metric_name)
170
- fields.metric_name = params.metric_name;
171
- if (params.comparison_operator)
172
- fields.comparison_operator = params.comparison_operator;
173
- if (params.threshold !== undefined)
174
- fields.threshold = params.threshold;
175
- if (params.duration_minutes !== undefined)
176
- fields.duration_minutes = params.duration_minutes;
177
- if (params.cooldown_minutes !== undefined)
178
- fields.cooldown_minutes = params.cooldown_minutes;
366
+ if (params.cloud_instance_pid)
367
+ fields.cloud_instance_pid = params.cloud_instance_pid;
368
+ if (targets.length > 0)
369
+ fields.cloud_instance_pids = targets;
370
+ if (trigger.metric_name)
371
+ fields.metric_name = trigger.metric_name;
372
+ if (trigger.comparison_operator)
373
+ fields.comparison_operator = trigger.comparison_operator;
374
+ if (trigger.threshold !== undefined)
375
+ fields.threshold = trigger.threshold;
376
+ if (trigger.duration_minutes !== undefined)
377
+ fields.duration_minutes = trigger.duration_minutes;
378
+ if (trigger.cooldown_minutes !== undefined)
379
+ fields.cooldown_minutes = trigger.cooldown_minutes;
179
380
  if (params.cron_expression)
180
381
  fields.cron_expression = params.cron_expression;
181
382
  if (params.start_time)
@@ -200,21 +401,32 @@ export function registerScalingTools(server) {
200
401
  });
201
402
  if (!result.success) {
202
403
  return {
203
- content: [{
204
- type: "text",
205
- text: `Failed to create scaling policy (${result.statusCode}): ${result.message}`,
206
- }],
404
+ content: [{ type: "text", text: explainPolicyError("create", result.statusCode, result.message) }],
207
405
  };
208
406
  }
407
+ const notes = ["Scaling policy created."];
408
+ if (scheduledNonStartStop && (!params.metric_name || params.threshold === undefined)) {
409
+ notes.push(`Neutral reactive defaults were filled in (${SCHEDULED_REACTIVE_DEFAULTS.metric_name} / ${SCHEDULED_REACTIVE_DEFAULTS.threshold} / '${SCHEDULED_REACTIVE_DEFAULTS.comparison_operator}') because the backend requires them on every non-start/stop policy. The rule fires on the cron schedule alone.`);
410
+ }
411
+ if (action === "expand_storage") {
412
+ const ceiling = params.details?.cluster_max_storage_gb;
413
+ notes.push(`Storage will DOUBLE on each fire up to ${ceiling} GiB, then stop. Every live data peer in the cluster is expanded to match, and storage bills per node.`);
414
+ }
209
415
  return {
210
416
  content: [
211
- { type: "text", text: "Scaling policy created." },
417
+ { type: "text", text: notes.join("\n\n") },
212
418
  { type: "text", text: JSON.stringify(result.data, null, 2) },
213
419
  ],
214
420
  };
215
421
  });
216
- server.tool("update_scaling_policy", "Update an existing scaling policy. Only the fields you pass are changed.", {
422
+ server.tool("update_scaling_policy", `Update an existing scaling policy. Only the fields you pass are changed - but note the backend re-validates the WHOLE policy, so a rule written under the old storage contract cannot be edited.
423
+
424
+ LEGACY expand_storage RULES: policies still carrying details.new_size_gb are outdated and every save 422s. There is no in-place migration - delete the rule and create a fresh one with details.cluster_max_storage_gb. Disabling one also fails; only \`delete_scaling_policy\` works.
425
+
426
+ Pass scaling_action when you know it so the storage-specific rules (${EXPAND_THRESHOLD_MIN}-${EXPAND_THRESHOLD_MAX} threshold band, '>' / '>=' only, doubling ceiling) can be checked before the request goes out.`, {
217
427
  policy_id: z.string().min(1).describe("Scaling policy PID"),
428
+ scaling_action: z.enum(SCALING_ACTIONS).optional()
429
+ .describe("The policy's action, from `list_scaling_policies`. Not sent as a change - used to validate the fields below against the right rules."),
218
430
  enabled: z.boolean().optional(),
219
431
  metric_name: z.enum(METRIC_NAMES).optional(),
220
432
  comparison_operator: z.enum(COMPARISON_OPERATORS).optional(),
@@ -228,8 +440,31 @@ export function registerScalingTools(server) {
228
440
  scheduled_stop_time: z.string().optional(),
229
441
  days_of_week: z.array(z.enum(["monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"])).optional(),
230
442
  timezone: z.string().optional(),
231
- details: z.record(z.unknown()).optional(),
232
- }, async ({ policy_id, ...rest }) => {
443
+ details: z.record(z.unknown()).optional()
444
+ .describe("Replacement action payload: { target_instance_type } | { cluster_max_storage_gb } | { max_replicas }."),
445
+ }, async ({ policy_id, scaling_action, ...rest }) => {
446
+ // These keys are rejected on the only action that ever accepted them, so
447
+ // they can only be a leftover from the pre-cascade contract.
448
+ if (rest.details?.new_size_gb !== undefined || rest.details?.growth_step_gb !== undefined) {
449
+ return {
450
+ content: [{
451
+ type: "text",
452
+ text: "details.new_size_gb / details.growth_step_gb belong to the retired storage contract and are rejected by the backend. Storage auto-scale doubles the volume up to details.cluster_max_storage_gb; for a one-off absolute resize use `scale_instance`.",
453
+ }],
454
+ };
455
+ }
456
+ if (scaling_action) {
457
+ const expandError = validateExpandTrigger(scaling_action, rest.threshold, rest.comparison_operator);
458
+ if (expandError) {
459
+ return { content: [{ type: "text", text: expandError }] };
460
+ }
461
+ if (rest.details) {
462
+ const detailsError = validateActionDetails(scaling_action, rest.details);
463
+ if (detailsError) {
464
+ return { content: [{ type: "text", text: detailsError }] };
465
+ }
466
+ }
467
+ }
233
468
  const fields = {};
234
469
  for (const [k, v] of Object.entries(rest)) {
235
470
  if (v !== undefined)
@@ -250,11 +485,11 @@ export function registerScalingTools(server) {
250
485
  skipOrgInjection: true,
251
486
  });
252
487
  if (!result.success) {
488
+ const hint = /new_size_gb|cluster_max_storage_gb/i.test(result.message)
489
+ ? "\n\nThis rule predates the cluster-cascade storage contract. Delete it and create a replacement with details.cluster_max_storage_gb."
490
+ : "";
253
491
  return {
254
- content: [{
255
- type: "text",
256
- text: `Failed to update scaling policy (${result.statusCode}): ${result.message}`,
257
- }],
492
+ content: [{ type: "text", text: explainPolicyError("update", result.statusCode, result.message) + hint }],
258
493
  };
259
494
  }
260
495
  return { content: [{ type: "text", text: JSON.stringify(result.data, null, 2) }] };
@@ -278,10 +513,7 @@ export function registerScalingTools(server) {
278
513
  });
279
514
  if (!result.success) {
280
515
  return {
281
- content: [{
282
- type: "text",
283
- text: `Failed to delete scaling policy (${result.statusCode}): ${result.message}`,
284
- }],
516
+ content: [{ type: "text", text: explainPolicyError("delete", result.statusCode, result.message) }],
285
517
  };
286
518
  }
287
519
  return { content: [{ type: "text", text: "Scaling policy deleted." }] };
@@ -1 +1 @@
1
- {"version":3,"file":"scaling.js","sourceRoot":"","sources":["../../src/tools/scaling.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"scaling.js","sourceRoot":"","sources":["../../src/tools/scaling.ts"],"names":[],"mappings":"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"}
@@ -9,7 +9,14 @@ export interface User {
9
9
  updated_at: string;
10
10
  }
11
11
  export interface Organization {
12
- id: string;
12
+ /**
13
+ * The organization's public id. `Organization` uses `pid` as its primary key on the
14
+ * backend and the table has no `id` column, so the API never serializes one - reading
15
+ * `id` here silently yields undefined. `id` stays declared, optional, only so an older
16
+ * or differently-shaped payload still type-checks.
17
+ */
18
+ pid: string;
19
+ id?: string;
13
20
  name: string;
14
21
  description: string | null;
15
22
  is_creator: boolean;
@@ -9,6 +9,8 @@ export const EXEMPT_TOOLS = new Set([
9
9
  "list_regions",
10
10
  "get_instance_types_for_region",
11
11
  "list_storage_types",
12
+ // Project server sizes - public reference data, same stance as the AWS lookups above.
13
+ "list_server_types",
12
14
  ]);
13
15
  export const WRITE_TOOLS = new Set([
14
16
  "create_or_login_user",
@@ -127,6 +129,9 @@ export const WRITE_TOOLS = new Set([
127
129
  // Postgres extensions (Module 26)
128
130
  "enable_timescaledb",
129
131
  "enable_pgvector",
132
+ // GitHub installation teardown (Module 19)
133
+ "disconnect_github_installation",
134
+ "disconnect_all_github_installations",
130
135
  ]);
131
136
  export function categorizeOperation(toolName) {
132
137
  if (EXEMPT_TOOLS.has(toolName))