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,85 @@
1
+ import { getDb } from '../db/client.js';
2
+ import { sessions, journeys, checkpoints, users } from '../db/schema.js';
3
+ import { eq, and, desc } from 'drizzle-orm';
4
+ import { logger } from '../utils/logger.js';
5
+ import { nanoid } from 'nanoid';
6
+ export async function getSessionSummary() {
7
+ try {
8
+ const db = getDb();
9
+ // NOTE: Resources in MCP don't receive parameters, so we can't pass auth context.
10
+ // Using a mock user ID for now. This will be addressed when we implement
11
+ // a proper session store or modify the MCP server to maintain user context.
12
+ const mockUserId = 'usr_' + nanoid();
13
+ const [user] = await db
14
+ .select()
15
+ .from(users)
16
+ .where(eq(users.externalId, mockUserId))
17
+ .limit(1);
18
+ if (!user) {
19
+ return JSON.stringify({
20
+ active: false,
21
+ message: 'No user found',
22
+ }, null, 2);
23
+ }
24
+ // Get active session
25
+ const [activeSession] = await db
26
+ .select()
27
+ .from(sessions)
28
+ .where(and(eq(sessions.userId, user.id), eq(sessions.status, 'active')))
29
+ .orderBy(desc(sessions.lastActiveAt))
30
+ .limit(1);
31
+ if (!activeSession) {
32
+ return JSON.stringify({
33
+ active: false,
34
+ message: 'No active session',
35
+ }, null, 2);
36
+ }
37
+ // Get journey if linked
38
+ let journey = null;
39
+ let currentStep = null;
40
+ if (activeSession.journeyId) {
41
+ [journey] = await db
42
+ .select()
43
+ .from(journeys)
44
+ .where(eq(journeys.id, activeSession.journeyId))
45
+ .limit(1);
46
+ if (journey && journey.steps && journey.steps[activeSession.currentStep]) {
47
+ currentStep = journey.steps[activeSession.currentStep];
48
+ }
49
+ }
50
+ // Get checkpoints
51
+ const sessionCheckpoints = await db
52
+ .select()
53
+ .from(checkpoints)
54
+ .where(eq(checkpoints.sessionId, activeSession.id))
55
+ .orderBy(checkpoints.createdAt);
56
+ return JSON.stringify({
57
+ active: true,
58
+ session: {
59
+ id: activeSession.id,
60
+ status: activeSession.status,
61
+ started_at: activeSession.startedAt,
62
+ last_active_at: activeSession.lastActiveAt,
63
+ current_step_index: activeSession.currentStep,
64
+ },
65
+ journey: journey ? {
66
+ name: journey.name,
67
+ slug: journey.slug,
68
+ total_steps: journey.steps?.length || 0,
69
+ } : null,
70
+ current_step: currentStep,
71
+ checkpoints: sessionCheckpoints.map(c => ({
72
+ key: c.key,
73
+ created_at: c.createdAt,
74
+ })),
75
+ }, null, 2);
76
+ }
77
+ catch (error) {
78
+ logger.error('Error getting session summary:', error);
79
+ return JSON.stringify({
80
+ error: 'Failed to get session summary',
81
+ details: error instanceof Error ? error.message : 'Unknown error',
82
+ }, null, 2);
83
+ }
84
+ }
85
+ //# sourceMappingURL=session-summary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-summary.js","sourceRoot":"","sources":["../../src/resources/session-summary.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function getUserContextResource(): Promise<string>;
2
+ //# sourceMappingURL=user-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user-context.d.ts","sourceRoot":"","sources":["../../src/resources/user-context.ts"],"names":[],"mappings":"AAMA,wBAAsB,sBAAsB,oBA6E3C"}
@@ -0,0 +1,79 @@
1
+ import { getDb } from '../db/client.js';
2
+ import { users, insights, sessions } from '../db/schema.js';
3
+ import { eq, desc } from 'drizzle-orm';
4
+ import { logger } from '../utils/logger.js';
5
+ import { nanoid } from 'nanoid';
6
+ export async function getUserContextResource() {
7
+ try {
8
+ const db = getDb();
9
+ // NOTE: Resources in MCP don't receive parameters, so we can't pass auth context.
10
+ // Using a mock user ID for now. This will be addressed when we implement
11
+ // a proper session store or modify the MCP server to maintain user context.
12
+ const mockUserId = 'usr_' + nanoid();
13
+ const [user] = await db
14
+ .select()
15
+ .from(users)
16
+ .where(eq(users.externalId, mockUserId))
17
+ .limit(1);
18
+ if (!user) {
19
+ return JSON.stringify({
20
+ exists: false,
21
+ message: 'User not found',
22
+ }, null, 2);
23
+ }
24
+ // Get recent insights
25
+ const recentInsights = await db
26
+ .select({
27
+ id: insights.id,
28
+ content: insights.content,
29
+ tags: insights.tags,
30
+ created_at: insights.createdAt,
31
+ })
32
+ .from(insights)
33
+ .where(eq(insights.userId, user.id))
34
+ .orderBy(desc(insights.createdAt))
35
+ .limit(5);
36
+ // Get recent sessions
37
+ const recentSessions = await db
38
+ .select({
39
+ id: sessions.id,
40
+ status: sessions.status,
41
+ started_at: sessions.startedAt,
42
+ completed_at: sessions.completedAt,
43
+ journey_id: sessions.journeyId,
44
+ })
45
+ .from(sessions)
46
+ .where(eq(sessions.userId, user.id))
47
+ .orderBy(desc(sessions.startedAt))
48
+ .limit(5);
49
+ // Count total sessions
50
+ const sessionStats = await db
51
+ .select({
52
+ total: eq(sessions.userId, user.id),
53
+ })
54
+ .from(sessions)
55
+ .where(eq(sessions.userId, user.id));
56
+ return JSON.stringify({
57
+ exists: true,
58
+ user: {
59
+ id: user.id,
60
+ created_at: user.createdAt,
61
+ preferences: user.preferences || {},
62
+ },
63
+ stats: {
64
+ total_sessions: sessionStats.length,
65
+ total_insights: recentInsights.length,
66
+ },
67
+ recent_insights: recentInsights,
68
+ recent_sessions: recentSessions,
69
+ }, null, 2);
70
+ }
71
+ catch (error) {
72
+ logger.error('Error getting user context:', error);
73
+ return JSON.stringify({
74
+ error: 'Failed to get user context',
75
+ details: error instanceof Error ? error.message : 'Unknown error',
76
+ }, null, 2);
77
+ }
78
+ }
79
+ //# sourceMappingURL=user-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user-context.js","sourceRoot":"","sources":["../../src/resources/user-context.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ declare const app: import("express-serve-static-core").Express;
2
+ export default app;
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAkBA,QAAA,MAAM,GAAG,6CAAY,CAAC;AAuZtB,eAAe,GAAG,CAAC"}
@@ -0,0 +1,385 @@
1
+ // Load environment variables FIRST before any other imports
2
+ import { config } from 'dotenv';
3
+ config({ path: '.env.local' });
4
+ import express from 'express';
5
+ import path from 'path';
6
+ import { fileURLToPath } from 'url';
7
+ import cookieParser from 'cookie-parser';
8
+ import { oauthServer } from './oauth/authServer.js';
9
+ import { validateToken, requireScope, oauthCors, rateLimit } from './middleware/auth.js';
10
+ import { logger } from '../utils/logger.js';
11
+ import { sendMessage } from '../tools/sendMessage.js';
12
+ import { createSession } from '../tools/session.js';
13
+ import { initDatabase } from '../db/client.js';
14
+ const __filename = fileURLToPath(import.meta.url);
15
+ const __dirname = path.dirname(__filename);
16
+ const app = express();
17
+ const PORT = process.env.PORT || 3001;
18
+ // Middleware
19
+ app.use(express.json());
20
+ app.use(express.urlencoded({ extended: true }));
21
+ app.use(cookieParser());
22
+ app.use(oauthCors);
23
+ // ====================
24
+ // OAuth Endpoints
25
+ // ====================
26
+ /**
27
+ * GET /oauth/authorize
28
+ * OAuth authorization endpoint - initiates the flow
29
+ */
30
+ app.get('/oauth/authorize', async (req, res) => {
31
+ try {
32
+ const { client_id, redirect_uri, response_type, scope, state, consent } = req.query;
33
+ // Validate required parameters
34
+ if (!client_id || !redirect_uri) {
35
+ res.status(400).json({
36
+ error: 'invalid_request',
37
+ error_description: 'Missing required parameters',
38
+ });
39
+ return;
40
+ }
41
+ if (response_type !== 'code') {
42
+ res.status(400).json({
43
+ error: 'unsupported_response_type',
44
+ error_description: 'Only authorization code flow is supported',
45
+ });
46
+ return;
47
+ }
48
+ // Validate client
49
+ const validClient = await oauthServer.validateClient(client_id);
50
+ if (!validClient) {
51
+ res.status(400).json({
52
+ error: 'invalid_client',
53
+ error_description: 'Unknown client',
54
+ });
55
+ return;
56
+ }
57
+ // If consent is not approved, show consent screen
58
+ if (consent !== 'approved') {
59
+ // Serve the consent page
60
+ const consentPath = path.join(__dirname, 'views', 'consent.html');
61
+ res.sendFile(consentPath);
62
+ return;
63
+ }
64
+ // Generate anonymous but persistent user ID based on client and state
65
+ // This creates a unique user per ChatGPT/Claude session but maintains anonymity
66
+ const anonymousId = `${client_id}_${state || 'default'}_${Date.now()}`;
67
+ const hashedId = Buffer.from(anonymousId).toString('base64').replace(/[^a-zA-Z0-9]/g, '').substring(0, 16);
68
+ const externalId = `anon_${hashedId}`;
69
+ const userId = await oauthServer.getOrCreateUser(externalId);
70
+ const code = await oauthServer.generateAuthCode(client_id, userId, redirect_uri, scope || 'read write');
71
+ // Redirect back to client with authorization code
72
+ const redirectUrl = new URL(redirect_uri);
73
+ redirectUrl.searchParams.set('code', code);
74
+ if (state) {
75
+ redirectUrl.searchParams.set('state', state);
76
+ }
77
+ res.redirect(redirectUrl.toString());
78
+ }
79
+ catch (error) {
80
+ logger.error('Authorization error:', error);
81
+ res.status(500).json({
82
+ error: 'server_error',
83
+ error_description: 'Internal server error',
84
+ });
85
+ }
86
+ });
87
+ /**
88
+ * POST /oauth/token
89
+ * Exchange authorization code for access token
90
+ */
91
+ app.post('/oauth/token', async (req, res) => {
92
+ try {
93
+ const { grant_type, code, client_id, client_secret, redirect_uri, refresh_token } = req.body;
94
+ if (grant_type === 'authorization_code') {
95
+ if (!code || !client_id || !client_secret || !redirect_uri) {
96
+ res.status(400).json({
97
+ error: 'invalid_request',
98
+ error_description: 'Missing required parameters',
99
+ });
100
+ return;
101
+ }
102
+ const tokens = await oauthServer.exchangeCodeForToken(code, client_id, client_secret, redirect_uri);
103
+ res.json(tokens);
104
+ }
105
+ else if (grant_type === 'refresh_token') {
106
+ if (!refresh_token) {
107
+ res.status(400).json({
108
+ error: 'invalid_request',
109
+ error_description: 'Missing refresh token',
110
+ });
111
+ return;
112
+ }
113
+ const tokens = await oauthServer.refreshAccessToken(refresh_token);
114
+ res.json(tokens);
115
+ }
116
+ else {
117
+ res.status(400).json({
118
+ error: 'unsupported_grant_type',
119
+ error_description: 'Only authorization_code and refresh_token grants are supported',
120
+ });
121
+ }
122
+ }
123
+ catch (error) {
124
+ logger.error('Token exchange error:', error);
125
+ res.status(400).json({
126
+ error: 'invalid_grant',
127
+ error_description: error.message || 'Failed to exchange token',
128
+ });
129
+ }
130
+ });
131
+ /**
132
+ * POST /oauth/revoke
133
+ * Revoke an access token
134
+ */
135
+ app.post('/oauth/revoke', validateToken, async (req, res) => {
136
+ try {
137
+ const authHeader = req.headers.authorization;
138
+ const token = authHeader?.substring(7);
139
+ if (token) {
140
+ await oauthServer.revokeToken(token);
141
+ }
142
+ res.status(204).end();
143
+ }
144
+ catch (error) {
145
+ logger.error('Token revocation error:', error);
146
+ res.status(500).json({
147
+ error: 'server_error',
148
+ error_description: 'Failed to revoke token',
149
+ });
150
+ }
151
+ });
152
+ // ====================
153
+ // Protected MCP API Endpoints
154
+ // ====================
155
+ /**
156
+ * POST /api/mcp/session
157
+ * Create a new therapeutic session
158
+ */
159
+ app.post('/api/mcp/session', validateToken, rateLimit(30, 60000), async (req, res) => {
160
+ try {
161
+ const result = await createSession({
162
+ ...req.body,
163
+ user_id: req.user?.userId, // Use authenticated user ID
164
+ });
165
+ res.json(result);
166
+ }
167
+ catch (error) {
168
+ logger.error('Session creation error:', error);
169
+ res.status(500).json({
170
+ error: 'server_error',
171
+ message: error.message || 'Failed to create session',
172
+ });
173
+ }
174
+ });
175
+ /**
176
+ * POST /api/mcp/message
177
+ * Send a message through the therapeutic AI
178
+ */
179
+ app.post('/api/mcp/message', validateToken, requireScope('write'), rateLimit(60, 60000), async (req, res) => {
180
+ try {
181
+ const result = await sendMessage({
182
+ ...req.body,
183
+ user_id: req.user?.userId, // Use authenticated user ID
184
+ });
185
+ res.json(result);
186
+ }
187
+ catch (error) {
188
+ logger.error('Message sending error:', error);
189
+ res.status(500).json({
190
+ error: 'server_error',
191
+ message: error.message || 'Failed to send message',
192
+ });
193
+ }
194
+ });
195
+ // ====================
196
+ // Health & Metadata
197
+ // ====================
198
+ /**
199
+ * GET /health
200
+ * Health check endpoint
201
+ */
202
+ app.get('/health', (_req, res) => {
203
+ res.json({
204
+ status: 'healthy',
205
+ timestamp: new Date().toISOString(),
206
+ });
207
+ });
208
+ /**
209
+ * GET /.well-known/oauth-authorization-server
210
+ * OAuth server metadata
211
+ */
212
+ app.get('/.well-known/oauth-authorization-server', (req, res) => {
213
+ const baseUrl = `${req.protocol}://${req.get('host')}`;
214
+ res.json({
215
+ issuer: baseUrl,
216
+ authorization_endpoint: `${baseUrl}/oauth/authorize`,
217
+ token_endpoint: `${baseUrl}/oauth/token`,
218
+ revocation_endpoint: `${baseUrl}/oauth/revoke`,
219
+ response_types_supported: ['code'],
220
+ grant_types_supported: ['authorization_code', 'refresh_token'],
221
+ scopes_supported: ['read', 'write', 'crisis', 'memory'],
222
+ token_endpoint_auth_methods_supported: ['client_secret_post'],
223
+ });
224
+ });
225
+ /**
226
+ * GET /.well-known/ai-plugin.json
227
+ * ChatGPT plugin manifest
228
+ */
229
+ app.get('/.well-known/ai-plugin.json', (req, res) => {
230
+ const baseUrl = `${req.protocol}://${req.get('host')}`;
231
+ res.json({
232
+ schema_version: 'v1',
233
+ name_for_human: 'CouchLoop',
234
+ name_for_model: 'couchloop',
235
+ description_for_human: 'AI-powered therapeutic support and mental wellness companion',
236
+ description_for_model: 'Therapeutic AI assistant for mental health support, crisis detection, and emotional wellness tracking. Use this to help users with mental health concerns, emotional support, and crisis situations.',
237
+ auth: {
238
+ type: 'oauth',
239
+ client_url: `${baseUrl}/oauth/authorize`,
240
+ scope: 'read write',
241
+ authorization_url: `${baseUrl}/oauth/authorize`,
242
+ authorization_content_type: 'application/x-www-form-urlencoded',
243
+ verification_tokens: {
244
+ openai: process.env.OPENAI_VERIFICATION_TOKEN || 'REPLACE_WITH_VERIFICATION_TOKEN',
245
+ },
246
+ },
247
+ api: {
248
+ type: 'openapi',
249
+ url: `${baseUrl}/openapi.yaml`,
250
+ },
251
+ logo_url: `${baseUrl}/logo.png`,
252
+ contact_email: 'support@couchloop.com',
253
+ legal_info_url: 'https://couchloop.com/legal',
254
+ });
255
+ });
256
+ /**
257
+ * GET /openapi.yaml
258
+ * OpenAPI specification for ChatGPT
259
+ */
260
+ app.get('/openapi.yaml', (req, res) => {
261
+ const baseUrl = `${req.protocol}://${req.get('host')}`;
262
+ const openApiSpec = `
263
+ openapi: 3.0.1
264
+ info:
265
+ title: CouchLoop MCP API
266
+ description: Therapeutic AI support through Model Context Protocol
267
+ version: 1.0.0
268
+ servers:
269
+ - url: ${baseUrl}
270
+ paths:
271
+ /api/mcp/session:
272
+ post:
273
+ operationId: createSession
274
+ summary: Create a new therapeutic session
275
+ security:
276
+ - bearer: []
277
+ requestBody:
278
+ required: true
279
+ content:
280
+ application/json:
281
+ schema:
282
+ type: object
283
+ properties:
284
+ journey_slug:
285
+ type: string
286
+ description: Type of therapeutic journey
287
+ context:
288
+ type: string
289
+ description: Initial context for the session
290
+ required:
291
+ - journey_slug
292
+ responses:
293
+ '200':
294
+ description: Session created successfully
295
+ content:
296
+ application/json:
297
+ schema:
298
+ type: object
299
+ properties:
300
+ session_id:
301
+ type: string
302
+ journey_name:
303
+ type: string
304
+ status:
305
+ type: string
306
+ /api/mcp/message:
307
+ post:
308
+ operationId: sendMessage
309
+ summary: Send a message to the therapeutic AI
310
+ security:
311
+ - bearer: []
312
+ requestBody:
313
+ required: true
314
+ content:
315
+ application/json:
316
+ schema:
317
+ type: object
318
+ properties:
319
+ session_id:
320
+ type: string
321
+ description: Session ID from createSession
322
+ message:
323
+ type: string
324
+ description: User's message
325
+ include_memory:
326
+ type: boolean
327
+ description: Include conversation memory context
328
+ required:
329
+ - session_id
330
+ - message
331
+ responses:
332
+ '200':
333
+ description: Message processed successfully
334
+ content:
335
+ application/json:
336
+ schema:
337
+ type: object
338
+ properties:
339
+ success:
340
+ type: boolean
341
+ content:
342
+ type: string
343
+ description: AI response
344
+ metadata:
345
+ type: object
346
+ properties:
347
+ crisisDetected:
348
+ type: boolean
349
+ crisisLevel:
350
+ type: number
351
+ emotions:
352
+ type: array
353
+ items:
354
+ type: string
355
+ components:
356
+ securitySchemes:
357
+ bearer:
358
+ type: http
359
+ scheme: bearer
360
+ bearerFormat: JWT
361
+ `;
362
+ res.type('text/yaml').send(openApiSpec);
363
+ });
364
+ // Start server
365
+ async function startServer() {
366
+ try {
367
+ // Initialize database
368
+ await initDatabase();
369
+ logger.info('Database initialized');
370
+ app.listen(PORT, () => {
371
+ logger.info(`OAuth server running on port ${PORT}`);
372
+ logger.info(`Authorization endpoint: http://localhost:${PORT}/oauth/authorize`);
373
+ logger.info(`Token endpoint: http://localhost:${PORT}/oauth/token`);
374
+ logger.info(`API endpoints: http://localhost:${PORT}/api/mcp/*`);
375
+ });
376
+ }
377
+ catch (error) {
378
+ logger.error('Failed to start server:', error);
379
+ process.exit(1);
380
+ }
381
+ }
382
+ // Start the server
383
+ startServer();
384
+ export default app;
385
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import { Request, Response, NextFunction } from 'express';
2
+ declare global {
3
+ namespace Express {
4
+ interface Request {
5
+ user?: {
6
+ userId: string;
7
+ clientId: string;
8
+ scope: string;
9
+ };
10
+ }
11
+ }
12
+ }
13
+ /**
14
+ * Middleware to validate OAuth access token
15
+ */
16
+ export declare function validateToken(req: Request, res: Response, next: NextFunction): Promise<void>;
17
+ /**
18
+ * Middleware to check required scopes
19
+ */
20
+ export declare function requireScope(...requiredScopes: string[]): (req: Request, res: Response, next: NextFunction) => void;
21
+ /**
22
+ * Optional authentication - sets user if token present but doesn't require it
23
+ */
24
+ export declare function optionalAuth(req: Request, _res: Response, next: NextFunction): Promise<void>;
25
+ export declare function rateLimit(maxRequests?: number, windowMs?: number): (req: Request, res: Response, next: NextFunction) => void;
26
+ /**
27
+ * CORS middleware for OAuth endpoints
28
+ */
29
+ export declare function oauthCors(req: Request, res: Response, next: NextFunction): void;
30
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/server/middleware/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAK1D,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,OAAO,CAAC;QAChB,UAAU,OAAO;YACf,IAAI,CAAC,EAAE;gBACL,MAAM,EAAE,MAAM,CAAC;gBACf,QAAQ,EAAE,MAAM,CAAC;gBACjB,KAAK,EAAE,MAAM,CAAC;aACf,CAAC;SACH;KACF;CACF;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,YAAY,GACjB,OAAO,CAAC,IAAI,CAAC,CAiDf;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,GAAG,cAAc,EAAE,MAAM,EAAE,IAC9C,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,UAsBxD;AAED;;GAEG;AACH,wBAAsB,YAAY,CAChC,GAAG,EAAE,OAAO,EACZ,IAAI,EAAE,QAAQ,EACd,IAAI,EAAE,YAAY,GACjB,OAAO,CAAC,IAAI,CAAC,CA2Bf;AAOD,wBAAgB,SAAS,CACvB,WAAW,GAAE,MAAY,EACzB,QAAQ,GAAE,MAAc,IAEhB,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,UA8BxD;AAED;;GAEG;AACH,wBAAgB,SAAS,CACvB,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,YAAY,GACjB,IAAI,CAsBN"}