@vibescope/mcp-server 0.3.0 → 0.3.3
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/dist/api-client/blockers.d.ts +46 -0
- package/dist/api-client/blockers.js +43 -0
- package/dist/api-client/cost.d.ts +112 -0
- package/dist/api-client/cost.js +76 -0
- package/dist/api-client/decisions.d.ts +55 -0
- package/dist/api-client/decisions.js +32 -0
- package/dist/api-client/discovery.d.ts +62 -0
- package/dist/api-client/discovery.js +21 -0
- package/dist/api-client/ideas.d.ts +75 -0
- package/dist/api-client/ideas.js +36 -0
- package/dist/api-client/index.d.ts +749 -0
- package/dist/api-client/index.js +291 -0
- package/dist/api-client/project.d.ts +132 -0
- package/dist/api-client/project.js +45 -0
- package/dist/api-client/session.d.ts +163 -0
- package/dist/api-client/session.js +52 -0
- package/dist/api-client/tasks.d.ts +328 -0
- package/dist/api-client/tasks.js +132 -0
- package/dist/api-client/types.d.ts +25 -0
- package/dist/api-client/types.js +4 -0
- package/dist/api-client/worktrees.d.ts +33 -0
- package/dist/api-client/worktrees.js +26 -0
- package/dist/api-client.d.ts +9 -0
- package/dist/api-client.js +104 -25
- package/dist/cli-init.d.ts +17 -0
- package/dist/cli-init.js +445 -0
- package/dist/cli.js +0 -0
- package/dist/handlers/cloud-agents.d.ts +21 -0
- package/dist/handlers/cloud-agents.js +91 -0
- package/dist/handlers/discovery.js +7 -0
- package/dist/handlers/index.d.ts +1 -0
- package/dist/handlers/index.js +3 -0
- package/dist/handlers/session.js +3 -1
- package/dist/handlers/tasks.js +10 -12
- package/dist/handlers/types.d.ts +2 -1
- package/dist/handlers/validation.js +5 -1
- package/dist/index.js +8 -3
- package/dist/token-tracking.js +2 -2
- package/dist/tools/blockers.d.ts +13 -0
- package/dist/tools/blockers.js +119 -0
- package/dist/tools/bodies-of-work.d.ts +19 -0
- package/dist/tools/bodies-of-work.js +280 -0
- package/dist/tools/cloud-agents.d.ts +9 -0
- package/dist/tools/cloud-agents.js +67 -0
- package/dist/tools/connectors.d.ts +14 -0
- package/dist/tools/connectors.js +188 -0
- package/dist/tools/cost.d.ts +11 -0
- package/dist/tools/cost.js +108 -0
- package/dist/tools/decisions.d.ts +12 -0
- package/dist/tools/decisions.js +108 -0
- package/dist/tools/deployment.d.ts +24 -0
- package/dist/tools/deployment.js +439 -0
- package/dist/tools/discovery.d.ts +10 -0
- package/dist/tools/discovery.js +73 -0
- package/dist/tools/fallback.d.ts +11 -0
- package/dist/tools/fallback.js +108 -0
- package/dist/tools/file-checkouts.d.ts +13 -0
- package/dist/tools/file-checkouts.js +141 -0
- package/dist/tools/findings.d.ts +13 -0
- package/dist/tools/findings.js +98 -0
- package/dist/tools/git-issues.d.ts +11 -0
- package/dist/tools/git-issues.js +127 -0
- package/dist/tools/ideas.d.ts +13 -0
- package/dist/tools/ideas.js +159 -0
- package/dist/tools/index.d.ts +71 -0
- package/dist/tools/index.js +98 -0
- package/dist/tools/milestones.d.ts +12 -0
- package/dist/tools/milestones.js +115 -0
- package/dist/tools/organizations.d.ts +17 -0
- package/dist/tools/organizations.js +221 -0
- package/dist/tools/progress.d.ts +9 -0
- package/dist/tools/progress.js +70 -0
- package/dist/tools/project.d.ts +13 -0
- package/dist/tools/project.js +199 -0
- package/dist/tools/requests.d.ts +10 -0
- package/dist/tools/requests.js +65 -0
- package/dist/tools/roles.d.ts +11 -0
- package/dist/tools/roles.js +109 -0
- package/dist/tools/session.d.ts +15 -0
- package/dist/tools/session.js +178 -0
- package/dist/tools/sprints.d.ts +18 -0
- package/dist/tools/sprints.js +295 -0
- package/dist/tools/tasks.d.ts +27 -0
- package/dist/tools/tasks.js +539 -0
- package/dist/tools/types.d.ts +7 -0
- package/dist/tools/types.js +6 -0
- package/dist/tools/validation.d.ts +10 -0
- package/dist/tools/validation.js +72 -0
- package/dist/tools/worktrees.d.ts +9 -0
- package/dist/tools/worktrees.js +63 -0
- package/dist/utils.d.ts +66 -0
- package/dist/utils.js +102 -0
- package/docs/TOOLS.md +55 -2
- package/package.json +5 -3
- package/scripts/generate-docs.ts +1 -1
- package/src/api-client/blockers.ts +86 -0
- package/src/api-client/cost.ts +185 -0
- package/src/api-client/decisions.ts +87 -0
- package/src/api-client/discovery.ts +81 -0
- package/src/api-client/ideas.ts +112 -0
- package/src/api-client/index.ts +378 -0
- package/src/api-client/project.ts +179 -0
- package/src/api-client/session.ts +220 -0
- package/src/api-client/tasks.ts +450 -0
- package/src/api-client/types.ts +32 -0
- package/src/api-client/worktrees.ts +53 -0
- package/src/api-client.test.ts +136 -9
- package/src/api-client.ts +125 -27
- package/src/cli-init.ts +504 -0
- package/src/handlers/__test-utils__.ts +2 -0
- package/src/handlers/cloud-agents.ts +138 -0
- package/src/handlers/discovery.ts +7 -0
- package/src/handlers/index.ts +3 -0
- package/src/handlers/session.ts +3 -1
- package/src/handlers/tasks.ts +10 -12
- package/src/handlers/tool-categories.test.ts +1 -1
- package/src/handlers/types.ts +2 -1
- package/src/handlers/validation.ts +6 -1
- package/src/index.test.ts +2 -2
- package/src/index.ts +8 -2
- package/src/token-tracking.ts +3 -2
- package/src/tools/blockers.ts +122 -0
- package/src/tools/bodies-of-work.ts +283 -0
- package/src/tools/cloud-agents.ts +70 -0
- package/src/tools/connectors.ts +191 -0
- package/src/tools/cost.ts +111 -0
- package/src/tools/decisions.ts +111 -0
- package/src/tools/deployment.ts +442 -0
- package/src/tools/discovery.ts +76 -0
- package/src/tools/fallback.ts +111 -0
- package/src/tools/file-checkouts.ts +145 -0
- package/src/tools/findings.ts +101 -0
- package/src/tools/git-issues.ts +130 -0
- package/src/tools/ideas.ts +162 -0
- package/src/tools/index.ts +131 -0
- package/src/tools/milestones.ts +118 -0
- package/src/tools/organizations.ts +224 -0
- package/src/tools/progress.ts +73 -0
- package/src/tools/project.ts +202 -0
- package/src/tools/requests.ts +68 -0
- package/src/tools/roles.ts +112 -0
- package/src/tools/session.ts +181 -0
- package/src/tools/sprints.ts +298 -0
- package/src/tools/tasks.ts +542 -0
- package/src/tools/tools.test.ts +222 -0
- package/src/tools/types.ts +9 -0
- package/src/tools/validation.ts +75 -0
- package/src/tools/worktrees.ts +66 -0
- package/src/tools.test.ts +1 -1
- package/src/utils.test.ts +229 -0
- package/src/utils.ts +117 -0
- package/dist/tools.d.ts +0 -2
- package/dist/tools.js +0 -3602
- package/src/tools.ts +0 -3607
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Git Worktree Tool Definitions
|
|
3
|
+
*
|
|
4
|
+
* Tools for managing git worktrees:
|
|
5
|
+
* - get_stale_worktrees: Get worktrees that need cleanup
|
|
6
|
+
* - clear_worktree_path: Clear worktree_path from a task after cleanup
|
|
7
|
+
*/
|
|
8
|
+
export const worktreeTools = [
|
|
9
|
+
{
|
|
10
|
+
name: 'get_stale_worktrees',
|
|
11
|
+
description: `Get worktrees that need cleanup.
|
|
12
|
+
|
|
13
|
+
Returns tasks with worktree_path set where:
|
|
14
|
+
- Task is completed or cancelled (worktree should have been cleaned up)
|
|
15
|
+
- Task has been abandoned (no activity for 24+ hours while in_progress)
|
|
16
|
+
|
|
17
|
+
IMPORTANT: Pass hostname (os.hostname()) to only see worktrees created on THIS machine.
|
|
18
|
+
Worktrees created on other machines cannot be removed locally.
|
|
19
|
+
|
|
20
|
+
For each stale worktree:
|
|
21
|
+
1. Run: git worktree remove <worktree_path>
|
|
22
|
+
2. Call: clear_worktree_path(task_id)`,
|
|
23
|
+
inputSchema: {
|
|
24
|
+
type: 'object',
|
|
25
|
+
properties: {
|
|
26
|
+
project_id: {
|
|
27
|
+
type: 'string',
|
|
28
|
+
description: 'Project UUID',
|
|
29
|
+
},
|
|
30
|
+
hostname: {
|
|
31
|
+
type: 'string',
|
|
32
|
+
description: 'Machine hostname (os.hostname()). Only returns worktrees created on this machine, preventing attempts to clean up worktrees on other machines.',
|
|
33
|
+
},
|
|
34
|
+
limit: {
|
|
35
|
+
type: 'number',
|
|
36
|
+
description: 'Max worktrees to return (default: 50)',
|
|
37
|
+
},
|
|
38
|
+
offset: {
|
|
39
|
+
type: 'number',
|
|
40
|
+
description: 'Number of worktrees to skip for pagination (default: 0)',
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
required: ['project_id'],
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
name: 'clear_worktree_path',
|
|
48
|
+
description: `Clear the worktree_path from a task after cleanup.
|
|
49
|
+
|
|
50
|
+
Call this AFTER removing the worktree with git worktree remove.
|
|
51
|
+
This marks the task as cleaned up so it won't appear in get_stale_worktrees.`,
|
|
52
|
+
inputSchema: {
|
|
53
|
+
type: 'object',
|
|
54
|
+
properties: {
|
|
55
|
+
task_id: {
|
|
56
|
+
type: 'string',
|
|
57
|
+
description: 'Task UUID',
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
required: ['task_id'],
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
];
|
package/dist/utils.d.ts
CHANGED
|
@@ -159,3 +159,69 @@ export declare function extractProjectNameFromGitUrl(gitUrl: string): string;
|
|
|
159
159
|
* // Returns: 'https://github.com/nonatomic/vibescope'
|
|
160
160
|
*/
|
|
161
161
|
export declare function normalizeGitUrl(gitUrl: string | null | undefined): string | null;
|
|
162
|
+
/**
|
|
163
|
+
* Extract a human-readable message from any error type.
|
|
164
|
+
* Handles Error objects, strings, and unknown values.
|
|
165
|
+
*
|
|
166
|
+
* @example
|
|
167
|
+
* try { ... } catch (e) {
|
|
168
|
+
* console.error(getErrorMessage(e));
|
|
169
|
+
* }
|
|
170
|
+
*/
|
|
171
|
+
export declare function getErrorMessage(error: unknown): string;
|
|
172
|
+
/**
|
|
173
|
+
* Type guard to check if a value is an object with an 'error' property.
|
|
174
|
+
* Useful for checking API responses that may contain application-level errors.
|
|
175
|
+
*
|
|
176
|
+
* @example
|
|
177
|
+
* if (hasErrorProperty(response.data)) {
|
|
178
|
+
* return error(getErrorMessage(response.data.error));
|
|
179
|
+
* }
|
|
180
|
+
*/
|
|
181
|
+
export declare function hasErrorProperty(value: unknown): value is {
|
|
182
|
+
error: unknown;
|
|
183
|
+
};
|
|
184
|
+
/**
|
|
185
|
+
* Extract an error message from an API response body.
|
|
186
|
+
* Handles the common pattern where API returns { error: string } or { error: { message: string } }.
|
|
187
|
+
* Returns null if no error is found.
|
|
188
|
+
*
|
|
189
|
+
* @example
|
|
190
|
+
* const apiError = extractApiError(response.data);
|
|
191
|
+
* if (apiError) {
|
|
192
|
+
* return error(apiError);
|
|
193
|
+
* }
|
|
194
|
+
*/
|
|
195
|
+
export declare function extractApiError(data: unknown): string | null;
|
|
196
|
+
/**
|
|
197
|
+
* Default pagination limits
|
|
198
|
+
*/
|
|
199
|
+
export declare const PAGINATION_LIMITS: {
|
|
200
|
+
/** Default maximum limit for paginated results */
|
|
201
|
+
readonly DEFAULT_MAX_LIMIT: 50;
|
|
202
|
+
/** Default limit when not specified */
|
|
203
|
+
readonly DEFAULT_LIMIT: 20;
|
|
204
|
+
/** Smaller limit for task listings */
|
|
205
|
+
readonly TASK_LIMIT: 20;
|
|
206
|
+
};
|
|
207
|
+
/**
|
|
208
|
+
* Cap pagination parameters to safe values.
|
|
209
|
+
* Ensures limit is between 1 and maxLimit, and offset is non-negative.
|
|
210
|
+
*
|
|
211
|
+
* @param limit - Requested limit (will be capped between 1 and maxLimit)
|
|
212
|
+
* @param offset - Requested offset (will be made non-negative)
|
|
213
|
+
* @param maxLimit - Maximum allowed limit (default: PAGINATION_LIMITS.DEFAULT_MAX_LIMIT)
|
|
214
|
+
* @returns Object with cappedLimit and safeOffset
|
|
215
|
+
*
|
|
216
|
+
* @example
|
|
217
|
+
* const { cappedLimit, safeOffset } = capPagination(limit, offset);
|
|
218
|
+
* const { data } = await query.range(safeOffset, safeOffset + cappedLimit - 1);
|
|
219
|
+
*
|
|
220
|
+
* @example
|
|
221
|
+
* // With custom max limit
|
|
222
|
+
* const { cappedLimit, safeOffset } = capPagination(limit, offset, 20);
|
|
223
|
+
*/
|
|
224
|
+
export declare function capPagination(limit: number | undefined, offset: number | undefined, maxLimit?: number): {
|
|
225
|
+
cappedLimit: number;
|
|
226
|
+
safeOffset: number;
|
|
227
|
+
};
|
package/dist/utils.js
CHANGED
|
@@ -396,3 +396,105 @@ export function normalizeGitUrl(gitUrl) {
|
|
|
396
396
|
normalized = normalized.toLowerCase();
|
|
397
397
|
return normalized;
|
|
398
398
|
}
|
|
399
|
+
// ============================================================================
|
|
400
|
+
// Error Handling Utilities
|
|
401
|
+
// Shared error extraction and type checking functions
|
|
402
|
+
// ============================================================================
|
|
403
|
+
/**
|
|
404
|
+
* Extract a human-readable message from any error type.
|
|
405
|
+
* Handles Error objects, strings, and unknown values.
|
|
406
|
+
*
|
|
407
|
+
* @example
|
|
408
|
+
* try { ... } catch (e) {
|
|
409
|
+
* console.error(getErrorMessage(e));
|
|
410
|
+
* }
|
|
411
|
+
*/
|
|
412
|
+
export function getErrorMessage(error) {
|
|
413
|
+
if (error instanceof Error) {
|
|
414
|
+
return error.message;
|
|
415
|
+
}
|
|
416
|
+
if (typeof error === 'string') {
|
|
417
|
+
return error;
|
|
418
|
+
}
|
|
419
|
+
return String(error);
|
|
420
|
+
}
|
|
421
|
+
/**
|
|
422
|
+
* Type guard to check if a value is an object with an 'error' property.
|
|
423
|
+
* Useful for checking API responses that may contain application-level errors.
|
|
424
|
+
*
|
|
425
|
+
* @example
|
|
426
|
+
* if (hasErrorProperty(response.data)) {
|
|
427
|
+
* return error(getErrorMessage(response.data.error));
|
|
428
|
+
* }
|
|
429
|
+
*/
|
|
430
|
+
export function hasErrorProperty(value) {
|
|
431
|
+
return typeof value === 'object' && value !== null && 'error' in value;
|
|
432
|
+
}
|
|
433
|
+
/**
|
|
434
|
+
* Extract an error message from an API response body.
|
|
435
|
+
* Handles the common pattern where API returns { error: string } or { error: { message: string } }.
|
|
436
|
+
* Returns null if no error is found.
|
|
437
|
+
*
|
|
438
|
+
* @example
|
|
439
|
+
* const apiError = extractApiError(response.data);
|
|
440
|
+
* if (apiError) {
|
|
441
|
+
* return error(apiError);
|
|
442
|
+
* }
|
|
443
|
+
*/
|
|
444
|
+
export function extractApiError(data) {
|
|
445
|
+
if (!hasErrorProperty(data)) {
|
|
446
|
+
return null;
|
|
447
|
+
}
|
|
448
|
+
const err = data.error;
|
|
449
|
+
// Direct string error
|
|
450
|
+
if (typeof err === 'string') {
|
|
451
|
+
return err;
|
|
452
|
+
}
|
|
453
|
+
// Nested error object with message property
|
|
454
|
+
if (typeof err === 'object' && err !== null && 'message' in err) {
|
|
455
|
+
const msg = err.message;
|
|
456
|
+
if (typeof msg === 'string') {
|
|
457
|
+
return msg;
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
// Fallback for unknown error structure
|
|
461
|
+
return 'Unknown error';
|
|
462
|
+
}
|
|
463
|
+
// ============================================================================
|
|
464
|
+
// Pagination Utilities
|
|
465
|
+
// ============================================================================
|
|
466
|
+
/**
|
|
467
|
+
* Default pagination limits
|
|
468
|
+
*/
|
|
469
|
+
export const PAGINATION_LIMITS = {
|
|
470
|
+
/** Default maximum limit for paginated results */
|
|
471
|
+
DEFAULT_MAX_LIMIT: 50,
|
|
472
|
+
/** Default limit when not specified */
|
|
473
|
+
DEFAULT_LIMIT: 20,
|
|
474
|
+
/** Smaller limit for task listings */
|
|
475
|
+
TASK_LIMIT: 20,
|
|
476
|
+
};
|
|
477
|
+
/**
|
|
478
|
+
* Cap pagination parameters to safe values.
|
|
479
|
+
* Ensures limit is between 1 and maxLimit, and offset is non-negative.
|
|
480
|
+
*
|
|
481
|
+
* @param limit - Requested limit (will be capped between 1 and maxLimit)
|
|
482
|
+
* @param offset - Requested offset (will be made non-negative)
|
|
483
|
+
* @param maxLimit - Maximum allowed limit (default: PAGINATION_LIMITS.DEFAULT_MAX_LIMIT)
|
|
484
|
+
* @returns Object with cappedLimit and safeOffset
|
|
485
|
+
*
|
|
486
|
+
* @example
|
|
487
|
+
* const { cappedLimit, safeOffset } = capPagination(limit, offset);
|
|
488
|
+
* const { data } = await query.range(safeOffset, safeOffset + cappedLimit - 1);
|
|
489
|
+
*
|
|
490
|
+
* @example
|
|
491
|
+
* // With custom max limit
|
|
492
|
+
* const { cappedLimit, safeOffset } = capPagination(limit, offset, 20);
|
|
493
|
+
*/
|
|
494
|
+
export function capPagination(limit, offset, maxLimit = PAGINATION_LIMITS.DEFAULT_MAX_LIMIT) {
|
|
495
|
+
const effectiveLimit = limit ?? PAGINATION_LIMITS.DEFAULT_LIMIT;
|
|
496
|
+
return {
|
|
497
|
+
cappedLimit: Math.min(Math.max(1, effectiveLimit), maxLimit),
|
|
498
|
+
safeOffset: Math.max(0, offset ?? 0)
|
|
499
|
+
};
|
|
500
|
+
}
|
package/docs/TOOLS.md
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
> Auto-generated from tool definitions. Do not edit manually.
|
|
4
4
|
>
|
|
5
|
-
> Generated: 2026-
|
|
5
|
+
> Generated: 2026-02-06
|
|
6
6
|
>
|
|
7
|
-
> Total tools:
|
|
7
|
+
> Total tools: 154
|
|
8
8
|
|
|
9
9
|
## Table of Contents
|
|
10
10
|
|
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
- [roles](#roles) - Agent role management (4 tools)
|
|
34
34
|
- [file_locks](#file-locks) - File checkout/locking for multi-agent (6 tools)
|
|
35
35
|
- [connectors](#connectors) - External integration connectors (7 tools)
|
|
36
|
+
- [cloud_agents](#cloud-agents) - Cloud agent management and cleanup (2 tools)
|
|
36
37
|
|
|
37
38
|
## session
|
|
38
39
|
|
|
@@ -59,6 +60,7 @@ Use mode:'full' for complete context, mode:'lite' (default) for minimal tokens.
|
|
|
59
60
|
| `role` | `string` | No | Agent role (e.g., "developer", "validator", "deployer", "reviewer", "maintainer"). Custom roles accepted. |
|
|
60
61
|
| `hostname` | `string` | No | Machine hostname for worktree tracking. Pass os.hostname() to filter stale worktrees to only those created on this machine. |
|
|
61
62
|
| `agent_type` | `string` | No | Agent type (e.g., "claude", "gemini", "cursor", "windsurf"). Custom agent types accepted. |
|
|
63
|
+
| `agent_name` | `string` | No | Explicit agent name (for cloud/remote agents). If provided, uses this name instead of selecting from persona pool. Cloud agents should pass their spawner-assigned name. |
|
|
62
64
|
|
|
63
65
|
---
|
|
64
66
|
|
|
@@ -1025,6 +1027,7 @@ Validate a completed task. Include test results in validation_notes. For github-
|
|
|
1025
1027
|
| `approved` | `boolean` | Yes | Whether the task passes validation (true = approved, false = needs more work) |
|
|
1026
1028
|
| `pr_checks_passing` | `boolean` | No | REQUIRED when approving tasks with PRs. Confirm you verified PR checks are passing via `gh pr view <PR_NUMBER> --json statusCheckRollup`. Set to true only if all required checks pass. |
|
|
1027
1029
|
| `skip_pr_check` | `boolean` | No | Skip PR existence check (use only for tasks that legitimately do not need a PR) |
|
|
1030
|
+
| `create_fix_task` | `boolean` | No | When rejecting (approved: false), create a new fix task linked to the original. The fix task will contain the rejection reason and be assigned the same git branch. |
|
|
1028
1031
|
|
|
1029
1032
|
---
|
|
1030
1033
|
|
|
@@ -2404,3 +2407,53 @@ Get event history for a connector or project. Shows delivery status and errors.
|
|
|
2404
2407
|
| `offset` | `number` | No | Pagination offset (default: 0) |
|
|
2405
2408
|
|
|
2406
2409
|
---
|
|
2410
|
+
|
|
2411
|
+
## cloud_agents
|
|
2412
|
+
|
|
2413
|
+
*Cloud agent management and cleanup*
|
|
2414
|
+
|
|
2415
|
+
### cleanup_stale_cloud_agents
|
|
2416
|
+
|
|
2417
|
+
Clean up stale cloud agents that failed to start or lost connection.
|
|
2418
|
+
|
|
2419
|
+
Finds agents stuck in 'starting' status (or optionally 'running' with no heartbeat)
|
|
2420
|
+
|
|
2421
|
+
and marks them as failed. Only operates on the current session's project.
|
|
2422
|
+
|
|
2423
|
+
Use this when:
|
|
2424
|
+
|
|
2425
|
+
- You see agents stuck in "starting" status on the dashboard
|
|
2426
|
+
|
|
2427
|
+
- Cloud agents failed to spawn but weren't cleaned up
|
|
2428
|
+
|
|
2429
|
+
- You want to clear ghost agents from a previous session
|
|
2430
|
+
|
|
2431
|
+
SECURITY: This only affects agents in YOUR current project. Cannot access other users' projects.
|
|
2432
|
+
|
|
2433
|
+
**Parameters:**
|
|
2434
|
+
|
|
2435
|
+
| Parameter | Type | Required | Description |
|
|
2436
|
+
|-----------|------|----------|-------------|
|
|
2437
|
+
| `project_id` | `string` | Yes | Project UUID (required) |
|
|
2438
|
+
| `stale_minutes` | `number` | No | Consider agents stale after this many minutes (default: 5) |
|
|
2439
|
+
| `include_running` | `boolean` | No | Also clean up "running" agents with no recent heartbeat (default: false) |
|
|
2440
|
+
| `dry_run` | `boolean` | No | If true, just report what would be cleaned without actually cleaning (default: false) |
|
|
2441
|
+
|
|
2442
|
+
---
|
|
2443
|
+
|
|
2444
|
+
### list_cloud_agents
|
|
2445
|
+
|
|
2446
|
+
List cloud agents for a project.
|
|
2447
|
+
|
|
2448
|
+
Returns all spawned cloud agents for the project with their current status.
|
|
2449
|
+
|
|
2450
|
+
Use this to check the state of cloud agents before/after cleanup.
|
|
2451
|
+
|
|
2452
|
+
**Parameters:**
|
|
2453
|
+
|
|
2454
|
+
| Parameter | Type | Required | Description |
|
|
2455
|
+
|-----------|------|----------|-------------|
|
|
2456
|
+
| `project_id` | `string` | Yes | Project UUID (required) |
|
|
2457
|
+
| `status` | `"starting" | "running" | "stopped" | "failed" | "all"` | No | Filter by status (default: all) |
|
|
2458
|
+
|
|
2459
|
+
---
|
package/package.json
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vibescope/mcp-server",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.3",
|
|
4
4
|
"description": "MCP server for Vibescope - AI project tracking tools",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
8
8
|
"bin": {
|
|
9
9
|
"vibescope-mcp": "dist/index.js",
|
|
10
|
-
"vibescope-cli": "dist/cli.js"
|
|
10
|
+
"vibescope-cli": "dist/cli.js",
|
|
11
|
+
"vibescope": "dist/cli-init.js",
|
|
12
|
+
"vibescope-init": "dist/cli-init.js"
|
|
11
13
|
},
|
|
12
14
|
"repository": {
|
|
13
15
|
"type": "git",
|
|
14
|
-
"url": "https://github.com/
|
|
16
|
+
"url": "https://github.com/PaulNonatomic/Vibescope.git",
|
|
15
17
|
"directory": "packages/mcp-server"
|
|
16
18
|
},
|
|
17
19
|
"publishConfig": {
|
package/scripts/generate-docs.ts
CHANGED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Blockers API Methods
|
|
3
|
+
*
|
|
4
|
+
* Methods for blocker management:
|
|
5
|
+
* - getBlockers: List blockers for a project
|
|
6
|
+
* - addBlocker: Create a new blocker
|
|
7
|
+
* - resolveBlocker: Mark blocker as resolved
|
|
8
|
+
* - deleteBlocker: Delete a blocker
|
|
9
|
+
* - getBlockersStats: Get blocker statistics
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import type { ApiResponse, RequestFn } from './types.js';
|
|
13
|
+
|
|
14
|
+
export interface BlockersMethods {
|
|
15
|
+
getBlockers(projectId: string, params?: {
|
|
16
|
+
status?: 'open' | 'resolved';
|
|
17
|
+
limit?: number;
|
|
18
|
+
offset?: number;
|
|
19
|
+
}): Promise<ApiResponse<{
|
|
20
|
+
blockers: Array<{
|
|
21
|
+
id: string;
|
|
22
|
+
description: string;
|
|
23
|
+
status: string;
|
|
24
|
+
created_at: string;
|
|
25
|
+
resolved_at?: string;
|
|
26
|
+
resolution_note?: string;
|
|
27
|
+
}>;
|
|
28
|
+
total_count: number;
|
|
29
|
+
has_more: boolean;
|
|
30
|
+
}>>;
|
|
31
|
+
|
|
32
|
+
addBlocker(projectId: string, description: string, sessionId?: string): Promise<ApiResponse<{
|
|
33
|
+
success: boolean;
|
|
34
|
+
blocker_id: string;
|
|
35
|
+
}>>;
|
|
36
|
+
|
|
37
|
+
resolveBlocker(blockerId: string, resolutionNote?: string): Promise<ApiResponse<{
|
|
38
|
+
success: boolean;
|
|
39
|
+
blocker_id: string;
|
|
40
|
+
}>>;
|
|
41
|
+
|
|
42
|
+
deleteBlocker(blockerId: string): Promise<ApiResponse<{
|
|
43
|
+
success: boolean;
|
|
44
|
+
}>>;
|
|
45
|
+
|
|
46
|
+
getBlockersStats(projectId: string): Promise<ApiResponse<{
|
|
47
|
+
total: number;
|
|
48
|
+
open: number;
|
|
49
|
+
resolved: number;
|
|
50
|
+
}>>;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function createBlockersMethods(request: RequestFn): BlockersMethods {
|
|
54
|
+
return {
|
|
55
|
+
async getBlockers(projectId, params) {
|
|
56
|
+
const queryParams = new URLSearchParams();
|
|
57
|
+
if (params?.status) queryParams.set('status', params.status);
|
|
58
|
+
if (params?.limit) queryParams.set('limit', params.limit.toString());
|
|
59
|
+
if (params?.offset) queryParams.set('offset', params.offset.toString());
|
|
60
|
+
const query = queryParams.toString();
|
|
61
|
+
const url = `/api/mcp/projects/${projectId}/blockers${query ? `?${query}` : ''}`;
|
|
62
|
+
return request('GET', url);
|
|
63
|
+
},
|
|
64
|
+
|
|
65
|
+
async addBlocker(projectId, description, sessionId) {
|
|
66
|
+
return request('POST', `/api/mcp/projects/${projectId}/blockers`, {
|
|
67
|
+
description,
|
|
68
|
+
session_id: sessionId
|
|
69
|
+
});
|
|
70
|
+
},
|
|
71
|
+
|
|
72
|
+
async resolveBlocker(blockerId, resolutionNote) {
|
|
73
|
+
return request('PATCH', `/api/mcp/blockers/${blockerId}/resolve`, {
|
|
74
|
+
resolution_note: resolutionNote
|
|
75
|
+
});
|
|
76
|
+
},
|
|
77
|
+
|
|
78
|
+
async deleteBlocker(blockerId) {
|
|
79
|
+
return request('DELETE', `/api/mcp/blockers/${blockerId}`);
|
|
80
|
+
},
|
|
81
|
+
|
|
82
|
+
async getBlockersStats(projectId) {
|
|
83
|
+
return request('GET', `/api/mcp/projects/${projectId}/blockers/stats`);
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cost API Methods
|
|
3
|
+
*
|
|
4
|
+
* Methods for cost tracking and alerts:
|
|
5
|
+
* - getCostSummary: Get cost summary by period
|
|
6
|
+
* - getCostAlerts: List cost alerts
|
|
7
|
+
* - addCostAlert: Create a cost alert
|
|
8
|
+
* - updateCostAlert: Update a cost alert
|
|
9
|
+
* - deleteCostAlert: Delete a cost alert
|
|
10
|
+
* - getTaskCosts: Get costs by task
|
|
11
|
+
* - getBodyOfWorkCosts: Get costs by body of work
|
|
12
|
+
* - getSprintCosts: Get costs by sprint
|
|
13
|
+
* - getTokenUsage: Get token usage stats
|
|
14
|
+
* - reportTokenUsage: Report token usage
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import type { ApiResponse, RequestFn } from './types.js';
|
|
18
|
+
|
|
19
|
+
export interface CostMethods {
|
|
20
|
+
getCostSummary(projectId: string, params?: {
|
|
21
|
+
period?: 'daily' | 'weekly' | 'monthly';
|
|
22
|
+
limit?: number;
|
|
23
|
+
}): Promise<ApiResponse<{
|
|
24
|
+
summary: Array<{
|
|
25
|
+
period: string;
|
|
26
|
+
total_cost: number;
|
|
27
|
+
input_tokens: number;
|
|
28
|
+
output_tokens: number;
|
|
29
|
+
api_calls: number;
|
|
30
|
+
}>;
|
|
31
|
+
}>>;
|
|
32
|
+
|
|
33
|
+
getCostAlerts(): Promise<ApiResponse<{
|
|
34
|
+
alerts: Array<{
|
|
35
|
+
id: string;
|
|
36
|
+
project_id?: string;
|
|
37
|
+
threshold_amount: number;
|
|
38
|
+
threshold_period: string;
|
|
39
|
+
alert_type: string;
|
|
40
|
+
enabled: boolean;
|
|
41
|
+
}>;
|
|
42
|
+
}>>;
|
|
43
|
+
|
|
44
|
+
addCostAlert(params: {
|
|
45
|
+
project_id?: string;
|
|
46
|
+
threshold_amount: number;
|
|
47
|
+
threshold_period: 'daily' | 'weekly' | 'monthly';
|
|
48
|
+
alert_type?: 'warning' | 'critical';
|
|
49
|
+
}): Promise<ApiResponse<{
|
|
50
|
+
success: boolean;
|
|
51
|
+
alert_id: string;
|
|
52
|
+
}>>;
|
|
53
|
+
|
|
54
|
+
updateCostAlert(alertId: string, updates: {
|
|
55
|
+
threshold_amount?: number;
|
|
56
|
+
threshold_period?: 'daily' | 'weekly' | 'monthly';
|
|
57
|
+
alert_type?: 'warning' | 'critical';
|
|
58
|
+
enabled?: boolean;
|
|
59
|
+
}): Promise<ApiResponse<{
|
|
60
|
+
success: boolean;
|
|
61
|
+
alert_id: string;
|
|
62
|
+
}>>;
|
|
63
|
+
|
|
64
|
+
deleteCostAlert(alertId: string): Promise<ApiResponse<{
|
|
65
|
+
success: boolean;
|
|
66
|
+
}>>;
|
|
67
|
+
|
|
68
|
+
getTaskCosts(projectId: string, limit?: number): Promise<ApiResponse<{
|
|
69
|
+
tasks: Array<{
|
|
70
|
+
task_id: string;
|
|
71
|
+
task_title: string;
|
|
72
|
+
total_cost: number;
|
|
73
|
+
input_tokens: number;
|
|
74
|
+
output_tokens: number;
|
|
75
|
+
}>;
|
|
76
|
+
}>>;
|
|
77
|
+
|
|
78
|
+
getBodyOfWorkCosts(params: {
|
|
79
|
+
body_of_work_id?: string;
|
|
80
|
+
project_id?: string;
|
|
81
|
+
limit?: number;
|
|
82
|
+
}): Promise<ApiResponse<{
|
|
83
|
+
bodies_of_work: Array<{
|
|
84
|
+
body_of_work_id: string;
|
|
85
|
+
title: string;
|
|
86
|
+
total_cost: number;
|
|
87
|
+
task_count: number;
|
|
88
|
+
}>;
|
|
89
|
+
}>>;
|
|
90
|
+
|
|
91
|
+
getSprintCosts(params: {
|
|
92
|
+
sprint_id?: string;
|
|
93
|
+
project_id?: string;
|
|
94
|
+
limit?: number;
|
|
95
|
+
}): Promise<ApiResponse<{
|
|
96
|
+
sprints: Array<{
|
|
97
|
+
sprint_id: string;
|
|
98
|
+
name: string;
|
|
99
|
+
total_cost: number;
|
|
100
|
+
task_count: number;
|
|
101
|
+
}>;
|
|
102
|
+
}>>;
|
|
103
|
+
|
|
104
|
+
getTokenUsage(): Promise<ApiResponse<{
|
|
105
|
+
session_tokens: {
|
|
106
|
+
input: number;
|
|
107
|
+
output: number;
|
|
108
|
+
};
|
|
109
|
+
estimated_cost: number;
|
|
110
|
+
}>>;
|
|
111
|
+
|
|
112
|
+
reportTokenUsage(sessionId: string, params: {
|
|
113
|
+
input_tokens: number;
|
|
114
|
+
output_tokens: number;
|
|
115
|
+
model?: string;
|
|
116
|
+
}): Promise<ApiResponse<{
|
|
117
|
+
success: boolean;
|
|
118
|
+
session_id: string;
|
|
119
|
+
total_input_tokens: number;
|
|
120
|
+
total_output_tokens: number;
|
|
121
|
+
}>>;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export function createCostMethods(request: RequestFn): CostMethods {
|
|
125
|
+
return {
|
|
126
|
+
async getCostSummary(projectId, params) {
|
|
127
|
+
const queryParams = new URLSearchParams();
|
|
128
|
+
if (params?.period) queryParams.set('period', params.period);
|
|
129
|
+
if (params?.limit) queryParams.set('limit', params.limit.toString());
|
|
130
|
+
const query = queryParams.toString();
|
|
131
|
+
const url = `/api/mcp/projects/${projectId}/cost-summary${query ? `?${query}` : ''}`;
|
|
132
|
+
return request('GET', url);
|
|
133
|
+
},
|
|
134
|
+
|
|
135
|
+
async getCostAlerts() {
|
|
136
|
+
return request('GET', '/api/mcp/cost-alerts');
|
|
137
|
+
},
|
|
138
|
+
|
|
139
|
+
async addCostAlert(params) {
|
|
140
|
+
return request('POST', '/api/mcp/cost-alerts', params);
|
|
141
|
+
},
|
|
142
|
+
|
|
143
|
+
async updateCostAlert(alertId, updates) {
|
|
144
|
+
return request('PATCH', `/api/mcp/cost-alerts/${alertId}`, updates);
|
|
145
|
+
},
|
|
146
|
+
|
|
147
|
+
async deleteCostAlert(alertId) {
|
|
148
|
+
return request('DELETE', `/api/mcp/cost-alerts/${alertId}`);
|
|
149
|
+
},
|
|
150
|
+
|
|
151
|
+
async getTaskCosts(projectId, limit) {
|
|
152
|
+
const url = limit
|
|
153
|
+
? `/api/mcp/projects/${projectId}/task-costs?limit=${limit}`
|
|
154
|
+
: `/api/mcp/projects/${projectId}/task-costs`;
|
|
155
|
+
return request('GET', url);
|
|
156
|
+
},
|
|
157
|
+
|
|
158
|
+
async getBodyOfWorkCosts(params) {
|
|
159
|
+
const queryParams = new URLSearchParams();
|
|
160
|
+
if (params.body_of_work_id) queryParams.set('body_of_work_id', params.body_of_work_id);
|
|
161
|
+
if (params.project_id) queryParams.set('project_id', params.project_id);
|
|
162
|
+
if (params.limit) queryParams.set('limit', params.limit.toString());
|
|
163
|
+
return request('GET', `/api/mcp/cost/bodies-of-work?${queryParams.toString()}`);
|
|
164
|
+
},
|
|
165
|
+
|
|
166
|
+
async getSprintCosts(params) {
|
|
167
|
+
const queryParams = new URLSearchParams();
|
|
168
|
+
if (params.sprint_id) queryParams.set('sprint_id', params.sprint_id);
|
|
169
|
+
if (params.project_id) queryParams.set('project_id', params.project_id);
|
|
170
|
+
if (params.limit) queryParams.set('limit', params.limit.toString());
|
|
171
|
+
return request('GET', `/api/mcp/cost/sprints?${queryParams.toString()}`);
|
|
172
|
+
},
|
|
173
|
+
|
|
174
|
+
async getTokenUsage() {
|
|
175
|
+
return request('GET', '/api/mcp/sessions/token-usage');
|
|
176
|
+
},
|
|
177
|
+
|
|
178
|
+
async reportTokenUsage(sessionId, params) {
|
|
179
|
+
return request('POST', '/api/mcp/sessions/token-usage', {
|
|
180
|
+
session_id: sessionId,
|
|
181
|
+
...params
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
}
|