vibekit-mcp 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 (3) hide show
  1. package/README.md +82 -64
  2. package/dist/index.js +532 -185
  3. package/package.json +36 -10
package/README.md CHANGED
@@ -1,101 +1,119 @@
1
1
  # vibekit-mcp
2
2
 
3
- MCP server for [VibeKit](https://vibekit.bot)manage AI-powered apps as native tools in Claude Desktop, Cursor, Windsurf, and any MCP-compatible client.
3
+ MCP server for VibeKit — deploy apps, manage hosting, and chat with AI agents from any MCP client.
4
4
 
5
- ## Setup
6
-
7
- ### Claude Desktop
8
-
9
- Add to your `claude_desktop_config.json`:
5
+ ## Installation
10
6
 
11
- ```json
12
- {
13
- "mcpServers": {
14
- "vibekit": {
15
- "command": "npx",
16
- "args": ["-y", "vibekit-mcp"],
17
- "env": {
18
- "VIBEKIT_API_KEY": "vk_your_key_here"
19
- }
20
- }
21
- }
22
- }
7
+ ```bash
8
+ npm install -g vibekit-mcp
23
9
  ```
24
10
 
25
- ### Cursor
11
+ ## Setup
12
+
13
+ 1. Get a VibeKit API key:
14
+ - Open [@the_vibe_kit_bot](https://t.me/the_vibe_kit_bot) in Telegram
15
+ - Send `/apikey` to generate your key
26
16
 
27
- Add to `.cursor/mcp.json` in your project:
17
+ 2. Add to your MCP client config (e.g. Claude Desktop) (`~/Library/Application Support/Claude/claude_desktop_config.json` on macOS):
28
18
 
29
19
  ```json
30
20
  {
31
21
  "mcpServers": {
32
22
  "vibekit": {
33
- "command": "npx",
34
- "args": ["-y", "vibekit-mcp"],
23
+ "command": "vibekit-mcp",
35
24
  "env": {
36
- "VIBEKIT_API_KEY": "vk_your_key_here"
25
+ "VIBEKIT_API_KEY": "vk_your_api_key_here"
37
26
  }
38
27
  }
39
28
  }
40
29
  }
41
30
  ```
42
31
 
43
- Get your API key at [app.vibekit.bot/settings](https://app.vibekit.bot/settings).
32
+ 3. Restart your MCP client
44
33
 
45
34
  ## Available Tools
46
35
 
47
- ### Apps
48
- - `vibekit_list_apps` — List all your hosted apps
49
- - `vibekit_app_info` Get app details
50
- - `vibekit_start` / `vibekit_stop` / `vibekit_restart` — Container control
36
+ ### Hosting
37
+
38
+ | Tool | Description |
39
+ |------|-------------|
40
+ | `vibekit_list_apps` | List all hosted apps |
41
+ | `vibekit_get_app` | Get details about a specific app |
42
+ | `vibekit_create_app` | Create new app from template |
43
+ | `vibekit_deploy` | Deploy GitHub repo to hosting |
44
+ | `vibekit_redeploy` | Redeploy app with latest code |
45
+ | `vibekit_app_logs` | Get application logs |
46
+ | `vibekit_restart_app` | Restart an app |
47
+ | `vibekit_stop_app` | Stop an app |
48
+ | `vibekit_start_app` | Start a stopped app |
49
+ | `vibekit_app_env` | Get app environment variables |
50
+ | `vibekit_set_env` | Set app environment variables |
51
+ | `vibekit_delete_app` | Delete an app permanently |
52
+
53
+ ### Agent
54
+
55
+ | Tool | Description |
56
+ |------|-------------|
57
+ | `vibekit_chat` | Chat with an app's AI agent |
58
+ | `vibekit_agent_status` | Get agent status |
59
+ | `vibekit_agent_history` | Get chat history with agent |
51
60
 
52
- ### AI Agent
53
- - `vibekit_chat` — Send a message to your app's AI agent
54
- - `vibekit_agent_status` — Agent status and model info
61
+ ### Database
55
62
 
56
- ### Deploy
57
- - `vibekit_deploy` — Trigger redeploy
58
- - `vibekit_deploys` Deploy history
59
- - `vibekit_rollback` Rollback to previous deploy
63
+ | Tool | Description |
64
+ |------|-------------|
65
+ | `vibekit_enable_database` | Enable database for an app |
66
+ | `vibekit_database_status` | Get database status and connection info |
60
67
 
61
- ### Logs & Files
62
- - `vibekit_logs` — View app logs
63
- - `vibekit_files` — Browse workspace files
68
+ ### QA
64
69
 
65
- ### Environment
66
- - `vibekit_env_list` / `vibekit_env_set` / `vibekit_env_delete` — Manage env vars
70
+ | Tool | Description |
71
+ |------|-------------|
72
+ | `vibekit_run_qa` | Run automated QA tests |
73
+ | `vibekit_qa_status` | Get QA test results |
67
74
 
68
- ### Database
69
- - `vibekit_db_status` — Database stats
70
- - `vibekit_db_schema` — Tables, columns, types
71
- - `vibekit_db_query` — Run read-only SQL
72
- - `vibekit_db_table` — Browse table data
75
+ ### Tasks
73
76
 
74
- ### Domain & QA
75
- - `vibekit_set_domain` — Set custom domain
76
- - `vibekit_qa` Run QA audit
77
+ | Tool | Description |
78
+ |------|-------------|
79
+ | `vibekit_submit_task` | Submit a coding task |
80
+ | `vibekit_get_task` | Get task status/result |
81
+ | `vibekit_list_tasks` | List recent tasks |
82
+ | `vibekit_wait_for_task` | Wait for task completion |
83
+ | `vibekit_create_schedule` | Create recurring scheduled task |
84
+ | `vibekit_list_schedules` | List scheduled tasks |
85
+ | `vibekit_delete_schedule` | Delete scheduled task |
77
86
 
78
- ### Tasks
79
- - `vibekit_submit_task` — Submit a headless coding task
80
- - `vibekit_task_status` Check task status
81
- - `vibekit_account` — Plan, balance, usage
87
+ ### Account
88
+
89
+ | Tool | Description |
90
+ |------|-------------|
91
+ | `vibekit_account` | Get account info (plan, credits, usage) |
92
+ | `vibekit_list_skills` | List implementation skills |
93
+ | `vibekit_get_skill` | Fetch specific skill content |
82
94
 
83
95
  ## Example Usage
84
96
 
85
- Once connected, you can say things like:
97
+ Once configured, you can use prompts like:
86
98
 
87
- - "List my VibeKit apps"
88
- - "Show me the logs for my surf app"
89
- - "Tell my agent to add a dark mode toggle"
90
- - "Run a SQL query on my database"
91
- - "Deploy my app"
99
+ - "Deploy my GitHub repo to VibeKit and create a new app"
100
+ - "Chat with the AI agent for my app about adding a contact form"
101
+ - "Show me the logs for my app and restart it if there are errors"
102
+ - "Enable a database for my app and check its status"
103
+ - "Run QA tests on my deployed app"
104
+ - "Check my VibeKit account balance and list my apps"
105
+ - "Create a weekly schedule to improve my app's performance"
92
106
 
93
- ## Links
107
+ ## Environment Variables
94
108
 
95
- - Website: https://vibekit.bot
96
- - Dashboard: https://app.vibekit.bot
97
- - CLI: https://www.npmjs.com/package/vibekit-cli
109
+ | Variable | Description | Default |
110
+ |----------|-------------|---------|
111
+ | `VIBEKIT_API_KEY` | Your VibeKit API key (required) | — |
112
+ | `VIBEKIT_API_URL` | API base URL | `https://vibekit.bot/api/v1` |
98
113
 
99
- ## License
114
+ ## Links
100
115
 
101
- MIT
116
+ - [VibeKit Website](https://vibekit.bot)
117
+ - [API Documentation](https://vibekit.bot/SKILL.md)
118
+ - [Get API Key](https://t.me/the_vibe_kit_bot)
119
+ - [GitHub](https://github.com/609NFT/vibekit)
package/dist/index.js CHANGED
@@ -6,381 +6,728 @@ const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
6
6
  const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
7
7
  const API_BASE = process.env.VIBEKIT_API_URL || "https://vibekit.bot/api/v1";
8
8
  const API_KEY = process.env.VIBEKIT_API_KEY || "";
9
+ const SKILLS_REGISTRY = "https://raw.githubusercontent.com/vibekit-apps/skills-registry/main";
10
+ // Skills cache (TTL: 5 minutes)
11
+ let skillsCache = null;
12
+ const CACHE_TTL = 5 * 60 * 1000;
9
13
  if (!API_KEY) {
10
- console.error("VIBEKIT_API_KEY is required. Get one at https://app.vibekit.bot/settings");
14
+ console.error("Error: VIBEKIT_API_KEY environment variable is required");
15
+ console.error("Get one at https://t.me/the_vibe_kit_bot with /apikey command");
11
16
  process.exit(1);
12
17
  }
13
- // ── API Helper ──────────────────────────────────────────────────────────────
14
- async function api(method, path, body) {
18
+ // API helper
19
+ async function apiRequest(method, path, body) {
15
20
  try {
16
21
  const res = await fetch(`${API_BASE}${path}`, {
17
22
  method,
18
- headers: { Authorization: `Bearer ${API_KEY}`, "Content-Type": "application/json" },
23
+ headers: {
24
+ "Authorization": `Bearer ${API_KEY}`,
25
+ "Content-Type": "application/json",
26
+ },
19
27
  body: body ? JSON.stringify(body) : undefined,
20
28
  });
21
- if (res.status === 204)
22
- return { ok: true, data: {} };
23
29
  const data = await res.json();
24
- if (!res.ok)
30
+ if (!res.ok) {
25
31
  return { ok: false, error: data.error || `HTTP ${res.status}` };
32
+ }
26
33
  return { ok: true, data };
27
34
  }
28
35
  catch (err) {
29
- return { ok: false, error: err.message || "Request failed" };
36
+ return { ok: false, error: err instanceof Error ? err.message : "Unknown error" };
30
37
  }
31
38
  }
32
- // ── Tool Definitions ────────────────────────────────────────────────────────
39
+ // Tool definitions
33
40
  const tools = [
34
- // Account
41
+ // Hosting & Apps
35
42
  {
36
- name: "vibekit_account",
37
- description: "Get account info: plan, balance, session usage.",
38
- inputSchema: { type: "object", properties: {} },
43
+ name: "vibekit_list_apps",
44
+ description: "List all hosted apps in your VibeKit account.",
45
+ inputSchema: {
46
+ type: "object",
47
+ properties: {},
48
+ },
39
49
  },
40
- // Apps
41
50
  {
42
- name: "vibekit_list_apps",
43
- description: "List all your hosted apps with status and URLs.",
44
- inputSchema: { type: "object", properties: {} },
51
+ name: "vibekit_get_app",
52
+ description: "Get details about a specific hosted app.",
53
+ inputSchema: {
54
+ type: "object",
55
+ properties: {
56
+ appId: {
57
+ type: "string",
58
+ description: "The app ID to get details for",
59
+ },
60
+ },
61
+ required: ["appId"],
62
+ },
45
63
  },
46
64
  {
47
- name: "vibekit_app_info",
48
- description: "Get details about a specific app.",
65
+ name: "vibekit_create_app",
66
+ description: "Create a new hosted app from a template.",
49
67
  inputSchema: {
50
68
  type: "object",
51
- properties: { slug: { type: "string", description: "App subdomain slug or full UUID" } },
52
- required: ["slug"],
69
+ properties: {
70
+ template: {
71
+ type: "string",
72
+ description: "Template to use (e.g., 'nextjs', 'react', 'express')",
73
+ },
74
+ subdomain: {
75
+ type: "string",
76
+ description: "Subdomain for the app (will be deployed to {subdomain}.vibekit.bot)",
77
+ },
78
+ },
79
+ required: ["template", "subdomain"],
53
80
  },
54
81
  },
55
- // Agent Chat
56
82
  {
57
- name: "vibekit_chat",
58
- description: "Send a message to an app's AI agent. The agent can modify code, deploy, fix bugs, add features.",
83
+ name: "vibekit_deploy",
84
+ description: "Deploy a GitHub repo to VibeKit hosting.",
59
85
  inputSchema: {
60
86
  type: "object",
61
87
  properties: {
62
- slug: { type: "string", description: "App subdomain slug" },
63
- message: { type: "string", description: "Message for the AI agent" },
88
+ repo: {
89
+ type: "string",
90
+ description: "GitHub repo in format 'owner/repo'",
91
+ },
92
+ subdomain: {
93
+ type: "string",
94
+ description: "Subdomain for the app (will be deployed to {subdomain}.vibekit.bot)",
95
+ },
64
96
  },
65
- required: ["slug", "message"],
97
+ required: ["repo", "subdomain"],
66
98
  },
67
99
  },
68
100
  {
69
- name: "vibekit_agent_status",
70
- description: "Get the AI agent's status and model info for an app.",
101
+ name: "vibekit_redeploy",
102
+ description: "Redeploy an existing hosted app to update it with latest code.",
71
103
  inputSchema: {
72
104
  type: "object",
73
- properties: { slug: { type: "string", description: "App subdomain slug" } },
74
- required: ["slug"],
105
+ properties: {
106
+ appId: {
107
+ type: "string",
108
+ description: "The app ID to redeploy",
109
+ },
110
+ },
111
+ required: ["appId"],
75
112
  },
76
113
  },
77
- // Deploy
78
114
  {
79
- name: "vibekit_deploy",
80
- description: "Trigger a redeploy for an app.",
115
+ name: "vibekit_app_logs",
116
+ description: "Get application logs for debugging and monitoring.",
81
117
  inputSchema: {
82
118
  type: "object",
83
- properties: { slug: { type: "string", description: "App subdomain slug" } },
84
- required: ["slug"],
119
+ properties: {
120
+ appId: {
121
+ type: "string",
122
+ description: "The app ID to get logs for",
123
+ },
124
+ lines: {
125
+ type: "number",
126
+ description: "Number of log lines to retrieve (default: 100)",
127
+ },
128
+ },
129
+ required: ["appId"],
85
130
  },
86
131
  },
87
132
  {
88
- name: "vibekit_deploys",
89
- description: "List deploy history for an app.",
133
+ name: "vibekit_restart_app",
134
+ description: "Restart a hosted app.",
90
135
  inputSchema: {
91
136
  type: "object",
92
- properties: { slug: { type: "string", description: "App subdomain slug" } },
93
- required: ["slug"],
137
+ properties: {
138
+ appId: {
139
+ type: "string",
140
+ description: "The app ID to restart",
141
+ },
142
+ },
143
+ required: ["appId"],
94
144
  },
95
145
  },
96
146
  {
97
- name: "vibekit_rollback",
98
- description: "Rollback an app to a previous deploy.",
147
+ name: "vibekit_stop_app",
148
+ description: "Stop a hosted app.",
99
149
  inputSchema: {
100
150
  type: "object",
101
151
  properties: {
102
- slug: { type: "string", description: "App subdomain slug" },
103
- deployId: { type: "string", description: "Deploy ID to rollback to" },
152
+ appId: {
153
+ type: "string",
154
+ description: "The app ID to stop",
155
+ },
104
156
  },
105
- required: ["slug", "deployId"],
157
+ required: ["appId"],
106
158
  },
107
159
  },
108
- // Logs
109
160
  {
110
- name: "vibekit_logs",
111
- description: "Get recent logs for an app.",
161
+ name: "vibekit_start_app",
162
+ description: "Start a stopped hosted app.",
112
163
  inputSchema: {
113
164
  type: "object",
114
165
  properties: {
115
- slug: { type: "string", description: "App subdomain slug" },
116
- lines: { type: "number", description: "Number of lines (default 50)" },
166
+ appId: {
167
+ type: "string",
168
+ description: "The app ID to start",
169
+ },
117
170
  },
118
- required: ["slug"],
171
+ required: ["appId"],
119
172
  },
120
173
  },
121
- // Container control
122
174
  {
123
- name: "vibekit_start",
124
- description: "Start an app's container.",
175
+ name: "vibekit_app_env",
176
+ description: "Get environment variables for a hosted app.",
125
177
  inputSchema: {
126
178
  type: "object",
127
- properties: { slug: { type: "string", description: "App subdomain slug" } },
128
- required: ["slug"],
179
+ properties: {
180
+ appId: {
181
+ type: "string",
182
+ description: "The app ID to get environment variables for",
183
+ },
184
+ },
185
+ required: ["appId"],
129
186
  },
130
187
  },
131
188
  {
132
- name: "vibekit_stop",
133
- description: "Stop an app's container.",
189
+ name: "vibekit_set_env",
190
+ description: "Set environment variables for a hosted app.",
134
191
  inputSchema: {
135
192
  type: "object",
136
- properties: { slug: { type: "string", description: "App subdomain slug" } },
137
- required: ["slug"],
193
+ properties: {
194
+ appId: {
195
+ type: "string",
196
+ description: "The app ID to set environment variables for",
197
+ },
198
+ vars: {
199
+ type: "object",
200
+ description: "Object of key-value pairs to set as environment variables",
201
+ },
202
+ },
203
+ required: ["appId", "vars"],
138
204
  },
139
205
  },
140
206
  {
141
- name: "vibekit_restart",
142
- description: "Restart an app's container.",
207
+ name: "vibekit_delete_app",
208
+ description: "Delete a hosted app permanently.",
143
209
  inputSchema: {
144
210
  type: "object",
145
- properties: { slug: { type: "string", description: "App subdomain slug" } },
146
- required: ["slug"],
211
+ properties: {
212
+ appId: {
213
+ type: "string",
214
+ description: "The app ID to delete",
215
+ },
216
+ },
217
+ required: ["appId"],
147
218
  },
148
219
  },
149
- // Env vars
220
+ // AI Agent
150
221
  {
151
- name: "vibekit_env_list",
152
- description: "List environment variables for an app.",
222
+ name: "vibekit_chat",
223
+ description: "Chat with an app's AI agent. The agent can read, write, and modify the app's code.",
153
224
  inputSchema: {
154
225
  type: "object",
155
226
  properties: {
156
- slug: { type: "string", description: "App subdomain slug" },
157
- reveal: { type: "boolean", description: "Show real values instead of masked" },
227
+ appId: {
228
+ type: "string",
229
+ description: "The app ID to chat with the agent for",
230
+ },
231
+ message: {
232
+ type: "string",
233
+ description: "Message to send to the AI agent",
234
+ },
158
235
  },
159
- required: ["slug"],
236
+ required: ["appId", "message"],
160
237
  },
161
238
  },
162
239
  {
163
- name: "vibekit_env_set",
164
- description: "Set an environment variable.",
240
+ name: "vibekit_agent_status",
241
+ description: "Get the status of an app's AI agent.",
165
242
  inputSchema: {
166
243
  type: "object",
167
244
  properties: {
168
- slug: { type: "string", description: "App subdomain slug" },
169
- key: { type: "string", description: "Variable name" },
170
- value: { type: "string", description: "Variable value" },
245
+ appId: {
246
+ type: "string",
247
+ description: "The app ID to get agent status for",
248
+ },
171
249
  },
172
- required: ["slug", "key", "value"],
250
+ required: ["appId"],
173
251
  },
174
252
  },
175
253
  {
176
- name: "vibekit_env_delete",
177
- description: "Delete an environment variable.",
254
+ name: "vibekit_agent_history",
255
+ description: "Get chat history with an app's AI agent.",
178
256
  inputSchema: {
179
257
  type: "object",
180
258
  properties: {
181
- slug: { type: "string", description: "App subdomain slug" },
182
- key: { type: "string", description: "Variable name to delete" },
259
+ appId: {
260
+ type: "string",
261
+ description: "The app ID to get agent history for",
262
+ },
263
+ limit: {
264
+ type: "number",
265
+ description: "Maximum number of messages to return (default: 20)",
266
+ },
183
267
  },
184
- required: ["slug", "key"],
268
+ required: ["appId"],
185
269
  },
186
270
  },
187
271
  // Database
188
272
  {
189
- name: "vibekit_db_status",
190
- description: "Get database status for an app (tables, size, connections).",
273
+ name: "vibekit_enable_database",
274
+ description: "Enable database for a hosted app.",
191
275
  inputSchema: {
192
276
  type: "object",
193
- properties: { slug: { type: "string", description: "App subdomain slug" } },
194
- required: ["slug"],
277
+ properties: {
278
+ appId: {
279
+ type: "string",
280
+ description: "The app ID to enable database for",
281
+ },
282
+ },
283
+ required: ["appId"],
195
284
  },
196
285
  },
197
286
  {
198
- name: "vibekit_db_schema",
199
- description: "Get database schema tables, columns, types, foreign keys.",
287
+ name: "vibekit_database_status",
288
+ description: "Get database status and connection info for an app.",
200
289
  inputSchema: {
201
290
  type: "object",
202
- properties: { slug: { type: "string", description: "App subdomain slug" } },
203
- required: ["slug"],
291
+ properties: {
292
+ appId: {
293
+ type: "string",
294
+ description: "The app ID to get database status for",
295
+ },
296
+ },
297
+ required: ["appId"],
204
298
  },
205
299
  },
300
+ // QA
206
301
  {
207
- name: "vibekit_db_query",
208
- description: "Run a read-only SQL query against an app's database.",
302
+ name: "vibekit_run_qa",
303
+ description: "Run automated QA tests on a hosted app.",
209
304
  inputSchema: {
210
305
  type: "object",
211
306
  properties: {
212
- slug: { type: "string", description: "App subdomain slug" },
213
- sql: { type: "string", description: "SQL query (SELECT only)" },
307
+ appId: {
308
+ type: "string",
309
+ description: "The app ID to run QA tests for",
310
+ },
214
311
  },
215
- required: ["slug", "sql"],
312
+ required: ["appId"],
216
313
  },
217
314
  },
218
315
  {
219
- name: "vibekit_db_table",
220
- description: "Browse data in a specific table.",
316
+ name: "vibekit_qa_status",
317
+ description: "Get QA test results and status for an app.",
221
318
  inputSchema: {
222
319
  type: "object",
223
320
  properties: {
224
- slug: { type: "string", description: "App subdomain slug" },
225
- table: { type: "string", description: "Table name" },
226
- limit: { type: "number", description: "Max rows (default 20)" },
321
+ appId: {
322
+ type: "string",
323
+ description: "The app ID to get QA status for",
324
+ },
227
325
  },
228
- required: ["slug", "table"],
326
+ required: ["appId"],
229
327
  },
230
328
  },
231
- // Files
329
+ // Tasks (existing)
232
330
  {
233
- name: "vibekit_files",
234
- description: "Browse workspace files for an app.",
331
+ name: "vibekit_submit_task",
332
+ description: "Submit a coding task to VibeKit. The AI will write code, commit to GitHub, and deploy to {subdomain}.vibekit.bot. Returns a task ID to poll for results.",
235
333
  inputSchema: {
236
334
  type: "object",
237
335
  properties: {
238
- slug: { type: "string", description: "App subdomain slug" },
239
- path: { type: "string", description: "Directory path (default: root)" },
336
+ task: {
337
+ type: "string",
338
+ description: "What you want built or changed. Be specific about features, design, and behavior.",
339
+ },
340
+ repo: {
341
+ type: "string",
342
+ description: "GitHub repo in format 'owner/repo'. Optional — will use user's current repo if not specified.",
343
+ },
344
+ branch: {
345
+ type: "string",
346
+ description: "Git branch to work on. Default: main",
347
+ },
348
+ deploy: {
349
+ type: "boolean",
350
+ description: "Auto-deploy to Vercel when done. Default: true",
351
+ },
352
+ callbackUrl: {
353
+ type: "string",
354
+ description: "Webhook URL to receive task completion notification.",
355
+ },
240
356
  },
241
- required: ["slug"],
357
+ required: ["task"],
242
358
  },
243
359
  },
244
- // QA
245
360
  {
246
- name: "vibekit_qa",
247
- description: "Run a QA audit on an app checks for bugs, accessibility, performance issues.",
361
+ name: "vibekit_get_task",
362
+ description: "Get the status and result of a previously submitted task.",
248
363
  inputSchema: {
249
364
  type: "object",
250
- properties: { slug: { type: "string", description: "App subdomain slug" } },
251
- required: ["slug"],
365
+ properties: {
366
+ taskId: {
367
+ type: "string",
368
+ description: "The task ID returned from vibekit_submit_task",
369
+ },
370
+ },
371
+ required: ["taskId"],
252
372
  },
253
373
  },
254
- // Domain
255
374
  {
256
- name: "vibekit_set_domain",
257
- description: "Set a custom domain for an app.",
375
+ name: "vibekit_list_tasks",
376
+ description: "List recent tasks submitted to VibeKit.",
258
377
  inputSchema: {
259
378
  type: "object",
260
379
  properties: {
261
- slug: { type: "string", description: "App subdomain slug" },
262
- domain: { type: "string", description: "Custom domain (e.g. myapp.com)" },
380
+ limit: {
381
+ type: "number",
382
+ description: "Max number of tasks to return. Default: 10",
383
+ },
384
+ status: {
385
+ type: "string",
386
+ enum: ["pending", "running", "completed", "failed"],
387
+ description: "Filter by status",
388
+ },
263
389
  },
264
- required: ["slug", "domain"],
265
390
  },
266
391
  },
267
- // Tasks (headless API)
268
392
  {
269
- name: "vibekit_submit_task",
270
- description: "Submit a coding task. An AI agent will build code and deploy it.",
393
+ name: "vibekit_wait_for_task",
394
+ description: "Wait for a task to complete and return the result. Polls every 5 seconds up to the timeout.",
271
395
  inputSchema: {
272
396
  type: "object",
273
397
  properties: {
274
- task: { type: "string", description: "What to build or change" },
275
- repo: { type: "string", description: "GitHub repo (owner/repo)" },
276
- branch: { type: "string", description: "Branch (default: main)" },
398
+ taskId: {
399
+ type: "string",
400
+ description: "The task ID to wait for",
401
+ },
402
+ timeoutSeconds: {
403
+ type: "number",
404
+ description: "Max seconds to wait. Default: 300 (5 minutes)",
405
+ },
277
406
  },
278
- required: ["task"],
407
+ required: ["taskId"],
279
408
  },
280
409
  },
281
410
  {
282
- name: "vibekit_task_status",
283
- description: "Check status of a submitted task.",
411
+ name: "vibekit_create_schedule",
412
+ description: "Create a scheduled recurring task. The AI will run this task automatically on the specified schedule.",
284
413
  inputSchema: {
285
414
  type: "object",
286
- properties: { taskId: { type: "string", description: "Task ID" } },
287
- required: ["taskId"],
415
+ properties: {
416
+ task: {
417
+ type: "string",
418
+ description: "What to do on each run. e.g., 'Improve SEO and page speed'",
419
+ },
420
+ repo: {
421
+ type: "string",
422
+ description: "GitHub repo in format 'owner/repo'",
423
+ },
424
+ cron: {
425
+ type: "string",
426
+ description: "Cron expression. e.g., '0 9 * * 1' for every Monday at 9am UTC",
427
+ },
428
+ name: {
429
+ type: "string",
430
+ description: "Friendly name for the schedule",
431
+ },
432
+ },
433
+ required: ["task", "repo", "cron"],
434
+ },
435
+ },
436
+ {
437
+ name: "vibekit_list_schedules",
438
+ description: "List all scheduled tasks.",
439
+ inputSchema: {
440
+ type: "object",
441
+ properties: {},
442
+ },
443
+ },
444
+ {
445
+ name: "vibekit_delete_schedule",
446
+ description: "Delete a scheduled task.",
447
+ inputSchema: {
448
+ type: "object",
449
+ properties: {
450
+ scheduleId: {
451
+ type: "string",
452
+ description: "The schedule ID to delete",
453
+ },
454
+ },
455
+ required: ["scheduleId"],
456
+ },
457
+ },
458
+ // Account
459
+ {
460
+ name: "vibekit_account",
461
+ description: "Get VibeKit account info including plan, credits balance, and usage.",
462
+ inputSchema: {
463
+ type: "object",
464
+ properties: {},
465
+ },
466
+ },
467
+ {
468
+ name: "vibekit_list_skills",
469
+ description: "List all available implementation skills. Returns skill IDs, names, descriptions, and tags. Use this to discover what skills are available before fetching specific ones.",
470
+ inputSchema: {
471
+ type: "object",
472
+ properties: {
473
+ tag: {
474
+ type: "string",
475
+ description: "Filter skills by tag (e.g., 'react', 'database', 'security')",
476
+ },
477
+ },
478
+ },
479
+ },
480
+ {
481
+ name: "vibekit_get_skill",
482
+ description: "Fetch the full content of a specific skill. Skills contain implementation patterns, code examples, and best practices for a domain. Fetch skills on-demand when you need guidance on a specific topic.",
483
+ inputSchema: {
484
+ type: "object",
485
+ properties: {
486
+ id: {
487
+ type: "string",
488
+ description: "Skill ID from vibekit_list_skills (e.g., 'nextjs', 'trpc', 'auth')",
489
+ },
490
+ },
491
+ required: ["id"],
288
492
  },
289
493
  },
290
494
  ];
291
- // ── Tool Handlers ───────────────────────────────────────────────────────────
495
+ // Tool handlers
292
496
  async function handleTool(name, args) {
293
497
  let result;
294
- const s = args.slug;
295
- const h = `/hosting/app/${s}`;
296
498
  switch (name) {
297
- case "vibekit_account":
298
- result = await api("GET", "/account");
299
- break;
499
+ // Hosting & Apps
300
500
  case "vibekit_list_apps":
301
- result = await api("GET", "/hosting/apps");
501
+ result = await apiRequest("GET", "/hosting/apps");
302
502
  break;
303
- case "vibekit_app_info":
304
- result = await api("GET", h);
503
+ case "vibekit_get_app":
504
+ result = await apiRequest("GET", `/hosting/app/${args.appId}`);
305
505
  break;
306
- case "vibekit_chat":
307
- result = await api("POST", `${h}/agent`, { message: args.message });
308
- break;
309
- case "vibekit_agent_status":
310
- result = await api("GET", `${h}/agent/status`);
506
+ case "vibekit_create_app":
507
+ result = await apiRequest("POST", "/hosting/apps", {
508
+ template: args.template,
509
+ subdomain: args.subdomain,
510
+ });
311
511
  break;
312
512
  case "vibekit_deploy":
313
- result = await api("POST", `${h}/redeploy`);
513
+ result = await apiRequest("POST", "/hosting/deploy", {
514
+ repo: args.repo,
515
+ subdomain: args.subdomain,
516
+ });
314
517
  break;
315
- case "vibekit_deploys":
316
- result = await api("GET", `${h}/deploys`);
518
+ case "vibekit_redeploy":
519
+ result = await apiRequest("POST", `/hosting/app/${args.appId}/redeploy`);
317
520
  break;
318
- case "vibekit_rollback":
319
- result = await api("POST", `${h}/deploys/${args.deployId}/rollback`);
521
+ case "vibekit_app_logs": {
522
+ let path = `/hosting/app/${args.appId}/logs`;
523
+ if (args.lines) {
524
+ path += `?lines=${args.lines}`;
525
+ }
526
+ else {
527
+ path += "?lines=100";
528
+ }
529
+ result = await apiRequest("GET", path);
320
530
  break;
321
- case "vibekit_logs":
322
- result = await api("GET", `${h}/logs?lines=${args.lines || 50}`);
531
+ }
532
+ case "vibekit_restart_app":
533
+ result = await apiRequest("POST", `/hosting/app/${args.appId}/restart`);
323
534
  break;
324
- case "vibekit_start":
325
- result = await api("POST", `${h}/start`);
535
+ case "vibekit_stop_app":
536
+ result = await apiRequest("POST", `/hosting/app/${args.appId}/stop`);
326
537
  break;
327
- case "vibekit_stop":
328
- result = await api("POST", `${h}/stop`);
538
+ case "vibekit_start_app":
539
+ result = await apiRequest("POST", `/hosting/app/${args.appId}/start`);
329
540
  break;
330
- case "vibekit_restart":
331
- result = await api("POST", `${h}/restart`);
541
+ case "vibekit_app_env":
542
+ result = await apiRequest("GET", `/hosting/app/${args.appId}/env`);
332
543
  break;
333
- case "vibekit_env_list":
334
- result = await api("GET", `${h}/env${args.reveal ? '?reveal=true' : ''}`);
544
+ case "vibekit_set_env":
545
+ result = await apiRequest("PUT", `/hosting/app/${args.appId}/env`, {
546
+ vars: args.vars,
547
+ });
335
548
  break;
336
- case "vibekit_env_set":
337
- result = await api("POST", `${h}/env`, { vars: { [args.key]: args.value } });
549
+ case "vibekit_delete_app":
550
+ result = await apiRequest("DELETE", `/hosting/app/${args.appId}`);
338
551
  break;
339
- case "vibekit_env_delete":
340
- result = await api("DELETE", `${h}/env/${args.key}`);
341
- break;
342
- case "vibekit_db_status":
343
- result = await api("GET", `${h}/database`);
552
+ // AI Agent
553
+ case "vibekit_chat":
554
+ result = await apiRequest("POST", `/hosting/app/${args.appId}/agent`, {
555
+ message: args.message,
556
+ });
344
557
  break;
345
- case "vibekit_db_schema":
346
- result = await api("GET", `${h}/database/schema`);
558
+ case "vibekit_agent_status":
559
+ result = await apiRequest("GET", `/hosting/app/${args.appId}/agent/status`);
347
560
  break;
348
- case "vibekit_db_query":
349
- result = await api("POST", `${h}/database/query`, { sql: args.sql });
561
+ case "vibekit_agent_history": {
562
+ let path = `/hosting/app/${args.appId}/agent/history`;
563
+ if (args.limit) {
564
+ path += `?limit=${args.limit}`;
565
+ }
566
+ else {
567
+ path += "?limit=20";
568
+ }
569
+ result = await apiRequest("GET", path);
350
570
  break;
351
- case "vibekit_db_table":
352
- result = await api("GET", `${h}/database/tables/${args.table}?limit=${args.limit || 20}`);
571
+ }
572
+ // Database
573
+ case "vibekit_enable_database":
574
+ result = await apiRequest("POST", `/hosting/app/${args.appId}/database`);
353
575
  break;
354
- case "vibekit_files":
355
- result = await api("GET", `${h}/agent/files${args.path ? `?path=${encodeURIComponent(args.path)}` : ''}`);
576
+ case "vibekit_database_status":
577
+ result = await apiRequest("GET", `/hosting/app/${args.appId}/database`);
356
578
  break;
357
- case "vibekit_qa":
358
- result = await api("POST", `${h}/qa`);
579
+ // QA
580
+ case "vibekit_run_qa":
581
+ result = await apiRequest("POST", `/hosting/app/${args.appId}/qa`);
359
582
  break;
360
- case "vibekit_set_domain":
361
- result = await api("POST", `${h}/domain`, { domain: args.domain });
583
+ case "vibekit_qa_status":
584
+ result = await apiRequest("GET", `/hosting/app/${args.appId}/qa`);
362
585
  break;
586
+ // Tasks (existing)
363
587
  case "vibekit_submit_task":
364
- result = await api("POST", "/task", { prompt: args.task, repo: args.repo, branch: args.branch });
588
+ result = await apiRequest("POST", "/task", {
589
+ task: args.task,
590
+ repo: args.repo,
591
+ branch: args.branch,
592
+ deploy: args.deploy ?? true,
593
+ callbackUrl: args.callbackUrl,
594
+ });
365
595
  break;
366
- case "vibekit_task_status":
367
- result = await api("GET", `/task/${args.taskId}`);
596
+ case "vibekit_get_task":
597
+ result = await apiRequest("GET", `/task/${args.taskId}`);
368
598
  break;
369
- default: result = { ok: false, error: `Unknown tool: ${name}` };
599
+ case "vibekit_list_tasks": {
600
+ let path = "/tasks";
601
+ const params = new URLSearchParams();
602
+ if (args.limit)
603
+ params.set("limit", String(args.limit));
604
+ if (args.status)
605
+ params.set("status", String(args.status));
606
+ if (params.toString())
607
+ path += `?${params.toString()}`;
608
+ result = await apiRequest("GET", path);
609
+ break;
610
+ }
611
+ case "vibekit_wait_for_task": {
612
+ const taskId = args.taskId;
613
+ const timeout = (args.timeoutSeconds || 300) * 1000;
614
+ const start = Date.now();
615
+ while (Date.now() - start < timeout) {
616
+ result = await apiRequest("GET", `/task/${taskId}`);
617
+ if (!result.ok)
618
+ break;
619
+ const task = result.data;
620
+ if (task.status === "completed" || task.status === "failed") {
621
+ break;
622
+ }
623
+ await new Promise((r) => setTimeout(r, 5000));
624
+ }
625
+ if (!result) {
626
+ result = { ok: false, error: "Timeout waiting for task" };
627
+ }
628
+ break;
629
+ }
630
+ case "vibekit_create_schedule":
631
+ result = await apiRequest("POST", "/schedule", {
632
+ task: args.task,
633
+ repo: args.repo,
634
+ cron: args.cron,
635
+ name: args.name,
636
+ });
637
+ break;
638
+ case "vibekit_list_schedules":
639
+ result = await apiRequest("GET", "/schedules");
640
+ break;
641
+ case "vibekit_delete_schedule":
642
+ result = await apiRequest("DELETE", `/schedule/${args.scheduleId}`);
643
+ break;
644
+ // Account
645
+ case "vibekit_account":
646
+ result = await apiRequest("GET", "/account");
647
+ break;
648
+ case "vibekit_list_skills": {
649
+ try {
650
+ // Check cache
651
+ if (skillsCache && Date.now() - skillsCache.fetchedAt < CACHE_TTL) {
652
+ let skills = skillsCache.manifest.skills;
653
+ if (args.tag) {
654
+ skills = skills.filter((s) => s.tags?.includes(args.tag));
655
+ }
656
+ result = { ok: true, data: { skills } };
657
+ break;
658
+ }
659
+ // Fetch manifest
660
+ const res = await fetch(`${SKILLS_REGISTRY}/skills.json`);
661
+ if (!res.ok) {
662
+ result = { ok: false, error: `Failed to fetch skills: ${res.status}` };
663
+ break;
664
+ }
665
+ const manifest = await res.json();
666
+ skillsCache = { manifest, fetchedAt: Date.now() };
667
+ let skills = manifest.skills;
668
+ if (args.tag) {
669
+ skills = skills.filter((s) => s.tags?.includes(args.tag));
670
+ }
671
+ result = { ok: true, data: { skills, count: skills.length } };
672
+ }
673
+ catch (err) {
674
+ result = { ok: false, error: err instanceof Error ? err.message : "Unknown error" };
675
+ }
676
+ break;
677
+ }
678
+ case "vibekit_get_skill": {
679
+ try {
680
+ const id = args.id;
681
+ if (!id) {
682
+ result = { ok: false, error: "Skill ID is required" };
683
+ break;
684
+ }
685
+ const res = await fetch(`${SKILLS_REGISTRY}/skills/${id}/SKILL.md`);
686
+ if (!res.ok) {
687
+ result = { ok: false, error: `Skill '${id}' not found (${res.status})` };
688
+ break;
689
+ }
690
+ const content = await res.text();
691
+ result = { ok: true, data: { id, content } };
692
+ }
693
+ catch (err) {
694
+ result = { ok: false, error: err instanceof Error ? err.message : "Unknown error" };
695
+ }
696
+ break;
697
+ }
698
+ default:
699
+ result = { ok: false, error: `Unknown tool: ${name}` };
370
700
  }
371
- const text = result.ok ? JSON.stringify(result.data, null, 2) : `Error: ${result.error}`;
701
+ const text = result.ok
702
+ ? JSON.stringify(result.data, null, 2)
703
+ : `Error: ${result.error}`;
372
704
  return { content: [{ type: "text", text }] };
373
705
  }
374
- // ── Server ──────────────────────────────────────────────────────────────────
375
- const server = new index_js_1.Server({ name: "vibekit-mcp", version: "0.3.0" }, { capabilities: { tools: {} } });
376
- server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => ({ tools }));
706
+ // Main server setup
707
+ const server = new index_js_1.Server({
708
+ name: "vibekit-mcp",
709
+ version: "0.4.0",
710
+ }, {
711
+ capabilities: {
712
+ tools: {},
713
+ },
714
+ });
715
+ // Handle tool listing
716
+ server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => ({
717
+ tools,
718
+ }));
719
+ // Handle tool calls
377
720
  server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
378
721
  const { name, arguments: args } = request.params;
379
722
  return handleTool(name, (args || {}));
380
723
  });
724
+ // Start server
381
725
  async function main() {
382
726
  const transport = new stdio_js_1.StdioServerTransport();
383
727
  await server.connect(transport);
384
728
  console.error("VibeKit MCP server running on stdio");
385
729
  }
386
- main().catch((err) => { console.error("Fatal:", err); process.exit(1); });
730
+ main().catch((err) => {
731
+ console.error("Fatal error:", err);
732
+ process.exit(1);
733
+ });
package/package.json CHANGED
@@ -1,16 +1,42 @@
1
1
  {
2
2
  "name": "vibekit-mcp",
3
- "version": "0.3.0",
4
- "description": "MCP server for VibeKit — manage AI-powered apps as tools in Claude Desktop, Cursor, Windsurf, etc.",
3
+ "version": "0.4.1",
4
+ "description": "MCP server for VibeKit — deploy apps, manage hosting, chat with AI agents, and run coding tasks from Claude Desktop, Cursor, and other MCP clients.",
5
5
  "main": "dist/index.js",
6
- "bin": { "vibekit-mcp": "./dist/index.js" },
7
- "files": ["dist/", "README.md"],
8
- "scripts": { "build": "tsc", "prepublishOnly": "npm run build" },
9
- "keywords": ["mcp", "vibekit", "claude", "cursor", "ai", "agent", "deploy", "model-context-protocol"],
10
- "author": "VibeKit",
6
+ "bin": {
7
+ "vibekit-mcp": "./dist/index.js"
8
+ },
9
+ "files": [
10
+ "dist/",
11
+ "README.md"
12
+ ],
13
+ "scripts": {
14
+ "build": "tsc",
15
+ "prepublishOnly": "npm run build"
16
+ },
17
+ "keywords": [
18
+ "mcp",
19
+ "vibekit",
20
+ "deploy",
21
+ "hosting",
22
+ "ai-agent",
23
+ "coding",
24
+ "cursor",
25
+ "claude-desktop"
26
+ ],
27
+ "author": "609.sol",
11
28
  "license": "MIT",
29
+ "repository": {
30
+ "type": "git",
31
+ "url": "https://github.com/609NFT/vibekit.git",
32
+ "directory": "packages/mcp-server"
33
+ },
12
34
  "homepage": "https://vibekit.bot",
13
- "repository": { "type": "git", "url": "https://github.com/vibekit-apps/vibekit-mcp" },
14
- "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" },
15
- "devDependencies": { "typescript": "^5.0.0", "@types/node": "^22.0.0" }
35
+ "dependencies": {
36
+ "@modelcontextprotocol/sdk": "^1.0.0"
37
+ },
38
+ "devDependencies": {
39
+ "@types/node": "^20.0.0",
40
+ "typescript": "^5.0.0"
41
+ }
16
42
  }