@selfhost.dev/mcp-server 0.3.0 → 0.4.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.
- package/README.md +109 -23
- package/dist/index.js +29 -4
- package/dist/index.js.map +1 -1
- package/dist/tools/deployment-domains.d.ts +2 -0
- package/dist/tools/deployment-domains.js +128 -0
- package/dist/tools/deployment-domains.js.map +1 -0
- package/dist/tools/deployment-notifications.d.ts +2 -0
- package/dist/tools/deployment-notifications.js +74 -0
- package/dist/tools/deployment-notifications.js.map +1 -0
- package/dist/tools/deployments.d.ts +2 -0
- package/dist/tools/deployments.js +302 -0
- package/dist/tools/deployments.js.map +1 -0
- package/dist/tools/env-vars.d.ts +2 -0
- package/dist/tools/env-vars.js +121 -0
- package/dist/tools/env-vars.js.map +1 -0
- package/dist/tools/github.d.ts +2 -0
- package/dist/tools/github.js +106 -0
- package/dist/tools/github.js.map +1 -0
- package/dist/tools/project-databases.d.ts +2 -0
- package/dist/tools/project-databases.js +169 -0
- package/dist/tools/project-databases.js.map +1 -0
- package/dist/tools/project-services.d.ts +2 -0
- package/dist/tools/project-services.js +94 -0
- package/dist/tools/project-services.js.map +1 -0
- package/dist/tools/projects.d.ts +2 -0
- package/dist/tools/projects.js +141 -0
- package/dist/tools/projects.js.map +1 -0
- package/dist/types/tiers.js +31 -1
- package/dist/types/tiers.js.map +1 -1
- package/package.json +10 -3
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { apiRequest } from "../client.js";
|
|
3
|
+
import { session } from "../session.js";
|
|
4
|
+
/**
|
|
5
|
+
* Project databases (CoolifyDatabase) - Postgres/Redis/MySQL/MongoDB instances
|
|
6
|
+
* attached to a project, provisioned via Coolify. Distinct from the AWS/Hetzner
|
|
7
|
+
* *managed instances* (`list_instances`/`create_instance`) - these live inside a
|
|
8
|
+
* PaaS project and share its server.
|
|
9
|
+
*
|
|
10
|
+
* Endpoints:
|
|
11
|
+
* - GET /api/v1/platform/projects/:pid/databases
|
|
12
|
+
* - POST /api/v1/platform/projects/:pid/databases/:db_type (202 - async provisioning)
|
|
13
|
+
* - DELETE /api/v1/platform/projects/:pid/databases/:database_pid (202; body {name} must match)
|
|
14
|
+
*
|
|
15
|
+
* The project must be `active` before creating a database (409 otherwise).
|
|
16
|
+
*/
|
|
17
|
+
const PROJECTS_BASE = "/api/v1/platform/projects";
|
|
18
|
+
const DB_TYPES = ["postgres", "redis", "mysql", "mongodb"];
|
|
19
|
+
// Coolify password rule: 8+ chars, no spaces or shell-dangerous chars.
|
|
20
|
+
const PASSWORD_RE = /^[A-Za-z0-9!@#%^*()_+\-=\[\]{}:,.?/~]+$/;
|
|
21
|
+
const DEFAULT_PORTS = { postgres: 5432, redis: 6379, mysql: 3306, mongodb: 27017 };
|
|
22
|
+
const NO_ORG = "No active organization. Call `list_organizations` then `select_organization` first.";
|
|
23
|
+
function hasOrg() {
|
|
24
|
+
return session.getActiveOrgId() !== null;
|
|
25
|
+
}
|
|
26
|
+
function dbTypePath(t) {
|
|
27
|
+
return t === "postgres" ? "postgresql" : t;
|
|
28
|
+
}
|
|
29
|
+
function checkPassword(label, v) {
|
|
30
|
+
if (!v)
|
|
31
|
+
return `${label} is required for this database type.`;
|
|
32
|
+
if (v.length < 8)
|
|
33
|
+
return `${label} must be at least 8 characters.`;
|
|
34
|
+
if (!PASSWORD_RE.test(v))
|
|
35
|
+
return `${label} contains invalid characters (no spaces or \` $ ; | & < > \\ ' ").`;
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
export function registerProjectDatabaseTools(server) {
|
|
39
|
+
server.tool("list_project_databases", "List the databases attached to a project (Postgres/Redis/MySQL/MongoDB provisioned via Coolify, NOT AWS managed instances). Returns pid, name, db_type, status (active | inactive | creating | failed | unknown), is_public, and public_port. Passwords are never returned here.", {
|
|
40
|
+
project_pid: z.string().min(1),
|
|
41
|
+
}, async ({ project_pid }) => {
|
|
42
|
+
if (!hasOrg())
|
|
43
|
+
return { content: [{ type: "text", text: NO_ORG }] };
|
|
44
|
+
const result = await apiRequest(`${PROJECTS_BASE}/${project_pid}/databases`, {
|
|
45
|
+
toolName: "list_project_databases",
|
|
46
|
+
});
|
|
47
|
+
if (!result.success) {
|
|
48
|
+
return { content: [{ type: "text", text: `Failed to list project databases (${result.statusCode}): ${result.message}` }] };
|
|
49
|
+
}
|
|
50
|
+
return { content: [{ type: "text", text: JSON.stringify(result.data, null, 2) }] };
|
|
51
|
+
});
|
|
52
|
+
server.tool("create_project_database", "Create a database inside a project (provisioned via Coolify; returns 202, status starts `creating` - poll `list_project_databases`). The project must be `active`. Provide the type-specific credentials (see fields). Passwords must be 8+ chars with no spaces or shell-dangerous chars. ⚠️ `is_public` defaults to true, which exposes the database on `public_port` - set it false to keep the DB internal to the project.", {
|
|
53
|
+
project_pid: z.string().min(1),
|
|
54
|
+
db_type: z.enum(DB_TYPES).describe("postgres | redis | mysql | mongodb"),
|
|
55
|
+
name: z.string().min(1).max(255),
|
|
56
|
+
is_public: z.boolean().optional().describe("Expose the DB on a public port (default true)"),
|
|
57
|
+
public_port: z.number().int().min(1024).max(65535).optional().describe("Public port when is_public (defaults: pg 5432, redis 6379, mysql 3306, mongo 27017)"),
|
|
58
|
+
// postgres
|
|
59
|
+
postgres_user: z.string().max(255).optional(),
|
|
60
|
+
postgres_password: z.string().optional(),
|
|
61
|
+
postgres_db: z.string().max(255).optional(),
|
|
62
|
+
// redis
|
|
63
|
+
redis_password: z.string().optional(),
|
|
64
|
+
// mysql
|
|
65
|
+
mysql_user: z.string().max(255).optional(),
|
|
66
|
+
mysql_password: z.string().optional(),
|
|
67
|
+
mysql_database: z.string().max(255).optional(),
|
|
68
|
+
mysql_root_password: z.string().optional(),
|
|
69
|
+
// mongodb
|
|
70
|
+
mongo_initdb_root_username: z.string().max(255).optional(),
|
|
71
|
+
mongo_initdb_root_password: z.string().optional(),
|
|
72
|
+
mongo_initdb_database: z.string().max(255).optional(),
|
|
73
|
+
}, async (args) => {
|
|
74
|
+
if (!hasOrg())
|
|
75
|
+
return { content: [{ type: "text", text: NO_ORG }] };
|
|
76
|
+
const dbType = args.db_type;
|
|
77
|
+
const isPublic = args.is_public ?? true;
|
|
78
|
+
const body = { name: args.name, is_public: isPublic };
|
|
79
|
+
if (isPublic)
|
|
80
|
+
body.public_port = args.public_port ?? DEFAULT_PORTS[dbType];
|
|
81
|
+
let err = null;
|
|
82
|
+
switch (dbType) {
|
|
83
|
+
case "postgres":
|
|
84
|
+
err = checkPassword("postgres_password", args.postgres_password);
|
|
85
|
+
if (!err && !args.postgres_user)
|
|
86
|
+
err = "postgres_user is required.";
|
|
87
|
+
if (!err && !args.postgres_db)
|
|
88
|
+
err = "postgres_db is required.";
|
|
89
|
+
if (!err) {
|
|
90
|
+
body.postgres_user = args.postgres_user;
|
|
91
|
+
body.postgres_password = args.postgres_password;
|
|
92
|
+
body.postgres_db = args.postgres_db;
|
|
93
|
+
body.instant_deploy = true;
|
|
94
|
+
}
|
|
95
|
+
break;
|
|
96
|
+
case "redis":
|
|
97
|
+
err = checkPassword("redis_password", args.redis_password);
|
|
98
|
+
if (!err) {
|
|
99
|
+
body.redis_password = args.redis_password;
|
|
100
|
+
body.instant_deploy = true;
|
|
101
|
+
}
|
|
102
|
+
break;
|
|
103
|
+
case "mysql":
|
|
104
|
+
err = checkPassword("mysql_password", args.mysql_password) || checkPassword("mysql_root_password", args.mysql_root_password);
|
|
105
|
+
if (!err && !args.mysql_user)
|
|
106
|
+
err = "mysql_user is required.";
|
|
107
|
+
if (!err && !args.mysql_database)
|
|
108
|
+
err = "mysql_database is required.";
|
|
109
|
+
if (!err) {
|
|
110
|
+
body.mysql_user = args.mysql_user;
|
|
111
|
+
body.mysql_password = args.mysql_password;
|
|
112
|
+
body.mysql_database = args.mysql_database;
|
|
113
|
+
body.mysql_root_password = args.mysql_root_password;
|
|
114
|
+
body.instant_deploy = true;
|
|
115
|
+
}
|
|
116
|
+
break;
|
|
117
|
+
case "mongodb":
|
|
118
|
+
err = checkPassword("mongo_initdb_root_password", args.mongo_initdb_root_password);
|
|
119
|
+
if (!err && !args.mongo_initdb_root_username)
|
|
120
|
+
err = "mongo_initdb_root_username is required.";
|
|
121
|
+
if (!err && !args.mongo_initdb_database)
|
|
122
|
+
err = "mongo_initdb_database is required.";
|
|
123
|
+
if (!err) {
|
|
124
|
+
body.mongo_initdb_root_username = args.mongo_initdb_root_username;
|
|
125
|
+
body.mongo_initdb_root_password = args.mongo_initdb_root_password;
|
|
126
|
+
body.mongo_initdb_database = args.mongo_initdb_database;
|
|
127
|
+
}
|
|
128
|
+
break;
|
|
129
|
+
}
|
|
130
|
+
if (err)
|
|
131
|
+
return { content: [{ type: "text", text: err }] };
|
|
132
|
+
const result = await apiRequest(`${PROJECTS_BASE}/${args.project_pid}/databases/${dbTypePath(dbType)}`, {
|
|
133
|
+
method: "POST",
|
|
134
|
+
body,
|
|
135
|
+
toolName: "create_project_database",
|
|
136
|
+
});
|
|
137
|
+
if (!result.success) {
|
|
138
|
+
return { content: [{ type: "text", text: `Failed to create database (${result.statusCode}): ${result.message}` }] };
|
|
139
|
+
}
|
|
140
|
+
return {
|
|
141
|
+
content: [
|
|
142
|
+
{ type: "text", text: `Database \`${args.name}\` (${dbType}) provisioning started. Poll \`list_project_databases\` until status is \`active\`.` },
|
|
143
|
+
{ type: "text", text: JSON.stringify(result.data, null, 2) },
|
|
144
|
+
],
|
|
145
|
+
};
|
|
146
|
+
});
|
|
147
|
+
server.tool("delete_project_database", "Delete a project database. The exact current `name` must be supplied and match (a safety check, 422 otherwise). Returns 202 (async tear-down). Irreversible.", {
|
|
148
|
+
project_pid: z.string().min(1),
|
|
149
|
+
database_pid: z.string().min(1),
|
|
150
|
+
name: z.string().min(1).describe("Exact current database name - must match"),
|
|
151
|
+
confirm: z.boolean().describe("Must be true. Permanently destroys the database and its data."),
|
|
152
|
+
}, async ({ project_pid, database_pid, name, confirm }) => {
|
|
153
|
+
if (!hasOrg())
|
|
154
|
+
return { content: [{ type: "text", text: NO_ORG }] };
|
|
155
|
+
if (!confirm) {
|
|
156
|
+
return { content: [{ type: "text", text: `⚠️ About to DELETE database \`${name}\` (${database_pid}) - all its data is destroyed. No undo.\n\nCall again with confirm=true to proceed.` }] };
|
|
157
|
+
}
|
|
158
|
+
const result = await apiRequest(`${PROJECTS_BASE}/${project_pid}/databases/${database_pid}`, {
|
|
159
|
+
method: "DELETE",
|
|
160
|
+
body: { name },
|
|
161
|
+
toolName: "delete_project_database",
|
|
162
|
+
});
|
|
163
|
+
if (!result.success) {
|
|
164
|
+
return { content: [{ type: "text", text: `Failed to delete database (${result.statusCode}): ${result.message}` }] };
|
|
165
|
+
}
|
|
166
|
+
return { content: [{ type: "text", text: "Database deletion queued." }] };
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
//# sourceMappingURL=project-databases.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-databases.js","sourceRoot":"","sources":["../../src/tools/project-databases.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { apiRequest } from "../client.js";
|
|
3
|
+
import { session } from "../session.js";
|
|
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.
|
|
8
|
+
*
|
|
9
|
+
* Endpoints:
|
|
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)
|
|
13
|
+
*
|
|
14
|
+
* The project must be `active` before creating a service (409 otherwise).
|
|
15
|
+
*/
|
|
16
|
+
const PROJECTS_BASE = "/api/v1/platform/projects";
|
|
17
|
+
const TEMPLATE_TYPES = ["supabase"];
|
|
18
|
+
const NO_ORG = "No active organization. Call `list_organizations` then `select_organization` first.";
|
|
19
|
+
function hasOrg() {
|
|
20
|
+
return session.getActiveOrgId() !== null;
|
|
21
|
+
}
|
|
22
|
+
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.", {
|
|
24
|
+
project_pid: z.string().min(1),
|
|
25
|
+
}, async ({ project_pid }) => {
|
|
26
|
+
if (!hasOrg())
|
|
27
|
+
return { content: [{ type: "text", text: NO_ORG }] };
|
|
28
|
+
const result = await apiRequest(`${PROJECTS_BASE}/${project_pid}/services`, {
|
|
29
|
+
toolName: "list_project_services",
|
|
30
|
+
});
|
|
31
|
+
if (!result.success) {
|
|
32
|
+
return { content: [{ type: "text", text: `Failed to list project services (${result.statusCode}): ${result.message}` }] };
|
|
33
|
+
}
|
|
34
|
+
return { content: [{ type: "text", text: JSON.stringify(result.data, null, 2) }] };
|
|
35
|
+
});
|
|
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.", {
|
|
37
|
+
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().optional().describe("Expose publicly (default true)"),
|
|
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 }) => {
|
|
45
|
+
if (!hasOrg())
|
|
46
|
+
return { content: [{ type: "text", text: NO_ORG }] };
|
|
47
|
+
const body = {
|
|
48
|
+
name,
|
|
49
|
+
dashboard_username,
|
|
50
|
+
dashboard_password,
|
|
51
|
+
instant_deploy: true,
|
|
52
|
+
};
|
|
53
|
+
if (is_public !== undefined)
|
|
54
|
+
body.is_public = is_public;
|
|
55
|
+
if (public_port !== undefined)
|
|
56
|
+
body.public_port = public_port;
|
|
57
|
+
const result = await apiRequest(`${PROJECTS_BASE}/${project_pid}/services/${template_type}`, {
|
|
58
|
+
method: "POST",
|
|
59
|
+
body,
|
|
60
|
+
toolName: "create_project_service",
|
|
61
|
+
});
|
|
62
|
+
if (!result.success) {
|
|
63
|
+
return { content: [{ type: "text", text: `Failed to create service (${result.statusCode}): ${result.message}` }] };
|
|
64
|
+
}
|
|
65
|
+
return {
|
|
66
|
+
content: [
|
|
67
|
+
{ type: "text", text: `Service \`${name}\` (${template_type}) provisioning started. Poll \`list_project_services\` until status is \`active\`.` },
|
|
68
|
+
{ type: "text", text: JSON.stringify(result.data, null, 2) },
|
|
69
|
+
],
|
|
70
|
+
};
|
|
71
|
+
});
|
|
72
|
+
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.", {
|
|
73
|
+
project_pid: z.string().min(1),
|
|
74
|
+
service_pid: z.string().min(1),
|
|
75
|
+
name: z.string().min(1).describe("Exact current service name - must match"),
|
|
76
|
+
confirm: z.boolean().describe("Must be true. Permanently destroys the service and its data."),
|
|
77
|
+
}, async ({ project_pid, service_pid, name, confirm }) => {
|
|
78
|
+
if (!hasOrg())
|
|
79
|
+
return { content: [{ type: "text", text: NO_ORG }] };
|
|
80
|
+
if (!confirm) {
|
|
81
|
+
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.` }] };
|
|
82
|
+
}
|
|
83
|
+
const result = await apiRequest(`${PROJECTS_BASE}/${project_pid}/services/${service_pid}`, {
|
|
84
|
+
method: "DELETE",
|
|
85
|
+
body: { name },
|
|
86
|
+
toolName: "delete_project_service",
|
|
87
|
+
});
|
|
88
|
+
if (!result.success) {
|
|
89
|
+
return { content: [{ type: "text", text: `Failed to delete service (${result.statusCode}): ${result.message}` }] };
|
|
90
|
+
}
|
|
91
|
+
return { content: [{ type: "text", text: "Service deletion queued." }] };
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=project-services.js.map
|
|
@@ -0,0 +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,yNAAyN,EACzN;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,EAAE,CAAC,QAAQ,CAAC,gCAAgC,CAAC;QAC5E,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;SACrB,CAAC;QACF,IAAI,SAAS,KAAK,SAAS;YAAE,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QACxD,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"}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { apiRequest } from "../client.js";
|
|
3
|
+
import { session } from "../session.js";
|
|
4
|
+
/**
|
|
5
|
+
* Projects (CoolifyProject) - the per-app container: a provisioned server +
|
|
6
|
+
* Coolify install + wildcard DNS that deployments and project databases attach
|
|
7
|
+
* to. Mounted on Rails as `resources :projects, controller: "coolify_projects"`
|
|
8
|
+
* so the URL path is `/projects` (NOT `/coolify_projects`).
|
|
9
|
+
*
|
|
10
|
+
* Endpoints:
|
|
11
|
+
* - GET /api/v1/platform/projects
|
|
12
|
+
* - GET /api/v1/platform/projects/:pid
|
|
13
|
+
* - POST /api/v1/platform/projects (202 - async provisioning)
|
|
14
|
+
* - PATCH /api/v1/platform/projects/:pid
|
|
15
|
+
* - DELETE /api/v1/platform/projects/:pid (202 - async tear-down)
|
|
16
|
+
* - GET /api/v1/platform/projects/:pid/metrics
|
|
17
|
+
*
|
|
18
|
+
* `organization_id` is required on every call and is auto-injected from the
|
|
19
|
+
* active org by the HTTP client (query for GET, body for POST/PATCH/DELETE).
|
|
20
|
+
*/
|
|
21
|
+
const PROJECTS_BASE = "/api/v1/platform/projects";
|
|
22
|
+
const DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
|
|
23
|
+
function requireOrg() {
|
|
24
|
+
return session.getActiveOrgId();
|
|
25
|
+
}
|
|
26
|
+
const NO_ORG = "No active organization. Call `list_organizations` then `select_organization` first.";
|
|
27
|
+
export function registerProjectTools(server) {
|
|
28
|
+
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
|
+
if (!requireOrg())
|
|
30
|
+
return { content: [{ type: "text", text: NO_ORG }] };
|
|
31
|
+
const result = await apiRequest(PROJECTS_BASE, {
|
|
32
|
+
toolName: "list_projects",
|
|
33
|
+
});
|
|
34
|
+
if (!result.success) {
|
|
35
|
+
return { content: [{ type: "text", text: `Failed to list projects (${result.statusCode}): ${result.message}` }] };
|
|
36
|
+
}
|
|
37
|
+
return { content: [{ type: "text", text: JSON.stringify(result.data, null, 2) }] };
|
|
38
|
+
});
|
|
39
|
+
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.", {
|
|
40
|
+
project_pid: z.string().min(1).describe("Project pid, e.g. prj_01h..."),
|
|
41
|
+
}, async ({ project_pid }) => {
|
|
42
|
+
if (!requireOrg())
|
|
43
|
+
return { content: [{ type: "text", text: NO_ORG }] };
|
|
44
|
+
const result = await apiRequest(`${PROJECTS_BASE}/${project_pid}`, {
|
|
45
|
+
toolName: "get_project",
|
|
46
|
+
});
|
|
47
|
+
if (!result.success) {
|
|
48
|
+
return { content: [{ type: "text", text: `Failed to get project (${result.statusCode}): ${result.message}` }] };
|
|
49
|
+
}
|
|
50
|
+
return { content: [{ type: "text", text: JSON.stringify(result.data, null, 2) }] };
|
|
51
|
+
});
|
|
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.", {
|
|
53
|
+
name: z.string().min(1).max(255).describe("Project name; unique per org, <=255 chars"),
|
|
54
|
+
description: z.string().optional().describe("Optional free-text description"),
|
|
55
|
+
}, async ({ name, description }) => {
|
|
56
|
+
if (!requireOrg())
|
|
57
|
+
return { content: [{ type: "text", text: NO_ORG }] };
|
|
58
|
+
const project = { name };
|
|
59
|
+
if (description !== undefined && description !== "")
|
|
60
|
+
project.description = description;
|
|
61
|
+
const result = await apiRequest(PROJECTS_BASE, {
|
|
62
|
+
method: "POST",
|
|
63
|
+
body: { project },
|
|
64
|
+
toolName: "create_project",
|
|
65
|
+
});
|
|
66
|
+
if (!result.success) {
|
|
67
|
+
return { content: [{ type: "text", text: `Failed to create project (${result.statusCode}): ${result.message}` }] };
|
|
68
|
+
}
|
|
69
|
+
return {
|
|
70
|
+
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.` },
|
|
72
|
+
{ type: "text", text: JSON.stringify(result.data, null, 2) },
|
|
73
|
+
],
|
|
74
|
+
};
|
|
75
|
+
});
|
|
76
|
+
server.tool("update_project", "Update a project's name and/or description. Only these two fields are editable - status, IPs, and domain are server-managed. Name must remain unique within the org.", {
|
|
77
|
+
project_pid: z.string().min(1),
|
|
78
|
+
name: z.string().min(1).max(255).describe("New name (required by the backend even if unchanged)"),
|
|
79
|
+
description: z.string().nullable().optional().describe("New description; pass null to clear"),
|
|
80
|
+
}, async ({ project_pid, name, description }) => {
|
|
81
|
+
if (!requireOrg())
|
|
82
|
+
return { content: [{ type: "text", text: NO_ORG }] };
|
|
83
|
+
const project = { name };
|
|
84
|
+
if (description !== undefined)
|
|
85
|
+
project.description = description;
|
|
86
|
+
const result = await apiRequest(`${PROJECTS_BASE}/${project_pid}`, {
|
|
87
|
+
method: "PATCH",
|
|
88
|
+
body: { project },
|
|
89
|
+
toolName: "update_project",
|
|
90
|
+
});
|
|
91
|
+
if (!result.success) {
|
|
92
|
+
return { content: [{ type: "text", text: `Failed to update project (${result.statusCode}): ${result.message}` }] };
|
|
93
|
+
}
|
|
94
|
+
return { content: [{ type: "text", text: JSON.stringify(result.data, null, 2) }] };
|
|
95
|
+
});
|
|
96
|
+
server.tool("delete_project", "Delete a project - tears down its provisioned server, Coolify install, DNS, and all attached deployments/databases/services. This is irreversible. Returns 202 (async tear-down; status moves to `deleting` then `terminated`). Blocked with 409 if the project is still `pending`/`provisioning`/`deleting`, or if it has an active deployment with a running container - pause active deployments first.", {
|
|
97
|
+
project_pid: z.string().min(1),
|
|
98
|
+
name: z.string().optional().describe("Project name for the confirmation message (cosmetic)"),
|
|
99
|
+
confirm: z.boolean().describe("Must be true. Permanently destroys the server and everything in the project."),
|
|
100
|
+
}, async ({ project_pid, name, confirm }) => {
|
|
101
|
+
if (!requireOrg())
|
|
102
|
+
return { content: [{ type: "text", text: NO_ORG }] };
|
|
103
|
+
if (!confirm) {
|
|
104
|
+
const label = name ? `\`${name}\` (${project_pid})` : project_pid;
|
|
105
|
+
return {
|
|
106
|
+
content: [{
|
|
107
|
+
type: "text",
|
|
108
|
+
text: `⚠️ About to DELETE project ${label}. This destroys the provisioned server and ALL deployments, databases, and services inside it. There is no undo.\n\nPause any active deployments first, then call again with confirm=true.`,
|
|
109
|
+
}],
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
const result = await apiRequest(`${PROJECTS_BASE}/${project_pid}`, {
|
|
113
|
+
method: "DELETE",
|
|
114
|
+
toolName: "delete_project",
|
|
115
|
+
});
|
|
116
|
+
if (!result.success) {
|
|
117
|
+
return { content: [{ type: "text", text: `Failed to delete project (${result.statusCode}): ${result.message}` }] };
|
|
118
|
+
}
|
|
119
|
+
return { content: [{ type: "text", text: "Project deletion started - status will move to `deleting` then disappear once tear-down completes." }] };
|
|
120
|
+
});
|
|
121
|
+
server.tool("get_project_metrics", "Get time-series infrastructure metrics for a project (server CPU/memory/disk/network, plus per-database and per-deployment container metrics) sourced from the project's monitoring agent heartbeats. Returns `agent_status`, `last_seen_at`, and a `batches` array. Each batch has `timestamp_ms` and `metric_sets`; a metric set with no `resource` belongs to the server, otherwise `resource.pid` identifies the database/service/deployment it describes. For a 'current' snapshot use a narrow window and read the newest batch. Heartbeats land ~every 25s, so poll no faster than ~30s.", {
|
|
122
|
+
project_pid: z.string().min(1),
|
|
123
|
+
start_date: z.string().regex(DATE_RE, "YYYY-MM-DD").optional().describe("Inclusive start date YYYY-MM-DD (default: 24h ago)"),
|
|
124
|
+
end_date: z.string().regex(DATE_RE, "YYYY-MM-DD").optional().describe("Inclusive end date YYYY-MM-DD (default: today)"),
|
|
125
|
+
}, async ({ project_pid, start_date, end_date }) => {
|
|
126
|
+
if (!requireOrg())
|
|
127
|
+
return { content: [{ type: "text", text: NO_ORG }] };
|
|
128
|
+
if (start_date && end_date && start_date > end_date) {
|
|
129
|
+
return { content: [{ type: "text", text: "Invalid date range: start_date must be on or before end_date." }] };
|
|
130
|
+
}
|
|
131
|
+
const result = await apiRequest(`${PROJECTS_BASE}/${project_pid}/metrics`, {
|
|
132
|
+
query: { start_date, end_date },
|
|
133
|
+
toolName: "get_project_metrics",
|
|
134
|
+
});
|
|
135
|
+
if (!result.success) {
|
|
136
|
+
return { content: [{ type: "text", text: `Failed to get project metrics (${result.statusCode}): ${result.message}` }] };
|
|
137
|
+
}
|
|
138
|
+
return { content: [{ type: "text", text: JSON.stringify(result.data, null, 2) }] };
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
//# sourceMappingURL=projects.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"projects.js","sourceRoot":"","sources":["../../src/tools/projects.ts"],"names":[],"mappings":"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"}
|
package/dist/types/tiers.js
CHANGED
|
@@ -24,7 +24,7 @@ export const EXEMPT_TOOLS = new Set([
|
|
|
24
24
|
"list_regions",
|
|
25
25
|
"get_instance_types_for_region",
|
|
26
26
|
"list_storage_types",
|
|
27
|
-
// Provider / Hetzner reference data
|
|
27
|
+
// Provider / Hetzner reference data - static, no BE call
|
|
28
28
|
"list_cloud_providers",
|
|
29
29
|
"list_hetzner_locations",
|
|
30
30
|
"list_hetzner_server_types",
|
|
@@ -107,6 +107,36 @@ export const WRITE_TOOLS = new Set([
|
|
|
107
107
|
"delete_agent_token",
|
|
108
108
|
"admin_revoke_invitation",
|
|
109
109
|
"admin_grant_credits",
|
|
110
|
+
// PaaS - Projects (Module 15)
|
|
111
|
+
"create_project",
|
|
112
|
+
"update_project",
|
|
113
|
+
"delete_project",
|
|
114
|
+
// PaaS - Deployments (Module 16)
|
|
115
|
+
"create_deployment",
|
|
116
|
+
"update_deployment",
|
|
117
|
+
"update_deployment_build_config",
|
|
118
|
+
"delete_deployment",
|
|
119
|
+
"trigger_deploy",
|
|
120
|
+
"redeploy_run",
|
|
121
|
+
"rollback_run",
|
|
122
|
+
// PaaS - Custom domains (Module 17)
|
|
123
|
+
"sync_deployment_domains",
|
|
124
|
+
"add_deployment_domain",
|
|
125
|
+
"remove_deployment_domain",
|
|
126
|
+
"verify_custom_domain",
|
|
127
|
+
// PaaS - Environment variables (Module 18)
|
|
128
|
+
"set_env_vars",
|
|
129
|
+
"merge_env_vars",
|
|
130
|
+
"delete_env_var",
|
|
131
|
+
// PaaS - Project databases (Module 20)
|
|
132
|
+
"create_project_database",
|
|
133
|
+
"delete_project_database",
|
|
134
|
+
// PaaS - Project services (Module 21)
|
|
135
|
+
"create_project_service",
|
|
136
|
+
"delete_project_service",
|
|
137
|
+
// PaaS - Deployment notifications (Module 22)
|
|
138
|
+
"bind_deployment_notification_channel",
|
|
139
|
+
"unbind_deployment_notification_channel",
|
|
110
140
|
]);
|
|
111
141
|
export function categorizeOperation(toolName) {
|
|
112
142
|
if (EXEMPT_TOOLS.has(toolName))
|
package/dist/types/tiers.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tiers.js","sourceRoot":"","sources":["../../src/types/tiers.ts"],"names":[],"mappings":"AAaA,MAAM,CAAC,MAAM,YAAY,GAAmD;IAC1E,IAAI,EAAE;QACJ,UAAU,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,aAAa,EAAE,CAAC,EAAE;QAC3C,WAAW,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE;QAC/C,aAAa,EAAE,CAAC;KACjB;IACD,OAAO,EAAE;QACP,UAAU,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,aAAa,EAAE,GAAG,EAAE;QAC7C,WAAW,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE;QAC/C,aAAa,EAAE,CAAC;KACjB;IACD,GAAG,EAAE;QACH,UAAU,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,aAAa,EAAE,CAAC,EAAE;QAC3C,WAAW,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,aAAa,EAAE,CAAC,EAAE;QAC5C,aAAa,EAAE,EAAE;KAClB;IACD,UAAU,EAAE;QACV,UAAU,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,aAAa,EAAE,EAAE,EAAE;QAC7C,WAAW,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,aAAa,EAAE,CAAC,EAAE;QAC5C,aAAa,EAAE,QAAQ;KACxB;CACF,CAAC;AAIF,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC;IAClC,cAAc;IACd,+BAA+B;IAC/B,oBAAoB;IACpB,yDAAyD;IACzD,sBAAsB;IACtB,wBAAwB;IACxB,2BAA2B;CAC5B,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC;IACjC,sBAAsB;IACtB,sBAAsB;IACtB,qBAAqB;IACrB,qBAAqB;IACrB,qBAAqB;IACrB,eAAe;IACf,eAAe;IACf,mBAAmB;IACnB,gBAAgB;IAChB,mBAAmB;IACnB,mBAAmB;IACnB,wBAAwB;IACxB,YAAY;IACZ,YAAY;IACZ,eAAe;IACf,uBAAuB;IACvB,uBAAuB;IACvB,iBAAiB;IACjB,iBAAiB;IACjB,eAAe;IACf,gBAAgB;IAChB,iBAAiB;IACjB,iBAAiB;IACjB,eAAe;IACf,gBAAgB;IAChB,iBAAiB;IACjB,kBAAkB;IAClB,eAAe;IACf,eAAe;IACf,sBAAsB;IACtB,sBAAsB;IACtB,sBAAsB;IACtB,iBAAiB;IACjB,iBAAiB;IACjB,mBAAmB;IACnB,mBAAmB;IACnB,mBAAmB;IACnB,mBAAmB;IACnB,eAAe;IACf,6BAA6B;IAC7B,6BAA6B;IAC7B,6BAA6B;IAC7B,2BAA2B;IAC3B,uBAAuB;IACvB,uBAAuB;IACvB,uBAAuB;IACvB,uBAAuB;IACvB,kBAAkB;IAClB,uBAAuB;IACvB,mBAAmB;IACnB,6BAA6B;IAC7B,sBAAsB;IACtB,sBAAsB;IACtB,sBAAsB;IACtB,+BAA+B;IAC/B,mBAAmB;IACnB,aAAa;IACb,gBAAgB;IAChB,YAAY;IACZ,0BAA0B;IAC1B,cAAc;IACd,sBAAsB;IACtB,qBAAqB;IACrB,qBAAqB;IACrB,qBAAqB;IACrB,6BAA6B;IAC7B,wBAAwB;IACxB,sBAAsB;IACtB,yBAAyB;IACzB,yBAAyB;IACzB,gBAAgB;IAChB,gBAAgB;IAChB,gBAAgB;IAChB,oBAAoB;IACpB,oBAAoB;IACpB,yBAAyB;IACzB,qBAAqB;
|
|
1
|
+
{"version":3,"file":"tiers.js","sourceRoot":"","sources":["../../src/types/tiers.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@selfhost.dev/mcp-server",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "MCP server for SelfHost.dev
|
|
3
|
+
"version": "0.4.0",
|
|
4
|
+
"description": "MCP server for SelfHost.dev - provision managed databases and deploy apps (PaaS) via natural language",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"bin": {
|
|
@@ -24,7 +24,14 @@
|
|
|
24
24
|
"cheap managed databases",
|
|
25
25
|
"cost efficient managed databases",
|
|
26
26
|
"SelfHost",
|
|
27
|
-
"cloudSql"
|
|
27
|
+
"cloudSql",
|
|
28
|
+
"paas",
|
|
29
|
+
"deploy",
|
|
30
|
+
"deployment",
|
|
31
|
+
"github",
|
|
32
|
+
"app hosting",
|
|
33
|
+
"deploy app",
|
|
34
|
+
"coolify"
|
|
28
35
|
],
|
|
29
36
|
"license": "MIT",
|
|
30
37
|
"engines": {
|