couchloop-eq-mcp 1.0.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 (222) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +358 -0
  3. package/assets/logo/README.md +12 -0
  4. package/assets/logo/couchloop_EQ-IconLogo.png +0 -0
  5. package/dist/auth/middleware.d.ts +8 -0
  6. package/dist/auth/middleware.d.ts.map +1 -0
  7. package/dist/auth/middleware.js +59 -0
  8. package/dist/auth/middleware.js.map +1 -0
  9. package/dist/clients/shrinkChatClient.d.ts +195 -0
  10. package/dist/clients/shrinkChatClient.d.ts.map +1 -0
  11. package/dist/clients/shrinkChatClient.js +349 -0
  12. package/dist/clients/shrinkChatClient.js.map +1 -0
  13. package/dist/db/client.d.ts +23 -0
  14. package/dist/db/client.d.ts.map +1 -0
  15. package/dist/db/client.js +78 -0
  16. package/dist/db/client.js.map +1 -0
  17. package/dist/db/migrate.d.ts +4 -0
  18. package/dist/db/migrate.d.ts.map +1 -0
  19. package/dist/db/migrate.js +34 -0
  20. package/dist/db/migrate.js.map +1 -0
  21. package/dist/db/migrations/schema.d.ts +1074 -0
  22. package/dist/db/migrations/schema.d.ts.map +1 -0
  23. package/dist/db/migrations/schema.js +160 -0
  24. package/dist/db/migrations/schema.js.map +1 -0
  25. package/dist/db/schema.d.ts +1213 -0
  26. package/dist/db/schema.d.ts.map +1 -0
  27. package/dist/db/schema.js +157 -0
  28. package/dist/db/schema.js.map +1 -0
  29. package/dist/db/seed.d.ts +4 -0
  30. package/dist/db/seed.d.ts.map +1 -0
  31. package/dist/db/seed.js +57 -0
  32. package/dist/db/seed.js.map +1 -0
  33. package/dist/db/seedOAuth.d.ts +4 -0
  34. package/dist/db/seedOAuth.d.ts.map +1 -0
  35. package/dist/db/seedOAuth.js +76 -0
  36. package/dist/db/seedOAuth.js.map +1 -0
  37. package/dist/index.d.ts +3 -0
  38. package/dist/index.d.ts.map +1 -0
  39. package/dist/index.js +93 -0
  40. package/dist/index.js.map +1 -0
  41. package/dist/resources/index.d.ts +11 -0
  42. package/dist/resources/index.d.ts.map +1 -0
  43. package/dist/resources/index.js +56 -0
  44. package/dist/resources/index.js.map +1 -0
  45. package/dist/resources/journey-status.d.ts +2 -0
  46. package/dist/resources/journey-status.d.ts.map +1 -0
  47. package/dist/resources/journey-status.js +42 -0
  48. package/dist/resources/journey-status.js.map +1 -0
  49. package/dist/resources/session-summary.d.ts +2 -0
  50. package/dist/resources/session-summary.d.ts.map +1 -0
  51. package/dist/resources/session-summary.js +85 -0
  52. package/dist/resources/session-summary.js.map +1 -0
  53. package/dist/resources/user-context.d.ts +2 -0
  54. package/dist/resources/user-context.d.ts.map +1 -0
  55. package/dist/resources/user-context.js +79 -0
  56. package/dist/resources/user-context.js.map +1 -0
  57. package/dist/server/index.d.ts +3 -0
  58. package/dist/server/index.d.ts.map +1 -0
  59. package/dist/server/index.js +385 -0
  60. package/dist/server/index.js.map +1 -0
  61. package/dist/server/middleware/auth.d.ts +30 -0
  62. package/dist/server/middleware/auth.d.ts.map +1 -0
  63. package/dist/server/middleware/auth.js +157 -0
  64. package/dist/server/middleware/auth.js.map +1 -0
  65. package/dist/server/oauth/anomalyDetection.d.ts +146 -0
  66. package/dist/server/oauth/anomalyDetection.d.ts.map +1 -0
  67. package/dist/server/oauth/anomalyDetection.js +405 -0
  68. package/dist/server/oauth/anomalyDetection.js.map +1 -0
  69. package/dist/server/oauth/authServer.d.ts +61 -0
  70. package/dist/server/oauth/authServer.d.ts.map +1 -0
  71. package/dist/server/oauth/authServer.js +283 -0
  72. package/dist/server/oauth/authServer.js.map +1 -0
  73. package/dist/server/oauth/dpop.d.ts +135 -0
  74. package/dist/server/oauth/dpop.d.ts.map +1 -0
  75. package/dist/server/oauth/dpop.js +338 -0
  76. package/dist/server/oauth/dpop.js.map +1 -0
  77. package/dist/server/oauth/gdpr/consent.d.ts +173 -0
  78. package/dist/server/oauth/gdpr/consent.d.ts.map +1 -0
  79. package/dist/server/oauth/gdpr/consent.js +388 -0
  80. package/dist/server/oauth/gdpr/consent.js.map +1 -0
  81. package/dist/server/oauth/gdpr/dataPortability.d.ts +214 -0
  82. package/dist/server/oauth/gdpr/dataPortability.d.ts.map +1 -0
  83. package/dist/server/oauth/gdpr/dataPortability.js +486 -0
  84. package/dist/server/oauth/gdpr/dataPortability.js.map +1 -0
  85. package/dist/server/oauth/gdpr/index.d.ts +103 -0
  86. package/dist/server/oauth/gdpr/index.d.ts.map +1 -0
  87. package/dist/server/oauth/gdpr/index.js +273 -0
  88. package/dist/server/oauth/gdpr/index.js.map +1 -0
  89. package/dist/server/oauth/gdpr/rightToErasure.d.ts +184 -0
  90. package/dist/server/oauth/gdpr/rightToErasure.d.ts.map +1 -0
  91. package/dist/server/oauth/gdpr/rightToErasure.js +527 -0
  92. package/dist/server/oauth/gdpr/rightToErasure.js.map +1 -0
  93. package/dist/server/oauth/monitoring/securityMonitor.d.ts +218 -0
  94. package/dist/server/oauth/monitoring/securityMonitor.d.ts.map +1 -0
  95. package/dist/server/oauth/monitoring/securityMonitor.js +615 -0
  96. package/dist/server/oauth/monitoring/securityMonitor.js.map +1 -0
  97. package/dist/server/oauth/pkce.d.ts +61 -0
  98. package/dist/server/oauth/pkce.d.ts.map +1 -0
  99. package/dist/server/oauth/pkce.js +157 -0
  100. package/dist/server/oauth/pkce.js.map +1 -0
  101. package/dist/server/oauth/providers/base.d.ts +147 -0
  102. package/dist/server/oauth/providers/base.d.ts.map +1 -0
  103. package/dist/server/oauth/providers/base.js +312 -0
  104. package/dist/server/oauth/providers/base.js.map +1 -0
  105. package/dist/server/oauth/providers/github.d.ts +55 -0
  106. package/dist/server/oauth/providers/github.d.ts.map +1 -0
  107. package/dist/server/oauth/providers/github.js +225 -0
  108. package/dist/server/oauth/providers/github.js.map +1 -0
  109. package/dist/server/oauth/providers/google.d.ts +49 -0
  110. package/dist/server/oauth/providers/google.d.ts.map +1 -0
  111. package/dist/server/oauth/providers/google.js +153 -0
  112. package/dist/server/oauth/providers/google.js.map +1 -0
  113. package/dist/server/oauth/providers/index.d.ts +9 -0
  114. package/dist/server/oauth/providers/index.d.ts.map +1 -0
  115. package/dist/server/oauth/providers/index.js +24 -0
  116. package/dist/server/oauth/providers/index.js.map +1 -0
  117. package/dist/server/oauth/refreshTokenRotation.d.ts +114 -0
  118. package/dist/server/oauth/refreshTokenRotation.d.ts.map +1 -0
  119. package/dist/server/oauth/refreshTokenRotation.js +344 -0
  120. package/dist/server/oauth/refreshTokenRotation.js.map +1 -0
  121. package/dist/server/oauth/security.d.ts +101 -0
  122. package/dist/server/oauth/security.d.ts.map +1 -0
  123. package/dist/server/oauth/security.js +268 -0
  124. package/dist/server/oauth/security.js.map +1 -0
  125. package/dist/server/oauth/tokenEncryption.d.ts +80 -0
  126. package/dist/server/oauth/tokenEncryption.d.ts.map +1 -0
  127. package/dist/server/oauth/tokenEncryption.js +218 -0
  128. package/dist/server/oauth/tokenEncryption.js.map +1 -0
  129. package/dist/tools/checkpoint.d.ts +35 -0
  130. package/dist/tools/checkpoint.d.ts.map +1 -0
  131. package/dist/tools/checkpoint.js +125 -0
  132. package/dist/tools/checkpoint.js.map +1 -0
  133. package/dist/tools/index.d.ts +412 -0
  134. package/dist/tools/index.d.ts.map +1 -0
  135. package/dist/tools/index.js +262 -0
  136. package/dist/tools/index.js.map +1 -0
  137. package/dist/tools/insight.d.ts +65 -0
  138. package/dist/tools/insight.d.ts.map +1 -0
  139. package/dist/tools/insight.js +190 -0
  140. package/dist/tools/insight.js.map +1 -0
  141. package/dist/tools/journey.d.ts +45 -0
  142. package/dist/tools/journey.d.ts.map +1 -0
  143. package/dist/tools/journey.js +115 -0
  144. package/dist/tools/journey.js.map +1 -0
  145. package/dist/tools/sendMessage.d.ts +6 -0
  146. package/dist/tools/sendMessage.d.ts.map +1 -0
  147. package/dist/tools/sendMessage.js +278 -0
  148. package/dist/tools/sendMessage.js.map +1 -0
  149. package/dist/tools/session.d.ts +106 -0
  150. package/dist/tools/session.d.ts.map +1 -0
  151. package/dist/tools/session.js +161 -0
  152. package/dist/tools/session.js.map +1 -0
  153. package/dist/types/auth.d.ts +37 -0
  154. package/dist/types/auth.d.ts.map +1 -0
  155. package/dist/types/auth.js +44 -0
  156. package/dist/types/auth.js.map +1 -0
  157. package/dist/types/checkpoint.d.ts +25 -0
  158. package/dist/types/checkpoint.d.ts.map +1 -0
  159. package/dist/types/checkpoint.js +8 -0
  160. package/dist/types/checkpoint.js.map +1 -0
  161. package/dist/types/insight.d.ts +83 -0
  162. package/dist/types/insight.d.ts.map +1 -0
  163. package/dist/types/insight.js +14 -0
  164. package/dist/types/insight.js.map +1 -0
  165. package/dist/types/journey.d.ts +155 -0
  166. package/dist/types/journey.d.ts.map +1 -0
  167. package/dist/types/journey.js +29 -0
  168. package/dist/types/journey.js.map +1 -0
  169. package/dist/types/session.d.ts +82 -0
  170. package/dist/types/session.d.ts.map +1 -0
  171. package/dist/types/session.js +13 -0
  172. package/dist/types/session.js.map +1 -0
  173. package/dist/utils/circuitBreaker.d.ts +86 -0
  174. package/dist/utils/circuitBreaker.d.ts.map +1 -0
  175. package/dist/utils/circuitBreaker.js +234 -0
  176. package/dist/utils/circuitBreaker.js.map +1 -0
  177. package/dist/utils/errorHandler.d.ts +101 -0
  178. package/dist/utils/errorHandler.d.ts.map +1 -0
  179. package/dist/utils/errorHandler.js +348 -0
  180. package/dist/utils/errorHandler.js.map +1 -0
  181. package/dist/utils/errors.d.ts +36 -0
  182. package/dist/utils/errors.d.ts.map +1 -0
  183. package/dist/utils/errors.js +77 -0
  184. package/dist/utils/errors.js.map +1 -0
  185. package/dist/utils/logger.d.ts +13 -0
  186. package/dist/utils/logger.d.ts.map +1 -0
  187. package/dist/utils/logger.js +49 -0
  188. package/dist/utils/logger.js.map +1 -0
  189. package/dist/utils/performanceMonitor.d.ts +106 -0
  190. package/dist/utils/performanceMonitor.d.ts.map +1 -0
  191. package/dist/utils/performanceMonitor.js +312 -0
  192. package/dist/utils/performanceMonitor.js.map +1 -0
  193. package/dist/utils/responseCache.d.ts +88 -0
  194. package/dist/utils/responseCache.d.ts.map +1 -0
  195. package/dist/utils/responseCache.js +245 -0
  196. package/dist/utils/responseCache.js.map +1 -0
  197. package/dist/utils/retryStrategy.d.ts +49 -0
  198. package/dist/utils/retryStrategy.d.ts.map +1 -0
  199. package/dist/utils/retryStrategy.js +167 -0
  200. package/dist/utils/retryStrategy.js.map +1 -0
  201. package/dist/workflows/definitions/daily-reflection.d.ts +3 -0
  202. package/dist/workflows/definitions/daily-reflection.d.ts.map +1 -0
  203. package/dist/workflows/definitions/daily-reflection.js +52 -0
  204. package/dist/workflows/definitions/daily-reflection.js.map +1 -0
  205. package/dist/workflows/definitions/gratitude-practice.d.ts +3 -0
  206. package/dist/workflows/definitions/gratitude-practice.d.ts.map +1 -0
  207. package/dist/workflows/definitions/gratitude-practice.js +52 -0
  208. package/dist/workflows/definitions/gratitude-practice.js.map +1 -0
  209. package/dist/workflows/definitions/weekly-review.d.ts +3 -0
  210. package/dist/workflows/definitions/weekly-review.d.ts.map +1 -0
  211. package/dist/workflows/definitions/weekly-review.js +74 -0
  212. package/dist/workflows/definitions/weekly-review.js.map +1 -0
  213. package/dist/workflows/engine.d.ts +21 -0
  214. package/dist/workflows/engine.d.ts.map +1 -0
  215. package/dist/workflows/engine.js +149 -0
  216. package/dist/workflows/engine.js.map +1 -0
  217. package/dist/workflows/index.d.ts +26 -0
  218. package/dist/workflows/index.d.ts.map +1 -0
  219. package/dist/workflows/index.js +14 -0
  220. package/dist/workflows/index.js.map +1 -0
  221. package/package.json +98 -0
  222. package/run-mcp-server.sh +16 -0
@@ -0,0 +1,278 @@
1
+ import { z } from 'zod';
2
+ import { eq, desc } from 'drizzle-orm';
3
+ import { getDb } from '../db/client.js';
4
+ import { getShrinkChatClient } from '../clients/shrinkChatClient.js';
5
+ import { sessions, checkpoints, journeys } from '../db/schema.js';
6
+ import { logger } from '../utils/logger.js';
7
+ import { NotFoundError } from '../utils/errors.js';
8
+ import { errorHandler, ErrorType } from '../utils/errorHandler.js';
9
+ import { v4 as uuidv4 } from 'uuid';
10
+ // Input validation schema
11
+ const SendMessageSchema = z.object({
12
+ session_id: z.string().uuid({
13
+ message: 'Invalid session ID format',
14
+ }),
15
+ message: z.string().min(1, 'Message cannot be empty'),
16
+ save_checkpoint: z.boolean().default(false),
17
+ checkpoint_key: z.string().optional(),
18
+ advance_step: z.boolean().default(false),
19
+ include_memory: z.boolean().default(true),
20
+ system_prompt: z.string().optional(),
21
+ conversation_type: z.string().optional(),
22
+ });
23
+ // type SendMessageInput = z.infer<typeof SendMessageSchema>; // Removed - unused type
24
+ /**
25
+ * Send a message through the shrink-chat therapeutic stack
26
+ * This is the primary integration point with the shrink-chat backend
27
+ */
28
+ export async function sendMessage(args) {
29
+ let threadId; // Declare at function level for error handler access
30
+ try {
31
+ // Validate input
32
+ const input = SendMessageSchema.parse(args);
33
+ logger.info(`Sending message for session ${input.session_id}`);
34
+ const db = getDb();
35
+ const client = getShrinkChatClient();
36
+ // 1. Get session and verify it exists
37
+ const [session] = await db
38
+ .select()
39
+ .from(sessions)
40
+ .where(eq(sessions.id, input.session_id))
41
+ .limit(1);
42
+ if (!session) {
43
+ throw new NotFoundError(`Session ${input.session_id} not found`);
44
+ }
45
+ // 2. Get or generate thread ID
46
+ // Threads in shrink-chat are created lazily on first message
47
+ threadId = session.threadId || undefined;
48
+ if (!threadId) {
49
+ // Generate a new thread ID for this session
50
+ threadId = uuidv4();
51
+ logger.info(`Generated new thread ID ${threadId} for session ${input.session_id}`);
52
+ // Update session with thread ID
53
+ await db.update(sessions)
54
+ .set({ threadId })
55
+ .where(eq(sessions.id, input.session_id));
56
+ }
57
+ // Get journey if exists
58
+ let journey = null;
59
+ if (session.journeyId) {
60
+ const [journeyRecord] = await db
61
+ .select()
62
+ .from(journeys)
63
+ .where(eq(journeys.id, session.journeyId))
64
+ .limit(1);
65
+ journey = journeyRecord;
66
+ }
67
+ // 3. Prepare context for shrink-chat
68
+ const memoryContext = input.include_memory && session.metadata
69
+ ? JSON.stringify(session.metadata)
70
+ : '';
71
+ const enhancedContext = {
72
+ sessionId: session.id,
73
+ journeyId: session.journeyId,
74
+ journeySlug: journey?.slug,
75
+ currentStep: session.currentStep,
76
+ sessionStatus: session.status,
77
+ };
78
+ // 4. Get conversation history if available
79
+ const recentCheckpoints = await db
80
+ .select()
81
+ .from(checkpoints)
82
+ .where(eq(checkpoints.sessionId, session.id))
83
+ .orderBy(desc(checkpoints.createdAt))
84
+ .limit(5);
85
+ const history = recentCheckpoints
86
+ .reverse()
87
+ .filter(cp => cp.value && typeof cp.value === 'object' && 'message' in cp.value && 'response' in cp.value)
88
+ .flatMap(cp => {
89
+ const val = cp.value;
90
+ return [
91
+ { role: 'user', content: val.message },
92
+ { role: 'assistant', content: val.response },
93
+ ];
94
+ })
95
+ .slice(-10); // Last 10 messages (5 exchanges)
96
+ // 5. Send message through shrink-chat
97
+ const response = await client.sendMessage(threadId, input.message, // This is 'prompt' in the API
98
+ {
99
+ memoryContext,
100
+ enhancedContext,
101
+ history,
102
+ systemPrompt: input.system_prompt,
103
+ conversationType: input.conversation_type,
104
+ idempotencyKey: uuidv4(),
105
+ });
106
+ // 6. Handle crisis detection if present
107
+ let crisisHandled = false;
108
+ if (response.crisisLevel && Number(response.crisisLevel) > 7) {
109
+ logger.warn(`Crisis detected: Level ${response.crisisLevel} for session ${session.id}`);
110
+ crisisHandled = await handleCrisisDetection(session.id, threadId, response);
111
+ }
112
+ // 7. Save checkpoint if requested
113
+ if (input.save_checkpoint) {
114
+ const checkpointKey = input.checkpoint_key || 'message_response';
115
+ await db.insert(checkpoints).values({
116
+ sessionId: session.id,
117
+ stepId: session.currentStep.toString(),
118
+ key: checkpointKey,
119
+ value: {
120
+ message: input.message,
121
+ response: response.content,
122
+ messageId: response.messageId,
123
+ crisisLevel: response.crisisLevel,
124
+ emotions: response.emotions,
125
+ therapeuticTechnique: response.therapeuticTechnique,
126
+ timestamp: new Date().toISOString(),
127
+ },
128
+ });
129
+ logger.debug(`Saved checkpoint '${checkpointKey}' for session ${session.id}`);
130
+ }
131
+ // 8. Advance step if requested (for journey progression)
132
+ if (input.advance_step && session.journeyId) {
133
+ const newStep = session.currentStep + 1;
134
+ await db.update(sessions)
135
+ .set({
136
+ currentStep: newStep,
137
+ updatedAt: new Date(),
138
+ })
139
+ .where(eq(sessions.id, input.session_id));
140
+ logger.info(`Advanced session ${session.id} to step ${newStep}`);
141
+ }
142
+ // 9. Return formatted response
143
+ return {
144
+ success: true,
145
+ content: response.content || '',
146
+ messageId: response.messageId,
147
+ metadata: {
148
+ crisisDetected: response.crisisDetected || (response.crisisLevel && Number(response.crisisLevel) > 7),
149
+ crisisLevel: response.crisisLevel,
150
+ crisisHandled,
151
+ crisisConfidence: response.crisis_confidence, // Add crisis confidence
152
+ ragConfidence: response.meta?.rag_confidence, // Add RAG confidence if available
153
+ emotions: response.emotions,
154
+ therapeuticTechnique: response.therapeuticTechnique,
155
+ resources: response.resources,
156
+ sessionId: session.id,
157
+ threadId,
158
+ currentStep: input.advance_step ? session.currentStep + 1 : session.currentStep,
159
+ },
160
+ timestamp: new Date().toISOString(),
161
+ };
162
+ }
163
+ catch (error) {
164
+ logger.error('Error in sendMessage:', error);
165
+ // Parse input for error handling (may have failed validation)
166
+ let sessionId;
167
+ let messageLength;
168
+ try {
169
+ const parsedInput = SendMessageSchema.parse(args);
170
+ sessionId = parsedInput.session_id;
171
+ messageLength = parsedInput.message.length;
172
+ }
173
+ catch {
174
+ // Input validation failed, use defaults
175
+ }
176
+ // Handle error with our error handler
177
+ const errorContext = await errorHandler.handle(error, {
178
+ sessionId,
179
+ threadId,
180
+ messageLength,
181
+ });
182
+ // Check if we should fallback based on error type
183
+ if (errorContext.recoverable && process.env.FALLBACK_TO_LOCAL_PROCESSING === 'true') {
184
+ // Fallback for recoverable errors
185
+ if (errorContext.type === ErrorType.NETWORK ||
186
+ errorContext.type === ErrorType.TIMEOUT ||
187
+ errorContext.type === ErrorType.SERVER) {
188
+ logger.info('Falling back to local processing due to recoverable error');
189
+ return handleLocalFallback(args);
190
+ }
191
+ }
192
+ // Special handling for crisis errors
193
+ if (errorContext.type === ErrorType.CRISIS) {
194
+ return {
195
+ success: false,
196
+ error: errorContext.userMessage || errorContext.message,
197
+ metadata: {
198
+ emergencyResources: errorContext.metadata?.emergencyResources,
199
+ crisisDetected: true,
200
+ },
201
+ timestamp: new Date().toISOString(),
202
+ };
203
+ }
204
+ // Return error response with appropriate user message
205
+ return {
206
+ success: false,
207
+ error: errorContext.userMessage || errorContext.message,
208
+ errorType: errorContext.type,
209
+ recoverable: errorContext.recoverable,
210
+ timestamp: new Date().toISOString(),
211
+ };
212
+ }
213
+ }
214
+ /**
215
+ * Handle crisis detection and escalation
216
+ */
217
+ async function handleCrisisDetection(sessionId, threadId, response) {
218
+ const db = getDb();
219
+ try {
220
+ // 1. Update session metadata with crisis flag
221
+ const [existingSession] = await db
222
+ .select()
223
+ .from(sessions)
224
+ .where(eq(sessions.id, sessionId))
225
+ .limit(1);
226
+ const updatedMetadata = {
227
+ ...(existingSession?.metadata || {}),
228
+ crisisDetected: true,
229
+ crisisLevel: response.crisisLevel,
230
+ crisisTimestamp: new Date().toISOString(),
231
+ lastCrisisThreadId: threadId,
232
+ };
233
+ await db.update(sessions)
234
+ .set({
235
+ metadata: updatedMetadata,
236
+ updatedAt: new Date(),
237
+ })
238
+ .where(eq(sessions.id, sessionId));
239
+ // 2. Save crisis checkpoint
240
+ await db.insert(checkpoints).values({
241
+ sessionId,
242
+ stepId: 'crisis',
243
+ key: 'crisis_detection',
244
+ value: {
245
+ level: response.crisisLevel,
246
+ resources: response.resources,
247
+ escalationPath: response.escalationPath,
248
+ threadId,
249
+ timestamp: new Date().toISOString(),
250
+ },
251
+ });
252
+ logger.info(`Crisis handled for session ${sessionId}, thread ${threadId}`);
253
+ return true;
254
+ }
255
+ catch (error) {
256
+ logger.error('Error handling crisis detection:', error);
257
+ return false;
258
+ }
259
+ }
260
+ /**
261
+ * Fallback to local processing when shrink-chat is unavailable
262
+ */
263
+ async function handleLocalFallback(args) {
264
+ logger.warn('Falling back to local processing due to shrink-chat unavailability');
265
+ const input = SendMessageSchema.parse(args);
266
+ // Basic local response - this would be expanded with actual logic
267
+ return {
268
+ success: true,
269
+ content: "I understand you're trying to communicate. The therapeutic service is temporarily unavailable, but your message has been noted. Please try again shortly or contact support if this persists.",
270
+ messageId: uuidv4(),
271
+ metadata: {
272
+ fallbackMode: true,
273
+ sessionId: input.session_id,
274
+ timestamp: new Date().toISOString(),
275
+ },
276
+ };
277
+ }
278
+ //# sourceMappingURL=sendMessage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sendMessage.js","sourceRoot":"","sources":["../../src/tools/sendMessage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,106 @@
1
+ export declare function createSession(args: any): Promise<{
2
+ error: string;
3
+ details?: any;
4
+ } | {
5
+ session_id: string;
6
+ journey: {
7
+ id: string;
8
+ name: string;
9
+ createdAt: Date;
10
+ updatedAt: Date;
11
+ slug: string;
12
+ description: string;
13
+ steps: {
14
+ id: string;
15
+ order: number;
16
+ type: "prompt" | "checkpoint" | "summary";
17
+ content: {
18
+ prompt?: string;
19
+ checkpoint_key?: string;
20
+ instructions?: string;
21
+ };
22
+ optional: boolean;
23
+ }[];
24
+ estimatedMinutes: number;
25
+ tags: string[];
26
+ } | null;
27
+ current_step: {
28
+ id: string;
29
+ order: number;
30
+ type: "prompt" | "checkpoint" | "summary";
31
+ content: {
32
+ prompt?: string;
33
+ checkpoint_key?: string;
34
+ instructions?: string;
35
+ };
36
+ optional: boolean;
37
+ } | null | undefined;
38
+ message: string;
39
+ }>;
40
+ export declare function resumeSession(args: any): Promise<{
41
+ error: string;
42
+ details?: any;
43
+ } | {
44
+ message: string;
45
+ session: null;
46
+ journey?: undefined;
47
+ current_step?: undefined;
48
+ checkpoints?: undefined;
49
+ } | {
50
+ session: {
51
+ id: string;
52
+ updatedAt: Date;
53
+ userId: string;
54
+ journeyId: string | null;
55
+ status: "active" | "paused" | "completed" | "abandoned";
56
+ currentStep: number;
57
+ startedAt: Date;
58
+ lastActiveAt: Date;
59
+ completedAt: Date | null;
60
+ metadata: unknown;
61
+ threadId: string | null;
62
+ lastSyncedAt: Date | null;
63
+ };
64
+ journey: {
65
+ id: string;
66
+ name: string;
67
+ createdAt: Date;
68
+ updatedAt: Date;
69
+ slug: string;
70
+ description: string;
71
+ steps: {
72
+ id: string;
73
+ order: number;
74
+ type: "prompt" | "checkpoint" | "summary";
75
+ content: {
76
+ prompt?: string;
77
+ checkpoint_key?: string;
78
+ instructions?: string;
79
+ };
80
+ optional: boolean;
81
+ }[];
82
+ estimatedMinutes: number;
83
+ tags: string[];
84
+ } | null | undefined;
85
+ current_step: {
86
+ id: string;
87
+ order: number;
88
+ type: "prompt" | "checkpoint" | "summary";
89
+ content: {
90
+ prompt?: string;
91
+ checkpoint_key?: string;
92
+ instructions?: string;
93
+ };
94
+ optional: boolean;
95
+ } | null | undefined;
96
+ checkpoints: {
97
+ id: string;
98
+ createdAt: Date;
99
+ sessionId: string;
100
+ stepId: string;
101
+ key: string;
102
+ value: unknown;
103
+ }[];
104
+ message: string;
105
+ }>;
106
+ //# sourceMappingURL=session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/tools/session.ts"],"names":[],"mappings":"AAQA,wBAAsB,aAAa,CAAC,IAAI,EAAE,GAAG;;;;;;;;;;;;;;;;;sBAsBhC,CAAC;8BACN,CAAC;4BACI,CAAC;;;;;;;;;;;;kBAFD,CAAC;0BACN,CAAC;wBACI,CAAC;;;;;GA+Cb;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;sBAnDhC,CAAC;8BACN,CAAC;4BACI,CAAC;;;;;;;;;;;;kBAFD,CAAC;0BACN,CAAC;wBACI,CAAC;;;;;;;;;;;;;GAyJb"}
@@ -0,0 +1,161 @@
1
+ import { getDb } from '../db/client.js';
2
+ import { sessions, journeys, users, checkpoints } from '../db/schema.js';
3
+ import { eq, desc, and } from 'drizzle-orm';
4
+ import { CreateSessionSchema, ResumeSessionSchema } from '../types/session.js';
5
+ import { extractUserFromContext } from '../types/auth.js';
6
+ import { handleError, NotFoundError } from '../utils/errors.js';
7
+ import { logger } from '../utils/logger.js';
8
+ export async function createSession(args) {
9
+ try {
10
+ const input = CreateSessionSchema.parse(args);
11
+ const db = getDb();
12
+ // Extract user ID from auth context or generate anonymous user
13
+ const externalUserId = await extractUserFromContext(input.auth);
14
+ const userResult = await db
15
+ .insert(users)
16
+ .values({
17
+ externalId: externalUserId,
18
+ preferences: {},
19
+ })
20
+ .onConflictDoUpdate({
21
+ target: users.externalId,
22
+ set: { updatedAt: new Date() },
23
+ })
24
+ .returning();
25
+ const user = userResult[0];
26
+ // Look up journey if specified
27
+ let journey = null;
28
+ let currentStep = null;
29
+ if (input.journey_slug) {
30
+ const [foundJourney] = await db
31
+ .select()
32
+ .from(journeys)
33
+ .where(eq(journeys.slug, input.journey_slug))
34
+ .limit(1);
35
+ if (!foundJourney) {
36
+ throw new NotFoundError('Journey with slug', input.journey_slug);
37
+ }
38
+ journey = foundJourney;
39
+ // Get first step
40
+ if (journey.steps && journey.steps.length > 0) {
41
+ currentStep = journey.steps[0];
42
+ }
43
+ }
44
+ // Create new session
45
+ const sessionResult = await db
46
+ .insert(sessions)
47
+ .values({
48
+ userId: user.id,
49
+ journeyId: journey?.id || null,
50
+ status: 'active',
51
+ currentStep: 0,
52
+ metadata: { context: input.context },
53
+ })
54
+ .returning();
55
+ const session = sessionResult[0];
56
+ logger.info(`Created new session: ${session.id}`);
57
+ return {
58
+ session_id: session.id,
59
+ journey: journey,
60
+ current_step: currentStep,
61
+ message: journey
62
+ ? `Started ${journey.name}. ${currentStep?.content?.prompt || ''}`
63
+ : 'Started freeform session.',
64
+ };
65
+ }
66
+ catch (error) {
67
+ logger.error('Error creating session:', error);
68
+ return handleError(error);
69
+ }
70
+ }
71
+ export async function resumeSession(args) {
72
+ try {
73
+ const input = ResumeSessionSchema.parse(args);
74
+ const db = getDb();
75
+ // Extract user ID from auth context or generate anonymous user
76
+ const externalUserId = await extractUserFromContext(input.auth);
77
+ const [user] = await db
78
+ .select()
79
+ .from(users)
80
+ .where(eq(users.externalId, externalUserId))
81
+ .limit(1);
82
+ if (!user) {
83
+ // Create user if doesn't exist
84
+ const [newUser] = await db
85
+ .insert(users)
86
+ .values({
87
+ externalId: externalUserId,
88
+ preferences: {},
89
+ })
90
+ .returning();
91
+ if (!newUser) {
92
+ throw new NotFoundError('User');
93
+ }
94
+ return {
95
+ message: 'No previous sessions found for this user. Please create a new session.',
96
+ session: null,
97
+ };
98
+ }
99
+ // Find session to resume
100
+ let session;
101
+ if (input.session_id) {
102
+ [session] = await db
103
+ .select()
104
+ .from(sessions)
105
+ .where(and(eq(sessions.id, input.session_id), eq(sessions.userId, user.id)))
106
+ .limit(1);
107
+ }
108
+ else {
109
+ // Get most recent pausable session
110
+ [session] = await db
111
+ .select()
112
+ .from(sessions)
113
+ .where(and(eq(sessions.userId, user.id), eq(sessions.status, 'paused')))
114
+ .orderBy(desc(sessions.lastActiveAt))
115
+ .limit(1);
116
+ }
117
+ if (!session) {
118
+ throw new NotFoundError('Session to resume');
119
+ }
120
+ // Get journey if linked
121
+ let journey = null;
122
+ let currentStep = null;
123
+ if (session.journeyId) {
124
+ [journey] = await db
125
+ .select()
126
+ .from(journeys)
127
+ .where(eq(journeys.id, session.journeyId))
128
+ .limit(1);
129
+ if (journey && journey.steps && journey.steps[session.currentStep]) {
130
+ currentStep = journey.steps[session.currentStep];
131
+ }
132
+ }
133
+ // Get existing checkpoints
134
+ const existingCheckpoints = await db
135
+ .select()
136
+ .from(checkpoints)
137
+ .where(eq(checkpoints.sessionId, session.id))
138
+ .orderBy(checkpoints.createdAt);
139
+ // Update session status to active
140
+ await db
141
+ .update(sessions)
142
+ .set({
143
+ status: 'active',
144
+ lastActiveAt: new Date(),
145
+ })
146
+ .where(eq(sessions.id, session.id));
147
+ logger.info(`Resumed session: ${session.id}`);
148
+ return {
149
+ session: session,
150
+ journey: journey,
151
+ current_step: currentStep,
152
+ checkpoints: existingCheckpoints,
153
+ message: `Resumed session. ${currentStep?.content?.prompt || 'Continue where you left off.'}`,
154
+ };
155
+ }
156
+ catch (error) {
157
+ logger.error('Error resuming session:', error);
158
+ return handleError(error);
159
+ }
160
+ }
161
+ //# sourceMappingURL=session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/tools/session.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * Authentication context that can be passed through MCP tool calls
4
+ * This allows the AI agent to provide user authentication info
5
+ */
6
+ export declare const AuthContextSchema: z.ZodObject<{
7
+ /**
8
+ * OAuth access token or session identifier
9
+ * This will be validated against the OAuth tokens table
10
+ */
11
+ token: z.ZodOptional<z.ZodString>;
12
+ /**
13
+ * External user identifier (from OAuth provider)
14
+ * Used as a fallback if token validation fails
15
+ */
16
+ user_id: z.ZodOptional<z.ZodString>;
17
+ /**
18
+ * Client identifier (ChatGPT, Claude, etc.)
19
+ * Helps track which AI agent is making the request
20
+ */
21
+ client_id: z.ZodOptional<z.ZodString>;
22
+ }, "strip", z.ZodTypeAny, {
23
+ user_id?: string | undefined;
24
+ client_id?: string | undefined;
25
+ token?: string | undefined;
26
+ }, {
27
+ user_id?: string | undefined;
28
+ client_id?: string | undefined;
29
+ token?: string | undefined;
30
+ }>;
31
+ export type AuthContext = z.infer<typeof AuthContextSchema>;
32
+ /**
33
+ * Extract user ID from authentication context
34
+ * Returns a mock user ID if no context is provided (backward compatibility)
35
+ */
36
+ export declare function extractUserFromContext(authContext?: AuthContext): Promise<string>;
37
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/types/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;GAGG;AACH,eAAO,MAAM,iBAAiB;IAC5B;;;OAGG;;IAGH;;;OAGG;;IAGH;;;OAGG;;;;;;;;;;EAEH,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE5D;;;GAGG;AACH,wBAAsB,sBAAsB,CAAC,WAAW,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAkBvF"}
@@ -0,0 +1,44 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * Authentication context that can be passed through MCP tool calls
4
+ * This allows the AI agent to provide user authentication info
5
+ */
6
+ export const AuthContextSchema = z.object({
7
+ /**
8
+ * OAuth access token or session identifier
9
+ * This will be validated against the OAuth tokens table
10
+ */
11
+ token: z.string().optional().describe('OAuth access token or session identifier'),
12
+ /**
13
+ * External user identifier (from OAuth provider)
14
+ * Used as a fallback if token validation fails
15
+ */
16
+ user_id: z.string().optional().describe('External user identifier from OAuth provider'),
17
+ /**
18
+ * Client identifier (ChatGPT, Claude, etc.)
19
+ * Helps track which AI agent is making the request
20
+ */
21
+ client_id: z.string().optional().describe('Client application identifier'),
22
+ });
23
+ /**
24
+ * Extract user ID from authentication context
25
+ * Returns a mock user ID if no context is provided (backward compatibility)
26
+ */
27
+ export async function extractUserFromContext(authContext) {
28
+ // If we have a user_id directly, use it
29
+ if (authContext?.user_id) {
30
+ return authContext.user_id;
31
+ }
32
+ // If we have a token, we could validate it here
33
+ // For now, we'll extract a user ID from the token if it's a JWT-like structure
34
+ if (authContext?.token) {
35
+ // TODO: Implement proper JWT validation and extraction
36
+ // For now, just use the token as a user identifier
37
+ return `oauth_${authContext.token.substring(0, 16)}`;
38
+ }
39
+ // Fallback to anonymous user with optional client tracking
40
+ const clientPrefix = authContext?.client_id ? `${authContext.client_id}_` : '';
41
+ const { nanoid } = await import('nanoid');
42
+ return `usr_${clientPrefix}${nanoid(8)}`;
43
+ }
44
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/types/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACxC;;;OAGG;IACH,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,0CAA0C,CAAC;IAEjF;;;OAGG;IACH,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,8CAA8C,CAAC;IAEvF;;;OAGG;IACH,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,+BAA+B,CAAC;CAC3E,CAAC,CAAC;AAIH;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,WAAyB;IACpE,wCAAwC;IACxC,IAAI,WAAW,EAAE,OAAO,EAAE,CAAC;QACzB,OAAO,WAAW,CAAC,OAAO,CAAC;IAC7B,CAAC;IAED,gDAAgD;IAChD,+EAA+E;IAC/E,IAAI,WAAW,EAAE,KAAK,EAAE,CAAC;QACvB,uDAAuD;QACvD,mDAAmD;QACnD,OAAO,SAAS,WAAW,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;IACvD,CAAC;IAED,2DAA2D;IAC3D,MAAM,YAAY,GAAG,WAAW,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IAC/E,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC1C,OAAO,OAAO,YAAY,GAAG,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;AAC3C,CAAC"}