@selfhost.dev/mcp-server 0.3.0 → 0.4.1

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 +147 -24
  2. package/dist/auth.d.ts +1 -1
  3. package/dist/auth.js +3 -3
  4. package/dist/client.js +1 -1
  5. package/dist/config.js +1 -1
  6. package/dist/index.js +29 -4
  7. package/dist/index.js.map +1 -1
  8. package/dist/rate-limiter.js +1 -1
  9. package/dist/tools/billing.js +14 -14
  10. package/dist/tools/credentials.js +1 -1
  11. package/dist/tools/database-users.js +9 -9
  12. package/dist/tools/deployment-domains.d.ts +2 -0
  13. package/dist/tools/deployment-domains.js +128 -0
  14. package/dist/tools/deployment-domains.js.map +1 -0
  15. package/dist/tools/deployment-notifications.d.ts +2 -0
  16. package/dist/tools/deployment-notifications.js +74 -0
  17. package/dist/tools/deployment-notifications.js.map +1 -0
  18. package/dist/tools/deployments.d.ts +2 -0
  19. package/dist/tools/deployments.js +302 -0
  20. package/dist/tools/deployments.js.map +1 -0
  21. package/dist/tools/env-vars.d.ts +2 -0
  22. package/dist/tools/env-vars.js +121 -0
  23. package/dist/tools/env-vars.js.map +1 -0
  24. package/dist/tools/github.d.ts +2 -0
  25. package/dist/tools/github.js +106 -0
  26. package/dist/tools/github.js.map +1 -0
  27. package/dist/tools/hetzner.js +13 -13
  28. package/dist/tools/instances.js +11 -11
  29. package/dist/tools/pgbouncer.js +4 -4
  30. package/dist/tools/pitr.js +16 -16
  31. package/dist/tools/project-databases.d.ts +2 -0
  32. package/dist/tools/project-databases.js +169 -0
  33. package/dist/tools/project-databases.js.map +1 -0
  34. package/dist/tools/project-services.d.ts +2 -0
  35. package/dist/tools/project-services.js +93 -0
  36. package/dist/tools/project-services.js.map +1 -0
  37. package/dist/tools/projects.d.ts +2 -0
  38. package/dist/tools/projects.js +141 -0
  39. package/dist/tools/projects.js.map +1 -0
  40. package/dist/tools/scaling.js +13 -13
  41. package/dist/types/models.js +1 -1
  42. package/dist/types/tiers.js +31 -1
  43. package/dist/types/tiers.js.map +1 -1
  44. package/package.json +10 -3
package/README.md CHANGED
@@ -1,6 +1,13 @@
1
1
  # SelfHost MCP Server
2
2
 
3
- A full-featured [Model Context Protocol](https://modelcontextprotocol.io/) server that brings [SelfHost's](https://selfhost.dev) database management capabilities directly into AI coding assistants. Provision, monitor, scale, and manage production database infrastructure — all through natural language, without leaving your editor.
3
+ The [SelfHost](https://selfhost.dev) cloud platform, one sentence away inside your AI coding assistant. Spin up production databases, ship apps straight from GitHub, wire up domains and environment variables, and watch builds stream live, all in plain English without ever leaving your editor.
4
+
5
+ SelfHost pairs the power of production-grade managed databases with the effortless, deploy-from-GitHub simplicity of a modern app platform. This [Model Context Protocol](https://modelcontextprotocol.io/) server puts the whole thing at your fingertips.
6
+
7
+ **Two products, one server:**
8
+
9
+ - **Projects** - your apps, shipped. Connect a GitHub repo, click deploy, and it's live: auto-detected builds (Nixpacks, Dockerfile, Docker Compose, or static), auto-deploy on every push, live streaming build logs, environment variables, custom domains, pause and resume to scale to zero, and databases right inside the project. The ease of Railway, Render, and Vercel, with nothing to manage.
10
+ - **Managed Databases** - production-grade database hosting, your way. PostgreSQL, MySQL, and MongoDB on AWS, or Postgres on Hetzner, in our cloud or your own account (BYOC), with backups, point-in-time recovery, autoscaling, alerting, and connection pooling.
4
11
 
5
12
  Works with **Claude Code**, **Cursor**, **Windsurf**, **Cline**, and any MCP-compatible client.
6
13
 
@@ -57,7 +64,7 @@ That's it. The server handles authentication, token refresh, and everything else
57
64
 
58
65
  ### First Run
59
66
 
60
- On first use, the MCP server opens your browser to sign in via SelfHost's console. After you authorize, credentials are saved locally (`~/.selfhost/credentials.json`) and auto-refreshed — you won't need to sign in again.
67
+ On first use, the MCP server opens your browser to sign in via SelfHost's console. After you authorize, credentials are saved locally (`~/.selfhost/credentials.json`) and auto-refreshed - you won't need to sign in again.
61
68
 
62
69
  ```
63
70
  You: "Show me my databases"
@@ -70,7 +77,29 @@ Claude: Authenticates → fetches your orgs → selects org → lists instances
70
77
 
71
78
  ## What Can You Do?
72
79
 
73
- ### Talk to your infrastructure in plain English
80
+ Talk to both products in plain English.
81
+
82
+ ### Ship and run apps with Projects
83
+
84
+ Connect a repo, deploy, and it's live - SelfHost takes your code from GitHub to a running app.
85
+
86
+ | You say | What happens |
87
+ |---------|-------------|
88
+ | *"Create a project and deploy my GitHub repo into it"* | Provisions the project, waits until it's ready, auto-detects the build, and deploys the repo |
89
+ | *"Deploy the main branch of my-org/api"* | Creates the deployment, triggers the build, and streams live logs until it's running |
90
+ | *"Turn on auto-deploy so every push ships"* | Enables auto-deploy; future pushes to the branch redeploy automatically |
91
+ | *"Add a private Postgres database to my project"* | Provisions a Postgres database inside the project, with the credentials and visibility you choose |
92
+ | *"Spin up Supabase in this project"* | Deploys the Supabase template alongside your app |
93
+ | *"Set DATABASE_URL on my app and redeploy"* | Updates the env var (without wiping the others) and rolls out the change |
94
+ | *"Point app.example.com at my deployment"* | Attaches the custom domain and returns the exact DNS records to add, then verifies them |
95
+ | *"Show me the build logs for the last deploy"* | Streams the build and container logs for that run |
96
+ | *"Pause my staging app so I stop paying for it"* | Pauses the deployment (scales to zero); resume instantly when you need it |
97
+ | *"Roll back to the last working deploy"* | Re-deploys the commit from the previous successful run |
98
+ | *"Notify my team channel when a deploy fails"* | Binds a notification channel to the app's deploy outcomes |
99
+
100
+ ### Manage database infrastructure with Managed Databases
101
+
102
+ Production-grade, standalone database hosting.
74
103
 
75
104
  | You say | What happens |
76
105
  |---------|-------------|
@@ -92,13 +121,13 @@ Claude: Authenticates → fetches your orgs → selects org → lists instances
92
121
 
93
122
  ### Safety Built In
94
123
 
95
- Destructive operations (delete, stop, reboot) require explicit confirmation. The server will always ask before proceeding — you'll never accidentally delete a production database.
124
+ Destructive operations (delete, stop, reboot) require explicit confirmation. The server will always ask before proceeding - you'll never accidentally delete a production database.
96
125
 
97
126
  ---
98
127
 
99
128
  ## Features
100
129
 
101
- ### 111 tools across 14 modules
130
+ ### 151 tools across 22 modules
102
131
 
103
132
  Every tool maps to a real API endpoint. No mock data, no shortcuts.
104
133
 
@@ -117,7 +146,7 @@ Automatic browser-based sign-in with Firebase. Tokens refresh transparently.
117
146
  | `reauthenticate` | Sign out and sign in again (switch accounts) |
118
147
 
119
148
  #### Organizations & Team Management
120
- Multi-tenant — everything is scoped to your org.
149
+ Multi-tenant - everything is scoped to your org.
121
150
 
122
151
  | Tool | Description |
123
152
  |------|-------------|
@@ -147,7 +176,7 @@ Bring your own AWS account (BYOC) or use SelfHost's managed infrastructure.
147
176
  | `get_aws_account_info` | AWS account ID and free tier status |
148
177
 
149
178
  #### Networking
150
- VPCs, subnets, and security groups. Optional — auto-created during provisioning if not specified.
179
+ VPCs, subnets, and security groups. Optional - auto-created during provisioning if not specified.
151
180
 
152
181
  | Tool | Description |
153
182
  |------|-------------|
@@ -237,29 +266,29 @@ PostgreSQL-only. Reduces connection overhead for high-concurrency workloads. Cli
237
266
  | `disable_pgbouncer` | Drain pool and disable (with confirmation) |
238
267
 
239
268
  #### Database Users
240
- DBMS-level credentials — distinct from the SelfHost platform login. Use for apps and people that need their own DB user.
269
+ DBMS-level credentials - distinct from the SelfHost platform login. Use for apps and people that need their own DB user.
241
270
 
242
271
  | Tool | Description |
243
272
  |------|-------------|
244
273
  | `list_database_users` | List users with role, status, target DB, expiry metadata |
245
274
  | `create_database_user` | Create user with role (read_only / read_write / admin) and optional connection limit + password expiry |
246
275
  | `update_database_user` | Change role, connection limit, or password expiry |
247
- | `delete_database_user` | Soft-delete user (with confirmation) — drops active connections |
248
- | `rotate_database_user_password` | Rotate password (with confirmation) — new value shown once |
276
+ | `delete_database_user` | Soft-delete user (with confirmation) - drops active connections |
277
+ | `rotate_database_user_password` | Rotate password (with confirmation) - new value shown once |
249
278
 
250
279
  #### Scaling
251
280
  Manual one-off resize plus auto-scaling policies (reactive metric-based, scheduled cron, and auto start/stop).
252
281
 
253
282
  | Tool | Description |
254
283
  |------|-------------|
255
- | `scale_instance` | Manual resize — change instance type, volume type, size, IOPS, throughput |
284
+ | `scale_instance` | Manual resize - change instance type, volume type, size, IOPS, throughput |
256
285
  | `list_scaling_policies` | List policies, optionally filtered to one instance |
257
- | `create_scaling_policy` | Create policy — reactive metric breach, scheduled cron, or auto start/stop schedule |
286
+ | `create_scaling_policy` | Create policy - reactive metric breach, scheduled cron, or auto start/stop schedule |
258
287
  | `update_scaling_policy` | Modify thresholds, schedule, or action details |
259
288
  | `delete_scaling_policy` | Remove a policy (with confirmation) |
260
289
 
261
290
  #### Point-in-Time Recovery (PITR)
262
- PostgreSQL-only, Pro+. Continuous WAL archiving to S3 + restore to any second within the retention window. Restore creates a brand-new instance — the source is untouched.
291
+ PostgreSQL-only, Pro+. Continuous WAL archiving to S3 + restore to any second within the retention window. Restore creates a brand-new instance - the source is untouched.
263
292
 
264
293
  | Tool | Description |
265
294
  |------|-------------|
@@ -279,18 +308,18 @@ Subscription lifecycle and payment-method linking. All endpoints scoped to the a
279
308
  | `get_subscription` | Get current subscription (404 = no subscription, on Free) |
280
309
  | `create_subscription` | Start a paid subscription (plan goes `pending` → `active` via Razorpay webhook) |
281
310
  | `change_subscription` | Upgrade or downgrade plan (downgrades scheduled at cycle end) |
282
- | `cancel_subscription` | Cancel — keeps access until cycle end (with confirmation) |
283
- | `link_billing_payment_method` | Initiate Razorpay link — returns short URL to open in browser |
311
+ | `cancel_subscription` | Cancel - keeps access until cycle end (with confirmation) |
312
+ | `link_billing_payment_method` | Initiate Razorpay link - returns short URL to open in browser |
284
313
  | `update_billing_contact` | Update billing phone / tax ID / country / state for invoices |
285
314
 
286
315
  #### Hetzner Cloud (Postgres-only)
287
- Provisioning on Hetzner Cloud as an alternative to AWS. Currently provision / get / status / delete only — no start / stop / reboot / update / scaling / PITR / pooling yet. Call `list_cloud_providers` at the start of any create-database intent to surface both options to the user.
316
+ Provisioning on Hetzner Cloud as an alternative to AWS. Currently provision / get / status / delete only - no start / stop / reboot / update / scaling / PITR / pooling yet. Call `list_cloud_providers` at the start of any create-database intent to surface both options to the user.
288
317
 
289
318
  | Tool | Description |
290
319
  |------|-------------|
291
320
  | `list_cloud_providers` | List available cloud providers (AWS, Hetzner) with capabilities + the create tool to use for each |
292
321
  | `list_hetzner_locations` | Hetzner datacenter locations (fsn1, nbg1, hel1, ash, sin) with country + continent |
293
- | `list_hetzner_server_types` | Hetzner server types (cpx11–cpx51) with vCPU / RAM / local disk |
322
+ | `list_hetzner_server_types` | Hetzner server types (cpx11-cpx51) with vCPU / RAM / local disk |
294
323
  | `create_hetzner_instance` | Provision a Postgres instance on Hetzner Cloud (region, server type, storage size, HA toggle, CIDR allowlist) |
295
324
  | `get_hetzner_instance` | Fetch a Hetzner instance's full details by PID |
296
325
  | `get_hetzner_instance_status` | Poll provisioning progress (per-step status: network → firewall → ssh_key → server → volume → load_balancer → ansible → finalize) |
@@ -298,8 +327,102 @@ Provisioning on Hetzner Cloud as an alternative to AWS. Currently provision / ge
298
327
 
299
328
  ---
300
329
 
330
+ ### PaaS - Projects (app containers)
331
+ A **project** is a per-app container: a provisioned server + Coolify install + wildcard DNS that deployments, databases, and services attach to. Creation is async (~2-5 min) - poll `get_project` until status is `active` before deploying into it.
332
+
333
+ | Tool | Description |
334
+ |------|-------------|
335
+ | `list_projects` | List projects in the org (pid, name, status, public_ip, domain) |
336
+ | `get_project` | Get one project; poll this for provisioning progress (active / failed) |
337
+ | `create_project` | Create a project and start async provisioning (returns status `pending`) |
338
+ | `update_project` | Rename / re-describe a project |
339
+ | `delete_project` | Tear down the server and everything in the project (with confirmation; blocked while provisioning or with running deployments) |
340
+ | `get_project_metrics` | Time-series server + database + deployment metrics from the monitoring agent (start_date/end_date) |
341
+
342
+ ### PaaS - Deployments (GitHub apps)
343
+ A **deployment** is an app built from a GitHub repo, living inside an `active` project. Build/run history is returned inline on the deployment.
344
+
345
+ | Tool | Description |
346
+ |------|-------------|
347
+ | `list_deployments` | List apps in the org, each with inline build runs (newest 50) |
348
+ | `get_deployment` | Get one app + runs; poll this for deploy/run progress |
349
+ | `create_deployment` | Deploy a GitHub repo into a project (repo_url, branch, build_pack, port, env_vars, …) |
350
+ | `update_deployment` | Pause/resume, toggle auto-deploy, set ignore_paths / max preview deployments |
351
+ | `update_deployment_build_config` | Change build_pack / base_directory / port / dockerfile / env_vars |
352
+ | `delete_deployment` | Remove the app and its Coolify resources (with confirmation) |
353
+ | `trigger_deploy` | Manually deploy the current branch (new run) |
354
+ | `get_deployment_logs` | Current application/container logs |
355
+ | `get_deployment_health` | Reachability of the deploy URL + attached domains |
356
+ | `get_run_logs` | Full build + container logs for one run (poll until terminal) |
357
+ | `redeploy_run` | Re-run a build from the same commit |
358
+ | `rollback_run` | Re-deploy the commit from a prior successful run |
359
+
360
+ ### PaaS - Custom Domains
361
+ | Tool | Description |
362
+ |------|-------------|
363
+ | `add_deployment_domain` | Attach a custom domain to a deployment (returns DNS records to add) |
364
+ | `sync_deployment_domains` | Set the full domain list for a deployment (set primary / remove several) |
365
+ | `remove_deployment_domain` | Remove one domain from a deployment |
366
+ | `verify_custom_domain` | Check DNS (TXT + CNAME) and advance verification → live HTTPS |
367
+ | `list_custom_domains` | List the org's custom-domain verification states |
368
+
369
+ ### PaaS - Environment Variables
370
+ | Tool | Description |
371
+ |------|-------------|
372
+ | `list_env_vars` | List a deployment's env vars (values returned in cleartext) |
373
+ | `set_env_vars` | **Replace** the entire env-var set (omitted keys are deleted) |
374
+ | `merge_env_vars` | Add/update env vars without deleting others (safe upsert) |
375
+ | `delete_env_var` | Remove one variable by key |
376
+
377
+ ### PaaS - GitHub
378
+ | Tool | Description |
379
+ |------|-------------|
380
+ | `list_github_installations` | Connected GitHub App installations + their accessible repos |
381
+ | `list_repo_branches` | Branches for a repo via an installation |
382
+ | `detect_repo_config` | Auto-detect build_pack / port / monorepo dirs / env-var hints for a repo |
383
+ | `get_github_connect_url` | Get a browser URL to connect GitHub (interactive; then re-list installations) |
384
+
385
+ ### PaaS - Project Databases
386
+ Postgres/Redis/MySQL/MongoDB provisioned inside a project (distinct from AWS/Hetzner managed instances).
387
+
388
+ | Tool | Description |
389
+ |------|-------------|
390
+ | `list_project_databases` | List databases attached to a project |
391
+ | `create_project_database` | Provision a Postgres/Redis/MySQL/MongoDB in a project (type-specific credentials) |
392
+ | `delete_project_database` | Delete a project database (exact name match + confirmation) |
393
+
394
+ ### PaaS - Project Services (templates)
395
+ | Tool | Description |
396
+ |------|-------------|
397
+ | `list_project_services` | List service-template instances (e.g. Supabase) in a project |
398
+ | `create_project_service` | Deploy a service template (currently `supabase`) into a project |
399
+ | `delete_project_service` | Delete a project service (exact name match + confirmation) |
400
+
401
+ ### PaaS - Deployment Notifications
402
+ | Tool | Description |
403
+ |------|-------------|
404
+ | `list_deployment_notification_bindings` | Channels notified on a deployment's deploy outcomes |
405
+ | `bind_deployment_notification_channel` | Notify an org channel (nchan_…) on deploy success/failure |
406
+ | `unbind_deployment_notification_channel` | Stop notifying a channel for a deployment |
407
+
408
+ ---
409
+
301
410
  ## Common Workflows
302
411
 
412
+ ### Deploy an app from GitHub (Projects)
413
+
414
+ ```
415
+ You: "Deploy my-org/web to a new project"
416
+
417
+ Claude: Creates a project → polls until it's provisioned and active
418
+ → detects the build config from the repo (build pack, port)
419
+ → creates the deployment and triggers the first build
420
+ → streams the build logs until the app is live
421
+ → hands you the deploy URL
422
+ ```
423
+
424
+ Then: *"add a private Postgres to it"*, *"set my env vars"*, *"point app.example.com at it"*, or *"turn on auto-deploy"* to round out the app.
425
+
303
426
  ### Switch AWS Account (BYOC vs Platform-Managed)
304
427
 
305
428
  ```
@@ -370,12 +493,12 @@ Reference data lookups (regions, instance types, storage types) are unlimited.
370
493
  | `API_URL` | `https://api.selfhost.dev` | SelfHost API endpoint |
371
494
  | `CONSOLE_URL` | `https://console.selfhost.dev` | SelfHost Console URL (for browser auth) |
372
495
  | `TIER` | Auto-detected | Override rate limit tier (`FREE`, `STARTER`, `PRO`, `ENTERPRISE`, `ADMIN`) |
373
- | `FIREBASE_API_KEY` | — | Skip browser auth (CI/headless) |
374
- | `FIREBASE_REFRESH_TOKEN` | — | Skip browser auth (CI/headless) |
496
+ | `FIREBASE_API_KEY` | - | Skip browser auth (CI/headless) |
497
+ | `FIREBASE_REFRESH_TOKEN` | - | Skip browser auth (CI/headless) |
375
498
 
376
499
  ### Local Development
377
500
 
378
- Both `API_URL` and `CONSOLE_URL` are optional overrides — they default to the production endpoints when not set.
501
+ Both `API_URL` and `CONSOLE_URL` are optional overrides - they default to the production endpoints when not set.
379
502
 
380
503
  **1. Local Rails API + Local Console**
381
504
 
@@ -452,7 +575,7 @@ Set `FIREBASE_API_KEY` and `FIREBASE_REFRESH_TOKEN` environment variables to ski
452
575
  ## Security
453
576
 
454
577
  - **Credentials stored locally** at `~/.selfhost/credentials.json` with `chmod 0600` (owner-only read/write)
455
- - **JWT auto-refresh** — tokens refresh 5 minutes before expiry, refresh tokens are rotated
456
- - **Sensitive fields stripped** — passwords, AWS keys, tokens, and secrets are redacted from API responses
457
- - **Destructive operations gated** — delete, stop, and reboot require explicit `confirm: true`
458
- - **No console.log** — all logging goes to stderr to avoid corrupting the MCP JSON-RPC stream on stdout
578
+ - **JWT auto-refresh** - tokens refresh 5 minutes before expiry, refresh tokens are rotated
579
+ - **Sensitive fields stripped** - passwords, AWS keys, tokens, and secrets are redacted from API responses
580
+ - **Destructive operations gated** - delete, stop, and reboot require explicit `confirm: true`
581
+ - **No console.log** - all logging goes to stderr to avoid corrupting the MCP JSON-RPC stream on stdout
package/dist/auth.d.ts CHANGED
@@ -2,7 +2,7 @@ export declare function wasAuthPrompted(): Promise<boolean>;
2
2
  export declare function markAuthPrompted(): Promise<void>;
3
3
  /**
4
4
  * Returns true if credentials are available (env vars or stored file).
5
- * No network calls — just a fast file existence check.
5
+ * No network calls - just a fast file existence check.
6
6
  */
7
7
  export declare function hasCredentials(): Promise<boolean>;
8
8
  /**
package/dist/auth.js CHANGED
@@ -130,7 +130,7 @@ async function resolveCredentials() {
130
130
  }
131
131
  /**
132
132
  * Returns true if credentials are available (env vars or stored file).
133
- * No network calls — just a fast file existence check.
133
+ * No network calls - just a fast file existence check.
134
134
  */
135
135
  export async function hasCredentials() {
136
136
  if (config.firebaseApiKey && config.firebaseRefreshToken)
@@ -169,7 +169,7 @@ async function _getValidTokenImpl() {
169
169
  return jwt;
170
170
  }
171
171
  catch {
172
- // Refresh token expired — re-authenticate via browser
172
+ // Refresh token expired - re-authenticate via browser
173
173
  cachedJwt = null;
174
174
  jwtExpiresAt = 0;
175
175
  const newCreds = await browserLogin();
@@ -192,7 +192,7 @@ export async function forceReauth() {
192
192
  await unlink(config.credentialsPath);
193
193
  }
194
194
  catch {
195
- // File may not exist — that's fine
195
+ // File may not exist - that's fine
196
196
  }
197
197
  const creds = await browserLogin();
198
198
  await saveCredentials(creds.apiKey, creds.refreshToken);
package/dist/client.js CHANGED
@@ -63,7 +63,7 @@ export async function apiRequest(path, options = {}) {
63
63
  };
64
64
  }
65
65
  catch (error) {
66
- // Rate limit errors are thrown before fetch — re-throw as-is
66
+ // Rate limit errors are thrown before fetch - re-throw as-is
67
67
  if (error instanceof Error && error.message.includes("Rate limit")) {
68
68
  throw error;
69
69
  }
package/dist/config.js CHANGED
@@ -5,7 +5,7 @@ function log(message) {
5
5
  const API_URL = process.env.API_URL || "https://api.selfhost.dev";
6
6
  const CONSOLE_URL = process.env.CONSOLE_URL || "https://console.selfhost.dev";
7
7
  const TIER_OVERRIDE = process.env.TIER;
8
- // Headless/CI fallback — skip browser login if these are set
8
+ // Headless/CI fallback - skip browser login if these are set
9
9
  const FIREBASE_API_KEY = process.env.FIREBASE_API_KEY;
10
10
  const FIREBASE_REFRESH_TOKEN = process.env.FIREBASE_REFRESH_TOKEN;
11
11
  export const config = {
package/dist/index.js CHANGED
@@ -18,6 +18,14 @@ import { registerScalingTools } from "./tools/scaling.js";
18
18
  import { registerPitrTools } from "./tools/pitr.js";
19
19
  import { registerBillingTools } from "./tools/billing.js";
20
20
  import { registerHetznerTools } from "./tools/hetzner.js";
21
+ import { registerProjectTools } from "./tools/projects.js";
22
+ import { registerDeploymentTools } from "./tools/deployments.js";
23
+ import { registerDeploymentDomainTools } from "./tools/deployment-domains.js";
24
+ import { registerEnvVarTools } from "./tools/env-vars.js";
25
+ import { registerGithubTools } from "./tools/github.js";
26
+ import { registerProjectDatabaseTools } from "./tools/project-databases.js";
27
+ import { registerProjectServiceTools } from "./tools/project-services.js";
28
+ import { registerDeploymentNotificationTools } from "./tools/deployment-notifications.js";
21
29
  const server = new McpServer({
22
30
  name: "selfhost",
23
31
  version: "0.1.0",
@@ -42,14 +50,31 @@ registerAlertTools(server);
42
50
  registerPgBouncerTools(server);
43
51
  // Module 10: Database users (DBMS-level credentials)
44
52
  registerDatabaseUserTools(server);
45
- // Module 11: Scaling — manual + auto-scaling policies + auto start/stop
53
+ // Module 11: Scaling - manual + auto-scaling policies + auto start/stop
46
54
  registerScalingTools(server);
47
55
  // Module 12: Point-in-Time Recovery (Postgres, Pro+)
48
56
  registerPitrTools(server);
49
- // Module 13: Billing — subscriptions + payment-method linking
57
+ // Module 13: Billing - subscriptions + payment-method linking
50
58
  registerBillingTools(server);
51
- // Module 14: Hetzner Cloud — Postgres-only provision/get/status/delete + provider discovery
59
+ // Module 14: Hetzner Cloud - Postgres-only provision/get/status/delete + provider discovery
52
60
  registerHetznerTools(server);
61
+ // ─── PaaS / Apps surface (/api/v1/platform/...) ──────────────────────────────
62
+ // Module 15: Projects - CoolifyProject app-container lifecycle + metrics
63
+ registerProjectTools(server);
64
+ // Module 16: Deployments - GitHub-repo apps, build runs, deploy/redeploy/rollback, logs, health
65
+ registerDeploymentTools(server);
66
+ // Module 17: Custom domains - deployment-scoped add/sync/remove + org DNS verification
67
+ registerDeploymentDomainTools(server);
68
+ // Module 18: Environment variables - list / set (replace) / merge / delete
69
+ registerEnvVarTools(server);
70
+ // Module 19: GitHub - installations (+repos), branches, repo config detection, connect URL
71
+ registerGithubTools(server);
72
+ // Module 20: Project databases - Postgres/Redis/MySQL/MongoDB inside a project
73
+ registerProjectDatabaseTools(server);
74
+ // Module 21: Project services - service templates (Supabase) inside a project
75
+ registerProjectServiceTools(server);
76
+ // Module 22: Deployment notifications - bind/unbind org channels to deploy outcomes
77
+ registerDeploymentNotificationTools(server);
53
78
  // Server utility tools
54
79
  server.tool("reauthenticate", "Clear stored credentials and sign in again (use to switch accounts or fix auth issues)", {}, async () => {
55
80
  try {
@@ -78,7 +103,7 @@ async function main() {
78
103
  if (!(await hasCredentials()) && !(await wasAuthPrompted())) {
79
104
  markAuthPrompted().catch(() => { });
80
105
  getValidToken().catch(() => {
81
- // Timeout or error — user can retry via any tool call
106
+ // Timeout or error - user can retry via any tool call
82
107
  });
83
108
  }
84
109
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,cAAc,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC1G,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;AACrE,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AACtE,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAE1D,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;IAC3B,IAAI,EAAE,UAAU;IAChB,OAAO,EAAE,OAAO;CACjB,CAAC,CAAC;AAEH,yBAAyB;AACzB,iBAAiB,CAAC,MAAM,CAAC,CAAC;AAE1B,oCAAoC;AACpC,yBAAyB,CAAC,MAAM,CAAC,CAAC;AAElC,8BAA8B;AAC9B,uBAAuB,CAAC,MAAM,CAAC,CAAC;AAEhC,wDAAwD;AACxD,uBAAuB,CAAC,MAAM,CAAC,CAAC;AAEhC,+BAA+B;AAC/B,qBAAqB,CAAC,MAAM,CAAC,CAAC;AAE9B,8BAA8B;AAC9B,qBAAqB,CAAC,MAAM,CAAC,CAAC;AAE9B,gCAAgC;AAChC,mBAAmB,CAAC,MAAM,CAAC,CAAC;AAE5B,mCAAmC;AACnC,kBAAkB,CAAC,MAAM,CAAC,CAAC;AAE3B,0DAA0D;AAC1D,sBAAsB,CAAC,MAAM,CAAC,CAAC;AAE/B,qDAAqD;AACrD,yBAAyB,CAAC,MAAM,CAAC,CAAC;AAElC,wEAAwE;AACxE,oBAAoB,CAAC,MAAM,CAAC,CAAC;AAE7B,qDAAqD;AACrD,iBAAiB,CAAC,MAAM,CAAC,CAAC;AAE1B,8DAA8D;AAC9D,oBAAoB,CAAC,MAAM,CAAC,CAAC;AAE7B,4FAA4F;AAC5F,oBAAoB,CAAC,MAAM,CAAC,CAAC;AAE7B,uBAAuB;AACvB,MAAM,CAAC,IAAI,CAAC,gBAAgB,EAAE,wFAAwF,EAAE,EAAE,EAAE,KAAK,IAAI,EAAE;IACrI,IAAI,CAAC;QACH,OAAO,CAAC,KAAK,EAAE,CAAC;QAChB,MAAM,WAAW,EAAE,CAAC;QACpB,OAAO;YACL,OAAO,EAAE,CAAC;oBACR,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,oJAAoJ;iBAC3J,CAAC;SACH,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,6BAA6B,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,CAAC;IACxH,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,KAAK,UAAU,IAAI;IACjB,MAAM,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;IAC9C,MAAM,CAAC,GAAG,CAAC,YAAY,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;IAExC,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;QACxB,MAAM,CAAC,GAAG,CAAC,kBAAkB,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC;IACtD,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAEhC,iGAAiG;IACjG,IAAI,CAAC,CAAC,MAAM,cAAc,EAAE,CAAC,IAAI,CAAC,CAAC,MAAM,eAAe,EAAE,CAAC,EAAE,CAAC;QAC5D,gBAAgB,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QACnC,aAAa,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE;YACzB,sDAAsD;QACxD,CAAC,CAAC,CAAC;IACL,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,MAAM,CAAC,GAAG,CAAC,gBAAgB,GAAG,EAAE,CAAC,CAAC;IAClC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -43,7 +43,7 @@ class RateLimiter {
43
43
  this.tier = tier;
44
44
  this.isAdmin = tier === "ADMIN";
45
45
  if (this.isAdmin) {
46
- config.log("Admin tier set — rate limits disabled.");
46
+ config.log("Admin tier set - rate limits disabled.");
47
47
  return;
48
48
  }
49
49
  const tierConfig = TIER_CONFIGS[tier];
@@ -2,15 +2,15 @@ import { z } from "zod";
2
2
  import { apiRequest } from "../client.js";
3
3
  import { session } from "../session.js";
4
4
  /**
5
- * Billing — subscription lifecycle + payment method linking.
5
+ * Billing - subscription lifecycle + payment method linking.
6
6
  *
7
7
  * Endpoints:
8
- * - GET /organizations/:pid/billing/subscription — current subscription
9
- * - POST /organizations/:pid/billing/subscriptions — create (first time)
10
- * - PATCH /organizations/:pid/billing/subscriptions — change plan (up/downgrade)
11
- * - DELETE /organizations/:pid/billing/subscriptions — cancel
12
- * - POST /organizations/:pid/billing/link — initiate Razorpay link
13
- * - PATCH /organizations/:pid/billing/contact — update contact / tax info
8
+ * - GET /organizations/:pid/billing/subscription - current subscription
9
+ * - POST /organizations/:pid/billing/subscriptions - create (first time)
10
+ * - PATCH /organizations/:pid/billing/subscriptions - change plan (up/downgrade)
11
+ * - DELETE /organizations/:pid/billing/subscriptions - cancel
12
+ * - POST /organizations/:pid/billing/link - initiate Razorpay link
13
+ * - PATCH /organizations/:pid/billing/contact - update contact / tax info
14
14
  *
15
15
  * All endpoints are org-scoped via the path. The org PID is taken from the
16
16
  * MCP session by default; pass `organization_id` to target a different org.
@@ -55,7 +55,7 @@ export function registerBillingTools(server) {
55
55
  return {
56
56
  content: [{
57
57
  type: "text",
58
- text: "Free is the default — no subscription needed. Use `change_subscription` with billing_plan=free to downgrade an existing paid subscription.",
58
+ text: "Free is the default - no subscription needed. Use `change_subscription` with billing_plan=free to downgrade an existing paid subscription.",
59
59
  }],
60
60
  };
61
61
  }
@@ -79,12 +79,12 @@ export function registerBillingTools(server) {
79
79
  }
80
80
  return {
81
81
  content: [
82
- { type: "text", text: `Subscription create requested for plan \`${billing_plan}\`. The lifecycle state will move from \`pending\` to \`active\` once Razorpay confirms — poll \`get_subscription\`.` },
82
+ { type: "text", text: `Subscription create requested for plan \`${billing_plan}\`. The lifecycle state will move from \`pending\` to \`active\` once Razorpay confirms - poll \`get_subscription\`.` },
83
83
  { type: "text", text: JSON.stringify(result.data, null, 2) },
84
84
  ],
85
85
  };
86
86
  });
87
- server.tool("change_subscription", "Change an existing subscription's plan (upgrade or downgrade). Upgrades apply immediately and prorate; downgrades are scheduled at the end of the current billing cycle. A downgrade may return 422 DOWNGRADE_BLOCKED if the org has resources above the target plan's caps (e.g. >3 instances on Starter) — surface the BE error message to the user.", {
87
+ server.tool("change_subscription", "Change an existing subscription's plan (upgrade or downgrade). Upgrades apply immediately and prorate; downgrades are scheduled at the end of the current billing cycle. A downgrade may return 422 DOWNGRADE_BLOCKED if the org has resources above the target plan's caps (e.g. >3 instances on Starter) - surface the BE error message to the user.", {
88
88
  organization_id: z.string().optional(),
89
89
  billing_plan: z.enum(PLANS).describe("Target plan"),
90
90
  }, async ({ organization_id, billing_plan }) => {
@@ -144,7 +144,7 @@ export function registerBillingTools(server) {
144
144
  }
145
145
  return {
146
146
  content: [
147
- { type: "text", text: "Subscription cancellation scheduled — org will move to `cancelling` until cycle end, then `cancelled`." },
147
+ { type: "text", text: "Subscription cancellation scheduled - org will move to `cancelling` until cycle end, then `cancelled`." },
148
148
  { type: "text", text: JSON.stringify(result.data, null, 2) },
149
149
  ],
150
150
  };
@@ -193,12 +193,12 @@ export function registerBillingTools(server) {
193
193
  }
194
194
  return {
195
195
  content: [
196
- { type: "text", text: "Razorpay link initiated. Open the `short_url` in a browser to add a card / UPI. The MCP can't complete the checkout — it's a browser-only flow." },
196
+ { type: "text", text: "Razorpay link initiated. Open the `short_url` in a browser to add a card / UPI. The MCP can't complete the checkout - it's a browser-only flow." },
197
197
  { type: "text", text: JSON.stringify(result.data, null, 2) },
198
198
  ],
199
199
  };
200
200
  });
201
- server.tool("update_billing_contact", "Update billing contact info on an already-linked org. Doesn't re-run Razorpay — only persists DB overrides for invoices.", {
201
+ server.tool("update_billing_contact", "Update billing contact info on an already-linked org. Doesn't re-run Razorpay - only persists DB overrides for invoices.", {
202
202
  organization_id: z.string().optional(),
203
203
  billing_contact_phone: z.string().optional(),
204
204
  tax_id: z.string().optional()
@@ -224,7 +224,7 @@ export function registerBillingTools(server) {
224
224
  return {
225
225
  content: [{
226
226
  type: "text",
227
- text: "No changes to apply — pass at least one of billing_contact_phone / tax_id / country_code / state_code.",
227
+ text: "No changes to apply - pass at least one of billing_contact_phone / tax_id / country_code / state_code.",
228
228
  }],
229
229
  };
230
230
  }
@@ -15,7 +15,7 @@ When selecting credentials for instance creation:
15
15
  - Filter by cloud_provider matching the user's chosen provider (e.g. "aws")
16
16
  - Only use credentials with status "active"
17
17
  - is_platform_managed=true → SelfHost's cloud account (no VPC needed)
18
- - is_platform_managed=false → user's own cloud account (BYOC — VPC required, use list_vpcs)
18
+ - is_platform_managed=false → user's own cloud account (BYOC - VPC required, use list_vpcs)
19
19
  - Present the user with a choice between platform-managed and their own credentials`, {
20
20
  organization_id: z.string().optional().describe("Organization PID (defaults to active org)"),
21
21
  }, async ({ organization_id }) => {
@@ -1,7 +1,7 @@
1
1
  import { z } from "zod";
2
2
  import { apiRequest } from "../client.js";
3
3
  /**
4
- * Database users — DBMS-level credentials (distinct from the platform login).
4
+ * Database users - DBMS-level credentials (distinct from the platform login).
5
5
  *
6
6
  * Endpoints:
7
7
  * - GET /aws/v1/instances/:id/database_users
@@ -70,12 +70,12 @@ export function registerDatabaseUserTools(server) {
70
70
  }
71
71
  return {
72
72
  content: [
73
- { type: "text", text: `Database user \`${username}\` create requested. Status will transition from \`pending\` to \`active\` once applied — poll \`list_database_users\`.` },
73
+ { type: "text", text: `Database user \`${username}\` create requested. Status will transition from \`pending\` to \`active\` once applied - poll \`list_database_users\`.` },
74
74
  { type: "text", text: JSON.stringify(result.data, null, 2) },
75
75
  ],
76
76
  };
77
77
  });
78
- server.tool("update_database_user", "Update a database user — change role, connection limit, or password expiry. Username and target database are immutable (delete + recreate to change them).", {
78
+ server.tool("update_database_user", "Update a database user - change role, connection limit, or password expiry. Username and target database are immutable (delete + recreate to change them).", {
79
79
  instance_id: z.string().min(1),
80
80
  user_id: z.string().min(1).describe("Database user PID (from list_database_users)"),
81
81
  role: z.enum(ROLES).optional(),
@@ -94,7 +94,7 @@ export function registerDatabaseUserTools(server) {
94
94
  return {
95
95
  content: [{
96
96
  type: "text",
97
- text: "No changes to apply — pass at least one of role / connection_limit / password_expiry_days.",
97
+ text: "No changes to apply - pass at least one of role / connection_limit / password_expiry_days.",
98
98
  }],
99
99
  };
100
100
  }
@@ -114,7 +114,7 @@ export function registerDatabaseUserTools(server) {
114
114
  }
115
115
  return { content: [{ type: "text", text: JSON.stringify(result.data, null, 2) }] };
116
116
  });
117
- server.tool("delete_database_user", "Soft-delete a database user. Existing connections opened by this user are terminated. The record is preserved for audit — contact support to recover.", {
117
+ server.tool("delete_database_user", "Soft-delete a database user. Existing connections opened by this user are terminated. The record is preserved for audit - contact support to recover.", {
118
118
  instance_id: z.string().min(1),
119
119
  user_id: z.string().min(1),
120
120
  username: z.string().optional().describe("Username for the confirmation message (cosmetic)"),
@@ -142,9 +142,9 @@ export function registerDatabaseUserTools(server) {
142
142
  }],
143
143
  };
144
144
  }
145
- return { content: [{ type: "text", text: "Database user delete requested — status will move to `deleting` and then disappear from the list." }] };
145
+ return { content: [{ type: "text", text: "Database user delete requested - status will move to `deleting` and then disappear from the list." }] };
146
146
  });
147
- server.tool("rotate_database_user_password", "Rotate the password for a database user. The new password is generated server-side and returned ONCE in the response. SECURITY: save it immediately — there is no way to retrieve it later. Existing connections using the old password are terminated.", {
147
+ server.tool("rotate_database_user_password", "Rotate the password for a database user. The new password is generated server-side and returned ONCE in the response. SECURITY: save it immediately - there is no way to retrieve it later. Existing connections using the old password are terminated.", {
148
148
  instance_id: z.string().min(1),
149
149
  user_id: z.string().min(1),
150
150
  confirm: z.boolean().describe("Must be true. Old password is invalidated immediately; apps and scripts must pick up the new value."),
@@ -153,7 +153,7 @@ export function registerDatabaseUserTools(server) {
153
153
  return {
154
154
  content: [{
155
155
  type: "text",
156
- text: `⚠️ About to ROTATE the password for database user ${user_id} on instance ${instance_id}.\n\nThe new password is shown ONCE in the response — save it before doing anything else.\nApps and scripts using the old password will lose connections immediately.\n\nCall again with confirm=true to proceed.`,
156
+ text: `⚠️ About to ROTATE the password for database user ${user_id} on instance ${instance_id}.\n\nThe new password is shown ONCE in the response - save it before doing anything else.\nApps and scripts using the old password will lose connections immediately.\n\nCall again with confirm=true to proceed.`,
157
157
  }],
158
158
  };
159
159
  }
@@ -172,7 +172,7 @@ export function registerDatabaseUserTools(server) {
172
172
  }
173
173
  return {
174
174
  content: [
175
- { type: "text", text: "🔑 New password generated. Copy it now — it will not be shown again." },
175
+ { type: "text", text: "🔑 New password generated. Copy it now - it will not be shown again." },
176
176
  { type: "text", text: JSON.stringify(result.data, null, 2) },
177
177
  ],
178
178
  };
@@ -0,0 +1,2 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function registerDeploymentDomainTools(server: McpServer): void;