@selfhost.dev/mcp-server 0.8.0 → 0.9.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.
Files changed (44) hide show
  1. package/README.md +100 -13
  2. package/dist/index.js +19 -1
  3. package/dist/index.js.map +1 -1
  4. package/dist/tools/alerts.js +83 -12
  5. package/dist/tools/alerts.js.map +1 -1
  6. package/dist/tools/backups.js +184 -16
  7. package/dist/tools/backups.js.map +1 -1
  8. package/dist/tools/billing.js +5 -1
  9. package/dist/tools/billing.js.map +1 -1
  10. package/dist/tools/capacity.d.ts +2 -0
  11. package/dist/tools/capacity.js +253 -0
  12. package/dist/tools/capacity.js.map +1 -0
  13. package/dist/tools/database-users.js +33 -6
  14. package/dist/tools/database-users.js.map +1 -1
  15. package/dist/tools/deployments.js +6 -2
  16. package/dist/tools/deployments.js.map +1 -1
  17. package/dist/tools/instance-logs.d.ts +2 -0
  18. package/dist/tools/instance-logs.js +151 -0
  19. package/dist/tools/instance-logs.js.map +1 -0
  20. package/dist/tools/instances.js +51 -7
  21. package/dist/tools/instances.js.map +1 -1
  22. package/dist/tools/organizations.js +98 -8
  23. package/dist/tools/organizations.js.map +1 -1
  24. package/dist/tools/postgres-tls.d.ts +16 -0
  25. package/dist/tools/postgres-tls.js +64 -0
  26. package/dist/tools/postgres-tls.js.map +1 -0
  27. package/dist/tools/project-activities.d.ts +2 -0
  28. package/dist/tools/project-activities.js +52 -0
  29. package/dist/tools/project-activities.js.map +1 -0
  30. package/dist/tools/project-backups.d.ts +2 -0
  31. package/dist/tools/project-backups.js +159 -0
  32. package/dist/tools/project-backups.js.map +1 -0
  33. package/dist/tools/project-databases.js +26 -2
  34. package/dist/tools/project-databases.js.map +1 -1
  35. package/dist/tools/project-services.js +136 -25
  36. package/dist/tools/project-services.js.map +1 -1
  37. package/dist/tools/projects.js +116 -13
  38. package/dist/tools/projects.js.map +1 -1
  39. package/dist/tools/scaling.js +135 -2
  40. package/dist/tools/scaling.js.map +1 -1
  41. package/dist/tools/webhooks.d.ts +2 -0
  42. package/dist/tools/webhooks.js +195 -0
  43. package/dist/tools/webhooks.js.map +1 -0
  44. package/package.json +3 -2
@@ -2,25 +2,76 @@ import { z } from "zod";
2
2
  import { apiRequest } from "../client.js";
3
3
  import { session } from "../session.js";
4
4
  /**
5
- * Project services (CoolifyService) - pre-packaged service templates deployed
6
- * into a project. Today the only supported template is `supabase`. There is no
7
- * catalog endpoint; the supported set is fixed server-side.
5
+ * Project services (CoolifyService) - one-click application templates deployed
6
+ * into a project. FOUR templates are live, not one: the backend resolves them
7
+ * from `ServiceProvisioning::Strategy.all`.
8
8
  *
9
9
  * Endpoints:
10
10
  * - GET /api/v1/platform/projects/:pid/services
11
- * - POST /api/v1/platform/projects/:pid/services/:template_type (202 - async provisioning)
12
- * - DELETE /api/v1/platform/projects/:pid/services/:service_pid (202; body {name} must match)
11
+ * - GET /api/v1/platform/projects/:pid/services/:service_pid (the ONLY source of credentials)
12
+ * - POST /api/v1/platform/projects/:pid/services/:template_type (202 - async provisioning)
13
+ * - DELETE /api/v1/platform/projects/:pid/services/:service_pid (202; body {name} must match)
13
14
  *
14
15
  * The project must be `active` before creating a service (409 otherwise).
16
+ *
17
+ * NOT AN ENDPOINT: `POST services/:pid/lock-signup` is deliberately deprecated and
18
+ * returns 422. The route only still exists so old console builds get a typed refusal
19
+ * instead of a 404. Do not add a tool for it.
20
+ *
21
+ * The backend ships templates ahead of its clients, so `list_project_services` can
22
+ * return a `template_type` this module does not know. Report it by its wire string
23
+ * rather than guessing - list and delete work on any type.
15
24
  */
16
25
  const PROJECTS_BASE = "/api/v1/platform/projects";
17
- const TEMPLATE_TYPES = ["supabase"];
26
+ /** Wire values accepted at `POST .../services/:template_type`. */
27
+ const TEMPLATE_TYPES = ["supabase", "n8n", "n8n-with-postgresql", "twenty"];
28
+ /**
29
+ * Per-template truth. `dashboardCreds` is the one that changes the call shape:
30
+ * Supabase takes its Studio credentials as env at deploy, while n8n and Twenty
31
+ * have no admin env at all - their first admin is whoever opens the URL first.
32
+ */
33
+ const TEMPLATES = {
34
+ supabase: {
35
+ label: "Supabase",
36
+ dashboardCreds: true,
37
+ boot: "about 5 minutes",
38
+ firstAdmin: "the dashboard username/password you pass here",
39
+ credentials: "dashboard username + password, `public_url`, and the anon key when present",
40
+ },
41
+ n8n: {
42
+ label: "n8n (workflow automation)",
43
+ dashboardCreds: false,
44
+ boot: "up to 10 minutes",
45
+ firstAdmin: "THE FIRST PERSON TO OPEN THE URL - n8n shows an owner-setup screen to whoever gets there first",
46
+ credentials: "`public_url` only",
47
+ },
48
+ "n8n-with-postgresql": {
49
+ label: "n8n backed by PostgreSQL",
50
+ dashboardCreds: false,
51
+ boot: "up to 10 minutes",
52
+ firstAdmin: "THE FIRST PERSON TO OPEN THE URL - n8n shows an owner-setup screen to whoever gets there first",
53
+ credentials: "`public_url` only",
54
+ },
55
+ twenty: {
56
+ label: "Twenty (CRM)",
57
+ dashboardCreds: false,
58
+ boot: "up to 15 minutes - it pulls images and runs migrations, so do not call it stuck early",
59
+ firstAdmin: "THE FIRST PERSON TO OPEN THE URL - Twenty shows a sign-up screen to whoever gets there first",
60
+ credentials: "`public_url` only",
61
+ },
62
+ };
18
63
  const NO_ORG = "No active organization. Call `list_organizations` then `select_organization` first.";
19
64
  function hasOrg() {
20
65
  return session.getActiveOrgId() !== null;
21
66
  }
22
67
  export function registerProjectServiceTools(server) {
23
- server.tool("list_project_services", "List the service-template instances deployed in a project (e.g. Supabase). Returns pid, name, template_type, status (active | inactive | creating | failed | unknown), is_public, public_port, and external_url. Credentials are not returned in the list.", {
68
+ server.tool("list_project_services", `List the one-click application templates deployed in a project. Returns pid, name, template_type, status (\`creating\` | \`active\` | \`inactive\` | \`failed\` | \`unknown\`), is_public, public_port, external_url, \`error_message\` when it failed, and a \`provisioning\` block with the per-stage progress.
69
+
70
+ CREDENTIALS ARE NOT HERE. Use \`get_project_service\` for those - it is the only endpoint that returns them.
71
+
72
+ \`external_url\` can be null on an otherwise \`active\` service when the project has no usable public IP; that is a real state, not a bug, and the service simply has no public URL to hand out.
73
+
74
+ A \`template_type\` you do not recognise means the backend shipped a template newer than this tool. Report the wire string as-is; delete still works on it.`, {
24
75
  project_pid: z.string().min(1),
25
76
  }, async ({ project_pid }) => {
26
77
  if (!hasOrg())
@@ -33,24 +84,77 @@ export function registerProjectServiceTools(server) {
33
84
  }
34
85
  return { content: [{ type: "text", text: JSON.stringify(result.data, null, 2) }] };
35
86
  });
36
- server.tool("create_project_service", "Deploy a service template into a project (currently only `supabase`). Returns 202, status starts `creating` - poll `list_project_services`. The project must be `active`. The dashboard password must be 8+ characters. `is_public` is REQUIRED and has no default: ASK THE USER whether the service should be publicly reachable (internet-exposed) or private to the project. Do not assume.", {
87
+ server.tool("get_project_service", `Get one deployed service, INCLUDING ITS CREDENTIALS. This is the only endpoint that returns them - \`list_project_services\` deliberately does not.
88
+
89
+ Credentials appear once the service reaches \`active\`; before that the block is simply absent and the right answer is "not ready yet", not an error. What you get depends on the template: Supabase returns the dashboard username and password plus \`public_url\` (and the anon key when present); n8n, n8n-with-postgresql and Twenty return \`public_url\` only, because their first admin is created through the app's own first-run screen rather than from env.
90
+
91
+ HAND THE URL OVER WITH THE WARNING ATTACHED for n8n and Twenty: the account is claimed by whoever opens it first, so an unattended public URL is an open door until the user completes setup.
92
+
93
+ Call this after \`create_project_service\` reports \`active\`, and give the user the credentials - creating a service and not passing on how to log into it leaves the job half done.`, {
37
94
  project_pid: z.string().min(1),
38
- template_type: z.enum(TEMPLATE_TYPES).describe("Service template (only `supabase` is supported today)"),
39
- name: z.string().min(1).max(255),
40
- dashboard_username: z.string().min(1).max(255).describe("Supabase Studio dashboard username"),
41
- dashboard_password: z.string().min(8).max(255).describe("Supabase Studio dashboard password (8+ chars)"),
42
- is_public: z.boolean().describe("Required choice (ask the user, do not assume): true = expose publicly (internet-reachable); false = private to the project."),
43
- public_port: z.number().int().min(1024).max(65535).optional(),
44
- }, async ({ project_pid, template_type, name, dashboard_username, dashboard_password, is_public, public_port }) => {
95
+ service_pid: z.string().min(1),
96
+ }, async ({ project_pid, service_pid }) => {
45
97
  if (!hasOrg())
46
98
  return { content: [{ type: "text", text: NO_ORG }] };
47
- const body = {
48
- name,
49
- dashboard_username,
50
- dashboard_password,
51
- instant_deploy: true,
52
- is_public,
53
- };
99
+ const result = await apiRequest(`${PROJECTS_BASE}/${project_pid}/services/${service_pid}`, {
100
+ toolName: "get_project_service",
101
+ });
102
+ if (!result.success) {
103
+ return { content: [{ type: "text", text: `Failed to get project service (${result.statusCode}): ${result.message}` }] };
104
+ }
105
+ return { content: [{ type: "text", text: JSON.stringify(result.data, null, 2) }] };
106
+ });
107
+ server.tool("create_project_service", `Deploy a one-click application template into a project. FOUR are available:
108
+
109
+ - \`supabase\` - Postgres + Studio + auth/storage/realtime. The ONLY one that takes admin credentials up front: \`dashboard_username\` and \`dashboard_password\` (8+ chars) are REQUIRED and become the Studio login. Boots in about 5 minutes.
110
+ - \`n8n\` - workflow automation, data in a bundled SQLite volume. Name only.
111
+ - \`n8n-with-postgresql\` - the same n8n, backed by a per-service PostgreSQL sidecar instead of SQLite. Pick this for anything beyond light use; the difference is durability and concurrency, and it cannot be switched afterwards. Name only.
112
+ - \`twenty\` - open-source CRM. Name only. Boots in up to 15 minutes (images + migrations) - do not declare it stuck early.
113
+
114
+ FIRST-ADMIN WARNING for n8n, n8n-with-postgresql and Twenty: these have no admin credentials at all. The first person to open the public URL gets the owner account. Tell the user to complete setup immediately, and do not post the URL anywhere until they have. Passing \`dashboard_username\`/\`dashboard_password\` to them does nothing - they are rejected here rather than sent and silently ignored.
115
+
116
+ \`is_public\` is REQUIRED with no default: ASK THE USER. These are web apps whose first-run setup happens at the public URL, so \`true\` is usually what they want, but do not assume it.
117
+
118
+ The project must be \`active\` (409 otherwise). Returns 202 with status \`creating\`; poll \`list_project_services\`, then call \`get_project_service\` for the credentials once it is \`active\`.
119
+
120
+ EXPECT THESE 422s: a duplicate service name inside the same project; \`public_port\` already claimed by another database or service in the project; and the host being out of RAM (a capacity guard refuses new services rather than thrashing the box - the fix is a bigger project server, and there is no in-place resize for projects, so it means a new project).`, {
121
+ project_pid: z.string().min(1),
122
+ template_type: z.enum(TEMPLATE_TYPES).describe("supabase | n8n | n8n-with-postgresql | twenty"),
123
+ name: z.string().min(1).max(255).describe("Unique within the project"),
124
+ is_public: z.boolean().describe("Required choice (ask the user, do not assume): true = internet-reachable; false = private to the project. First-run setup for these apps happens at the public URL."),
125
+ dashboard_username: z.string().min(1).max(255).optional().describe("Supabase ONLY - the Studio dashboard username. Required for supabase, rejected for every other template."),
126
+ dashboard_password: z.string().min(8).max(255).optional().describe("Supabase ONLY - the Studio dashboard password, 8+ chars. Required for supabase, rejected for every other template."),
127
+ public_port: z.number().int().min(1024).max(65535).optional().describe("Optional. Must not collide with another database or service in this project."),
128
+ }, async ({ project_pid, template_type, name, is_public, dashboard_username, dashboard_password, public_port }) => {
129
+ if (!hasOrg())
130
+ return { content: [{ type: "text", text: NO_ORG }] };
131
+ const template = TEMPLATES[template_type];
132
+ // Fail loudly on a credential/template mismatch instead of sending fields the
133
+ // backend drops. Silently ignoring them is how "I set a Twenty admin password"
134
+ // becomes a false belief the user acts on.
135
+ if (template.dashboardCreds) {
136
+ if (!dashboard_username || !dashboard_password) {
137
+ return {
138
+ content: [{
139
+ type: "text",
140
+ text: `\`${template_type}\` requires both dashboard_username and dashboard_password (8+ chars) - they become the Supabase Studio login. Ask the user for them.`,
141
+ }],
142
+ };
143
+ }
144
+ }
145
+ else if (dashboard_username || dashboard_password) {
146
+ return {
147
+ content: [{
148
+ type: "text",
149
+ text: `\`${template_type}\` has no admin credentials to set, so dashboard_username / dashboard_password do not apply and were not sent. Its first admin is ${template.firstAdmin}. Re-run without them.`,
150
+ }],
151
+ };
152
+ }
153
+ const body = { name, is_public, instant_deploy: true };
154
+ if (template.dashboardCreds) {
155
+ body.dashboard_username = dashboard_username;
156
+ body.dashboard_password = dashboard_password;
157
+ }
54
158
  if (public_port !== undefined)
55
159
  body.public_port = public_port;
56
160
  const result = await apiRequest(`${PROJECTS_BASE}/${project_pid}/services/${template_type}`, {
@@ -61,14 +165,21 @@ export function registerProjectServiceTools(server) {
61
165
  if (!result.success) {
62
166
  return { content: [{ type: "text", text: `Failed to create service (${result.statusCode}): ${result.message}` }] };
63
167
  }
168
+ const lines = [
169
+ `${template.label} service \`${name}\` is provisioning (status: creating). Expect ${template.boot}.`,
170
+ `Poll \`list_project_services\`, then call \`get_project_service\` for ${template.credentials}.`,
171
+ ];
172
+ if (!template.dashboardCreds) {
173
+ lines.push(`SECURITY: the first admin is ${template.firstAdmin}. Tell the user to open the URL and finish setup as soon as it is up, and not to share it before then.`);
174
+ }
64
175
  return {
65
176
  content: [
66
- { type: "text", text: `Service \`${name}\` (${template_type}) provisioning started. Poll \`list_project_services\` until status is \`active\`.` },
177
+ { type: "text", text: lines.join("\n\n") },
67
178
  { type: "text", text: JSON.stringify(result.data, null, 2) },
68
179
  ],
69
180
  };
70
181
  });
71
- server.tool("delete_project_service", "Delete a project service. The exact current `name` must be supplied and match (a safety check, 422 otherwise). Returns 202 (async tear-down). Irreversible.", {
182
+ server.tool("delete_project_service", "Delete a project service. The exact current `name` must be supplied and match (a safety check, 422 otherwise). Returns 202 (async tear-down) and removes the service's volumes, configs and networks along with it. Irreversible. Works on any template_type, including one this tool does not recognise.", {
72
183
  project_pid: z.string().min(1),
73
184
  service_pid: z.string().min(1),
74
185
  name: z.string().min(1).describe("Exact current service name - must match"),
@@ -77,7 +188,7 @@ export function registerProjectServiceTools(server) {
77
188
  if (!hasOrg())
78
189
  return { content: [{ type: "text", text: NO_ORG }] };
79
190
  if (!confirm) {
80
- return { content: [{ type: "text", text: `⚠️ About to DELETE service \`${name}\` (${service_pid}) - all its data is destroyed. No undo.\n\nCall again with confirm=true to proceed.` }] };
191
+ return { content: [{ type: "text", text: `About to DELETE service \`${name}\` (${service_pid}) - its volumes, configs and networks go with it. No undo.\n\nCall again with confirm=true to proceed.` }] };
81
192
  }
82
193
  const result = await apiRequest(`${PROJECTS_BASE}/${project_pid}/services/${service_pid}`, {
83
194
  method: "DELETE",
@@ -1 +1 @@
1
- {"version":3,"file":"project-services.js","sourceRoot":"","sources":["../../src/tools/project-services.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAExC;;;;;;;;;;;GAWG;AAEH,MAAM,aAAa,GAAG,2BAA2B,CAAC;AAClD,MAAM,cAAc,GAAG,CAAC,UAAU,CAAU,CAAC;AAE7C,MAAM,MAAM,GACV,qFAAqF,CAAC;AAExF,SAAS,MAAM;IACb,OAAO,OAAO,CAAC,cAAc,EAAE,KAAK,IAAI,CAAC;AAC3C,CAAC;AAED,MAAM,UAAU,2BAA2B,CAAC,MAAiB;IAC3D,MAAM,CAAC,IAAI,CACT,uBAAuB,EACvB,4PAA4P,EAC5P;QACE,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;KAC/B,EACD,KAAK,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE;QACxB,IAAI,CAAC,MAAM,EAAE;YAAE,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;QACpE,MAAM,MAAM,GAAG,MAAM,UAAU,CAAU,GAAG,aAAa,IAAI,WAAW,WAAW,EAAE;YACnF,QAAQ,EAAE,uBAAuB;SAClC,CAAC,CAAC;QACH,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,oCAAoC,MAAM,CAAC,UAAU,MAAM,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC;QAC5H,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;IACrF,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,wBAAwB,EACxB,gYAAgY,EAChY;QACE,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QAC9B,aAAa,EAAE,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,QAAQ,CAAC,uDAAuD,CAAC;QACvG,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;QAChC,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,oCAAoC,CAAC;QAC7F,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,+CAA+C,CAAC;QACxG,SAAS,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,6HAA6H,CAAC;QAC9J,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE;KAC9D,EACD,KAAK,EAAE,EAAE,WAAW,EAAE,aAAa,EAAE,IAAI,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,SAAS,EAAE,WAAW,EAAE,EAAE,EAAE;QAC7G,IAAI,CAAC,MAAM,EAAE;YAAE,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;QACpE,MAAM,IAAI,GAA4B;YACpC,IAAI;YACJ,kBAAkB;YAClB,kBAAkB;YAClB,cAAc,EAAE,IAAI;YACpB,SAAS;SACV,CAAC;QACF,IAAI,WAAW,KAAK,SAAS;YAAE,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAE9D,MAAM,MAAM,GAAG,MAAM,UAAU,CAAU,GAAG,aAAa,IAAI,WAAW,aAAa,aAAa,EAAE,EAAE;YACpG,MAAM,EAAE,MAAM;YACd,IAAI;YACJ,QAAQ,EAAE,wBAAwB;SACnC,CAAC,CAAC;QACH,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,6BAA6B,MAAM,CAAC,UAAU,MAAM,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC;QACrH,CAAC;QACD,OAAO;YACL,OAAO,EAAE;gBACP,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,IAAI,OAAO,aAAa,oFAAoF,EAAE;gBACjJ,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;aAC7D;SACF,CAAC;IACJ,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,wBAAwB,EACxB,6JAA6J,EAC7J;QACE,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QAC9B,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QAC9B,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,yCAAyC,CAAC;QAC3E,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,8DAA8D,CAAC;KAC9F,EACD,KAAK,EAAE,EAAE,WAAW,EAAE,WAAW,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE;QACpD,IAAI,CAAC,MAAM,EAAE;YAAE,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;QACpE,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,iCAAiC,IAAI,OAAO,WAAW,qFAAqF,EAAE,CAAC,EAAE,CAAC;QAC7L,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,UAAU,CAAU,GAAG,aAAa,IAAI,WAAW,aAAa,WAAW,EAAE,EAAE;YAClG,MAAM,EAAE,QAAQ;YAChB,IAAI,EAAE,EAAE,IAAI,EAAE;YACd,QAAQ,EAAE,wBAAwB;SACnC,CAAC,CAAC;QACH,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,6BAA6B,MAAM,CAAC,UAAU,MAAM,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC;QACrH,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,0BAA0B,EAAE,CAAC,EAAE,CAAC;IAC3E,CAAC,CACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"project-services.js","sourceRoot":"","sources":["../../src/tools/project-services.ts"],"names":[],"mappings":"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"}
@@ -26,17 +26,82 @@ import { session } from "../session.js";
26
26
  const PROJECTS_BASE = "/api/v1/platform/projects";
27
27
  const SERVER_TYPES_URL = "/api/v1/platform/server_types";
28
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"];
29
+ /**
30
+ * Sizes the backend will provision. All 19, not the 4 this used to list.
31
+ *
32
+ * The old list was the Cost-Optimized line only, so an agent could reach 4 of
33
+ * 19 sizes and none of the machines sold outside Europe. Three families -
34
+ * `cost_optimized` (cx*), `regular_purpose` (cpx*) and `general_purpose` (ccx*)
35
+ * in `category` terms. Geography lives in FAMILY_GEOGRAPHY below, stated once.
36
+ *
37
+ * Deliberately excluded: `cpx11` and `cpx12`. They are real, priced, purchasable
38
+ * 2 GB Hetzner types, but the platform selector filters below 4 GB (2 GB cannot
39
+ * run the full Supabase stack) and the create gate rejects them with a 422 that
40
+ * says so. Offering them here would only produce guaranteed failures.
41
+ *
42
+ * Also excluded: ARM types. `create_project` rejects any non-x86 architecture.
43
+ */
44
+ const SERVER_TYPES = [
45
+ "cx23", "cx33", "cx43", "cx53",
46
+ "cpx21", "cpx22", "cpx31", "cpx32", "cpx41", "cpx42", "cpx51", "cpx52", "cpx62",
47
+ "ccx13", "ccx23", "ccx33", "ccx43", "ccx53", "ccx63",
48
+ ];
49
+ /** The six Hetzner locations a project server can run in. */
50
+ const LOCATIONS = ["fsn1", "nbg1", "hel1", "ash", "hil", "sin"];
51
+ /** Human labels, so the model can talk about places rather than codes. */
52
+ const LOCATION_LABELS = {
53
+ fsn1: "Falkenstein, Germany",
54
+ nbg1: "Nuremberg, Germany",
55
+ hel1: "Helsinki, Finland",
56
+ ash: "Ashburn, Virginia, USA",
57
+ hil: "Hillsboro, Oregon, USA",
58
+ sin: "Singapore",
59
+ };
31
60
  /** Backend default when `project[server_type]` is omitted (`coolify_projects_controller`). */
32
61
  const DEFAULT_SERVER_TYPE = "cx23";
33
- /** Static specs, so the model can size a project without a second call. Prices come from the API. */
62
+ /**
63
+ * Static specs, so the model can size a project without a second call. Prices and
64
+ * live availability come from `list_server_types`.
65
+ *
66
+ * These carry NO geography. Where a size can actually be provisioned is a live fact
67
+ * and the previous version of this table got it wrong: it labelled `cpx21/31/41/51`
68
+ * "US only", but the catalogue reports them `offered` in all six locations and merely
69
+ * out of stock outside the US. Stating geography per size means restating it 19 times
70
+ * and being wrong in 19 places, so the family note below says it once and the API
71
+ * settles it.
72
+ */
34
73
  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",
74
+ cx23: "2 vCPU, 4 GB RAM, 40 GB disk (shared CPU)",
75
+ cx33: "4 vCPU, 8 GB RAM, 80 GB disk (shared CPU)",
76
+ cx43: "8 vCPU, 16 GB RAM, 160 GB disk (shared CPU)",
77
+ cx53: "16 vCPU, 32 GB RAM, 320 GB disk (shared CPU)",
78
+ cpx21: "3 vCPU, 4 GB RAM, 80 GB disk (shared CPU)",
79
+ cpx31: "4 vCPU, 8 GB RAM, 160 GB disk (shared CPU)",
80
+ cpx41: "8 vCPU, 16 GB RAM, 240 GB disk (shared CPU)",
81
+ cpx51: "16 vCPU, 32 GB RAM, 360 GB disk (shared CPU)",
82
+ cpx22: "2 vCPU, 4 GB RAM, 80 GB disk (shared CPU)",
83
+ cpx32: "4 vCPU, 8 GB RAM, 160 GB disk (shared CPU)",
84
+ cpx42: "8 vCPU, 16 GB RAM, 320 GB disk (shared CPU)",
85
+ cpx52: "12 vCPU, 24 GB RAM, 480 GB disk (shared CPU)",
86
+ cpx62: "16 vCPU, 32 GB RAM, 640 GB disk (shared CPU)",
87
+ ccx13: "2 vCPU, 8 GB RAM, 80 GB disk (dedicated CPU)",
88
+ ccx23: "4 vCPU, 16 GB RAM, 160 GB disk (dedicated CPU)",
89
+ ccx33: "8 vCPU, 32 GB RAM, 240 GB disk (dedicated CPU)",
90
+ ccx43: "16 vCPU, 64 GB RAM, 360 GB disk (dedicated CPU)",
91
+ ccx53: "32 vCPU, 128 GB RAM, 600 GB disk (dedicated CPU)",
92
+ ccx63: "48 vCPU, 192 GB RAM, 960 GB disk (dedicated CPU)",
39
93
  };
94
+ /**
95
+ * Where each family is sold, said once. `category` is the field the catalogue
96
+ * returns, so an agent can match this against a live response.
97
+ */
98
+ const FAMILY_GEOGRAPHY = "`cx*` Cost-Optimized (`cost_optimized`) is sold in the three European locations only. " +
99
+ "`cpx*` Regular (`regular_purpose`) comes in two generations that never share a location: " +
100
+ "the `cpx*2` line sells in Europe + Singapore, and the `cpx*1` line is listed everywhere but " +
101
+ "in practice only carries stock in the two US locations. " +
102
+ "`ccx*` Dedicated (`general_purpose`) is sold in all six. " +
103
+ "The two Regular generations are NOT interchangeable: cpx21 is 3 cores / 80 GB where cpx22 is " +
104
+ "2 cores / 80 GB, and cpx41 is 240 GB where cpx42 is 320 GB.";
40
105
  function requireOrg() {
41
106
  return session.getActiveOrgId();
42
107
  }
@@ -44,9 +109,19 @@ const NO_ORG = "No active organization. Call `list_organizations` then `select_o
44
109
  export function registerProjectTools(server) {
45
110
  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
111
 
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.
112
+ Returns all six locations - ${LOCATIONS.map((l) => `${"`"}${l}${"`"} ${LOCATION_LABELS[l]}`).join(", ")} - each with the sizes sold there: code, cores, memory_gb, disk_gb, ${"`"}category${"`"}, ${"`"}cpu_type${"`"}, ${"`"}architecture${"`"}, ${"`"}offered${"`"}, ${"`"}available${"`"}, ${"`"}deprecated${"`"} + ${"`"}deprecation${"`"}, ${"`"}hourly_price_cents${"`"} and a formatted ${"`"}display_price${"`"}. Prices are all-in (platform margin already folded in) and billed hourly against wallet credit.
113
+
114
+ PRICES DIFFER PER LOCATION for the same size, so always name the location alongside a price. ${FAMILY_GEOGRAPHY}
115
+
116
+ Because of that geography, the cheapest US or APAC option is several times the cheapest European one. Say so up front rather than letting the user discover it after they pick a region.
48
117
 
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 () => {
118
+ Availability is three states, not two. ${"`"}offered: false${"`"} means Hetzner does not sell that size in that location at all - do not offer it there, and do not read the ${"`"}null${"`"} ${"`"}available${"`"} beside it as "out of stock". ${"`"}offered: true, available: false${"`"} means it IS sold there but has no stock right now; that is a one-tap correction (name a location that does have it), not a dead end. Only ${"`"}available: true${"`"} can be provisioned.
119
+
120
+ Stock genuinely flaps - successive reads minutes apart disagree - so treat availability as live, re-read before acting on it, and never cache it into advice. Expect the cheap end to be the tightest: it is normal for most of the Cost-Optimized line to be out of stock across all three European locations at once, leaving ${DEFAULT_SERVER_TYPE} as the only cheap size that can actually be provisioned.
121
+
122
+ ${"`"}deprecated: true${"`"} means Hetzner has announced an end of life for that size but still sells it; ${"`"}deprecation${"`"} carries the detail. Do not put a user's new project on one.
123
+
124
+ Call this before ${"`"}create_project${"`"} and show the user the options - the project server is the main cost of a project, and ${"`"}create_project${"`"} defaults to the smallest (${DEFAULT_SERVER_TYPE}) in Europe if you don't choose.`, {}, async () => {
50
125
  const result = await apiRequest(SERVER_TYPES_URL, {
51
126
  toolName: "list_server_types",
52
127
  skipOrgInjection: true,
@@ -56,7 +131,13 @@ Call this before ${"`"}create_project${"`"} and show the user the options - the
56
131
  }
57
132
  return { content: [{ type: "text", text: JSON.stringify(result.data, null, 2) }] };
58
133
  });
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 () => {
134
+ 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.
135
+
136
+ Returns pid, name, status (\`pending\` | \`provisioning\` | \`active\` | \`failed\` | \`stopped\` - \`deleting\` and \`terminated\` are filtered out server-side), \`public_ip\`, \`instance_domain\`, timestamps, and - the fields worth reading that are easy to miss - \`server_type\` and \`location\` (which machine, and WHERE it runs), \`backups_enabled\`, plus a server-computed \`ready\` and \`readiness_detail\`.
137
+
138
+ \`ready\` IS NOT \`status == "active"\`. A project is ready only when it is active, carries no terminal error, AND every service and database inside it is ready too. So an \`active\` project can still be not-ready because something in it is mid-provision. \`readiness_detail\` lists each child service and database with its own status - use that to say what is holding a project up instead of reporting it as broken.
139
+
140
+ Answer "where does this run?" from \`location\`, not from the user's guess: a server cannot be moved after creation, and its price depends on where it is.`, {}, async () => {
60
141
  if (!requireOrg())
61
142
  return { content: [{ type: "text", text: NO_ORG }] };
62
143
  const result = await apiRequest(PROJECTS_BASE, {
@@ -67,7 +148,16 @@ Call this before ${"`"}create_project${"`"} and show the user the options - the
67
148
  }
68
149
  return { content: [{ type: "text", text: JSON.stringify(result.data, null, 2) }] };
69
150
  });
70
- server.tool("get_project", "Get one project by pid. Use this to POLL provisioning progress after `create_project`: re-call every ~5-10s until `status` becomes `active` (ready for deployments) or `failed` (provisioning errored). `status` of `deleting` or a 404 means it has been/ is being torn down. `public_ip` and `instance_domain` populate during provisioning.", {
151
+ server.tool("get_project", `Get one project by pid. Use this to POLL provisioning progress after \`create_project\`: re-call every ~5-10s until \`status\` becomes \`active\` (the server and Coolify are up, deployments can be created) or \`failed\`. A \`status\` of \`deleting\`, or a 404, means it is being or has been torn down. \`public_ip\` and \`instance_domain\` populate during provisioning.
152
+
153
+ TWO DIFFERENT QUESTIONS, TWO DIFFERENT FIELDS:
154
+ - \`status == "active"\` - the project's own server is up. This is what gates \`create_deployment\`.
155
+ - \`ready\` - active AND no terminal error AND every service and database inside the project is also ready. This is what gates telling the user "your project is up".
156
+ An active-but-not-ready project is normal while a service is still booting; \`readiness_detail\` names the child that is holding it.
157
+
158
+ Also here and worth reporting: \`location\` (where the server actually runs - a server cannot be moved, and the price follows the location), \`server_type\`, and \`backups_enabled\`.
159
+
160
+ If a project has been provisioning for more than ~15 minutes, treat it as stuck rather than slow. \`list_project_activities\` shows what the server and the platform were doing.`, {
71
161
  project_pid: z.string().min(1).describe("Project pid, e.g. prj_01h..."),
72
162
  }, async ({ project_pid }) => {
73
163
  if (!requireOrg())
@@ -84,12 +174,21 @@ Call this before ${"`"}create_project${"`"} and show the user the options - the
84
174
 
85
175
  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
176
 
177
+ PLACE IT DELIBERATELY: \`location\` decides where the server runs AND what it costs - the same size is a different price in different locations, and the cheap Cost-Optimized line is sold in Europe only. Omitting it lets the platform pick. A server cannot be moved afterwards, and there is no scaling path for a project server either, so the size and the place you choose here are both effectively permanent.
178
+
179
+ CHECK STOCK FIRST. A cheap size is frequently out of stock in every location that sells it, so a \`server_type\` chosen from the list above without reading \`available\` will often 422. When that happens the 422 names the locations that do have it - use them rather than silently falling back.
180
+
181
+ BACK IT UP AT CREATE: \`backups_requested\` turns on automatic daily server backups (7 kept) as soon as the server exists. It is FREE - there is no backup SKU for projects, so it adds nothing to the bill. Recommend it for anything that will hold data. It can also be turned on later with \`enable_project_backups\`.
182
+
87
183
  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\`).`, {
88
184
  name: z.string().min(1).max(255).describe("Project name; unique per org, <=255 chars"),
89
185
  description: z.string().optional().describe("Optional free-text description"),
186
+ backups_requested: z.boolean().optional().describe("Enable automatic daily server backups (7 kept) once provisioned. Free - no backup charge for projects. Defaults to off."),
90
187
  server_type: z.enum(SERVER_TYPES).optional()
91
188
  .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 }) => {
189
+ location: z.enum(LOCATIONS).optional()
190
+ .describe(`Where the server runs: ${LOCATIONS.map((l) => `${l} (${LOCATION_LABELS[l]})`).join(", ")}. A location you name is honoured or refused with a 422 - never silently swapped - so an unavailable (server_type, location) pair fails and names locations that would work. Omit to let the platform place it, which picks the first location with stock. A server CANNOT be moved afterwards, and the price is the price of the location it runs in.`),
191
+ }, async ({ name, description, server_type, location, backups_requested }) => {
93
192
  if (!requireOrg())
94
193
  return { content: [{ type: "text", text: NO_ORG }] };
95
194
  const project = { name };
@@ -97,6 +196,10 @@ COSTS MONEY: the server bills hourly against wallet credit from the moment provi
97
196
  project.description = description;
98
197
  if (server_type)
99
198
  project.server_type = server_type;
199
+ if (location)
200
+ project.location = location;
201
+ if (backups_requested !== undefined)
202
+ project.backups_requested = backups_requested;
100
203
  const result = await apiRequest(PROJECTS_BASE, {
101
204
  method: "POST",
102
205
  body: { project },
@@ -110,7 +213,7 @@ COSTS MONEY: the server bills hourly against wallet credit from the moment provi
110
213
  content: [
111
214
  {
112
215
  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.`,
216
+ text: `Project \`${name}\` created on ${size} (${SERVER_TYPE_SPECS[size]})${server_type ? "" : " - the default size, because none was chosen"}${location ? ` in ${LOCATION_LABELS[location]}` : " in a location the platform picked"} and provisioning started (status: pending). ${backups_requested ? "Daily backups will be enabled once the server is up." : "Backups are OFF - `enable_project_backups` turns them on for free."} Billing starts now. This takes ~2-5 min - poll \`get_project\` until status is \`active\` before deploying.`,
114
217
  },
115
218
  { type: "text", text: JSON.stringify(result.data, null, 2) },
116
219
  ],
@@ -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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"}