@vibescope/mcp-server 0.0.1 → 0.1.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.
Files changed (170) hide show
  1. package/README.md +113 -98
  2. package/dist/api-client.d.ts +1114 -0
  3. package/dist/api-client.js +698 -0
  4. package/dist/cli.d.ts +1 -6
  5. package/dist/cli.js +39 -240
  6. package/dist/config/tool-categories.d.ts +31 -0
  7. package/dist/config/tool-categories.js +253 -0
  8. package/dist/handlers/blockers.js +57 -58
  9. package/dist/handlers/bodies-of-work.d.ts +2 -0
  10. package/dist/handlers/bodies-of-work.js +106 -476
  11. package/dist/handlers/cost.d.ts +1 -0
  12. package/dist/handlers/cost.js +35 -113
  13. package/dist/handlers/decisions.d.ts +2 -0
  14. package/dist/handlers/decisions.js +28 -27
  15. package/dist/handlers/deployment.js +112 -828
  16. package/dist/handlers/discovery.js +31 -0
  17. package/dist/handlers/fallback.d.ts +2 -0
  18. package/dist/handlers/fallback.js +39 -134
  19. package/dist/handlers/findings.js +43 -67
  20. package/dist/handlers/git-issues.d.ts +9 -13
  21. package/dist/handlers/git-issues.js +80 -225
  22. package/dist/handlers/ideas.d.ts +3 -0
  23. package/dist/handlers/ideas.js +53 -134
  24. package/dist/handlers/index.d.ts +2 -0
  25. package/dist/handlers/index.js +6 -0
  26. package/dist/handlers/milestones.d.ts +2 -0
  27. package/dist/handlers/milestones.js +51 -98
  28. package/dist/handlers/organizations.js +79 -275
  29. package/dist/handlers/progress.d.ts +2 -0
  30. package/dist/handlers/progress.js +25 -123
  31. package/dist/handlers/project.js +42 -221
  32. package/dist/handlers/requests.d.ts +2 -0
  33. package/dist/handlers/requests.js +23 -83
  34. package/dist/handlers/session.js +99 -585
  35. package/dist/handlers/sprints.d.ts +32 -0
  36. package/dist/handlers/sprints.js +274 -0
  37. package/dist/handlers/tasks.d.ts +7 -10
  38. package/dist/handlers/tasks.js +230 -900
  39. package/dist/handlers/tool-docs.d.ts +8 -0
  40. package/dist/handlers/tool-docs.js +657 -0
  41. package/dist/handlers/types.d.ts +11 -3
  42. package/dist/handlers/validation.d.ts +1 -1
  43. package/dist/handlers/validation.js +26 -153
  44. package/dist/index.js +473 -160
  45. package/dist/knowledge.js +106 -9
  46. package/dist/tools.js +4 -0
  47. package/dist/validators.d.ts +21 -0
  48. package/dist/validators.js +91 -0
  49. package/package.json +2 -3
  50. package/src/api-client.ts +1752 -0
  51. package/src/cli.test.ts +128 -302
  52. package/src/cli.ts +41 -285
  53. package/src/handlers/__test-setup__.ts +210 -0
  54. package/src/handlers/__test-utils__.ts +4 -134
  55. package/src/handlers/blockers.test.ts +114 -124
  56. package/src/handlers/blockers.ts +68 -70
  57. package/src/handlers/bodies-of-work.test.ts +236 -831
  58. package/src/handlers/bodies-of-work.ts +194 -525
  59. package/src/handlers/cost.test.ts +149 -113
  60. package/src/handlers/cost.ts +44 -132
  61. package/src/handlers/decisions.test.ts +111 -209
  62. package/src/handlers/decisions.ts +35 -27
  63. package/src/handlers/deployment.test.ts +193 -239
  64. package/src/handlers/deployment.ts +140 -895
  65. package/src/handlers/discovery.test.ts +20 -67
  66. package/src/handlers/discovery.ts +32 -0
  67. package/src/handlers/fallback.test.ts +128 -361
  68. package/src/handlers/fallback.ts +62 -148
  69. package/src/handlers/findings.test.ts +127 -345
  70. package/src/handlers/findings.ts +49 -66
  71. package/src/handlers/git-issues.test.ts +623 -0
  72. package/src/handlers/git-issues.ts +174 -0
  73. package/src/handlers/ideas.test.ts +229 -343
  74. package/src/handlers/ideas.ts +69 -143
  75. package/src/handlers/index.ts +6 -0
  76. package/src/handlers/milestones.test.ts +167 -281
  77. package/src/handlers/milestones.ts +54 -93
  78. package/src/handlers/organizations.test.ts +275 -467
  79. package/src/handlers/organizations.ts +84 -294
  80. package/src/handlers/progress.test.ts +112 -218
  81. package/src/handlers/progress.ts +29 -142
  82. package/src/handlers/project.test.ts +203 -226
  83. package/src/handlers/project.ts +48 -238
  84. package/src/handlers/requests.test.ts +74 -342
  85. package/src/handlers/requests.ts +25 -83
  86. package/src/handlers/session.test.ts +241 -206
  87. package/src/handlers/session.ts +110 -657
  88. package/src/handlers/sprints.test.ts +711 -0
  89. package/src/handlers/sprints.ts +497 -0
  90. package/src/handlers/tasks.test.ts +608 -353
  91. package/src/handlers/tasks.ts +248 -1025
  92. package/src/handlers/types.ts +12 -4
  93. package/src/handlers/validation.test.ts +189 -572
  94. package/src/handlers/validation.ts +29 -166
  95. package/src/index.ts +473 -184
  96. package/src/knowledge.ts +107 -9
  97. package/src/tools.ts +2506 -0
  98. package/src/validators.test.ts +223 -223
  99. package/src/validators.ts +127 -0
  100. package/tsconfig.json +1 -1
  101. package/vitest.config.ts +14 -13
  102. package/dist/cli.test.d.ts +0 -1
  103. package/dist/cli.test.js +0 -367
  104. package/dist/handlers/__test-utils__.d.ts +0 -72
  105. package/dist/handlers/__test-utils__.js +0 -176
  106. package/dist/handlers/checkouts.d.ts +0 -37
  107. package/dist/handlers/checkouts.js +0 -377
  108. package/dist/handlers/knowledge-query.d.ts +0 -22
  109. package/dist/handlers/knowledge-query.js +0 -253
  110. package/dist/handlers/knowledge.d.ts +0 -12
  111. package/dist/handlers/knowledge.js +0 -108
  112. package/dist/handlers/roles.d.ts +0 -30
  113. package/dist/handlers/roles.js +0 -281
  114. package/dist/handlers/tasks.test.d.ts +0 -1
  115. package/dist/handlers/tasks.test.js +0 -431
  116. package/dist/utils.test.d.ts +0 -1
  117. package/dist/utils.test.js +0 -532
  118. package/dist/validators.test.d.ts +0 -1
  119. package/dist/validators.test.js +0 -176
  120. package/src/tmpclaude-0078-cwd +0 -1
  121. package/src/tmpclaude-0ee1-cwd +0 -1
  122. package/src/tmpclaude-2dd5-cwd +0 -1
  123. package/src/tmpclaude-344c-cwd +0 -1
  124. package/src/tmpclaude-3860-cwd +0 -1
  125. package/src/tmpclaude-4b63-cwd +0 -1
  126. package/src/tmpclaude-5c73-cwd +0 -1
  127. package/src/tmpclaude-5ee3-cwd +0 -1
  128. package/src/tmpclaude-6795-cwd +0 -1
  129. package/src/tmpclaude-709e-cwd +0 -1
  130. package/src/tmpclaude-9839-cwd +0 -1
  131. package/src/tmpclaude-d829-cwd +0 -1
  132. package/src/tmpclaude-e072-cwd +0 -1
  133. package/src/tmpclaude-f6ee-cwd +0 -1
  134. package/tmpclaude-0439-cwd +0 -1
  135. package/tmpclaude-132f-cwd +0 -1
  136. package/tmpclaude-15bb-cwd +0 -1
  137. package/tmpclaude-165a-cwd +0 -1
  138. package/tmpclaude-1ba9-cwd +0 -1
  139. package/tmpclaude-21a3-cwd +0 -1
  140. package/tmpclaude-2a38-cwd +0 -1
  141. package/tmpclaude-2adf-cwd +0 -1
  142. package/tmpclaude-2f56-cwd +0 -1
  143. package/tmpclaude-3626-cwd +0 -1
  144. package/tmpclaude-3727-cwd +0 -1
  145. package/tmpclaude-40bc-cwd +0 -1
  146. package/tmpclaude-436f-cwd +0 -1
  147. package/tmpclaude-4783-cwd +0 -1
  148. package/tmpclaude-4b6d-cwd +0 -1
  149. package/tmpclaude-4ba4-cwd +0 -1
  150. package/tmpclaude-51e6-cwd +0 -1
  151. package/tmpclaude-5ecf-cwd +0 -1
  152. package/tmpclaude-6f97-cwd +0 -1
  153. package/tmpclaude-7fb2-cwd +0 -1
  154. package/tmpclaude-825c-cwd +0 -1
  155. package/tmpclaude-8baf-cwd +0 -1
  156. package/tmpclaude-8d9f-cwd +0 -1
  157. package/tmpclaude-975c-cwd +0 -1
  158. package/tmpclaude-9983-cwd +0 -1
  159. package/tmpclaude-a045-cwd +0 -1
  160. package/tmpclaude-ac4a-cwd +0 -1
  161. package/tmpclaude-b593-cwd +0 -1
  162. package/tmpclaude-b891-cwd +0 -1
  163. package/tmpclaude-c032-cwd +0 -1
  164. package/tmpclaude-cf43-cwd +0 -1
  165. package/tmpclaude-d040-cwd +0 -1
  166. package/tmpclaude-dcdd-cwd +0 -1
  167. package/tmpclaude-dcee-cwd +0 -1
  168. package/tmpclaude-e16b-cwd +0 -1
  169. package/tmpclaude-ecd2-cwd +0 -1
  170. package/tmpclaude-f48d-cwd +0 -1
package/dist/cli.d.ts CHANGED
@@ -8,10 +8,6 @@
8
8
  * 1 = Non-compliant (block exit, loop back)
9
9
  * 2 = Error (allow exit with warning)
10
10
  */
11
- export interface AuthContext {
12
- userId: string;
13
- apiKeyId: string;
14
- }
15
11
  export interface VerificationResult {
16
12
  status: 'compliant' | 'non_compliant' | 'no_session' | 'error';
17
13
  reason: string;
@@ -28,7 +24,6 @@ export interface VerificationResult {
28
24
  session_duration_minutes: number | null;
29
25
  };
30
26
  }
27
+ export declare function normalizeGitUrl(url: string): string;
31
28
  export declare function detectGitUrl(): string | null;
32
- export declare function hashApiKey(key: string): string;
33
- export declare function validateApiKey(supabase: any, apiKey: string): Promise<AuthContext | null>;
34
29
  export declare function verify(gitUrl?: string, projectId?: string): Promise<VerificationResult>;
package/dist/cli.js CHANGED
@@ -8,19 +8,30 @@
8
8
  * 1 = Non-compliant (block exit, loop back)
9
9
  * 2 = Error (allow exit with warning)
10
10
  */
11
- import { createClient } from '@supabase/supabase-js';
12
- import { createHash } from 'crypto';
13
11
  import { execSync } from 'child_process';
14
- import { normalizeGitUrl } from './utils.js';
15
12
  // ============================================================================
16
- // Configuration
13
+ // Configuration (read at runtime for testability)
17
14
  // ============================================================================
18
- const SUPABASE_URL = process.env.SUPABASE_URL || process.env.PUBLIC_SUPABASE_URL;
19
- const SUPABASE_SERVICE_KEY = process.env.SUPABASE_SERVICE_KEY;
20
- const API_KEY = process.env.VIBESCOPE_API_KEY;
15
+ function getApiKey() {
16
+ return process.env.VIBESCOPE_API_KEY;
17
+ }
18
+ function getApiUrl() {
19
+ return process.env.VIBESCOPE_API_URL || 'https://vibescope.dev';
20
+ }
21
21
  // ============================================================================
22
22
  // Git URL Detection
23
23
  // ============================================================================
24
+ export function normalizeGitUrl(url) {
25
+ // Remove .git suffix
26
+ let normalized = url.replace(/\.git$/, '');
27
+ // Convert SSH to HTTPS format
28
+ if (normalized.startsWith('git@')) {
29
+ normalized = normalized
30
+ .replace(/^git@/, 'https://')
31
+ .replace(/:([^/])/, '/$1');
32
+ }
33
+ return normalized;
34
+ }
24
35
  export function detectGitUrl() {
25
36
  try {
26
37
  const url = execSync('git config --get remote.origin.url', {
@@ -28,7 +39,6 @@ export function detectGitUrl() {
28
39
  timeout: 5000,
29
40
  stdio: ['pipe', 'pipe', 'pipe'],
30
41
  }).trim();
31
- // Normalize: remove .git suffix, convert SSH to HTTPS format
32
42
  return normalizeGitUrl(url);
33
43
  }
34
44
  catch {
@@ -36,252 +46,42 @@ export function detectGitUrl() {
36
46
  }
37
47
  }
38
48
  // ============================================================================
39
- // Authentication (reused from index.ts)
40
- // ============================================================================
41
- export function hashApiKey(key) {
42
- return createHash('sha256').update(key).digest('hex');
43
- }
44
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
45
- export async function validateApiKey(supabase, apiKey) {
46
- const keyHash = hashApiKey(apiKey);
47
- const { data, error } = await supabase
48
- .from('api_keys')
49
- .select('id, user_id')
50
- .eq('key_hash', keyHash)
51
- .single();
52
- if (error || !data) {
53
- return null;
54
- }
55
- // Cast to expected shape since we're using untyped client
56
- const row = data;
57
- return {
58
- userId: row.user_id,
59
- apiKeyId: row.id,
60
- };
61
- }
62
- // ============================================================================
63
49
  // Verification Logic
64
50
  // ============================================================================
65
51
  export async function verify(gitUrl, projectId) {
66
- // Check environment
67
- if (!SUPABASE_URL || !SUPABASE_SERVICE_KEY) {
68
- return {
69
- status: 'error',
70
- reason: 'Missing SUPABASE_URL or SUPABASE_SERVICE_KEY environment variables',
71
- };
72
- }
73
- if (!API_KEY) {
52
+ // Check environment (read at runtime for testability)
53
+ const apiKey = getApiKey();
54
+ if (!apiKey) {
74
55
  return {
75
56
  status: 'error',
76
57
  reason: 'VIBESCOPE_API_KEY environment variable not set',
77
58
  };
78
59
  }
79
- const supabase = createClient(SUPABASE_URL, SUPABASE_SERVICE_KEY);
80
- // Validate API key
81
- const auth = await validateApiKey(supabase, API_KEY);
82
- if (!auth) {
83
- return {
84
- status: 'error',
85
- reason: 'Invalid VIBESCOPE_API_KEY',
86
- };
87
- }
88
60
  // Auto-detect git URL if not provided
89
61
  if (!gitUrl && !projectId) {
90
62
  gitUrl = detectGitUrl() || undefined;
91
63
  }
92
- // Find project
93
- let projectQuery = supabase
94
- .from('projects')
95
- .select('id, name, git_url')
96
- .eq('user_id', auth.userId);
97
- if (projectId) {
98
- projectQuery = projectQuery.eq('id', projectId);
99
- }
100
- else if (gitUrl) {
101
- projectQuery = projectQuery.eq('git_url', gitUrl);
102
- }
103
- else {
104
- return {
105
- status: 'no_session',
106
- reason: 'Could not detect git URL and no project_id provided',
107
- continuation_prompt: 'Could not detect which project you are working on. Please call start_work_session(git_url: "...") with your repository URL.',
108
- };
109
- }
110
- const { data: project, error: projectError } = await projectQuery.single();
111
- if (projectError || !project) {
112
- // Project not found - this is OK, might be an untracked repo
113
- return {
114
- status: 'compliant',
115
- reason: `No Vibescope project found for ${gitUrl || projectId}. Untracked repository - exit allowed.`,
116
- details: {
117
- session_started: false,
118
- project_id: null,
119
- project_name: null,
120
- git_url: gitUrl || null,
121
- in_progress_tasks: 0,
122
- tasks_completed_this_session: 0,
123
- progress_logs_this_session: 0,
124
- blockers_logged_this_session: 0,
125
- session_duration_minutes: null,
126
- },
127
- };
128
- }
129
- // Check for agent session
130
- const { data: session } = await supabase
131
- .from('agent_sessions')
132
- .select('id, last_synced_at, created_at')
133
- .eq('api_key_id', auth.apiKeyId)
134
- .eq('project_id', project.id)
135
- .single();
136
- if (!session) {
137
- return {
138
- status: 'non_compliant',
139
- reason: 'No Vibescope session started for this project',
140
- continuation_prompt: `[VIBESCOPE ENFORCEMENT] You have not started a Vibescope work session.
141
-
142
- BEFORE you can exit, you MUST call:
143
- start_work_session(git_url: "${project.git_url || project.id}")
144
-
145
- This registers your session and gives you project context.`,
146
- details: {
147
- session_started: false,
148
- project_id: project.id,
149
- project_name: project.name,
150
- git_url: project.git_url,
151
- in_progress_tasks: 0,
152
- tasks_completed_this_session: 0,
153
- progress_logs_this_session: 0,
154
- blockers_logged_this_session: 0,
155
- session_duration_minutes: null,
156
- },
157
- };
158
- }
159
- const sessionStartTime = new Date(session.created_at);
160
- const lastSyncTime = new Date(session.last_synced_at);
161
- const now = new Date();
162
- const sessionDurationMinutes = Math.round((now.getTime() - sessionStartTime.getTime()) / 60000);
163
- // Grace period: if session is less than 1 minute, allow exit
164
- if (sessionDurationMinutes < 1) {
165
- return {
166
- status: 'compliant',
167
- reason: 'Very short session (< 1 minute) - exit allowed',
168
- details: {
169
- session_started: true,
170
- project_id: project.id,
171
- project_name: project.name,
172
- git_url: project.git_url,
173
- in_progress_tasks: 0,
174
- tasks_completed_this_session: 0,
175
- progress_logs_this_session: 0,
176
- blockers_logged_this_session: 0,
177
- session_duration_minutes: sessionDurationMinutes,
178
- },
179
- };
180
- }
181
- // Check for in-progress tasks
182
- const { data: inProgressTasks } = await supabase
183
- .from('tasks')
184
- .select('id, title, progress_percentage')
185
- .eq('project_id', project.id)
186
- .eq('status', 'in_progress');
187
- const inProgressCount = inProgressTasks?.length || 0;
188
- if (inProgressCount > 0) {
189
- const taskList = inProgressTasks
190
- .map((t) => ` - ${t.title} (${t.progress_percentage}% complete)`)
191
- .join('\n');
192
- return {
193
- status: 'non_compliant',
194
- reason: `You have ${inProgressCount} task(s) still in_progress`,
195
- continuation_prompt: `[VIBESCOPE ENFORCEMENT] You have ${inProgressCount} task(s) still marked as in_progress:
196
-
197
- ${taskList}
198
-
199
- You MUST either:
200
- 1. Complete them: complete_task(task_id: "...", summary: "...")
201
- 2. Log why you're stopping: log_progress(project_id: "${project.id}", summary: "Stopping because...")`,
202
- details: {
203
- session_started: true,
204
- project_id: project.id,
205
- project_name: project.name,
206
- git_url: project.git_url,
207
- in_progress_tasks: inProgressCount,
208
- tasks_completed_this_session: 0,
209
- progress_logs_this_session: 0,
210
- blockers_logged_this_session: 0,
211
- session_duration_minutes: sessionDurationMinutes,
64
+ try {
65
+ const response = await fetch(`${getApiUrl()}/api/mcp/verify`, {
66
+ method: 'POST',
67
+ headers: {
68
+ 'Content-Type': 'application/json',
212
69
  },
213
- };
214
- }
215
- // Check for activity this session
216
- const sessionStartIso = sessionStartTime.toISOString();
217
- const [completedResult, progressResult, blockerResult] = await Promise.all([
218
- // Tasks completed after session start
219
- supabase
220
- .from('tasks')
221
- .select('id', { count: 'exact' })
222
- .eq('project_id', project.id)
223
- .eq('status', 'completed')
224
- .gte('completed_at', sessionStartIso),
225
- // Progress logs by agent after session start
226
- supabase
227
- .from('progress_logs')
228
- .select('id', { count: 'exact' })
229
- .eq('project_id', project.id)
230
- .eq('created_by', 'agent')
231
- .gte('created_at', sessionStartIso),
232
- // Blockers logged by agent after session start
233
- supabase
234
- .from('blockers')
235
- .select('id', { count: 'exact' })
236
- .eq('project_id', project.id)
237
- .eq('created_by', 'agent')
238
- .gte('created_at', sessionStartIso),
239
- ]);
240
- const tasksCompleted = completedResult.count || 0;
241
- const progressLogsCount = progressResult.count || 0;
242
- const blockersLogged = blockerResult.count || 0;
243
- // Check if any tracked work was done
244
- const anyWorkTracked = tasksCompleted > 0 || progressLogsCount > 0 || blockersLogged > 0;
245
- if (!anyWorkTracked && sessionDurationMinutes >= 5) {
70
+ body: JSON.stringify({
71
+ api_key: apiKey,
72
+ git_url: gitUrl,
73
+ project_id: projectId,
74
+ }),
75
+ });
76
+ const result = await response.json();
77
+ return result;
78
+ }
79
+ catch (err) {
246
80
  return {
247
- status: 'non_compliant',
248
- reason: `Session active for ${sessionDurationMinutes} minutes but no work was tracked`,
249
- continuation_prompt: `[VIBESCOPE ENFORCEMENT] Your session has been active for ${sessionDurationMinutes} minutes but no work was tracked.
250
-
251
- The human is watching the dashboard and will see an empty session.
252
-
253
- You MUST either:
254
- 1. Pick a task and work on it: get_next_task(project_id: "${project.id}")
255
- 2. Log why you did nothing: log_progress(project_id: "${project.id}", summary: "No work done because...")`,
256
- details: {
257
- session_started: true,
258
- project_id: project.id,
259
- project_name: project.name,
260
- git_url: project.git_url,
261
- in_progress_tasks: 0,
262
- tasks_completed_this_session: tasksCompleted,
263
- progress_logs_this_session: progressLogsCount,
264
- blockers_logged_this_session: blockersLogged,
265
- session_duration_minutes: sessionDurationMinutes,
266
- },
81
+ status: 'error',
82
+ reason: err instanceof Error ? err.message : 'Network error',
267
83
  };
268
84
  }
269
- // All checks passed - compliant!
270
- return {
271
- status: 'compliant',
272
- reason: 'All tracked work completed properly',
273
- details: {
274
- session_started: true,
275
- project_id: project.id,
276
- project_name: project.name,
277
- git_url: project.git_url,
278
- in_progress_tasks: 0,
279
- tasks_completed_this_session: tasksCompleted,
280
- progress_logs_this_session: progressLogsCount,
281
- blockers_logged_this_session: blockersLogged,
282
- session_duration_minutes: sessionDurationMinutes,
283
- },
284
- };
285
85
  }
286
86
  // ============================================================================
287
87
  // CLI Entry Point
@@ -332,8 +132,7 @@ Exit Codes:
332
132
 
333
133
  Environment Variables:
334
134
  VIBESCOPE_API_KEY Required - Your Vibescope API key
335
- SUPABASE_URL Required - Supabase project URL
336
- SUPABASE_SERVICE_KEY Required - Supabase service role key
135
+ VIBESCOPE_API_URL Optional - API URL (default: https://vibescope.dev)
337
136
  `);
338
137
  process.exit(0);
339
138
  }
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Tool Categories Configuration
3
+ *
4
+ * Defines the categorization of MCP tools for discovery.
5
+ * Moved to separate config for lazy-loading optimization.
6
+ */
7
+ export interface ToolEntry {
8
+ name: string;
9
+ brief: string;
10
+ }
11
+ export interface CategoryEntry {
12
+ description: string;
13
+ tools: ToolEntry[];
14
+ }
15
+ export declare const TOOL_CATEGORIES: Record<string, CategoryEntry>;
16
+ /**
17
+ * Get list of category names
18
+ */
19
+ export declare function getCategoryNames(): string[];
20
+ /**
21
+ * Get category summary (without full tool list)
22
+ */
23
+ export declare function getCategorySummary(): Array<{
24
+ name: string;
25
+ description: string;
26
+ tool_count: number;
27
+ }>;
28
+ /**
29
+ * Get tools in a specific category
30
+ */
31
+ export declare function getCategoryTools(category: string): CategoryEntry | undefined;
@@ -0,0 +1,253 @@
1
+ /**
2
+ * Tool Categories Configuration
3
+ *
4
+ * Defines the categorization of MCP tools for discovery.
5
+ * Moved to separate config for lazy-loading optimization.
6
+ */
7
+ export const TOOL_CATEGORIES = {
8
+ session: {
9
+ description: 'Session lifecycle and monitoring',
10
+ tools: [
11
+ { name: 'start_work_session', brief: 'Initialize session, get next task' },
12
+ { name: 'get_help', brief: 'Get workflow guidance' },
13
+ { name: 'get_token_usage', brief: 'View token stats' },
14
+ { name: 'heartbeat', brief: 'Maintain active status' },
15
+ { name: 'end_work_session', brief: 'End session, release tasks' },
16
+ ],
17
+ },
18
+ project: {
19
+ description: 'Project CRUD and configuration',
20
+ tools: [
21
+ { name: 'get_project_context', brief: 'Full project info' },
22
+ { name: 'get_git_workflow', brief: 'Git branching config' },
23
+ { name: 'create_project', brief: 'Create new project' },
24
+ { name: 'update_project', brief: 'Modify project settings' },
25
+ { name: 'update_project_readme', brief: 'Sync README to dashboard' },
26
+ ],
27
+ },
28
+ tasks: {
29
+ description: 'Task management and tracking',
30
+ tools: [
31
+ { name: 'get_tasks', brief: 'List project tasks' },
32
+ { name: 'get_next_task', brief: 'Get highest priority task' },
33
+ { name: 'add_task', brief: 'Create new task' },
34
+ { name: 'update_task', brief: 'Update task status/progress' },
35
+ { name: 'complete_task', brief: 'Mark task done' },
36
+ { name: 'delete_task', brief: 'Remove a task' },
37
+ { name: 'batch_update_tasks', brief: 'Update multiple tasks' },
38
+ { name: 'batch_complete_tasks', brief: 'Complete multiple tasks' },
39
+ { name: 'add_task_reference', brief: 'Add URL to task' },
40
+ { name: 'remove_task_reference', brief: 'Remove URL from task' },
41
+ ],
42
+ },
43
+ milestones: {
44
+ description: 'Task breakdown into steps',
45
+ tools: [
46
+ { name: 'add_milestone', brief: 'Add step to task' },
47
+ { name: 'update_milestone', brief: 'Update milestone' },
48
+ { name: 'complete_milestone', brief: 'Mark step done' },
49
+ { name: 'delete_milestone', brief: 'Remove milestone' },
50
+ { name: 'get_milestones', brief: 'List task milestones' },
51
+ ],
52
+ },
53
+ progress: {
54
+ description: 'Progress logging and activity',
55
+ tools: [
56
+ { name: 'log_progress', brief: 'Record progress update' },
57
+ { name: 'get_activity_feed', brief: 'Combined activity feed' },
58
+ ],
59
+ },
60
+ blockers: {
61
+ description: 'Blocker management',
62
+ tools: [
63
+ { name: 'add_blocker', brief: 'Record a blocker' },
64
+ { name: 'resolve_blocker', brief: 'Mark resolved' },
65
+ { name: 'get_blockers', brief: 'List blockers' },
66
+ { name: 'delete_blocker', brief: 'Remove blocker' },
67
+ ],
68
+ },
69
+ decisions: {
70
+ description: 'Architectural decisions',
71
+ tools: [
72
+ { name: 'log_decision', brief: 'Record decision' },
73
+ { name: 'get_decisions', brief: 'List decisions' },
74
+ { name: 'delete_decision', brief: 'Remove decision' },
75
+ ],
76
+ },
77
+ ideas: {
78
+ description: 'Feature ideas tracking',
79
+ tools: [
80
+ { name: 'add_idea', brief: 'Record an idea' },
81
+ { name: 'update_idea', brief: 'Update idea status' },
82
+ { name: 'get_ideas', brief: 'List ideas' },
83
+ { name: 'delete_idea', brief: 'Remove idea' },
84
+ { name: 'convert_idea_to_task', brief: 'Convert idea to task' },
85
+ ],
86
+ },
87
+ findings: {
88
+ description: 'Audit findings/knowledge base',
89
+ tools: [
90
+ { name: 'add_finding', brief: 'Record audit finding' },
91
+ { name: 'get_findings', brief: 'List findings' },
92
+ { name: 'update_finding', brief: 'Update finding status' },
93
+ { name: 'delete_finding', brief: 'Remove finding' },
94
+ ],
95
+ },
96
+ validation: {
97
+ description: 'Cross-agent task validation',
98
+ tools: [
99
+ { name: 'get_tasks_awaiting_validation', brief: 'Unvalidated tasks' },
100
+ { name: 'claim_validation', brief: 'Claim task for review' },
101
+ { name: 'validate_task', brief: 'Approve/reject task' },
102
+ ],
103
+ },
104
+ deployment: {
105
+ description: 'Deployment coordination',
106
+ tools: [
107
+ { name: 'request_deployment', brief: 'Request deploy' },
108
+ { name: 'claim_deployment_validation', brief: 'Claim for validation' },
109
+ { name: 'report_validation', brief: 'Report build/test results' },
110
+ { name: 'check_deployment_status', brief: 'Get deploy status' },
111
+ { name: 'start_deployment', brief: 'Begin deployment' },
112
+ { name: 'complete_deployment', brief: 'Mark deploy done' },
113
+ { name: 'cancel_deployment', brief: 'Cancel deployment' },
114
+ { name: 'add_deployment_requirement', brief: 'Add pre-deploy step' },
115
+ { name: 'complete_deployment_requirement', brief: 'Mark step done' },
116
+ { name: 'get_deployment_requirements', brief: 'List pre-deploy steps' },
117
+ { name: 'schedule_deployment', brief: 'Schedule future deployment' },
118
+ { name: 'get_scheduled_deployments', brief: 'List scheduled deployments' },
119
+ { name: 'update_scheduled_deployment', brief: 'Update schedule config' },
120
+ { name: 'delete_scheduled_deployment', brief: 'Delete schedule' },
121
+ { name: 'trigger_scheduled_deployment', brief: 'Manual trigger' },
122
+ { name: 'check_due_deployments', brief: 'Check due schedules' },
123
+ ],
124
+ },
125
+ fallback: {
126
+ description: 'Background activities when idle',
127
+ tools: [
128
+ { name: 'start_fallback_activity', brief: 'Start background work' },
129
+ { name: 'stop_fallback_activity', brief: 'Stop background work' },
130
+ { name: 'get_activity_history', brief: 'Activity history' },
131
+ { name: 'get_activity_schedules', brief: 'Activity schedules' },
132
+ ],
133
+ },
134
+ bodies_of_work: {
135
+ description: 'Group tasks into bodies of work',
136
+ tools: [
137
+ { name: 'create_body_of_work', brief: 'Create task group' },
138
+ { name: 'update_body_of_work', brief: 'Update settings' },
139
+ { name: 'get_body_of_work', brief: 'Get with tasks' },
140
+ { name: 'get_bodies_of_work', brief: 'List bodies of work' },
141
+ { name: 'delete_body_of_work', brief: 'Remove body of work' },
142
+ { name: 'add_task_to_body_of_work', brief: 'Add task to group' },
143
+ { name: 'remove_task_from_body_of_work', brief: 'Remove from group' },
144
+ { name: 'activate_body_of_work', brief: 'Activate for work' },
145
+ ],
146
+ },
147
+ requests: {
148
+ description: 'User request handling',
149
+ tools: [
150
+ { name: 'get_pending_requests', brief: 'Unhandled requests' },
151
+ { name: 'acknowledge_request', brief: 'Mark handled' },
152
+ { name: 'answer_question', brief: 'Answer user question' },
153
+ ],
154
+ },
155
+ organizations: {
156
+ description: 'Organization and team management',
157
+ tools: [
158
+ { name: 'list_organizations', brief: 'List user orgs' },
159
+ { name: 'create_organization', brief: 'Create new org' },
160
+ { name: 'update_organization', brief: 'Update org settings' },
161
+ { name: 'delete_organization', brief: 'Delete org' },
162
+ { name: 'list_org_members', brief: 'List org members' },
163
+ { name: 'invite_member', brief: 'Invite by email' },
164
+ { name: 'update_member_role', brief: 'Change member role' },
165
+ { name: 'remove_member', brief: 'Remove from org' },
166
+ { name: 'leave_organization', brief: 'Leave an org' },
167
+ { name: 'share_project_with_org', brief: 'Share project' },
168
+ { name: 'update_project_share', brief: 'Update share perms' },
169
+ { name: 'unshare_project', brief: 'Remove share' },
170
+ { name: 'list_project_shares', brief: 'List project shares' },
171
+ ],
172
+ },
173
+ cost: {
174
+ description: 'Cost monitoring and alerts',
175
+ tools: [
176
+ { name: 'get_cost_summary', brief: 'Cost by period' },
177
+ { name: 'get_cost_alerts', brief: 'List cost alerts' },
178
+ { name: 'add_cost_alert', brief: 'Add threshold alert' },
179
+ { name: 'update_cost_alert', brief: 'Update alert config' },
180
+ { name: 'delete_cost_alert', brief: 'Remove alert' },
181
+ { name: 'get_task_costs', brief: 'Cost per task' },
182
+ ],
183
+ },
184
+ knowledge: {
185
+ description: 'Queryable knowledge base from project data',
186
+ tools: [
187
+ { name: 'query_knowledge_base', brief: 'Aggregated project knowledge in one call' },
188
+ ],
189
+ },
190
+ subtasks: {
191
+ description: 'Subtask management',
192
+ tools: [
193
+ { name: 'add_subtask', brief: 'Add subtask to parent' },
194
+ { name: 'get_subtasks', brief: 'List subtasks' },
195
+ ],
196
+ },
197
+ sprints: {
198
+ description: 'Sprint planning and tracking',
199
+ tools: [
200
+ { name: 'create_sprint', brief: 'Create new sprint' },
201
+ { name: 'update_sprint', brief: 'Update sprint' },
202
+ { name: 'get_sprint', brief: 'Get sprint details' },
203
+ { name: 'get_sprints', brief: 'List sprints' },
204
+ { name: 'delete_sprint', brief: 'Remove sprint' },
205
+ { name: 'start_sprint', brief: 'Start sprint' },
206
+ { name: 'complete_sprint', brief: 'End sprint' },
207
+ { name: 'add_task_to_sprint', brief: 'Add task' },
208
+ { name: 'remove_task_from_sprint', brief: 'Remove task' },
209
+ { name: 'get_sprint_backlog', brief: 'Available tasks' },
210
+ { name: 'get_sprint_velocity', brief: 'Velocity metrics' },
211
+ ],
212
+ },
213
+ git_issues: {
214
+ description: 'Git issue tracking',
215
+ tools: [
216
+ { name: 'add_git_issue', brief: 'Record git issue' },
217
+ { name: 'resolve_git_issue', brief: 'Mark resolved' },
218
+ { name: 'get_git_issues', brief: 'List git issues' },
219
+ { name: 'delete_git_issue', brief: 'Remove issue' },
220
+ ],
221
+ },
222
+ dependencies: {
223
+ description: 'Task dependencies',
224
+ tools: [
225
+ { name: 'add_task_dependency', brief: 'Add dependency' },
226
+ { name: 'remove_task_dependency', brief: 'Remove dependency' },
227
+ { name: 'get_task_dependencies', brief: 'List dependencies' },
228
+ { name: 'get_next_body_of_work_task', brief: 'Next available task' },
229
+ ],
230
+ },
231
+ };
232
+ /**
233
+ * Get list of category names
234
+ */
235
+ export function getCategoryNames() {
236
+ return Object.keys(TOOL_CATEGORIES);
237
+ }
238
+ /**
239
+ * Get category summary (without full tool list)
240
+ */
241
+ export function getCategorySummary() {
242
+ return Object.entries(TOOL_CATEGORIES).map(([name, cat]) => ({
243
+ name,
244
+ description: cat.description,
245
+ tool_count: cat.tools.length,
246
+ }));
247
+ }
248
+ /**
249
+ * Get tools in a specific category
250
+ */
251
+ export function getCategoryTools(category) {
252
+ return TOOL_CATEGORIES[category];
253
+ }