@selfhost.dev/mcp-server 0.4.1 → 0.6.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 +78 -51
- package/dist/index.js +15 -7
- package/dist/index.js.map +1 -1
- package/dist/rate-limiter.js +8 -10
- package/dist/rate-limiter.js.map +1 -1
- package/dist/session.d.ts +0 -1
- package/dist/session.js +3 -12
- package/dist/session.js.map +1 -1
- package/dist/tools/alerts.js +8 -3
- package/dist/tools/alerts.js.map +1 -1
- package/dist/tools/auth.js +0 -1
- package/dist/tools/auth.js.map +1 -1
- package/dist/tools/billing.js +65 -69
- package/dist/tools/billing.js.map +1 -1
- package/dist/tools/{hetzner.d.ts → chproxy.d.ts} +1 -1
- package/dist/tools/chproxy.js +148 -0
- package/dist/tools/chproxy.js.map +1 -0
- package/dist/tools/database-users.js +11 -5
- package/dist/tools/database-users.js.map +1 -1
- package/dist/tools/instances.js +266 -62
- package/dist/tools/instances.js.map +1 -1
- package/dist/tools/mysql-config.d.ts +2 -0
- package/dist/tools/mysql-config.js +43 -0
- package/dist/tools/mysql-config.js.map +1 -0
- package/dist/tools/organizations.js +0 -1
- package/dist/tools/organizations.js.map +1 -1
- package/dist/tools/pgbouncer.js +3 -2
- package/dist/tools/pgbouncer.js.map +1 -1
- package/dist/tools/pitr.js +13 -9
- package/dist/tools/pitr.js.map +1 -1
- package/dist/tools/project-databases.js +1 -1
- package/dist/tools/proxysql.d.ts +15 -0
- package/dist/tools/proxysql.js +141 -0
- package/dist/tools/proxysql.js.map +1 -0
- package/dist/types/models.d.ts +1 -1
- package/dist/types/tiers.d.ts +1 -1
- package/dist/types/tiers.js +13 -26
- package/dist/types/tiers.js.map +1 -1
- package/package.json +5 -1
- package/dist/tools/hetzner.js +0 -263
- package/dist/tools/hetzner.js.map +0 -1
package/dist/tools/hetzner.js
DELETED
|
@@ -1,263 +0,0 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
|
-
import { apiRequest } from "../client.js";
|
|
3
|
-
import { session } from "../session.js";
|
|
4
|
-
/**
|
|
5
|
-
* Hetzner Cloud - Postgres-only provisioning.
|
|
6
|
-
*
|
|
7
|
-
* Backend endpoints (added in selfhost-dev/selfhost PR #983):
|
|
8
|
-
* - POST /hetzner/v1/instances - provision
|
|
9
|
-
* - GET /hetzner/v1/instances/:pid - read
|
|
10
|
-
* - GET /hetzner/v1/instances/:pid/status - provisioning progress
|
|
11
|
-
* - DELETE /hetzner/v1/instances/:pid - destroy
|
|
12
|
-
*
|
|
13
|
-
* Limitations vs AWS today:
|
|
14
|
-
* - Postgres only (no MySQL, no MongoDB)
|
|
15
|
-
* - No list endpoint - callers must keep track of `pid` after create
|
|
16
|
-
* - No start / stop / reboot / update / fork
|
|
17
|
-
* - No scaling, no PITR, no PgBouncer, no database-user management
|
|
18
|
-
*
|
|
19
|
-
* Locations + server types are hardcoded here to mirror the Rails CLI
|
|
20
|
-
* registry. When the backend ships discovery endpoints we'll switch these
|
|
21
|
-
* tools over.
|
|
22
|
-
*/
|
|
23
|
-
function resolveOrgId(organization_id) {
|
|
24
|
-
return organization_id || session.getActiveOrgId();
|
|
25
|
-
}
|
|
26
|
-
const noOrgMessage = "No organization selected. Call `select_organization` first or pass an organization_id.";
|
|
27
|
-
// --- Static reference data ---------------------------------------------------
|
|
28
|
-
const CLOUD_PROVIDERS = [
|
|
29
|
-
{
|
|
30
|
-
id: "aws",
|
|
31
|
-
name: "Amazon Web Services (AWS)",
|
|
32
|
-
capabilities: "Full lifecycle: create / list / start / stop / reboot / update / fork / delete; multi-AZ; replicas; auto-scaling; scheduled scaling; PITR; PgBouncer; database users; alerts; backup policies.",
|
|
33
|
-
create_tool: "create_instance",
|
|
34
|
-
list_tool: "list_instances",
|
|
35
|
-
notes: "Production-ready. Use for any workload that needs HA, replicas, or any of the lifecycle ops above. Available in 20+ AWS regions.",
|
|
36
|
-
},
|
|
37
|
-
{
|
|
38
|
-
id: "hetzner",
|
|
39
|
-
name: "Hetzner Cloud",
|
|
40
|
-
capabilities: "Provisioning only: create / read / status / delete. No start / stop / reboot / update / fork; no scaling; no PITR; no PgBouncer; no database users; no alerts.",
|
|
41
|
-
create_tool: "create_hetzner_instance",
|
|
42
|
-
list_tool: null,
|
|
43
|
-
notes: "Cheaper than AWS for Postgres workloads but BE feature surface is currently limited. Use only when the user explicitly asks for Hetzner. Postgres only.",
|
|
44
|
-
},
|
|
45
|
-
];
|
|
46
|
-
const HETZNER_LOCATIONS = [
|
|
47
|
-
{ code: "fsn1", name: "Falkenstein", country: "Germany", continent: "Europe" },
|
|
48
|
-
{ code: "nbg1", name: "Nuremberg", country: "Germany", continent: "Europe" },
|
|
49
|
-
{ code: "hel1", name: "Helsinki", country: "Finland", continent: "Europe" },
|
|
50
|
-
{ code: "ash", name: "Ashburn, VA", country: "United States", continent: "North America" },
|
|
51
|
-
{ code: "sin", name: "Singapore", country: "Singapore", continent: "Asia" },
|
|
52
|
-
];
|
|
53
|
-
const HETZNER_SERVER_TYPES = [
|
|
54
|
-
{ code: "cpx11", vcpu: 2, memory_gb: 2, disk_gb: 40, cpu_family: "AMD" },
|
|
55
|
-
{ code: "cpx21", vcpu: 3, memory_gb: 4, disk_gb: 80, cpu_family: "AMD" },
|
|
56
|
-
{ code: "cpx22", vcpu: 4, memory_gb: 4, disk_gb: 80, cpu_family: "AMD" },
|
|
57
|
-
{ code: "cpx31", vcpu: 4, memory_gb: 8, disk_gb: 160, cpu_family: "AMD" },
|
|
58
|
-
{ code: "cpx42", vcpu: 8, memory_gb: 16, disk_gb: 240, cpu_family: "AMD" },
|
|
59
|
-
{ code: "cpx51", vcpu: 16, memory_gb: 32, disk_gb: 360, cpu_family: "AMD" },
|
|
60
|
-
];
|
|
61
|
-
// --- Schemas -----------------------------------------------------------------
|
|
62
|
-
const cidrRangeSchema = z.object({
|
|
63
|
-
cidr: z.string().min(1).describe("CIDR range, e.g. 10.0.0.0/24"),
|
|
64
|
-
name: z.string().optional().describe("Friendly label"),
|
|
65
|
-
port: z.number().int().optional().describe("Port allowed by this rule (default: 5432)"),
|
|
66
|
-
description: z.string().optional(),
|
|
67
|
-
});
|
|
68
|
-
const LOCATION_CODES = HETZNER_LOCATIONS.map((l) => l.code);
|
|
69
|
-
const SERVER_TYPE_CODES = HETZNER_SERVER_TYPES.map((s) => s.code);
|
|
70
|
-
// --- Registration ------------------------------------------------------------
|
|
71
|
-
export function registerHetznerTools(server) {
|
|
72
|
-
// ----- Provider discovery -------------------------------------------------
|
|
73
|
-
server.tool("list_cloud_providers", "List the cloud providers SelfHost can provision Postgres on. Call this whenever the user expresses an intent to create a database - present the options and ask which one they want before choosing the create tool. The response includes capabilities and the specific create tool for each provider.", {}, async () => {
|
|
74
|
-
return {
|
|
75
|
-
content: [
|
|
76
|
-
{ type: "text", text: JSON.stringify(CLOUD_PROVIDERS, null, 2) },
|
|
77
|
-
],
|
|
78
|
-
};
|
|
79
|
-
});
|
|
80
|
-
server.tool("list_hetzner_locations", "List the Hetzner Cloud locations (datacenters) available for provisioning. Returns an array of `{code, name, country, continent}`. The `code` is what `create_hetzner_instance` expects for its `region` param. Ask the user which one they want before creating.", {}, async () => {
|
|
81
|
-
return {
|
|
82
|
-
content: [
|
|
83
|
-
{ type: "text", text: JSON.stringify(HETZNER_LOCATIONS, null, 2) },
|
|
84
|
-
],
|
|
85
|
-
};
|
|
86
|
-
});
|
|
87
|
-
server.tool("list_hetzner_server_types", "List the Hetzner Cloud server types available for Postgres. Returns an array of `{code, vcpu, memory_gb, disk_gb, cpu_family}`. The `code` is what `create_hetzner_instance` expects for its `server_type` param. Note: `disk_gb` is the server's local disk; the database storage is a separately-attached Hetzner Volume sized via the `storage_size` param at create time.", {}, async () => {
|
|
88
|
-
return {
|
|
89
|
-
content: [
|
|
90
|
-
{ type: "text", text: JSON.stringify(HETZNER_SERVER_TYPES, null, 2) },
|
|
91
|
-
],
|
|
92
|
-
};
|
|
93
|
-
});
|
|
94
|
-
// ----- Provisioning -------------------------------------------------------
|
|
95
|
-
server.tool("create_hetzner_instance", `Provision a new Postgres database on Hetzner Cloud.
|
|
96
|
-
|
|
97
|
-
RECOMMENDED FLOW:
|
|
98
|
-
1. Call \`list_cloud_providers\` and ask the user which provider they want.
|
|
99
|
-
2. If Hetzner: call \`list_hetzner_locations\` and let the user pick a region.
|
|
100
|
-
3. Call \`list_hetzner_server_types\` and let the user pick a size.
|
|
101
|
-
4. Confirm storage_size (separate Hetzner Volume, in GB).
|
|
102
|
-
5. Then call this tool.
|
|
103
|
-
|
|
104
|
-
IMPORTANT:
|
|
105
|
-
- The password returned in the response is shown ONCE. Save it immediately - there's no way to retrieve it.
|
|
106
|
-
- Hetzner integration is currently provision/delete only. After creation, use \`get_hetzner_instance_status\` to poll provisioning progress, and \`get_hetzner_instance\` to read details. To remove it, use \`delete_hetzner_instance\`.
|
|
107
|
-
- Provisioning takes ~5-10 minutes (network + firewall + SSH key + server + volume + load balancer + Ansible/autobase playbook + Cloudflare DNS).`, {
|
|
108
|
-
organization_id: z.string().optional()
|
|
109
|
-
.describe("Organization PID (defaults to active org)"),
|
|
110
|
-
name: z.string().min(1).max(63)
|
|
111
|
-
.describe("Instance name (used for DNS host)"),
|
|
112
|
-
region: z.enum(LOCATION_CODES)
|
|
113
|
-
.describe("Hetzner location code - call list_hetzner_locations to see options"),
|
|
114
|
-
server_type: z.enum(SERVER_TYPE_CODES)
|
|
115
|
-
.describe("Hetzner server type - call list_hetzner_server_types to see options"),
|
|
116
|
-
storage_size: z.number().int().min(10).max(10240)
|
|
117
|
-
.describe("Database storage size in GB (Hetzner Volume, separate from server local disk)"),
|
|
118
|
-
db_version: z.string().optional()
|
|
119
|
-
.describe("Postgres version (default: 18)"),
|
|
120
|
-
high_availability: z.boolean().optional()
|
|
121
|
-
.describe("Provision a 3-node cluster with a load balancer (extra ~€5/mo). Default: false (single-node, public IP only)"),
|
|
122
|
-
public_access: z.boolean().optional()
|
|
123
|
-
.describe("Expose port 5432 to the internet (default: true). Combine with allowed_cidr_ranges to restrict."),
|
|
124
|
-
backup_enabled: z.boolean().optional()
|
|
125
|
-
.describe("Enable automated backups (default: true)"),
|
|
126
|
-
username: z.string().regex(/^[a-z_][a-z0-9_]{0,30}$/i).optional()
|
|
127
|
-
.describe("Database username (default: postgres)"),
|
|
128
|
-
delete_protection: z.boolean().optional()
|
|
129
|
-
.describe("Prevent accidental deletion (recommended for production)"),
|
|
130
|
-
allowed_cidr_ranges: z.array(cidrRangeSchema).max(24).optional()
|
|
131
|
-
.describe("IP whitelist on port 5432 (max 24 ranges). Merged with the internal 10.0.0.0/16 rule."),
|
|
132
|
-
}, async (params) => {
|
|
133
|
-
const orgId = resolveOrgId(params.organization_id);
|
|
134
|
-
if (!orgId) {
|
|
135
|
-
return { content: [{ type: "text", text: noOrgMessage }] };
|
|
136
|
-
}
|
|
137
|
-
const body = {
|
|
138
|
-
organization_id: orgId,
|
|
139
|
-
name: params.name,
|
|
140
|
-
region: params.region,
|
|
141
|
-
server_type: params.server_type,
|
|
142
|
-
storage_size: params.storage_size,
|
|
143
|
-
};
|
|
144
|
-
if (params.db_version !== undefined)
|
|
145
|
-
body.db_version = params.db_version;
|
|
146
|
-
if (params.high_availability !== undefined)
|
|
147
|
-
body.high_availability = params.high_availability;
|
|
148
|
-
if (params.public_access !== undefined)
|
|
149
|
-
body.public_access = params.public_access;
|
|
150
|
-
if (params.backup_enabled !== undefined)
|
|
151
|
-
body.backup_enabled = params.backup_enabled;
|
|
152
|
-
if (params.username !== undefined)
|
|
153
|
-
body.username = params.username;
|
|
154
|
-
if (params.delete_protection !== undefined)
|
|
155
|
-
body.delete_protection = params.delete_protection;
|
|
156
|
-
if (params.allowed_cidr_ranges !== undefined)
|
|
157
|
-
body.allowed_cidr_ranges = params.allowed_cidr_ranges;
|
|
158
|
-
const result = await apiRequest("/hetzner/v1/instances", {
|
|
159
|
-
method: "POST",
|
|
160
|
-
body,
|
|
161
|
-
toolName: "create_hetzner_instance",
|
|
162
|
-
skipOrgInjection: true,
|
|
163
|
-
});
|
|
164
|
-
if (!result.success) {
|
|
165
|
-
return {
|
|
166
|
-
content: [{
|
|
167
|
-
type: "text",
|
|
168
|
-
text: `Failed to create Hetzner instance (${result.statusCode}): ${result.message}`,
|
|
169
|
-
}],
|
|
170
|
-
};
|
|
171
|
-
}
|
|
172
|
-
const data = result.data;
|
|
173
|
-
const lines = [
|
|
174
|
-
"Hetzner instance provisioning started!",
|
|
175
|
-
"",
|
|
176
|
-
`PID: ${data.pid}`,
|
|
177
|
-
];
|
|
178
|
-
if (data.host)
|
|
179
|
-
lines.push(`Host: ${data.host}`);
|
|
180
|
-
if (data.username)
|
|
181
|
-
lines.push(`Username: ${data.username}`);
|
|
182
|
-
if (data.password) {
|
|
183
|
-
lines.push(`Password: ${data.password}`);
|
|
184
|
-
lines.push("");
|
|
185
|
-
lines.push("⚠️ SAVE THIS PASSWORD NOW - it cannot be retrieved again.");
|
|
186
|
-
}
|
|
187
|
-
lines.push("");
|
|
188
|
-
lines.push(`Poll provisioning progress with \`get_hetzner_instance_status\` (pid: ${data.pid}). Provisioning typically takes 5-10 minutes.`);
|
|
189
|
-
return {
|
|
190
|
-
content: [
|
|
191
|
-
{ type: "text", text: lines.join("\n") },
|
|
192
|
-
{ type: "text", text: JSON.stringify(data, null, 2) },
|
|
193
|
-
],
|
|
194
|
-
};
|
|
195
|
-
});
|
|
196
|
-
server.tool("get_hetzner_instance", "Get details for a single Hetzner instance by PID. Returns the full record including name, region, server_type, storage_size, high_availability, public_access, host (DNS name), and creation timestamps.", {
|
|
197
|
-
pid: z.string().min(1).describe("Hetzner instance PID (returned by create_hetzner_instance)"),
|
|
198
|
-
}, async ({ pid }) => {
|
|
199
|
-
const result = await apiRequest(`/hetzner/v1/instances/${pid}`, {
|
|
200
|
-
toolName: "get_hetzner_instance",
|
|
201
|
-
skipOrgInjection: true,
|
|
202
|
-
});
|
|
203
|
-
if (!result.success) {
|
|
204
|
-
return {
|
|
205
|
-
content: [{
|
|
206
|
-
type: "text",
|
|
207
|
-
text: `Failed to get Hetzner instance (${result.statusCode}): ${result.message}`,
|
|
208
|
-
}],
|
|
209
|
-
};
|
|
210
|
-
}
|
|
211
|
-
return { content: [{ type: "text", text: JSON.stringify(result.data, null, 2) }] };
|
|
212
|
-
});
|
|
213
|
-
server.tool("get_hetzner_instance_status", "Poll the provisioning progress of a Hetzner instance. Returns `{pid, status, progress: {step_name: 'completed' | 'pending', ...}}`. Use this after `create_hetzner_instance` until `status` is terminal (e.g. `running` or `failed`). Steps include network, firewall, ssh_key, server, volume, load_balancer (HA only), ansible, finalize.", {
|
|
214
|
-
pid: z.string().min(1),
|
|
215
|
-
}, async ({ pid }) => {
|
|
216
|
-
const result = await apiRequest(`/hetzner/v1/instances/${pid}/status`, {
|
|
217
|
-
toolName: "get_hetzner_instance_status",
|
|
218
|
-
skipOrgInjection: true,
|
|
219
|
-
});
|
|
220
|
-
if (!result.success) {
|
|
221
|
-
return {
|
|
222
|
-
content: [{
|
|
223
|
-
type: "text",
|
|
224
|
-
text: `Failed to get Hetzner instance status (${result.statusCode}): ${result.message}`,
|
|
225
|
-
}],
|
|
226
|
-
};
|
|
227
|
-
}
|
|
228
|
-
return { content: [{ type: "text", text: JSON.stringify(result.data, null, 2) }] };
|
|
229
|
-
});
|
|
230
|
-
server.tool("delete_hetzner_instance", "Delete a Hetzner instance and all associated resources (server, volume, firewall, network, load balancer if HA, DNS record). IRREVERSIBLE - there's no `start` / `stop` on Hetzner; deletion is the only way to remove an instance.", {
|
|
231
|
-
pid: z.string().min(1),
|
|
232
|
-
confirm: z.boolean().describe("Must be true to proceed. ALL DATA on this instance will be permanently lost."),
|
|
233
|
-
}, async ({ pid, confirm }) => {
|
|
234
|
-
if (!confirm) {
|
|
235
|
-
return {
|
|
236
|
-
content: [{
|
|
237
|
-
type: "text",
|
|
238
|
-
text: `⚠️ About to DELETE Hetzner instance ${pid}.\n\nThis action is IRREVERSIBLE. Server, volume, firewall, network, load balancer, and DNS records will all be removed. All data will be lost.\n\nCall again with confirm=true to proceed.`,
|
|
239
|
-
}],
|
|
240
|
-
};
|
|
241
|
-
}
|
|
242
|
-
const result = await apiRequest(`/hetzner/v1/instances/${pid}`, {
|
|
243
|
-
method: "DELETE",
|
|
244
|
-
toolName: "delete_hetzner_instance",
|
|
245
|
-
skipOrgInjection: true,
|
|
246
|
-
});
|
|
247
|
-
if (!result.success) {
|
|
248
|
-
return {
|
|
249
|
-
content: [{
|
|
250
|
-
type: "text",
|
|
251
|
-
text: `Failed to delete Hetzner instance (${result.statusCode}): ${result.message}`,
|
|
252
|
-
}],
|
|
253
|
-
};
|
|
254
|
-
}
|
|
255
|
-
return {
|
|
256
|
-
content: [
|
|
257
|
-
{ type: "text", text: `Hetzner instance ${pid} delete requested. Resources are being torn down.` },
|
|
258
|
-
{ type: "text", text: JSON.stringify(result.data, null, 2) },
|
|
259
|
-
],
|
|
260
|
-
};
|
|
261
|
-
});
|
|
262
|
-
}
|
|
263
|
-
//# sourceMappingURL=hetzner.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"hetzner.js","sourceRoot":"","sources":["../../src/tools/hetzner.ts"],"names":[],"mappings":"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"}
|