vibeteam 0.2.2 → 0.2.4
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/bin/cli.js +334 -38
- package/dist/server/server/index.js +2078 -1822
- package/mcp/server.js +389 -0
- package/package.json +5 -2
- package/public/apple-touch-icon.png +0 -0
- package/public/assets/index-DURW-QlU.js +4330 -0
- package/public/assets/index-DgQWq5c0.css +1 -0
- package/public/favicon-16x16.png +0 -0
- package/public/favicon-32x32.png +0 -0
- package/public/favicon.ico +0 -0
- package/public/favicon.svg +14 -0
- package/public/index.html +21 -0
- package/public/logo.svg +22 -0
- package/public/models/.gitkeep +0 -0
- package/public/models/models/.gitkeep +0 -0
- package/public/site.webmanifest +25 -0
- package/public/sounds/sounds/yoshi.mp3 +0 -0
- package/public/sounds/yoshi.mp3 +0 -0
- package/dist/server/server/CommitWatcher.js +0 -307
package/mcp/server.js
ADDED
|
@@ -0,0 +1,389 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* VibeTeam MCP Server
|
|
5
|
+
*
|
|
6
|
+
* Exposes VibeTeam's agent orchestration API as MCP tools so that
|
|
7
|
+
* Claude Code (or any MCP-compatible AI) can control VibeTeam remotely.
|
|
8
|
+
*
|
|
9
|
+
* Usage:
|
|
10
|
+
* claude mcp add vibeteam -- node /path/to/vibeteam/packages/cli/mcp/server.js
|
|
11
|
+
* # or if installed globally via npm:
|
|
12
|
+
* claude mcp add vibeteam -- vibeteam-mcp
|
|
13
|
+
*
|
|
14
|
+
* Environment variables:
|
|
15
|
+
* VIBETEAM_PORT — VibeTeam backend port (default: 4003)
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
19
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
20
|
+
import {
|
|
21
|
+
CallToolRequestSchema,
|
|
22
|
+
ListToolsRequestSchema,
|
|
23
|
+
} from '@modelcontextprotocol/sdk/types.js';
|
|
24
|
+
|
|
25
|
+
const BASE_URL = `http://localhost:${process.env.VIBETEAM_PORT || 4003}`;
|
|
26
|
+
|
|
27
|
+
// ---------------------------------------------------------------------------
|
|
28
|
+
// HTTP helpers
|
|
29
|
+
// ---------------------------------------------------------------------------
|
|
30
|
+
|
|
31
|
+
async function apiGet(path) {
|
|
32
|
+
const res = await fetch(`${BASE_URL}${path}`);
|
|
33
|
+
if (!res.ok) {
|
|
34
|
+
const text = await res.text();
|
|
35
|
+
throw new Error(`GET ${path} failed (${res.status}): ${text}`);
|
|
36
|
+
}
|
|
37
|
+
return res.json();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async function apiPost(path, body) {
|
|
41
|
+
const res = await fetch(`${BASE_URL}${path}`, {
|
|
42
|
+
method: 'POST',
|
|
43
|
+
headers: { 'Content-Type': 'application/json' },
|
|
44
|
+
body: JSON.stringify(body),
|
|
45
|
+
});
|
|
46
|
+
if (!res.ok) {
|
|
47
|
+
const text = await res.text();
|
|
48
|
+
throw new Error(`POST ${path} failed (${res.status}): ${text}`);
|
|
49
|
+
}
|
|
50
|
+
return res.json();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
async function apiDelete(path) {
|
|
54
|
+
const res = await fetch(`${BASE_URL}${path}`, { method: 'DELETE' });
|
|
55
|
+
if (!res.ok) {
|
|
56
|
+
const text = await res.text();
|
|
57
|
+
throw new Error(`DELETE ${path} failed (${res.status}): ${text}`);
|
|
58
|
+
}
|
|
59
|
+
return res.json();
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// ---------------------------------------------------------------------------
|
|
63
|
+
// Tool definitions
|
|
64
|
+
// ---------------------------------------------------------------------------
|
|
65
|
+
|
|
66
|
+
const TOOLS = [
|
|
67
|
+
{
|
|
68
|
+
name: 'vibeteam_overview',
|
|
69
|
+
description:
|
|
70
|
+
'Get a full overview of the VibeTeam system: all agents with status, projects, active pipelines, and task counts by column. Use this first to understand what is going on.',
|
|
71
|
+
inputSchema: { type: 'object', properties: {}, required: [] },
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
name: 'vibeteam_list_agents',
|
|
75
|
+
description:
|
|
76
|
+
'List all VibeTeam agents (Claude Code sessions) with their current status, name, and project.',
|
|
77
|
+
inputSchema: { type: 'object', properties: {}, required: [] },
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
name: 'vibeteam_create_agent',
|
|
81
|
+
description:
|
|
82
|
+
'Spawn a new Claude Code agent in a project. Returns the new agent session.',
|
|
83
|
+
inputSchema: {
|
|
84
|
+
type: 'object',
|
|
85
|
+
properties: {
|
|
86
|
+
name: { type: 'string', description: 'Display name for the agent' },
|
|
87
|
+
projectId: { type: 'string', description: 'Project ID to work in' },
|
|
88
|
+
prompt: { type: 'string', description: 'Initial prompt to send to the agent after spawn' },
|
|
89
|
+
},
|
|
90
|
+
required: ['projectId'],
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
name: 'vibeteam_send_message',
|
|
95
|
+
description: 'Send a prompt/message to a running agent.',
|
|
96
|
+
inputSchema: {
|
|
97
|
+
type: 'object',
|
|
98
|
+
properties: {
|
|
99
|
+
sessionId: { type: 'string', description: 'Agent session ID' },
|
|
100
|
+
prompt: { type: 'string', description: 'Message to send' },
|
|
101
|
+
},
|
|
102
|
+
required: ['sessionId', 'prompt'],
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
name: 'vibeteam_agent_output',
|
|
107
|
+
description:
|
|
108
|
+
'Get the recent terminal output from an agent. Useful for checking what an agent has done.',
|
|
109
|
+
inputSchema: {
|
|
110
|
+
type: 'object',
|
|
111
|
+
properties: {
|
|
112
|
+
sessionId: { type: 'string', description: 'Agent session ID' },
|
|
113
|
+
lines: { type: 'number', description: 'Number of terminal lines to return (default 100, max 500)' },
|
|
114
|
+
},
|
|
115
|
+
required: ['sessionId'],
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
name: 'vibeteam_stop_agent',
|
|
120
|
+
description: 'Stop and remove an agent.',
|
|
121
|
+
inputSchema: {
|
|
122
|
+
type: 'object',
|
|
123
|
+
properties: {
|
|
124
|
+
sessionId: { type: 'string', description: 'Agent session ID to stop' },
|
|
125
|
+
},
|
|
126
|
+
required: ['sessionId'],
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
name: 'vibeteam_list_projects',
|
|
131
|
+
description: 'List all registered projects.',
|
|
132
|
+
inputSchema: { type: 'object', properties: {}, required: [] },
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
name: 'vibeteam_list_tasks',
|
|
136
|
+
description:
|
|
137
|
+
'List kanban tasks. Optionally filter by project ID or column.',
|
|
138
|
+
inputSchema: {
|
|
139
|
+
type: 'object',
|
|
140
|
+
properties: {
|
|
141
|
+
projectId: { type: 'string', description: 'Filter tasks by project ID' },
|
|
142
|
+
column: {
|
|
143
|
+
type: 'string',
|
|
144
|
+
description: 'Filter by column: ideas, planning, in_progress, ai_review, human_review, done',
|
|
145
|
+
},
|
|
146
|
+
},
|
|
147
|
+
required: [],
|
|
148
|
+
},
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
name: 'vibeteam_create_task',
|
|
152
|
+
description: 'Create a new kanban task.',
|
|
153
|
+
inputSchema: {
|
|
154
|
+
type: 'object',
|
|
155
|
+
properties: {
|
|
156
|
+
projectId: { type: 'string', description: 'Project ID' },
|
|
157
|
+
title: { type: 'string', description: 'Task title' },
|
|
158
|
+
description: { type: 'string', description: 'Task description' },
|
|
159
|
+
columnId: {
|
|
160
|
+
type: 'string',
|
|
161
|
+
description: 'Column to place task in (default: planning)',
|
|
162
|
+
},
|
|
163
|
+
priority: {
|
|
164
|
+
type: 'string',
|
|
165
|
+
description: 'Priority: low, medium, high, urgent (default: medium)',
|
|
166
|
+
},
|
|
167
|
+
tags: {
|
|
168
|
+
type: 'array',
|
|
169
|
+
items: { type: 'string' },
|
|
170
|
+
description: 'Tags for the task',
|
|
171
|
+
},
|
|
172
|
+
},
|
|
173
|
+
required: ['projectId', 'title'],
|
|
174
|
+
},
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
name: 'vibeteam_move_task',
|
|
178
|
+
description: 'Move a kanban task to a different column.',
|
|
179
|
+
inputSchema: {
|
|
180
|
+
type: 'object',
|
|
181
|
+
properties: {
|
|
182
|
+
taskId: { type: 'string', description: 'Task ID to move' },
|
|
183
|
+
column: {
|
|
184
|
+
type: 'string',
|
|
185
|
+
description: 'Target column: ideas, planning, in_progress, ai_review, human_review, done',
|
|
186
|
+
},
|
|
187
|
+
},
|
|
188
|
+
required: ['taskId', 'column'],
|
|
189
|
+
},
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
name: 'vibeteam_start_pipeline',
|
|
193
|
+
description:
|
|
194
|
+
'Start a planning pipeline for a kanban task. The pipeline orchestrates an agent through plan → implement → review → ship phases.',
|
|
195
|
+
inputSchema: {
|
|
196
|
+
type: 'object',
|
|
197
|
+
properties: {
|
|
198
|
+
taskId: { type: 'string', description: 'Kanban task ID' },
|
|
199
|
+
projectId: { type: 'string', description: 'Project ID' },
|
|
200
|
+
},
|
|
201
|
+
required: ['taskId', 'projectId'],
|
|
202
|
+
},
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
name: 'vibeteam_run_task',
|
|
206
|
+
description:
|
|
207
|
+
'One-shot: create a kanban task AND start a pipeline for it immediately. This is the simplest way to tell VibeTeam "do this thing".',
|
|
208
|
+
inputSchema: {
|
|
209
|
+
type: 'object',
|
|
210
|
+
properties: {
|
|
211
|
+
projectId: { type: 'string', description: 'Project ID' },
|
|
212
|
+
title: { type: 'string', description: 'Task title' },
|
|
213
|
+
description: { type: 'string', description: 'Detailed task description' },
|
|
214
|
+
priority: { type: 'string', description: 'Priority: low, medium, high, urgent' },
|
|
215
|
+
tags: { type: 'array', items: { type: 'string' }, description: 'Tags' },
|
|
216
|
+
},
|
|
217
|
+
required: ['projectId', 'title'],
|
|
218
|
+
},
|
|
219
|
+
},
|
|
220
|
+
{
|
|
221
|
+
name: 'vibeteam_pipeline_status',
|
|
222
|
+
description: 'Get detailed status of a pipeline.',
|
|
223
|
+
inputSchema: {
|
|
224
|
+
type: 'object',
|
|
225
|
+
properties: {
|
|
226
|
+
pipelineId: { type: 'string', description: 'Pipeline ID' },
|
|
227
|
+
},
|
|
228
|
+
required: ['pipelineId'],
|
|
229
|
+
},
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
name: 'vibeteam_restart_server',
|
|
233
|
+
description:
|
|
234
|
+
'Gracefully restart the VibeTeam backend server. Sessions, pipelines, and tasks persist. Agents keep running in tmux. Use this after making changes to the backend code.',
|
|
235
|
+
inputSchema: { type: 'object', properties: {}, required: [] },
|
|
236
|
+
},
|
|
237
|
+
];
|
|
238
|
+
|
|
239
|
+
// ---------------------------------------------------------------------------
|
|
240
|
+
// Tool handlers
|
|
241
|
+
// ---------------------------------------------------------------------------
|
|
242
|
+
|
|
243
|
+
async function handleTool(name, args) {
|
|
244
|
+
switch (name) {
|
|
245
|
+
case 'vibeteam_overview': {
|
|
246
|
+
const data = await apiGet('/api/overview');
|
|
247
|
+
return JSON.stringify(data, null, 2);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
case 'vibeteam_list_agents': {
|
|
251
|
+
const data = await apiGet('/sessions');
|
|
252
|
+
const agents = (data.sessions || []).map((s) => ({
|
|
253
|
+
id: s.id,
|
|
254
|
+
name: s.name,
|
|
255
|
+
status: s.status,
|
|
256
|
+
currentTool: s.currentTool || null,
|
|
257
|
+
projectId: s.projectId || null,
|
|
258
|
+
cwd: s.cwd,
|
|
259
|
+
}));
|
|
260
|
+
return JSON.stringify({ agents }, null, 2);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
case 'vibeteam_create_agent': {
|
|
264
|
+
const body = { projectId: args.projectId };
|
|
265
|
+
if (args.name) body.name = args.name;
|
|
266
|
+
if (args.prompt) body.prompt = args.prompt;
|
|
267
|
+
const data = await apiPost('/sessions', body);
|
|
268
|
+
return JSON.stringify(data, null, 2);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
case 'vibeteam_send_message': {
|
|
272
|
+
const data = await apiPost(`/sessions/${args.sessionId}/prompt`, {
|
|
273
|
+
prompt: args.prompt,
|
|
274
|
+
});
|
|
275
|
+
return JSON.stringify(data, null, 2);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
case 'vibeteam_agent_output': {
|
|
279
|
+
const lines = args.lines || 100;
|
|
280
|
+
const data = await apiGet(`/sessions/${args.sessionId}/output?lines=${lines}`);
|
|
281
|
+
return JSON.stringify(data, null, 2);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
case 'vibeteam_stop_agent': {
|
|
285
|
+
const data = await apiDelete(`/sessions/${args.sessionId}`);
|
|
286
|
+
return JSON.stringify(data, null, 2);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
case 'vibeteam_list_projects': {
|
|
290
|
+
const data = await apiGet('/projects');
|
|
291
|
+
return JSON.stringify(data, null, 2);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
case 'vibeteam_list_tasks': {
|
|
295
|
+
let path = '/kanban/tasks';
|
|
296
|
+
const params = [];
|
|
297
|
+
if (args.projectId) params.push(`projectId=${encodeURIComponent(args.projectId)}`);
|
|
298
|
+
if (params.length) path += '?' + params.join('&');
|
|
299
|
+
const data = await apiGet(path);
|
|
300
|
+
let tasks = data.tasks || [];
|
|
301
|
+
if (args.column) {
|
|
302
|
+
tasks = tasks.filter((t) => t.columnId === args.column);
|
|
303
|
+
}
|
|
304
|
+
return JSON.stringify({ tasks }, null, 2);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
case 'vibeteam_create_task': {
|
|
308
|
+
const data = await apiPost('/kanban/tasks', {
|
|
309
|
+
projectId: args.projectId,
|
|
310
|
+
title: args.title,
|
|
311
|
+
description: args.description || '',
|
|
312
|
+
columnId: args.columnId || 'planning',
|
|
313
|
+
priority: args.priority || 'medium',
|
|
314
|
+
tags: args.tags || [],
|
|
315
|
+
});
|
|
316
|
+
return JSON.stringify(data, null, 2);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
case 'vibeteam_move_task': {
|
|
320
|
+
const data = await apiPost(`/kanban/tasks/${args.taskId}/move`, {
|
|
321
|
+
toColumn: args.column,
|
|
322
|
+
});
|
|
323
|
+
return JSON.stringify(data, null, 2);
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
case 'vibeteam_start_pipeline': {
|
|
327
|
+
const data = await apiPost('/pipelines', {
|
|
328
|
+
taskId: args.taskId,
|
|
329
|
+
projectId: args.projectId,
|
|
330
|
+
});
|
|
331
|
+
return JSON.stringify(data, null, 2);
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
case 'vibeteam_run_task': {
|
|
335
|
+
const data = await apiPost('/api/run-task', {
|
|
336
|
+
projectId: args.projectId,
|
|
337
|
+
title: args.title,
|
|
338
|
+
description: args.description || '',
|
|
339
|
+
priority: args.priority,
|
|
340
|
+
tags: args.tags,
|
|
341
|
+
});
|
|
342
|
+
return JSON.stringify(data, null, 2);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
case 'vibeteam_pipeline_status': {
|
|
346
|
+
const data = await apiGet(`/pipelines/${args.pipelineId}`);
|
|
347
|
+
return JSON.stringify(data, null, 2);
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
case 'vibeteam_restart_server': {
|
|
351
|
+
const data = await apiPost('/api/restart', {});
|
|
352
|
+
return JSON.stringify(data, null, 2);
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
default:
|
|
356
|
+
throw new Error(`Unknown tool: ${name}`);
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
// ---------------------------------------------------------------------------
|
|
361
|
+
// Server setup
|
|
362
|
+
// ---------------------------------------------------------------------------
|
|
363
|
+
|
|
364
|
+
const server = new Server(
|
|
365
|
+
{ name: 'vibeteam', version: '0.2.3' },
|
|
366
|
+
{ capabilities: { tools: {} } },
|
|
367
|
+
);
|
|
368
|
+
|
|
369
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
370
|
+
tools: TOOLS,
|
|
371
|
+
}));
|
|
372
|
+
|
|
373
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
374
|
+
const { name, arguments: args } = request.params;
|
|
375
|
+
try {
|
|
376
|
+
const result = await handleTool(name, args || {});
|
|
377
|
+
return { content: [{ type: 'text', text: result }] };
|
|
378
|
+
} catch (err) {
|
|
379
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
380
|
+
return {
|
|
381
|
+
content: [{ type: 'text', text: `Error: ${message}` }],
|
|
382
|
+
isError: true,
|
|
383
|
+
};
|
|
384
|
+
}
|
|
385
|
+
});
|
|
386
|
+
|
|
387
|
+
// Start
|
|
388
|
+
const transport = new StdioServerTransport();
|
|
389
|
+
await server.connect(transport);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vibeteam",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.4",
|
|
4
4
|
"description": "3D visualization of Claude Code as an interactive workshop",
|
|
5
5
|
"author": "asara",
|
|
6
6
|
"license": "MIT",
|
|
@@ -22,12 +22,14 @@
|
|
|
22
22
|
],
|
|
23
23
|
"type": "module",
|
|
24
24
|
"bin": {
|
|
25
|
-
"vibeteam": "./bin/cli.js"
|
|
25
|
+
"vibeteam": "./bin/cli.js",
|
|
26
|
+
"vibeteam-mcp": "./mcp/server.js"
|
|
26
27
|
},
|
|
27
28
|
"files": [
|
|
28
29
|
"bin/",
|
|
29
30
|
"hooks/",
|
|
30
31
|
"dist/",
|
|
32
|
+
"mcp/",
|
|
31
33
|
"public/",
|
|
32
34
|
"!dist/**/*.map",
|
|
33
35
|
"data/.gitkeep"
|
|
@@ -39,6 +41,7 @@
|
|
|
39
41
|
},
|
|
40
42
|
"dependencies": {
|
|
41
43
|
"@deepgram/sdk": "^4.11.3",
|
|
44
|
+
"@modelcontextprotocol/sdk": "^1.12.1",
|
|
42
45
|
"chokidar": "^4.0.0",
|
|
43
46
|
"ws": "^8.18.0"
|
|
44
47
|
},
|
|
Binary file
|