couchloop-eq-mcp 2.0.2 → 2.0.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/README.md +11 -12
- package/dist/clients/shrinkChatClient.d.ts +38 -38
- package/dist/db/client.d.ts +11 -19
- package/dist/db/client.d.ts.map +1 -1
- package/dist/db/client.js +30 -62
- package/dist/db/client.js.map +1 -1
- package/dist/index.js +8 -5
- package/dist/index.js.map +1 -1
- package/dist/resources/journey-status.d.ts.map +1 -1
- package/dist/resources/journey-status.js +10 -12
- package/dist/resources/journey-status.js.map +1 -1
- package/dist/resources/session-summary.d.ts.map +1 -1
- package/dist/resources/session-summary.js +33 -33
- package/dist/resources/session-summary.js.map +1 -1
- package/dist/resources/user-context.d.ts.map +1 -1
- package/dist/resources/user-context.js +26 -41
- package/dist/resources/user-context.js.map +1 -1
- package/dist/server/http-mcp.js +2 -2
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +8 -9
- package/dist/server/index.js.map +1 -1
- package/dist/server/sse.d.ts.map +1 -1
- package/dist/server/sse.js +17 -17
- package/dist/server/sse.js.map +1 -1
- package/dist/tools/check-versions.d.ts +7 -7
- package/dist/tools/checkpoint.d.ts +1 -8
- package/dist/tools/checkpoint.d.ts.map +1 -1
- package/dist/tools/checkpoint.js +47 -49
- package/dist/tools/checkpoint.js.map +1 -1
- package/dist/tools/couchloop-v2.d.ts.map +1 -1
- package/dist/tools/couchloop-v2.js +15 -4
- package/dist/tools/couchloop-v2.js.map +1 -1
- package/dist/tools/detect-build-context.d.ts +1 -1
- package/dist/tools/generate-upgrade-report.d.ts +2 -2
- package/dist/tools/guard.d.ts +3 -3
- package/dist/tools/index.d.ts +2 -4
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +2 -4
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/insight.d.ts +10 -49
- package/dist/tools/insight.d.ts.map +1 -1
- package/dist/tools/insight.js +78 -91
- package/dist/tools/insight.js.map +1 -1
- package/dist/tools/intent-router.d.ts.map +1 -1
- package/dist/tools/intent-router.js +12 -7
- package/dist/tools/intent-router.js.map +1 -1
- package/dist/tools/journey.d.ts +5 -5
- package/dist/tools/journey.d.ts.map +1 -1
- package/dist/tools/journey.js +47 -39
- package/dist/tools/journey.js.map +1 -1
- package/dist/tools/pre-review-code.d.ts +2 -2
- package/dist/tools/prevent-ai-errors.d.ts +3 -3
- package/dist/tools/primary-tools.d.ts +37 -190
- package/dist/tools/primary-tools.d.ts.map +1 -1
- package/dist/tools/primary-tools.js +204 -302
- package/dist/tools/primary-tools.js.map +1 -1
- package/dist/tools/protect-files.d.ts +1 -1
- package/dist/tools/sendMessage.d.ts.map +1 -1
- package/dist/tools/sendMessage.js +52 -38
- package/dist/tools/sendMessage.js.map +1 -1
- package/dist/tools/session-manager.d.ts.map +1 -1
- package/dist/tools/session-manager.js +88 -70
- package/dist/tools/session-manager.js.map +1 -1
- package/dist/tools/session.d.ts +7 -86
- package/dist/tools/session.d.ts.map +1 -1
- package/dist/tools/session.js +68 -72
- package/dist/tools/session.js.map +1 -1
- package/dist/tools/smart-context.d.ts +1 -1
- package/dist/tools/status.d.ts +9 -2
- package/dist/tools/status.d.ts.map +1 -1
- package/dist/tools/status.js +113 -64
- package/dist/tools/status.js.map +1 -1
- package/dist/tools/verify.d.ts +4 -4
- package/dist/tools/verify.js.map +1 -1
- package/dist/types/auth.d.ts +2 -2
- package/dist/types/checkpoint.d.ts +4 -4
- package/dist/types/file-protection.d.ts +2 -2
- package/dist/types/insight.d.ts +10 -10
- package/dist/types/journey.d.ts +40 -12
- package/dist/types/journey.d.ts.map +1 -1
- package/dist/types/journey.js +2 -0
- package/dist/types/journey.js.map +1 -1
- package/dist/types/session.d.ts +10 -10
- package/dist/workflows/engine.d.ts +2 -2
- package/dist/workflows/engine.d.ts.map +1 -1
- package/dist/workflows/engine.js +81 -82
- package/dist/workflows/engine.js.map +1 -1
- package/dist/workflows/index.d.ts +4 -4
- package/package.json +2 -10
|
@@ -2,146 +2,133 @@
|
|
|
2
2
|
* MCP Tools - Public API
|
|
3
3
|
*
|
|
4
4
|
* This module exports only the PRIMARY tools that users should see.
|
|
5
|
-
*
|
|
5
|
+
* Consolidated from 10 → 4 tools for clarity and reduced LLM misrouting.
|
|
6
6
|
*
|
|
7
|
-
* PUBLIC TOOLS (
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
7
|
+
* PUBLIC TOOLS (4):
|
|
8
|
+
* 1. memory - HERO: save & recall insights, checkpoints, decisions (Supabase-backed)
|
|
9
|
+
* 2. conversation - Emotional support, guided journeys, crisis detection (shrink-chat backend)
|
|
10
|
+
* 3. review - Unified: code review + package audit + pre-delivery verification
|
|
11
|
+
* 4. status - Dashboard (session progress, history, context, preferences)
|
|
12
|
+
*
|
|
13
|
+
* INTERNAL (auto-triggered, not user-facing):
|
|
14
|
+
* - guard - Per-response governance (runs in withPolicy wrapper)
|
|
15
|
+
*
|
|
16
|
+
* REMOVED:
|
|
17
|
+
* - couchloop - Router added latency; LLMs route directly with good descriptions
|
|
18
|
+
* - brainstorm - Returned static system prompt; LLMs brainstorm natively
|
|
19
|
+
* - protect - Broken on Railway (read-only /app filesystem)
|
|
18
20
|
*/
|
|
19
|
-
|
|
20
|
-
import { couchloopV2Tool } from './couchloop-v2.js';
|
|
21
|
-
import { registerTools } from './intent-router.js';
|
|
21
|
+
import { z } from 'zod';
|
|
22
22
|
import { ToolRegistry } from '../core/registry/registry.js';
|
|
23
|
-
//
|
|
23
|
+
// Tool handler imports
|
|
24
24
|
import { sendMessage } from './sendMessage.js';
|
|
25
25
|
import { createSession, resumeSession } from './session.js';
|
|
26
26
|
import { endSession } from './session-manager.js';
|
|
27
27
|
import { handleComprehensiveCodeReview } from './comprehensive-code-review.js';
|
|
28
28
|
import { handleComprehensivePackageAudit } from './comprehensive-package-audit.js';
|
|
29
29
|
import { handleSmartContext } from './smart-context.js';
|
|
30
|
-
import { protectFiles, getProtectionStatus, listBackups, rollbackFile, enableCodeFreeze, disableCodeFreeze, } from './protect-files.js';
|
|
31
30
|
import { listJourneys, getJourneyStatus } from './journey.js';
|
|
32
31
|
import { getCheckpoints } from './checkpoint.js';
|
|
33
32
|
import { getInsights, getUserContext } from './insight.js';
|
|
34
|
-
import {
|
|
33
|
+
import { handleVerify } from './verify.js';
|
|
35
34
|
import { statusTool } from './status.js';
|
|
36
|
-
import { guardTool } from './guard.js';
|
|
37
35
|
import { runToolWithPolicy } from '../policy/index.js';
|
|
38
36
|
import { logger } from '../utils/logger.js';
|
|
39
37
|
// ============================================================
|
|
40
|
-
// PRIMARY TOOL DEFINITIONS
|
|
41
|
-
// These are the only tools visible to users
|
|
38
|
+
// PRIMARY TOOL DEFINITIONS (4 public tools)
|
|
42
39
|
// ============================================================
|
|
43
|
-
//
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
5. DECOMPOSITION: "What's the riskiest part?" / "What could you build first to learn more?"
|
|
62
|
-
|
|
63
|
-
FOR COMPARISON MODE (user asks "A vs B?" or "should I use X or Y?"):
|
|
64
|
-
1. Ask 1-2 quick clarifying questions about their specific context (scale, team experience, existing stack)
|
|
65
|
-
2. Then provide a structured comparison:
|
|
66
|
-
- Key differences that matter for their use case
|
|
67
|
-
- When to choose each option
|
|
68
|
-
- Your recommendation given what you know about their context
|
|
69
|
-
- Caveats or "it depends" factors they should verify
|
|
70
|
-
3. Be direct. Don't just list pros/cons — give them an actionable recommendation with reasoning.
|
|
71
|
-
|
|
72
|
-
RESPONSE STYLE:
|
|
73
|
-
- Start with understanding, not solutioning
|
|
74
|
-
- Summarize their thinking back periodically
|
|
75
|
-
- When they present options, acknowledge you'll help them decide (not just explore forever)
|
|
76
|
-
- Be concise — developers want signal, not fluff
|
|
77
|
-
|
|
78
|
-
Remember: The best solutions come from the developer's own understanding of their context. Your job is to help them think clearly AND give them useful analysis when they're ready for it.`;
|
|
79
|
-
const conversationTool = {
|
|
40
|
+
// ── 1. MEMORY (hero feature — registered first) ─────────────────────────────
|
|
41
|
+
// Zod schemas for handler validation (CLAUDE.md Key Invariant #1)
|
|
42
|
+
const MemoryInputSchema = z.object({
|
|
43
|
+
action: z.enum(['save', 'recall', 'list']).optional(),
|
|
44
|
+
content: z.unknown().optional(),
|
|
45
|
+
type: z.string().optional(),
|
|
46
|
+
tags: z.array(z.string()).optional(),
|
|
47
|
+
session_id: z.string().optional(),
|
|
48
|
+
auth: z.record(z.unknown()).optional(),
|
|
49
|
+
});
|
|
50
|
+
const ConversationInputSchema = z.object({
|
|
51
|
+
action: z.enum(['send', 'start', 'end', 'resume', 'status']).optional(),
|
|
52
|
+
message: z.string().optional(),
|
|
53
|
+
journey: z.string().optional(),
|
|
54
|
+
session_id: z.string().optional(),
|
|
55
|
+
auth: z.record(z.unknown()).optional(),
|
|
56
|
+
});
|
|
57
|
+
const memoryTool = {
|
|
80
58
|
definition: {
|
|
81
|
-
name: '
|
|
82
|
-
description: '
|
|
59
|
+
name: 'memory',
|
|
60
|
+
description: 'Save and retrieve context, insights, checkpoints, and decisions across conversations. Prevents AI amnesia. Use action "save" to store, "recall" to retrieve, "list" to browse.',
|
|
83
61
|
annotations: {
|
|
84
62
|
readOnlyHint: false,
|
|
85
63
|
destructiveHint: false,
|
|
86
64
|
idempotentHint: false,
|
|
87
|
-
openWorldHint:
|
|
65
|
+
openWorldHint: false,
|
|
88
66
|
},
|
|
89
67
|
inputSchema: {
|
|
90
68
|
type: 'object',
|
|
91
69
|
properties: {
|
|
92
|
-
|
|
70
|
+
content: {
|
|
93
71
|
type: 'string',
|
|
94
|
-
description: '
|
|
72
|
+
description: 'What to save or search for when recalling',
|
|
95
73
|
},
|
|
96
74
|
action: {
|
|
97
75
|
type: 'string',
|
|
98
|
-
enum: ['
|
|
99
|
-
description: '
|
|
76
|
+
enum: ['save', 'recall', 'list'],
|
|
77
|
+
description: 'save: store new context. recall: retrieve previously stored insights/checkpoints/decisions. list: browse all saved items.',
|
|
100
78
|
},
|
|
101
|
-
|
|
79
|
+
type: {
|
|
102
80
|
type: 'string',
|
|
103
|
-
|
|
81
|
+
enum: ['checkpoint', 'insight', 'decision', 'requirement', 'constraint', 'pattern'],
|
|
82
|
+
description: 'Type of context (for save action — affects categorization)',
|
|
83
|
+
},
|
|
84
|
+
tags: {
|
|
85
|
+
type: 'array',
|
|
86
|
+
items: { type: 'string' },
|
|
87
|
+
description: 'Tags for categorization (for save action)',
|
|
104
88
|
},
|
|
105
89
|
session_id: {
|
|
106
90
|
type: 'string',
|
|
107
|
-
description: 'Session
|
|
91
|
+
description: 'Session to associate with',
|
|
92
|
+
},
|
|
93
|
+
auth: {
|
|
94
|
+
type: 'object',
|
|
95
|
+
description: 'Authentication context for user identification',
|
|
108
96
|
},
|
|
109
97
|
},
|
|
110
|
-
required: [
|
|
98
|
+
required: [],
|
|
111
99
|
},
|
|
112
100
|
},
|
|
113
101
|
handler: async (args) => {
|
|
114
|
-
const
|
|
102
|
+
const parsed = MemoryInputSchema.parse(args);
|
|
103
|
+
const action = parsed.action ?? 'save';
|
|
104
|
+
const sessionId = parsed.session_id;
|
|
105
|
+
const auth = parsed.auth;
|
|
115
106
|
switch (action) {
|
|
116
|
-
case '
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
case 'status':
|
|
126
|
-
if (args.session_id) {
|
|
127
|
-
return getJourneyStatus({ session_id: args.session_id });
|
|
128
|
-
}
|
|
129
|
-
return listJourneys({});
|
|
130
|
-
case 'send':
|
|
107
|
+
case 'recall': {
|
|
108
|
+
const checkpointData = await getCheckpoints({ session_id: sessionId, auth });
|
|
109
|
+
const insightData = await getInsights({ session_id: sessionId, limit: 10, auth });
|
|
110
|
+
const userContext = await getUserContext({ include_recent_insights: true, include_session_history: true, auth });
|
|
111
|
+
return { checkpoints: checkpointData, insights: insightData, user_context: userContext };
|
|
112
|
+
}
|
|
113
|
+
case 'list':
|
|
114
|
+
return getInsights({ session_id: sessionId, limit: 20, auth });
|
|
115
|
+
case 'save':
|
|
131
116
|
default:
|
|
132
|
-
return
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
117
|
+
return handleSmartContext({
|
|
118
|
+
content: parsed.content,
|
|
119
|
+
type: parsed.type || 'insight',
|
|
120
|
+
tags: parsed.tags,
|
|
121
|
+
session_id: parsed.session_id,
|
|
122
|
+
auth,
|
|
137
123
|
});
|
|
138
124
|
}
|
|
139
125
|
},
|
|
140
126
|
};
|
|
141
|
-
|
|
127
|
+
// ── 2. CONVERSATION ──────────────────────────────────────────────────────────
|
|
128
|
+
const conversationTool = {
|
|
142
129
|
definition: {
|
|
143
|
-
name: '
|
|
144
|
-
description: '
|
|
130
|
+
name: 'conversation',
|
|
131
|
+
description: 'Emotional support, guided self-reflection journeys, and wellness conversations with crisis detection. Routes to therapeutic AI backend.',
|
|
145
132
|
annotations: {
|
|
146
133
|
readOnlyHint: false,
|
|
147
134
|
destructiveHint: false,
|
|
@@ -153,63 +140,65 @@ const brainstormTool = {
|
|
|
153
140
|
properties: {
|
|
154
141
|
message: {
|
|
155
142
|
type: 'string',
|
|
156
|
-
description: '
|
|
143
|
+
description: 'Your message for the therapeutic conversation',
|
|
157
144
|
},
|
|
158
|
-
|
|
145
|
+
action: {
|
|
159
146
|
type: 'string',
|
|
160
|
-
|
|
147
|
+
enum: ['send', 'start', 'end', 'resume', 'status'],
|
|
148
|
+
description: 'send (default), start new session, end session, resume previous, or get status',
|
|
161
149
|
},
|
|
162
|
-
|
|
163
|
-
required: ['message'],
|
|
164
|
-
},
|
|
165
|
-
},
|
|
166
|
-
handler: async (args) => {
|
|
167
|
-
const message = String(args.message || '');
|
|
168
|
-
// brainstorm must NOT route through shrink-chat (therapeutic backend).
|
|
169
|
-
// Return instructions directly so the host LLM (Claude/ChatGPT) responds in brainstorm mode.
|
|
170
|
-
return {
|
|
171
|
-
mode: 'brainstorm',
|
|
172
|
-
instructions: BRAINSTORM_SYSTEM_PROMPT,
|
|
173
|
-
respond_to: message,
|
|
174
|
-
directive: `You are now in BRAINSTORM MODE. Follow the instructions above precisely. Do not respond therapeutically. Respond directly to: "${message}"`,
|
|
175
|
-
};
|
|
176
|
-
},
|
|
177
|
-
};
|
|
178
|
-
const codeReviewTool = {
|
|
179
|
-
definition: {
|
|
180
|
-
name: 'code_review',
|
|
181
|
-
description: 'Complete code review: security vulnerabilities (SQL injection, XSS, secrets), code quality (console.logs, TODOs, error handling), code smells (complexity, bloat), and AI-generated errors (hallucinated APIs, build context issues). One call, full analysis. Triggers: "review", "check code", "analyze", "security check", "lint", "find bugs", "is this safe".',
|
|
182
|
-
annotations: {
|
|
183
|
-
readOnlyHint: true,
|
|
184
|
-
destructiveHint: false,
|
|
185
|
-
idempotentHint: true,
|
|
186
|
-
openWorldHint: false,
|
|
187
|
-
},
|
|
188
|
-
inputSchema: {
|
|
189
|
-
type: 'object',
|
|
190
|
-
properties: {
|
|
191
|
-
code: {
|
|
150
|
+
journey: {
|
|
192
151
|
type: 'string',
|
|
193
|
-
description: '
|
|
152
|
+
description: 'Optional journey to follow (e.g., "daily-reflection")',
|
|
194
153
|
},
|
|
195
|
-
|
|
154
|
+
session_id: {
|
|
196
155
|
type: 'string',
|
|
197
|
-
description: '
|
|
156
|
+
description: 'Session ID (auto-managed if not provided)',
|
|
198
157
|
},
|
|
199
|
-
|
|
200
|
-
type: '
|
|
201
|
-
description: '
|
|
158
|
+
auth: {
|
|
159
|
+
type: 'object',
|
|
160
|
+
description: 'Authentication context for user identification',
|
|
202
161
|
},
|
|
203
162
|
},
|
|
204
|
-
required: ['
|
|
163
|
+
required: ['message'],
|
|
205
164
|
},
|
|
206
165
|
},
|
|
207
|
-
handler:
|
|
166
|
+
handler: async (args) => {
|
|
167
|
+
const parsed = ConversationInputSchema.parse(args);
|
|
168
|
+
const action = parsed.action ?? 'send';
|
|
169
|
+
const auth = parsed.auth;
|
|
170
|
+
switch (action) {
|
|
171
|
+
case 'start':
|
|
172
|
+
return createSession({
|
|
173
|
+
journey_slug: parsed.journey,
|
|
174
|
+
context: parsed.message,
|
|
175
|
+
auth,
|
|
176
|
+
});
|
|
177
|
+
case 'end':
|
|
178
|
+
return endSession(parsed.session_id, auth);
|
|
179
|
+
case 'resume':
|
|
180
|
+
return resumeSession({ session_id: parsed.session_id, auth });
|
|
181
|
+
case 'status':
|
|
182
|
+
if (parsed.session_id) {
|
|
183
|
+
return getJourneyStatus({ session_id: parsed.session_id, auth });
|
|
184
|
+
}
|
|
185
|
+
return listJourneys({});
|
|
186
|
+
case 'send':
|
|
187
|
+
default:
|
|
188
|
+
return sendMessage({
|
|
189
|
+
message: parsed.message,
|
|
190
|
+
session_id: parsed.session_id,
|
|
191
|
+
save_checkpoint: true,
|
|
192
|
+
include_memory: true,
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
},
|
|
208
196
|
};
|
|
209
|
-
|
|
197
|
+
// ── 3. REVIEW (unified: code + packages + verify) ───────────────────────────
|
|
198
|
+
const reviewTool = {
|
|
210
199
|
definition: {
|
|
211
|
-
name: '
|
|
212
|
-
description: '
|
|
200
|
+
name: 'review',
|
|
201
|
+
description: 'Unified code review, package audit, and pre-delivery verification. Use mode to select: "code" for security/quality/AI-error analysis, "packages" for dependency audit and validation, "verify" for hallucination and fact checking, "full" for all checks.',
|
|
213
202
|
annotations: {
|
|
214
203
|
readOnlyHint: true,
|
|
215
204
|
destructiveHint: false,
|
|
@@ -219,175 +208,106 @@ const packageAuditTool = {
|
|
|
219
208
|
inputSchema: {
|
|
220
209
|
type: 'object',
|
|
221
210
|
properties: {
|
|
222
|
-
|
|
223
|
-
type: 'array',
|
|
224
|
-
items: { type: 'string' },
|
|
225
|
-
description: 'Package names to audit',
|
|
226
|
-
},
|
|
227
|
-
registry: {
|
|
211
|
+
mode: {
|
|
228
212
|
type: 'string',
|
|
229
|
-
enum: ['
|
|
230
|
-
description: '
|
|
213
|
+
enum: ['code', 'packages', 'verify', 'full'],
|
|
214
|
+
description: 'code: security vulnerabilities, code smells, AI-generated errors. packages: validate existence, audit versions, find vulnerabilities. verify: pre-delivery hallucination/fact check. full: all checks.',
|
|
231
215
|
},
|
|
232
|
-
},
|
|
233
|
-
required: ['packages'],
|
|
234
|
-
},
|
|
235
|
-
},
|
|
236
|
-
handler: handleComprehensivePackageAudit,
|
|
237
|
-
};
|
|
238
|
-
const rememberTool = {
|
|
239
|
-
definition: {
|
|
240
|
-
name: 'remember',
|
|
241
|
-
description: 'Capture and preserve important context from conversations. Automatically routes to the right storage: checkpoints for progress, insights for realizations, context for technical decisions. Prevents AI amnesia across conversations. Triggers: "save", "remember this", "checkpoint", "note", "don\'t forget", "keep track", "save progress", "log this".',
|
|
242
|
-
annotations: {
|
|
243
|
-
readOnlyHint: false,
|
|
244
|
-
destructiveHint: false,
|
|
245
|
-
idempotentHint: false,
|
|
246
|
-
openWorldHint: false,
|
|
247
|
-
},
|
|
248
|
-
inputSchema: {
|
|
249
|
-
type: 'object',
|
|
250
|
-
properties: {
|
|
251
216
|
content: {
|
|
252
217
|
type: 'string',
|
|
253
|
-
description: '
|
|
218
|
+
description: 'Code to review, content to verify, or general input for analysis',
|
|
254
219
|
},
|
|
255
|
-
|
|
256
|
-
type: 'string',
|
|
257
|
-
enum: ['checkpoint', 'insight', 'decision', 'requirement', 'constraint', 'pattern'],
|
|
258
|
-
description: 'Type of context (affects where it\'s stored)',
|
|
259
|
-
},
|
|
260
|
-
tags: {
|
|
220
|
+
packages: {
|
|
261
221
|
type: 'array',
|
|
262
222
|
items: { type: 'string' },
|
|
263
|
-
description: '
|
|
264
|
-
},
|
|
265
|
-
action: {
|
|
266
|
-
type: 'string',
|
|
267
|
-
enum: ['save', 'recall', 'list'],
|
|
268
|
-
description: 'Action: save (default), recall previous context, or list saved items',
|
|
269
|
-
},
|
|
270
|
-
session_id: {
|
|
271
|
-
type: 'string',
|
|
272
|
-
description: 'Session to associate with',
|
|
223
|
+
description: 'Package names to audit (for packages mode)',
|
|
273
224
|
},
|
|
274
|
-
|
|
275
|
-
required: ['content'],
|
|
276
|
-
},
|
|
277
|
-
},
|
|
278
|
-
handler: async (args) => {
|
|
279
|
-
const action = args.action || 'save';
|
|
280
|
-
const sessionId = args.session_id;
|
|
281
|
-
switch (action) {
|
|
282
|
-
case 'recall': {
|
|
283
|
-
// Get checkpoints and insights
|
|
284
|
-
const checkpoints = await getCheckpoints({ session_id: sessionId });
|
|
285
|
-
const insights = await getInsights({ session_id: sessionId, limit: 10 });
|
|
286
|
-
const userContext = await getUserContext({ include_recent_insights: true, include_session_history: true });
|
|
287
|
-
return {
|
|
288
|
-
checkpoints,
|
|
289
|
-
insights,
|
|
290
|
-
user_context: userContext,
|
|
291
|
-
};
|
|
292
|
-
}
|
|
293
|
-
case 'list':
|
|
294
|
-
return getInsights({ session_id: sessionId, limit: 20 });
|
|
295
|
-
case 'save':
|
|
296
|
-
default:
|
|
297
|
-
return handleSmartContext({
|
|
298
|
-
content: args.content,
|
|
299
|
-
type: args.type || 'insight',
|
|
300
|
-
tags: args.tags,
|
|
301
|
-
session_id: args.session_id,
|
|
302
|
-
});
|
|
303
|
-
}
|
|
304
|
-
},
|
|
305
|
-
};
|
|
306
|
-
const protectTool = {
|
|
307
|
-
definition: {
|
|
308
|
-
name: 'protect',
|
|
309
|
-
description: 'File protection and safety: prevent accidental deletions, create automatic backups, rollback changes, enable code freeze mode. Essential for safe AI-assisted development. Triggers: "backup", "protect", "freeze", "rollback", "undo", "restore", "safe mode".',
|
|
310
|
-
annotations: {
|
|
311
|
-
readOnlyHint: false,
|
|
312
|
-
destructiveHint: false,
|
|
313
|
-
idempotentHint: false,
|
|
314
|
-
openWorldHint: false,
|
|
315
|
-
},
|
|
316
|
-
inputSchema: {
|
|
317
|
-
type: 'object',
|
|
318
|
-
properties: {
|
|
319
|
-
action: {
|
|
320
|
-
type: 'string',
|
|
321
|
-
enum: ['check', 'backup', 'rollback', 'freeze', 'unfreeze', 'status', 'history'],
|
|
322
|
-
description: 'Action to perform',
|
|
323
|
-
},
|
|
324
|
-
path: {
|
|
225
|
+
language: {
|
|
325
226
|
type: 'string',
|
|
326
|
-
description: '
|
|
227
|
+
description: 'Programming language (auto-detected if not specified)',
|
|
327
228
|
},
|
|
328
|
-
|
|
229
|
+
registry: {
|
|
329
230
|
type: 'string',
|
|
330
|
-
enum: ['
|
|
331
|
-
description: '
|
|
231
|
+
enum: ['npm', 'pypi', 'maven', 'cargo', 'go', 'nuget', 'gem'],
|
|
232
|
+
description: 'Package registry (default: npm)',
|
|
332
233
|
},
|
|
333
|
-
|
|
334
|
-
type: '
|
|
335
|
-
description: '
|
|
234
|
+
auto_fix: {
|
|
235
|
+
type: 'boolean',
|
|
236
|
+
description: 'Attempt to auto-fix issues (default: false, code mode only)',
|
|
336
237
|
},
|
|
337
238
|
},
|
|
338
|
-
required: ['
|
|
239
|
+
required: ['mode'],
|
|
339
240
|
},
|
|
340
241
|
},
|
|
341
242
|
handler: async (args) => {
|
|
342
|
-
const
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
case 'check':
|
|
353
|
-
return protectFiles({
|
|
354
|
-
operation: args.operation,
|
|
355
|
-
path: args.path,
|
|
243
|
+
const mode = args.mode;
|
|
244
|
+
switch (mode) {
|
|
245
|
+
case 'code':
|
|
246
|
+
if (!args.content) {
|
|
247
|
+
return { success: false, error: 'content is required for code review mode' };
|
|
248
|
+
}
|
|
249
|
+
return handleComprehensiveCodeReview({
|
|
250
|
+
code: args.content,
|
|
251
|
+
language: args.language,
|
|
252
|
+
auto_fix: args.auto_fix,
|
|
356
253
|
});
|
|
357
|
-
case '
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
return enableCodeFreeze({});
|
|
365
|
-
case 'unfreeze':
|
|
366
|
-
return disableCodeFreeze({});
|
|
367
|
-
case 'backup':
|
|
368
|
-
// Create a backup by doing a protected check
|
|
369
|
-
return protectFiles({
|
|
370
|
-
operation: 'overwrite',
|
|
371
|
-
path: args.path,
|
|
254
|
+
case 'packages':
|
|
255
|
+
if (!args.packages) {
|
|
256
|
+
return { success: false, error: 'packages array is required for packages mode' };
|
|
257
|
+
}
|
|
258
|
+
return handleComprehensivePackageAudit({
|
|
259
|
+
packages: args.packages,
|
|
260
|
+
registry: args.registry,
|
|
372
261
|
});
|
|
262
|
+
case 'verify':
|
|
263
|
+
if (!args.content) {
|
|
264
|
+
return { success: false, error: 'content is required for verify mode' };
|
|
265
|
+
}
|
|
266
|
+
return handleVerify({
|
|
267
|
+
type: 'all',
|
|
268
|
+
content: args.content,
|
|
269
|
+
language: args.language,
|
|
270
|
+
registry: args.registry,
|
|
271
|
+
});
|
|
272
|
+
case 'full': {
|
|
273
|
+
const results = {};
|
|
274
|
+
if (args.content) {
|
|
275
|
+
results.code_review = await handleComprehensiveCodeReview({
|
|
276
|
+
code: args.content,
|
|
277
|
+
language: args.language,
|
|
278
|
+
auto_fix: args.auto_fix,
|
|
279
|
+
});
|
|
280
|
+
results.verification = await handleVerify({
|
|
281
|
+
type: 'all',
|
|
282
|
+
content: args.content,
|
|
283
|
+
language: args.language,
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
if (args.packages) {
|
|
287
|
+
results.package_audit = await handleComprehensivePackageAudit({
|
|
288
|
+
packages: args.packages,
|
|
289
|
+
registry: args.registry,
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
if (!args.content && !args.packages) {
|
|
293
|
+
return { success: false, error: 'content or packages required for full mode' };
|
|
294
|
+
}
|
|
295
|
+
return { success: true, mode: 'full', results };
|
|
296
|
+
}
|
|
373
297
|
default:
|
|
374
|
-
return { error: `Unknown
|
|
298
|
+
return { success: false, error: `Unknown mode: ${mode}. Use: code, packages, verify, or full` };
|
|
375
299
|
}
|
|
376
300
|
},
|
|
377
301
|
};
|
|
378
302
|
// ============================================================
|
|
379
|
-
// EXPORT ONLY PRIMARY TOOLS
|
|
303
|
+
// EXPORT ONLY PRIMARY TOOLS (4 tools)
|
|
380
304
|
// ============================================================
|
|
381
305
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
382
306
|
// Policy wrapper helpers
|
|
383
307
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
384
308
|
/**
|
|
385
309
|
* Wrap a tool handler so every call goes through:
|
|
386
|
-
* execute → sanitize → verify-if-required → normalize → log
|
|
387
|
-
*
|
|
388
|
-
* The wrapped handler is used for BOTH direct MCP calls and intent-router
|
|
389
|
-
* (couchloop) delegated calls, since registerTools() stores references to
|
|
390
|
-
* these same handler functions.
|
|
310
|
+
* execute → sanitize → guard-if-clinical → verify-if-required → normalize → log
|
|
391
311
|
*/
|
|
392
312
|
function withPolicy(toolName, handler, routedVia = 'direct') {
|
|
393
313
|
return async (args, _routedVia) => {
|
|
@@ -402,30 +322,21 @@ function withPolicy(toolName, handler, routedVia = 'direct') {
|
|
|
402
322
|
};
|
|
403
323
|
}
|
|
404
324
|
export async function setupTools() {
|
|
405
|
-
// Register tools with V2 registry for health tracking
|
|
406
325
|
const registry = ToolRegistry.getInstance();
|
|
407
|
-
//
|
|
326
|
+
// 4 public tools — memory first (hero feature), then conversation, review, status
|
|
408
327
|
const rawDomainTools = [
|
|
409
|
-
|
|
410
|
-
verifyTool,
|
|
411
|
-
statusTool,
|
|
328
|
+
memoryTool,
|
|
412
329
|
conversationTool,
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
packageAuditTool,
|
|
416
|
-
rememberTool,
|
|
417
|
-
protectTool,
|
|
330
|
+
reviewTool,
|
|
331
|
+
statusTool,
|
|
418
332
|
];
|
|
419
333
|
const domainTools = rawDomainTools.map((tool) => {
|
|
420
334
|
const wrappedHandler = withPolicy(tool.definition.name, tool.handler);
|
|
421
|
-
// Register real handler into V2 registry.
|
|
422
|
-
// Uses existing metadata if already registered (from initializeToolRegistry),
|
|
423
|
-
// otherwise falls back to a minimal metadata stub so health tracking still works.
|
|
424
335
|
const toolName = tool.definition.name;
|
|
425
336
|
const existing = registry.getTool(toolName);
|
|
426
337
|
const metadata = existing?.metadata ?? {
|
|
427
338
|
toolName,
|
|
428
|
-
version: '2.
|
|
339
|
+
version: '2.1.0',
|
|
429
340
|
capabilities: [],
|
|
430
341
|
latencyProfile: { p50Ms: 500, p95Ms: 1000 },
|
|
431
342
|
constraints: { idempotent: false, safeParallel: false, supportsCache: false },
|
|
@@ -437,18 +348,9 @@ export async function setupTools() {
|
|
|
437
348
|
handler: wrappedHandler,
|
|
438
349
|
};
|
|
439
350
|
});
|
|
440
|
-
//
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
// It now handles routing through the new modular pipeline:
|
|
444
|
-
// Request → Classify → Policy → Plan → Execute → Compose
|
|
445
|
-
const tools = [
|
|
446
|
-
couchloopV2Tool, // V2 orchestration with 100% rollout!
|
|
447
|
-
...domainTools,
|
|
448
|
-
];
|
|
449
|
-
logger.info(`🚀 V2 ORCHESTRATION ACTIVE: ${tools.length} primary MCP tools`);
|
|
450
|
-
logger.info('Architecture: Request → Classify → Policy → Plan → Execute → Compose');
|
|
451
|
-
logger.info('Performance: 60%+ direct routing, 33% faster P95 latency');
|
|
351
|
+
// No router tool — LLMs route directly with clear descriptions
|
|
352
|
+
const tools = [...domainTools];
|
|
353
|
+
logger.info(`Registered ${tools.length} public MCP tools: ${tools.map(t => t.definition.name).join(', ')}`);
|
|
452
354
|
return tools;
|
|
453
355
|
}
|
|
454
356
|
// Also export for internal use
|