@vibetocloud/mcp 1.0.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.
@@ -0,0 +1,417 @@
1
+ ---
2
+ name: vibetocloud-onboard
3
+ description: "Onboard an existing application to vibetocloud: authenticate, set up git remote, scaffold docker-compose.yml if needed, configure secrets, and push code."
4
+ ---
5
+
6
+ # Vibetocloud Onboard
7
+
8
+ Announce at start: "I'm using vibetocloud-onboard to set up your project on vibetocloud."
9
+
10
+ ## Prerequisites
11
+
12
+ The vibetocloud MCP server must be configured in Claude Code. If MCP tools are not available, tell the user to add the vibetocloud MCP server to their Claude Code settings first (see `skills/README.md` for setup instructions).
13
+
14
+ ---
15
+
16
+ ## Step 1 — Check existing auth
17
+
18
+ Read `.vibetocloud/config.json` using the Read tool.
19
+
20
+ - If the file exists and contains a non-empty `token` field: call `org_authenticate` with that token.
21
+ - If `org_authenticate` succeeds: skip to **Step 2**.
22
+ - If it fails (token expired): proceed to authenticate below.
23
+ - If the file does not exist or `token` is empty: proceed to authenticate below.
24
+
25
+ **Authenticate:**
26
+
27
+ Use the AskUserQuestion tool with options `["Yes", "No"]` to ask:
28
+ "Would you like to pre-approve all vibetocloud MCP tools so Claude Code stops asking for permission on every call?"
29
+
30
+ **If Yes:** Read `~/.claude/settings.json` using the Read tool. Add `"mcp__vibetocloud__*"` to the `permissions.allow` array (create the `permissions` key and `allow` array if they don't exist). Write the updated file back. Tell the user: "vibetocloud tools pre-approved. You won't be prompted again."
31
+
32
+ Use the AskUserQuestion tool with options `["Login", "Register"]` to ask:
33
+ "Do you already have a vibetocloud account, or are you signing up for the first time?"
34
+
35
+ **If Login:**
36
+
37
+ Ask the user: "What is your email address?"
38
+
39
+ Call `org_request_otp` with:
40
+ ```json
41
+ { "email": "<user email>" }
42
+ ```
43
+
44
+ If the call fails, tell the user the error and stop.
45
+
46
+ Tell the user: "A one-time code has been sent to your email. Please enter it."
47
+
48
+ Ask the user for the code, then call `org_verify_otp` with:
49
+ ```json
50
+ { "email": "<user email>", "code": "<entered code>" }
51
+ ```
52
+
53
+ If the call fails, tell the user the error and stop.
54
+
55
+ **If Register:**
56
+
57
+ Ask the user for:
58
+ - Full name
59
+ - Email address
60
+ - Organisation name
61
+
62
+ Call `org_register` with:
63
+ ```json
64
+ { "name": "<full name>", "email": "<email>", "orgName": "<org name>" }
65
+ ```
66
+
67
+ If the call fails, tell the user the error and stop.
68
+
69
+ Tell the user: "Account created! Sending a one-time code to verify your email."
70
+
71
+ Call `org_request_otp` with:
72
+ ```json
73
+ { "email": "<user email>" }
74
+ ```
75
+
76
+ If the call fails, tell the user the error and stop.
77
+
78
+ Tell the user: "A one-time code has been sent to your email. Please enter it."
79
+
80
+ Ask the user for the code, then call `org_verify_otp` with:
81
+ ```json
82
+ { "email": "<user email>", "code": "<entered code>" }
83
+ ```
84
+
85
+ If the call fails, tell the user the error and stop.
86
+
87
+ **After successful verify (both flows):**
88
+
89
+ On success the response contains `{ token, userId, orgId, userName, orgName }`.
90
+
91
+ Write `.vibetocloud/config.json` using the Write tool:
92
+ ```json
93
+ {
94
+ "token": "<token from response>",
95
+ "orgId": "<orgId from response>",
96
+ "appId": "",
97
+ "environment": "",
98
+ "remote": ""
99
+ }
100
+ ```
101
+
102
+ Add `.vibetocloud/` to `.gitignore` — read the current `.gitignore` first, then append the line if it is not already present.
103
+
104
+ Tell the user: "Welcome, <userName>! You're signed in to org <orgName>."
105
+
106
+ ---
107
+
108
+ ## Step 2 — App setup
109
+
110
+ Call `app_list` with:
111
+ ```json
112
+ { "token": "<token>", "orgId": "<orgId>" }
113
+ ```
114
+
115
+ Build an options list from the response: one option per existing app (label = app name), plus a final option `"Create new app"`.
116
+
117
+ Use the AskUserQuestion tool with those options to ask:
118
+ "Is this project already registered on vibetocloud, or should I create a new one?"
119
+
120
+ **If an existing app is selected:** save its `id` as `appId` in `.vibetocloud/config.json`.
121
+
122
+ **If "Create new app":** ask the user for a name (lowercase letters, numbers and hyphens only — suggest the current directory name lowercased with spaces replaced by hyphens). Call `app_create` with:
123
+ ```json
124
+ { "token": "<token>", "name": "<app name>", "orgId": "<orgId>" }
125
+ ```
126
+
127
+ The response contains `{ id, name, gitUrl, ... }`. Save `id` as `appId` and `gitUrl` in `.vibetocloud/config.json`.
128
+
129
+ Save `"dev"` as `environment` in `.vibetocloud/config.json`.
130
+
131
+ ---
132
+
133
+ ## Step 3 — Git remote
134
+
135
+ Run the Bash tool:
136
+ ```bash
137
+ git remote -v
138
+ ```
139
+
140
+ **Case A — no remotes:** Run:
141
+ ```bash
142
+ git remote add origin <gitUrl from config>
143
+ ```
144
+ Save `"origin"` as `remote` in `.vibetocloud/config.json`. Tell the user: "vibetocloud set as origin."
145
+
146
+ **Case B — `origin` exists pointing to an external host:**
147
+ Run:
148
+ ```bash
149
+ git remote add vibetocloud <gitUrl from config>
150
+ ```
151
+
152
+ Use the AskUserQuestion tool with options `["Yes — make vibetocloud my new origin", "No — keep my current origin"]` to ask:
153
+ "Your current origin points to an external host. Do you want to make vibetocloud your new origin? (Your current origin will be saved as `origin-backup`.)"
154
+
155
+ If **Yes**:
156
+ ```bash
157
+ git remote rename origin origin-backup
158
+ git remote rename vibetocloud origin
159
+ ```
160
+ Save `"origin"` as `remote` in `.vibetocloud/config.json`. Tell the user: "vibetocloud is now origin. Your previous origin is saved as origin-backup."
161
+
162
+ If **No**: Save `"vibetocloud"` as `remote` in `.vibetocloud/config.json`. Tell the user: "All skill pushes will target the `vibetocloud` remote explicitly."
163
+
164
+ ---
165
+
166
+ ## Step 4 — docker-compose.yml
167
+
168
+ Check whether `docker-compose.yml` or `compose.yaml` exists in the project root using the Read tool.
169
+
170
+ **If found:** tell the user "Found docker-compose.yml." Continue to Step 5.
171
+
172
+ **If not found:**
173
+
174
+ Detect project type by checking for these files in order:
175
+ 1. `package.json` → Node.js
176
+ 2. `requirements.txt` or `pyproject.toml` → Python
177
+ 3. `Dockerfile` → custom image
178
+ 4. None of the above → use the AskUserQuestion tool with options `["Node.js", "Python", "Other (Dockerfile)"]` to ask: "What runtime does your application use?"
179
+
180
+ Generate a `docker-compose.yml` appropriate for the detected type.
181
+
182
+ **Node.js template:**
183
+ ```yaml
184
+ services:
185
+ app:
186
+ build: .
187
+ ports:
188
+ - "3000:3000"
189
+ env_file:
190
+ - .env
191
+ environment:
192
+ - NODE_ENV=production
193
+ restart: unless-stopped
194
+ ```
195
+
196
+ **Python template:**
197
+ ```yaml
198
+ services:
199
+ app:
200
+ build: .
201
+ ports:
202
+ - "8000:8000"
203
+ env_file:
204
+ - .env
205
+ environment:
206
+ - PYTHONUNBUFFERED=1
207
+ restart: unless-stopped
208
+ ```
209
+
210
+ **Custom image (has Dockerfile):**
211
+ ```yaml
212
+ services:
213
+ app:
214
+ build: .
215
+ ports:
216
+ - "8080:8080"
217
+ env_file:
218
+ - .env
219
+ restart: unless-stopped
220
+ ```
221
+
222
+ Show the generated file to the user and use the AskUserQuestion tool with options `["Looks good", "I want to make changes"]` to ask: "Does this docker-compose.yml look correct?"
223
+
224
+ If **"I want to make changes"**: ask the user to describe the changes and update the file accordingly before writing.
225
+
226
+ After confirmed, write `docker-compose.yml` using the Write tool.
227
+
228
+ ---
229
+
230
+ ## Step 5 — Pre-flight check
231
+
232
+ Read `docker-compose.yml` (or `compose.yaml`) and run both checks before pushing.
233
+
234
+ > **How secrets reach your containers:** at deploy time vibetocloud writes all configured secrets to a `.env` file in your app directory. Docker Compose loads this file automatically when each service declares `env_file: - .env`. This means you do **not** need `${VAR}` references in your compose file — just add `env_file: - .env` to each service and the variables will be available at runtime.
235
+
236
+ If `docker-compose.yml` does not already have `env_file: - .env` on each service, tell the user and use the AskUserQuestion tool with options `["Yes — add it now", "No — I'll add it manually"]` to ask: "Would you like me to add `env_file: - .env` to your docker-compose.yml services now?"
237
+
238
+ If Yes, add `env_file:\n - .env` under each service in `docker-compose.yml`.
239
+
240
+ Also check `.gitignore` for a `.env` entry. If missing, append it — the `.env` file is generated at deploy time and must never be committed.
241
+
242
+ ### Check 1 — Build method
243
+
244
+ For each service, inspect the `image:` and `build:` keys.
245
+
246
+ **Supported:**
247
+ - `build: .` or `build: <path>` — builds from a local Dockerfile ✅
248
+ - `image: <public-image>` with no `${...}` references and no private registry hostname ✅ (e.g. `redis:alpine`, `postgres:15`)
249
+
250
+ **Not supported:**
251
+ - `image:` containing `${...}` — image name uses an unresolved environment variable ❌
252
+ - `image:` referencing a private registry — any URL containing `.dkr.ecr.`, `gcr.io`, `ghcr.io`, `azurecr.io`, or any hostname-style prefix ❌
253
+
254
+ If any service uses an unsupported build method, **stop** and tell the user what was found, then use the AskUserQuestion tool with options `["Yes — create a Dockerfile", "No — I'll handle it myself"]` to ask:
255
+ "vibetocloud cannot pull this image. Would you like me to create a Dockerfile so vibetocloud can build it directly?"
256
+
257
+ If Yes, help them create a suitable Dockerfile and update the service in `docker-compose.yml` to use `build: .` instead. Then re-run both checks. If No, stop — do not push until this is resolved.
258
+
259
+ ### Check 2 — Unresolved environment variables
260
+
261
+ Scan the full `docker-compose.yml` for `${VARIABLE_NAME}` patterns. Collect all unique variable names referenced.
262
+
263
+ Remove from the list:
264
+ - Variables that have an inline default in the compose file (`${VAR:-default}`)
265
+ - Common platform-provided variables: `PORT`, `NODE_ENV`, `PYTHONUNBUFFERED`, `HOST`, `TZ`
266
+
267
+ If any variables remain unaccounted for, tell the user which ones, then use the AskUserQuestion tool with options `["Yes — add them now", "No — continue anyway"]` to ask:
268
+ "These environment variables are referenced in docker-compose.yml but not configured as secrets. The application may fail to start if they are required. Would you like to add them now?"
269
+
270
+ If Yes, collect the values one at a time as `NAME=value`. For each, call `app_create_secret` with:
271
+ ```json
272
+ {
273
+ "token": "<token>",
274
+ "applicationId": "<appId>",
275
+ "environment": "<environment>",
276
+ "name": "<NAME>",
277
+ "value": "<value>"
278
+ }
279
+ ```
280
+ Note: names must be uppercase with underscores (e.g. `DATABASE_URL`). Convert lowercase automatically.
281
+ Tell the user: "⚠️ Secret values are encrypted and cannot be retrieved — make sure you have them saved elsewhere."
282
+
283
+ If No, continue with a warning.
284
+
285
+ ### Check 3 — Environment variables used in application code
286
+
287
+ Scan the source files for environment variable references using the Bash tool.
288
+
289
+ **Determine the scan command based on the detected project type:**
290
+
291
+ Node.js / TypeScript (`.js`, `.ts`, `.jsx`, `.tsx`):
292
+ ```bash
293
+ grep -rh --include="*.js" --include="*.ts" --include="*.jsx" --include="*.tsx" \
294
+ --exclude-dir=node_modules --exclude-dir=dist --exclude-dir=build --exclude-dir=.next \
295
+ --exclude-dir=coverage --exclude-dir=.git \
296
+ -oP 'process\.env\.([A-Z0-9_]+)' . | sort -u
297
+ ```
298
+
299
+ Python (`.py`):
300
+ ```bash
301
+ grep -rh --include="*.py" \
302
+ --exclude-dir=__pycache__ --exclude-dir=.venv --exclude-dir=venv --exclude-dir=.git \
303
+ -oP '(?:os\.environ(?:\.get)?\(["\x27])([A-Z0-9_a-z]+)|(?:os\.getenv\(["\x27])([A-Z0-9_a-z]+)' . \
304
+ | grep -oP '[A-Z0-9_a-z]+$' | sort -u
305
+ ```
306
+
307
+ If neither pattern yields results, skip this check.
308
+
309
+ **Also check for dynamic references** (values that cannot be extracted):
310
+
311
+ ```bash
312
+ grep -rn --include="*.js" --include="*.ts" --include="*.jsx" --include="*.tsx" \
313
+ --exclude-dir=node_modules --exclude-dir=dist --exclude-dir=build \
314
+ 'process\.env\[' .
315
+ ```
316
+
317
+ If any dynamic references are found, warn the user:
318
+ > "⚠️ Your code contains dynamic environment variable references (e.g. `process.env[someVar]`) in the files listed above. These cannot be checked automatically — make sure any variables accessed this way are configured as secrets."
319
+
320
+ **Build the list of variables found in code**, then remove:
321
+ - Variables already added as secrets during Check 2
322
+ - Variables with inline defaults in docker-compose (`${VAR:-default}`)
323
+ - Common platform-provided variables: `PORT`, `NODE_ENV`, `PYTHONUNBUFFERED`, `HOST`, `TZ`, `PATH`, `HOME`, `USER`
324
+
325
+ If any variables remain, tell the user which ones were found and in which files (re-run grep without `-h` to get filenames), then use the AskUserQuestion tool with options `["Yes — add them now", "No — continue anyway"]` to ask:
326
+ "These environment variables are used in your application code but not configured as secrets. Would you like to add them now?"
327
+
328
+ If Yes, collect the values one at a time as `NAME=value` and call `app_create_secret` for each (same call as in Check 2 above). Tell the user: "⚠️ Secret values are encrypted and cannot be retrieved — make sure you have them saved elsewhere." If No, continue with a warning.
329
+
330
+ ### Check 4 — NODE_ENV for Node.js apps
331
+
332
+ If the project has a `package.json`, scan `docker-compose.yml` for `NODE_ENV=production`:
333
+
334
+ ```bash
335
+ grep "NODE_ENV" docker-compose.yml 2>/dev/null || true
336
+ ```
337
+
338
+ If `NODE_ENV=production` is not present in any service's `environment:` block, warn the user:
339
+
340
+ > "⚠️ `NODE_ENV=production` is not set in your docker-compose.yml. Node.js apps often disable static file serving, enable production error handling, and trust proxies only when this variable is set. Without it your app may fail the health check or behave unexpectedly in production."
341
+
342
+ Use the AskUserQuestion tool with options `["Yes — add it now", "No — I'll add it manually"]` to ask: "Would you like me to add `NODE_ENV=production` to your main app service?"
343
+
344
+ If Yes, add `NODE_ENV=production` under the `environment:` key of the first service that has a `build:` directive in `docker-compose.yml`. If no `environment:` key exists on that service, add one.
345
+
346
+ ---
347
+
348
+ ### Check 5 — .dockerignore audit
349
+
350
+ Check whether `.dockerignore` exists using the Read tool. If it does not exist, skip this check.
351
+
352
+ If it exists, read it and flag any line that would exclude a file critical to the build. Dangerous patterns include:
353
+ - `package.json`, `**/package.json`, or `*.json` globs at any path level
354
+ - `package-lock.json`, `yarn.lock`, `pnpm-lock.yaml`
355
+ - `requirements.txt`, `pyproject.toml`
356
+ - `Dockerfile`
357
+
358
+ For each flagged line, explain the risk. For example: "`client/*.json` would exclude `client/package.json` from the build context, causing any `COPY client/package.json` instruction in your Dockerfile to fail."
359
+
360
+ Use the AskUserQuestion tool with options `["Yes — remove flagged lines", "No — I know what I'm doing"]` to ask: "These .dockerignore patterns may exclude files needed during the Docker build. Would you like me to remove them?"
361
+
362
+ If Yes, remove the flagged lines from `.dockerignore` and write the file back using the Write tool.
363
+
364
+ ---
365
+
366
+ If all checks pass with no issues, tell the user: "✅ Pre-flight check passed — build method is supported, environment variables are accounted for, and your Docker configuration looks clean."
367
+
368
+ ---
369
+
370
+ ## Step 6 — First push
371
+
372
+ Stage and commit any newly created files:
373
+ ```bash
374
+ git add -A
375
+ git status
376
+ ```
377
+
378
+ If there are uncommitted changes, run:
379
+ ```bash
380
+ git commit -m "chore: add vibetocloud configuration"
381
+ ```
382
+
383
+ Get the current branch:
384
+ ```bash
385
+ git rev-parse --abbrev-ref HEAD
386
+ ```
387
+
388
+ **If the current branch is not `main` or `master`:**
389
+
390
+ Use the AskUserQuestion tool with options `["Yes — merge into main", "No — push this branch as-is"]` to ask:
391
+ "You're on branch `<branch>`. vibetocloud deploys from `main`. Would you like to merge this branch into `main` now?"
392
+
393
+ **If Yes:**
394
+ ```bash
395
+ git checkout main
396
+ git pull <remote from config> main --no-edit
397
+ git merge <feature branch> --no-edit
398
+ git push <remote from config> main
399
+ ```
400
+
401
+ If any of these fail, show the error and ask the user to resolve it manually before continuing.
402
+
403
+ Tell the user: "Branch merged. Deploying from `main`."
404
+
405
+ **If No:** warn the user: "⚠️ You are pushing branch `<branch>` — remember to merge it into `main` before deploying, or deploy will target this branch."
406
+
407
+ Push to the platform:
408
+ ```bash
409
+ git push <remote from config> HEAD:<current branch>
410
+ ```
411
+
412
+ If the push fails due to no upstream tracking branch, run:
413
+ ```bash
414
+ git push --set-upstream <remote from config> <current branch>
415
+ ```
416
+
417
+ Tell the user: "✅ Your code is on vibetocloud. Run `/vibetocloud-deploy` to trigger your first deployment."
@@ -0,0 +1,51 @@
1
+ ---
2
+ name: vibetocloud-platform-logs
3
+ description: Access platform-level logs for the VibeToCloud platform itself (not a deployed app). Use when debugging the vibetocloud.io host, investigating platform-wide issues, or when the user mentions Grafana, the logging server, or needing an SSH tunnel to inspect logs.
4
+ ---
5
+
6
+ # VibeToCloud Platform Logs
7
+
8
+ Announce at start: "I'm using vibetocloud-platform-logs to access the platform Grafana logs."
9
+
10
+ This skill is for debugging the **VibeToCloud platform itself** (the `vibetocloud.io` host).
11
+ For debugging a *deployed application's* services, use `vibetocloud-debug` instead.
12
+
13
+ ---
14
+
15
+ ## Step 1 — Open the SSH tunnel
16
+
17
+ Grafana runs on the `vibetocloud.io` host on port `3010` and is not exposed publicly.
18
+ Open a local tunnel that forwards local port `3110` to it:
19
+
20
+ ```bash
21
+ ssh -L 3110:localhost:3010 ubuntu@vibetocloud.io -fN
22
+ ```
23
+
24
+ Notes:
25
+ - `-fN` runs the tunnel in the background without opening a shell, so the command returns immediately.
26
+ - If the command fails with "Address already in use", a tunnel is likely already open — proceed to Step 2.
27
+ - This requires SSH access to `vibetocloud.io` as the `ubuntu` user.
28
+
29
+ ---
30
+
31
+ ## Step 2 — Open Grafana
32
+
33
+ Once the tunnel is up, Grafana is reachable at:
34
+
35
+ **http://localhost:3110/**
36
+
37
+ Credentials:
38
+ - Username: `admin`
39
+ - Password: `change-me`
40
+
41
+ Use the Explore / Logs views in Grafana to inspect platform logs.
42
+
43
+ ---
44
+
45
+ ## Step 3 — Close the tunnel (when done)
46
+
47
+ The tunnel runs in the background. To close it when finished:
48
+
49
+ ```bash
50
+ pkill -f "ssh -L 3110:localhost:3010"
51
+ ```