@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
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# SelfHost MCP Server
|
|
2
2
|
|
|
3
|
-
A full-featured [Model Context Protocol](https://modelcontextprotocol.io/) server that brings [SelfHost
|
|
3
|
+
A full-featured [Model Context Protocol](https://modelcontextprotocol.io/) server that brings the [SelfHost](https://selfhost.dev) cloud platform directly into AI coding assistants. Provision, monitor, scale, and manage production database infrastructure **and** deploy apps from GitHub - projects, builds, env vars, custom domains, and more - all through natural language, without leaving your editor.
|
|
4
4
|
|
|
5
5
|
Works with **Claude Code**, **Cursor**, **Windsurf**, **Cline**, and any MCP-compatible client.
|
|
6
6
|
|
|
@@ -57,7 +57,7 @@ That's it. The server handles authentication, token refresh, and everything else
|
|
|
57
57
|
|
|
58
58
|
### First Run
|
|
59
59
|
|
|
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
|
|
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.
|
|
61
61
|
|
|
62
62
|
```
|
|
63
63
|
You: "Show me my databases"
|
|
@@ -89,16 +89,22 @@ Claude: Authenticates → fetches your orgs → selects org → lists instances
|
|
|
89
89
|
| *"Upgrade my org to the Pro plan"* | Confirms billing state, creates or changes the subscription |
|
|
90
90
|
| *"Spin up a Postgres instance on Hetzner in Helsinki"* | Confirms provider, walks through Hetzner location + server type, provisions on Hetzner Cloud |
|
|
91
91
|
| *"What cloud providers can I use?"* | Lists AWS and Hetzner with their capabilities so you can pick |
|
|
92
|
+
| *"Create a project and deploy my GitHub repo into it"* | Provisions a project, waits for it to be ready, detects the build config, and deploys the repo |
|
|
93
|
+
| *"Deploy the main branch of my-org/api"* | Creates a deployment, triggers the build, and streams build logs until it's live |
|
|
94
|
+
| *"Set DATABASE_URL on my app and redeploy"* | Updates the env var (without wiping the others) and rolls out the change |
|
|
95
|
+
| *"Add a Postgres database to my project"* | Provisions a Postgres database inside the project with the credentials you choose |
|
|
96
|
+
| *"Point app.example.com at my deployment"* | Attaches the custom domain and returns the exact DNS records to add, then verifies them |
|
|
97
|
+
| *"Roll back my app to the last working deploy"* | Re-deploys the commit from the previous successful run |
|
|
92
98
|
|
|
93
99
|
### Safety Built In
|
|
94
100
|
|
|
95
|
-
Destructive operations (delete, stop, reboot) require explicit confirmation. The server will always ask before proceeding
|
|
101
|
+
Destructive operations (delete, stop, reboot) require explicit confirmation. The server will always ask before proceeding - you'll never accidentally delete a production database.
|
|
96
102
|
|
|
97
103
|
---
|
|
98
104
|
|
|
99
105
|
## Features
|
|
100
106
|
|
|
101
|
-
###
|
|
107
|
+
### 151 tools across 22 modules
|
|
102
108
|
|
|
103
109
|
Every tool maps to a real API endpoint. No mock data, no shortcuts.
|
|
104
110
|
|
|
@@ -117,7 +123,7 @@ Automatic browser-based sign-in with Firebase. Tokens refresh transparently.
|
|
|
117
123
|
| `reauthenticate` | Sign out and sign in again (switch accounts) |
|
|
118
124
|
|
|
119
125
|
#### Organizations & Team Management
|
|
120
|
-
Multi-tenant
|
|
126
|
+
Multi-tenant - everything is scoped to your org.
|
|
121
127
|
|
|
122
128
|
| Tool | Description |
|
|
123
129
|
|------|-------------|
|
|
@@ -147,7 +153,7 @@ Bring your own AWS account (BYOC) or use SelfHost's managed infrastructure.
|
|
|
147
153
|
| `get_aws_account_info` | AWS account ID and free tier status |
|
|
148
154
|
|
|
149
155
|
#### Networking
|
|
150
|
-
VPCs, subnets, and security groups. Optional
|
|
156
|
+
VPCs, subnets, and security groups. Optional - auto-created during provisioning if not specified.
|
|
151
157
|
|
|
152
158
|
| Tool | Description |
|
|
153
159
|
|------|-------------|
|
|
@@ -237,29 +243,29 @@ PostgreSQL-only. Reduces connection overhead for high-concurrency workloads. Cli
|
|
|
237
243
|
| `disable_pgbouncer` | Drain pool and disable (with confirmation) |
|
|
238
244
|
|
|
239
245
|
#### Database Users
|
|
240
|
-
DBMS-level credentials
|
|
246
|
+
DBMS-level credentials - distinct from the SelfHost platform login. Use for apps and people that need their own DB user.
|
|
241
247
|
|
|
242
248
|
| Tool | Description |
|
|
243
249
|
|------|-------------|
|
|
244
250
|
| `list_database_users` | List users with role, status, target DB, expiry metadata |
|
|
245
251
|
| `create_database_user` | Create user with role (read_only / read_write / admin) and optional connection limit + password expiry |
|
|
246
252
|
| `update_database_user` | Change role, connection limit, or password expiry |
|
|
247
|
-
| `delete_database_user` | Soft-delete user (with confirmation)
|
|
248
|
-
| `rotate_database_user_password` | Rotate password (with confirmation)
|
|
253
|
+
| `delete_database_user` | Soft-delete user (with confirmation) - drops active connections |
|
|
254
|
+
| `rotate_database_user_password` | Rotate password (with confirmation) - new value shown once |
|
|
249
255
|
|
|
250
256
|
#### Scaling
|
|
251
257
|
Manual one-off resize plus auto-scaling policies (reactive metric-based, scheduled cron, and auto start/stop).
|
|
252
258
|
|
|
253
259
|
| Tool | Description |
|
|
254
260
|
|------|-------------|
|
|
255
|
-
| `scale_instance` | Manual resize
|
|
261
|
+
| `scale_instance` | Manual resize - change instance type, volume type, size, IOPS, throughput |
|
|
256
262
|
| `list_scaling_policies` | List policies, optionally filtered to one instance |
|
|
257
|
-
| `create_scaling_policy` | Create policy
|
|
263
|
+
| `create_scaling_policy` | Create policy - reactive metric breach, scheduled cron, or auto start/stop schedule |
|
|
258
264
|
| `update_scaling_policy` | Modify thresholds, schedule, or action details |
|
|
259
265
|
| `delete_scaling_policy` | Remove a policy (with confirmation) |
|
|
260
266
|
|
|
261
267
|
#### 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
|
|
268
|
+
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
269
|
|
|
264
270
|
| Tool | Description |
|
|
265
271
|
|------|-------------|
|
|
@@ -279,18 +285,18 @@ Subscription lifecycle and payment-method linking. All endpoints scoped to the a
|
|
|
279
285
|
| `get_subscription` | Get current subscription (404 = no subscription, on Free) |
|
|
280
286
|
| `create_subscription` | Start a paid subscription (plan goes `pending` → `active` via Razorpay webhook) |
|
|
281
287
|
| `change_subscription` | Upgrade or downgrade plan (downgrades scheduled at cycle end) |
|
|
282
|
-
| `cancel_subscription` | Cancel
|
|
283
|
-
| `link_billing_payment_method` | Initiate Razorpay link
|
|
288
|
+
| `cancel_subscription` | Cancel - keeps access until cycle end (with confirmation) |
|
|
289
|
+
| `link_billing_payment_method` | Initiate Razorpay link - returns short URL to open in browser |
|
|
284
290
|
| `update_billing_contact` | Update billing phone / tax ID / country / state for invoices |
|
|
285
291
|
|
|
286
292
|
#### Hetzner Cloud (Postgres-only)
|
|
287
|
-
Provisioning on Hetzner Cloud as an alternative to AWS. Currently provision / get / status / delete only
|
|
293
|
+
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
294
|
|
|
289
295
|
| Tool | Description |
|
|
290
296
|
|------|-------------|
|
|
291
297
|
| `list_cloud_providers` | List available cloud providers (AWS, Hetzner) with capabilities + the create tool to use for each |
|
|
292
298
|
| `list_hetzner_locations` | Hetzner datacenter locations (fsn1, nbg1, hel1, ash, sin) with country + continent |
|
|
293
|
-
| `list_hetzner_server_types` | Hetzner server types (cpx11
|
|
299
|
+
| `list_hetzner_server_types` | Hetzner server types (cpx11-cpx51) with vCPU / RAM / local disk |
|
|
294
300
|
| `create_hetzner_instance` | Provision a Postgres instance on Hetzner Cloud (region, server type, storage size, HA toggle, CIDR allowlist) |
|
|
295
301
|
| `get_hetzner_instance` | Fetch a Hetzner instance's full details by PID |
|
|
296
302
|
| `get_hetzner_instance_status` | Poll provisioning progress (per-step status: network → firewall → ssh_key → server → volume → load_balancer → ansible → finalize) |
|
|
@@ -298,6 +304,86 @@ Provisioning on Hetzner Cloud as an alternative to AWS. Currently provision / ge
|
|
|
298
304
|
|
|
299
305
|
---
|
|
300
306
|
|
|
307
|
+
### PaaS - Projects (app containers)
|
|
308
|
+
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.
|
|
309
|
+
|
|
310
|
+
| Tool | Description |
|
|
311
|
+
|------|-------------|
|
|
312
|
+
| `list_projects` | List projects in the org (pid, name, status, public_ip, domain) |
|
|
313
|
+
| `get_project` | Get one project; poll this for provisioning progress (active / failed) |
|
|
314
|
+
| `create_project` | Create a project and start async provisioning (returns status `pending`) |
|
|
315
|
+
| `update_project` | Rename / re-describe a project |
|
|
316
|
+
| `delete_project` | Tear down the server and everything in the project (with confirmation; blocked while provisioning or with running deployments) |
|
|
317
|
+
| `get_project_metrics` | Time-series server + database + deployment metrics from the monitoring agent (start_date/end_date) |
|
|
318
|
+
|
|
319
|
+
### PaaS - Deployments (GitHub apps)
|
|
320
|
+
A **deployment** is an app built from a GitHub repo, living inside an `active` project. Build/run history is returned inline on the deployment.
|
|
321
|
+
|
|
322
|
+
| Tool | Description |
|
|
323
|
+
|------|-------------|
|
|
324
|
+
| `list_deployments` | List apps in the org, each with inline build runs (newest 50) |
|
|
325
|
+
| `get_deployment` | Get one app + runs; poll this for deploy/run progress |
|
|
326
|
+
| `create_deployment` | Deploy a GitHub repo into a project (repo_url, branch, build_pack, port, env_vars, …) |
|
|
327
|
+
| `update_deployment` | Pause/resume, toggle auto-deploy, set ignore_paths / max preview deployments |
|
|
328
|
+
| `update_deployment_build_config` | Change build_pack / base_directory / port / dockerfile / env_vars |
|
|
329
|
+
| `delete_deployment` | Remove the app and its Coolify resources (with confirmation) |
|
|
330
|
+
| `trigger_deploy` | Manually deploy the current branch (new run) |
|
|
331
|
+
| `get_deployment_logs` | Current application/container logs |
|
|
332
|
+
| `get_deployment_health` | Reachability of the deploy URL + attached domains |
|
|
333
|
+
| `get_run_logs` | Full build + container logs for one run (poll until terminal) |
|
|
334
|
+
| `redeploy_run` | Re-run a build from the same commit |
|
|
335
|
+
| `rollback_run` | Re-deploy the commit from a prior successful run |
|
|
336
|
+
|
|
337
|
+
### PaaS - Custom Domains
|
|
338
|
+
| Tool | Description |
|
|
339
|
+
|------|-------------|
|
|
340
|
+
| `add_deployment_domain` | Attach a custom domain to a deployment (returns DNS records to add) |
|
|
341
|
+
| `sync_deployment_domains` | Set the full domain list for a deployment (set primary / remove several) |
|
|
342
|
+
| `remove_deployment_domain` | Remove one domain from a deployment |
|
|
343
|
+
| `verify_custom_domain` | Check DNS (TXT + CNAME) and advance verification → live HTTPS |
|
|
344
|
+
| `list_custom_domains` | List the org's custom-domain verification states |
|
|
345
|
+
|
|
346
|
+
### PaaS - Environment Variables
|
|
347
|
+
| Tool | Description |
|
|
348
|
+
|------|-------------|
|
|
349
|
+
| `list_env_vars` | List a deployment's env vars (values returned in cleartext) |
|
|
350
|
+
| `set_env_vars` | **Replace** the entire env-var set (omitted keys are deleted) |
|
|
351
|
+
| `merge_env_vars` | Add/update env vars without deleting others (safe upsert) |
|
|
352
|
+
| `delete_env_var` | Remove one variable by key |
|
|
353
|
+
|
|
354
|
+
### PaaS - GitHub
|
|
355
|
+
| Tool | Description |
|
|
356
|
+
|------|-------------|
|
|
357
|
+
| `list_github_installations` | Connected GitHub App installations + their accessible repos |
|
|
358
|
+
| `list_repo_branches` | Branches for a repo via an installation |
|
|
359
|
+
| `detect_repo_config` | Auto-detect build_pack / port / monorepo dirs / env-var hints for a repo |
|
|
360
|
+
| `get_github_connect_url` | Get a browser URL to connect GitHub (interactive; then re-list installations) |
|
|
361
|
+
|
|
362
|
+
### PaaS - Project Databases
|
|
363
|
+
Postgres/Redis/MySQL/MongoDB provisioned inside a project (distinct from AWS/Hetzner managed instances).
|
|
364
|
+
|
|
365
|
+
| Tool | Description |
|
|
366
|
+
|------|-------------|
|
|
367
|
+
| `list_project_databases` | List databases attached to a project |
|
|
368
|
+
| `create_project_database` | Provision a Postgres/Redis/MySQL/MongoDB in a project (type-specific credentials) |
|
|
369
|
+
| `delete_project_database` | Delete a project database (exact name match + confirmation) |
|
|
370
|
+
|
|
371
|
+
### PaaS - Project Services (templates)
|
|
372
|
+
| Tool | Description |
|
|
373
|
+
|------|-------------|
|
|
374
|
+
| `list_project_services` | List service-template instances (e.g. Supabase) in a project |
|
|
375
|
+
| `create_project_service` | Deploy a service template (currently `supabase`) into a project |
|
|
376
|
+
| `delete_project_service` | Delete a project service (exact name match + confirmation) |
|
|
377
|
+
|
|
378
|
+
### PaaS - Deployment Notifications
|
|
379
|
+
| Tool | Description |
|
|
380
|
+
|------|-------------|
|
|
381
|
+
| `list_deployment_notification_bindings` | Channels notified on a deployment's deploy outcomes |
|
|
382
|
+
| `bind_deployment_notification_channel` | Notify an org channel (nchan_…) on deploy success/failure |
|
|
383
|
+
| `unbind_deployment_notification_channel` | Stop notifying a channel for a deployment |
|
|
384
|
+
|
|
385
|
+
---
|
|
386
|
+
|
|
301
387
|
## Common Workflows
|
|
302
388
|
|
|
303
389
|
### Switch AWS Account (BYOC vs Platform-Managed)
|
|
@@ -370,12 +456,12 @@ Reference data lookups (regions, instance types, storage types) are unlimited.
|
|
|
370
456
|
| `API_URL` | `https://api.selfhost.dev` | SelfHost API endpoint |
|
|
371
457
|
| `CONSOLE_URL` | `https://console.selfhost.dev` | SelfHost Console URL (for browser auth) |
|
|
372
458
|
| `TIER` | Auto-detected | Override rate limit tier (`FREE`, `STARTER`, `PRO`, `ENTERPRISE`, `ADMIN`) |
|
|
373
|
-
| `FIREBASE_API_KEY` |
|
|
374
|
-
| `FIREBASE_REFRESH_TOKEN` |
|
|
459
|
+
| `FIREBASE_API_KEY` | - | Skip browser auth (CI/headless) |
|
|
460
|
+
| `FIREBASE_REFRESH_TOKEN` | - | Skip browser auth (CI/headless) |
|
|
375
461
|
|
|
376
462
|
### Local Development
|
|
377
463
|
|
|
378
|
-
Both `API_URL` and `CONSOLE_URL` are optional overrides
|
|
464
|
+
Both `API_URL` and `CONSOLE_URL` are optional overrides - they default to the production endpoints when not set.
|
|
379
465
|
|
|
380
466
|
**1. Local Rails API + Local Console**
|
|
381
467
|
|
|
@@ -452,7 +538,7 @@ Set `FIREBASE_API_KEY` and `FIREBASE_REFRESH_TOKEN` environment variables to ski
|
|
|
452
538
|
## Security
|
|
453
539
|
|
|
454
540
|
- **Credentials stored locally** at `~/.selfhost/credentials.json` with `chmod 0600` (owner-only read/write)
|
|
455
|
-
- **JWT auto-refresh**
|
|
456
|
-
- **Sensitive fields stripped**
|
|
457
|
-
- **Destructive operations gated**
|
|
458
|
-
- **No console.log**
|
|
541
|
+
- **JWT auto-refresh** - tokens refresh 5 minutes before expiry, refresh tokens are rotated
|
|
542
|
+
- **Sensitive fields stripped** - passwords, AWS keys, tokens, and secrets are redacted from API responses
|
|
543
|
+
- **Destructive operations gated** - delete, stop, and reboot require explicit `confirm: true`
|
|
544
|
+
- **No console.log** - all logging goes to stderr to avoid corrupting the MCP JSON-RPC stream on stdout
|
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
|
|
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
|
|
57
|
+
// Module 13: Billing - subscriptions + payment-method linking
|
|
50
58
|
registerBillingTools(server);
|
|
51
|
-
// Module 14: Hetzner Cloud
|
|
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
|
|
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;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { apiRequest } from "../client.js";
|
|
3
|
+
import { session } from "../session.js";
|
|
4
|
+
/**
|
|
5
|
+
* Custom domains for deployments. Two layers:
|
|
6
|
+
* - Deployment-scoped DeploymentDomain (rides on the deployment payload)
|
|
7
|
+
* - Org-scoped CustomDomainVerification (DNS ownership state, shared across deployments)
|
|
8
|
+
*
|
|
9
|
+
* Endpoints:
|
|
10
|
+
* - PATCH /api/v1/platform/github_repo_deployments/:pid/domains full-replace the domain set
|
|
11
|
+
* - POST /api/v1/platform/github_repo_deployments/:pid/domains append one domain
|
|
12
|
+
* - DELETE /api/v1/platform/github_repo_deployments/:pid/domains/:domain remove one
|
|
13
|
+
* - GET /api/v1/platform/custom_domains list org domain verifications
|
|
14
|
+
* - POST /api/v1/platform/custom_domains/:domain/verify check DNS records live
|
|
15
|
+
*
|
|
16
|
+
* Adding a domain auto-creates the org verification record and returns the DNS
|
|
17
|
+
* records (a TXT for ownership + a CNAME for routing) the user must add. A
|
|
18
|
+
* domain only goes live (and gets a cert) once `verify_custom_domain` confirms
|
|
19
|
+
* BOTH records.
|
|
20
|
+
*/
|
|
21
|
+
const DEPLOYMENTS_BASE = "/api/v1/platform/github_repo_deployments";
|
|
22
|
+
const CUSTOM_DOMAINS_BASE = "/api/v1/platform/custom_domains";
|
|
23
|
+
const NO_ORG = "No active organization. Call `list_organizations` then `select_organization` first.";
|
|
24
|
+
function hasOrg() {
|
|
25
|
+
return session.getActiveOrgId() !== null;
|
|
26
|
+
}
|
|
27
|
+
function normalizeDomain(domain) {
|
|
28
|
+
return domain.trim().toLowerCase().replace(/^https?:\/\//, "").replace(/\/.*$/, "");
|
|
29
|
+
}
|
|
30
|
+
export function registerDeploymentDomainTools(server) {
|
|
31
|
+
server.tool("sync_deployment_domains", "Set the FULL list of custom domains on a deployment (replaces any existing set - domains not included are removed). Use this to set/change the primary domain or remove several at once. For just adding one domain, prefer `add_deployment_domain`. Each domain that's new auto-creates an org verification record; the response/`get_deployment` then carries the DNS records to add. The deployment must be provisioned (422 otherwise).", {
|
|
32
|
+
deployment_pid: z.string().min(1),
|
|
33
|
+
domains: z.array(z.object({
|
|
34
|
+
domain: z.string().min(1),
|
|
35
|
+
is_primary: z.boolean().optional().describe("Mark this as the primary domain (at most one)"),
|
|
36
|
+
})).describe("The complete desired domain set; replaces the current set atomically"),
|
|
37
|
+
}, async ({ deployment_pid, domains }) => {
|
|
38
|
+
if (!hasOrg())
|
|
39
|
+
return { content: [{ type: "text", text: NO_ORG }] };
|
|
40
|
+
const normalized = domains.map((d) => ({ domain: normalizeDomain(d.domain), is_primary: d.is_primary ?? false }));
|
|
41
|
+
const result = await apiRequest(`${DEPLOYMENTS_BASE}/${deployment_pid}/domains`, {
|
|
42
|
+
method: "PATCH",
|
|
43
|
+
body: { domains: normalized },
|
|
44
|
+
toolName: "sync_deployment_domains",
|
|
45
|
+
});
|
|
46
|
+
if (!result.success) {
|
|
47
|
+
return { content: [{ type: "text", text: `Failed to sync domains (${result.statusCode}): ${result.message}` }] };
|
|
48
|
+
}
|
|
49
|
+
return {
|
|
50
|
+
content: [
|
|
51
|
+
{ type: "text", text: "Domains updated. Add the DNS records shown, then call `verify_custom_domain` for each domain. `get_deployment` shows current domain status." },
|
|
52
|
+
{ type: "text", text: JSON.stringify(result.data, null, 2) },
|
|
53
|
+
],
|
|
54
|
+
};
|
|
55
|
+
});
|
|
56
|
+
server.tool("add_deployment_domain", "Add (append) one custom domain to a deployment as its primary domain, keeping any existing domains. Auto-creates the org verification record and returns the DNS records (TXT + CNAME) to configure. After adding the records at your DNS provider, call `verify_custom_domain`. The deployment must be provisioned (422 otherwise).", {
|
|
57
|
+
deployment_pid: z.string().min(1),
|
|
58
|
+
domain: z.string().min(1).describe("e.g. app.example.com (scheme/path are stripped)"),
|
|
59
|
+
}, async ({ deployment_pid, domain }) => {
|
|
60
|
+
if (!hasOrg())
|
|
61
|
+
return { content: [{ type: "text", text: NO_ORG }] };
|
|
62
|
+
const result = await apiRequest(`${DEPLOYMENTS_BASE}/${deployment_pid}/domains`, {
|
|
63
|
+
method: "POST",
|
|
64
|
+
body: { domain: normalizeDomain(domain) },
|
|
65
|
+
toolName: "add_deployment_domain",
|
|
66
|
+
});
|
|
67
|
+
if (!result.success) {
|
|
68
|
+
return { content: [{ type: "text", text: `Failed to add domain (${result.statusCode}): ${result.message}` }] };
|
|
69
|
+
}
|
|
70
|
+
return {
|
|
71
|
+
content: [
|
|
72
|
+
{ type: "text", text: "Domain added. Configure the DNS records returned below, then call `verify_custom_domain`." },
|
|
73
|
+
{ type: "text", text: JSON.stringify(result.data, null, 2) },
|
|
74
|
+
],
|
|
75
|
+
};
|
|
76
|
+
});
|
|
77
|
+
server.tool("remove_deployment_domain", "Remove one custom domain from a deployment. The remaining domains are re-synced and primary metadata updated.", {
|
|
78
|
+
deployment_pid: z.string().min(1),
|
|
79
|
+
domain: z.string().min(1),
|
|
80
|
+
}, async ({ deployment_pid, domain }) => {
|
|
81
|
+
if (!hasOrg())
|
|
82
|
+
return { content: [{ type: "text", text: NO_ORG }] };
|
|
83
|
+
const result = await apiRequest(`${DEPLOYMENTS_BASE}/${deployment_pid}/domains/${encodeURIComponent(normalizeDomain(domain))}`, {
|
|
84
|
+
method: "DELETE",
|
|
85
|
+
toolName: "remove_deployment_domain",
|
|
86
|
+
});
|
|
87
|
+
if (!result.success) {
|
|
88
|
+
return { content: [{ type: "text", text: `Failed to remove domain (${result.statusCode}): ${result.message}` }] };
|
|
89
|
+
}
|
|
90
|
+
return {
|
|
91
|
+
content: [
|
|
92
|
+
{ type: "text", text: "Domain removed." },
|
|
93
|
+
{ type: "text", text: JSON.stringify(result.data, null, 2) },
|
|
94
|
+
],
|
|
95
|
+
};
|
|
96
|
+
});
|
|
97
|
+
server.tool("verify_custom_domain", "Check a custom domain's DNS records live and advance its verification. The domain must have been added to a deployment first. Outcomes: `verified` (both TXT + CNAME present → domain goes live with HTTPS); `ownership_verified` (TXT only - add the CNAME); `routing_configured` (CNAME only - add the TXT); or 422 `pending_verification` (neither found yet - DNS can take up to 48h). The `checks` object reports each record's status and expected value.", {
|
|
98
|
+
domain: z.string().min(1),
|
|
99
|
+
}, async ({ domain }) => {
|
|
100
|
+
if (!hasOrg())
|
|
101
|
+
return { content: [{ type: "text", text: NO_ORG }] };
|
|
102
|
+
const result = await apiRequest(`${CUSTOM_DOMAINS_BASE}/${encodeURIComponent(normalizeDomain(domain))}/verify`, {
|
|
103
|
+
method: "POST",
|
|
104
|
+
toolName: "verify_custom_domain",
|
|
105
|
+
});
|
|
106
|
+
if (!result.success) {
|
|
107
|
+
const parts = [
|
|
108
|
+
{ type: "text", text: `Domain not fully verified yet (${result.statusCode}): ${result.message}` },
|
|
109
|
+
];
|
|
110
|
+
if (result.data)
|
|
111
|
+
parts.push({ type: "text", text: JSON.stringify(result.data, null, 2) });
|
|
112
|
+
return { content: parts };
|
|
113
|
+
}
|
|
114
|
+
return { content: [{ type: "text", text: JSON.stringify(result.data, null, 2) }] };
|
|
115
|
+
});
|
|
116
|
+
server.tool("list_custom_domains", "List all custom-domain verifications for the active organization, with each domain's status (pending_verification | ownership_verified | routing_configured | verified) and when it was verified.", {}, async () => {
|
|
117
|
+
if (!hasOrg())
|
|
118
|
+
return { content: [{ type: "text", text: NO_ORG }] };
|
|
119
|
+
const result = await apiRequest(CUSTOM_DOMAINS_BASE, {
|
|
120
|
+
toolName: "list_custom_domains",
|
|
121
|
+
});
|
|
122
|
+
if (!result.success) {
|
|
123
|
+
return { content: [{ type: "text", text: `Failed to list custom domains (${result.statusCode}): ${result.message}` }] };
|
|
124
|
+
}
|
|
125
|
+
return { content: [{ type: "text", text: JSON.stringify(result.data, null, 2) }] };
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=deployment-domains.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deployment-domains.js","sourceRoot":"","sources":["../../src/tools/deployment-domains.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { apiRequest } from "../client.js";
|
|
3
|
+
import { session } from "../session.js";
|
|
4
|
+
/**
|
|
5
|
+
* Deployment notification bindings - link an existing org notification channel
|
|
6
|
+
* (the `nchan_...` channels from `list_notification_channels`) to a deployment,
|
|
7
|
+
* so it's notified on terminal deploy-run outcomes (succeeded / failed / aborted).
|
|
8
|
+
* Binding covers all terminal events; there is no per-event selection.
|
|
9
|
+
*
|
|
10
|
+
* Endpoints (base /api/v1/platform/github_repo_deployments/:pid/notifications):
|
|
11
|
+
* - GET /notifications list enabled bindings
|
|
12
|
+
* - POST /notifications bind a channel (body {notification_channel_pid})
|
|
13
|
+
* - DELETE /notifications/:channel_pid unbind a channel
|
|
14
|
+
*
|
|
15
|
+
* Note: only org OWNERS may manage these bindings. Create the channel itself via
|
|
16
|
+
* `create_notification_channel` first.
|
|
17
|
+
*/
|
|
18
|
+
const DEPLOYMENTS_BASE = "/api/v1/platform/github_repo_deployments";
|
|
19
|
+
const NO_ORG = "No active organization. Call `list_organizations` then `select_organization` first.";
|
|
20
|
+
function hasOrg() {
|
|
21
|
+
return session.getActiveOrgId() !== null;
|
|
22
|
+
}
|
|
23
|
+
export function registerDeploymentNotificationTools(server) {
|
|
24
|
+
server.tool("list_deployment_notification_bindings", "List the notification channels bound to a deployment (which channels get notified when a deploy succeeds/fails/aborts). Returns binding_pid, notification_channel_pid, channel_type, name, and bound_at.", {
|
|
25
|
+
deployment_pid: z.string().min(1),
|
|
26
|
+
}, async ({ deployment_pid }) => {
|
|
27
|
+
if (!hasOrg())
|
|
28
|
+
return { content: [{ type: "text", text: NO_ORG }] };
|
|
29
|
+
const result = await apiRequest(`${DEPLOYMENTS_BASE}/${deployment_pid}/notifications`, {
|
|
30
|
+
toolName: "list_deployment_notification_bindings",
|
|
31
|
+
});
|
|
32
|
+
if (!result.success) {
|
|
33
|
+
return { content: [{ type: "text", text: `Failed to list notification bindings (${result.statusCode}): ${result.message}` }] };
|
|
34
|
+
}
|
|
35
|
+
return { content: [{ type: "text", text: JSON.stringify(result.data, null, 2) }] };
|
|
36
|
+
});
|
|
37
|
+
server.tool("bind_deployment_notification_channel", "Bind an existing org notification channel to a deployment so it's notified on deploy outcomes. The channel pid (nchan_...) comes from `list_notification_channels` (create one with `create_notification_channel` if needed). Returns 422 if already bound, 404 if the channel doesn't exist. Org owner only.", {
|
|
38
|
+
deployment_pid: z.string().min(1),
|
|
39
|
+
notification_channel_pid: z.string().min(1).describe("Org notification channel pid, e.g. nchan_..."),
|
|
40
|
+
}, async ({ deployment_pid, notification_channel_pid }) => {
|
|
41
|
+
if (!hasOrg())
|
|
42
|
+
return { content: [{ type: "text", text: NO_ORG }] };
|
|
43
|
+
const result = await apiRequest(`${DEPLOYMENTS_BASE}/${deployment_pid}/notifications`, {
|
|
44
|
+
method: "POST",
|
|
45
|
+
body: { notification_channel_pid },
|
|
46
|
+
toolName: "bind_deployment_notification_channel",
|
|
47
|
+
});
|
|
48
|
+
if (!result.success) {
|
|
49
|
+
return { content: [{ type: "text", text: `Failed to bind notification channel (${result.statusCode}): ${result.message}` }] };
|
|
50
|
+
}
|
|
51
|
+
return {
|
|
52
|
+
content: [
|
|
53
|
+
{ type: "text", text: "Notification channel bound to deployment." },
|
|
54
|
+
{ type: "text", text: JSON.stringify(result.data, null, 2) },
|
|
55
|
+
],
|
|
56
|
+
};
|
|
57
|
+
});
|
|
58
|
+
server.tool("unbind_deployment_notification_channel", "Unbind a notification channel from a deployment (it will no longer be notified on deploy outcomes). Pass the notification_channel_pid (NOT the binding pid). Org owner only.", {
|
|
59
|
+
deployment_pid: z.string().min(1),
|
|
60
|
+
notification_channel_pid: z.string().min(1).describe("The notification channel pid (nchan_...) to unbind"),
|
|
61
|
+
}, async ({ deployment_pid, notification_channel_pid }) => {
|
|
62
|
+
if (!hasOrg())
|
|
63
|
+
return { content: [{ type: "text", text: NO_ORG }] };
|
|
64
|
+
const result = await apiRequest(`${DEPLOYMENTS_BASE}/${deployment_pid}/notifications/${notification_channel_pid}`, {
|
|
65
|
+
method: "DELETE",
|
|
66
|
+
toolName: "unbind_deployment_notification_channel",
|
|
67
|
+
});
|
|
68
|
+
if (!result.success) {
|
|
69
|
+
return { content: [{ type: "text", text: `Failed to unbind notification channel (${result.statusCode}): ${result.message}` }] };
|
|
70
|
+
}
|
|
71
|
+
return { content: [{ type: "text", text: "Notification channel unbound from deployment." }] };
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=deployment-notifications.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deployment-notifications.js","sourceRoot":"","sources":["../../src/tools/deployment-notifications.ts"],"names":[],"mappings":"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"}
|