airweave-mcp-search 0.6.51 → 0.6.53

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.
@@ -1,10 +1,15 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * Airweave MCP Server - HTTP/Streamable Transport
3
+ * Airweave MCP Server - HTTP/Streamable Transport with Redis Session Management
4
4
  *
5
5
  * This is the production HTTP server for cloud-based AI platforms like OpenAI Agent Builder.
6
6
  * Uses the modern Streamable HTTP transport (MCP 2025-03-26) instead of deprecated SSE.
7
7
  *
8
+ * Session Management:
9
+ * - Redis stores session metadata (API key, collection, timestamps)
10
+ * - Each pod maintains an in-memory cache of McpServer/Transport instances
11
+ * - Sessions can be served by any pod (stateless, horizontally scalable)
12
+ *
8
13
  * Endpoint: https://mcp.airweave.ai/mcp
9
14
  * Protocol: MCP 2025-03-26 (Streamable HTTP)
10
15
  * Authentication: Bearer token, X-API-Key, or query parameter
@@ -1 +1 @@
1
- {"version":3,"file":"index-http.d.ts","sourceRoot":"","sources":["../src/index-http.ts"],"names":[],"mappings":";AAEA;;;;;;;;;GASG"}
1
+ {"version":3,"file":"index-http.d.ts","sourceRoot":"","sources":["../src/index-http.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;;;GAcG"}
@@ -1,10 +1,15 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * Airweave MCP Server - HTTP/Streamable Transport
3
+ * Airweave MCP Server - HTTP/Streamable Transport with Redis Session Management
4
4
  *
5
5
  * This is the production HTTP server for cloud-based AI platforms like OpenAI Agent Builder.
6
6
  * Uses the modern Streamable HTTP transport (MCP 2025-03-26) instead of deprecated SSE.
7
7
  *
8
+ * Session Management:
9
+ * - Redis stores session metadata (API key, collection, timestamps)
10
+ * - Each pod maintains an in-memory cache of McpServer/Transport instances
11
+ * - Sessions can be served by any pod (stateless, horizontally scalable)
12
+ *
8
13
  * Endpoint: https://mcp.airweave.ai/mcp
9
14
  * Protocol: MCP 2025-03-26 (Streamable HTTP)
10
15
  * Authentication: Bearer token, X-API-Key, or query parameter
@@ -15,8 +20,11 @@ import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/
15
20
  import { AirweaveClient } from './api/airweave-client.js';
16
21
  import { createSearchTool } from './tools/search-tool.js';
17
22
  import { createConfigTool } from './tools/config-tool.js';
23
+ import { RedisSessionManager } from './session/redis-session-manager.js';
18
24
  const app = express();
19
25
  app.use(express.json({ limit: '10mb' }));
26
+ // Initialize Redis session manager
27
+ const sessionManager = new RedisSessionManager();
20
28
  // Create MCP server instance with tools
21
29
  const createMcpServer = (apiKey) => {
22
30
  const collection = process.env.AIRWEAVE_COLLECTION || 'default';
@@ -48,12 +56,16 @@ const createMcpServer = (apiKey) => {
48
56
  return server;
49
57
  };
50
58
  // Health check endpoint
51
- app.get('/health', (req, res) => {
59
+ app.get('/health', async (req, res) => {
60
+ const redisConnected = sessionManager.isConnected();
52
61
  res.json({
53
- status: 'healthy',
62
+ status: redisConnected ? 'healthy' : 'degraded',
54
63
  transport: 'streamable-http',
55
64
  protocol: 'MCP 2025-03-26',
56
65
  collection: process.env.AIRWEAVE_COLLECTION || 'unknown',
66
+ redis: {
67
+ connected: redisConnected
68
+ },
57
69
  timestamp: new Date().toISOString()
58
70
  });
59
71
  });
@@ -88,9 +100,36 @@ app.get('/', (req, res) => {
88
100
  }
89
101
  });
90
102
  });
91
- // Session management: Map session IDs to { server, transport, apiKey }
92
- const sessions = new Map();
93
- // Main MCP endpoint (Streamable HTTP)
103
+ // Local cache: Map session IDs to { server, transport, data }
104
+ // This cache is per-pod and reconstructed from Redis as needed
105
+ const localSessionCache = new Map();
106
+ /**
107
+ * Helper function to create or recreate session objects (server + transport)
108
+ * Note: apiKey parameter is the PLAINTEXT key needed for API calls
109
+ */
110
+ async function createSessionObjects(sessionData, apiKey) {
111
+ const { sessionId, collection, baseUrl } = sessionData;
112
+ // Create a new server with the API key
113
+ const server = createMcpServer(apiKey);
114
+ // Create a new transport for this session
115
+ const transport = new StreamableHTTPServerTransport({
116
+ sessionIdGenerator: () => sessionId
117
+ });
118
+ // Set up session management callbacks
119
+ transport.onsessioninitialized = (sid) => {
120
+ console.log(`[${new Date().toISOString()}] Session initialized: ${sid}`);
121
+ };
122
+ // Set up cleanup on close
123
+ transport.onclose = async () => {
124
+ console.log(`[${new Date().toISOString()}] Session closed: ${sessionId}`);
125
+ localSessionCache.delete(sessionId);
126
+ await sessionManager.deleteSession(sessionId);
127
+ };
128
+ // Connect the transport to the server
129
+ await server.connect(transport);
130
+ return { server, transport, data: sessionData };
131
+ }
132
+ // Main MCP endpoint (Streamable HTTP) with Redis session management
94
133
  app.post('/mcp', async (req, res) => {
95
134
  try {
96
135
  // Extract API key from request headers or query parameters
@@ -111,45 +150,132 @@ app.post('/mcp', async (req, res) => {
111
150
  return;
112
151
  }
113
152
  // Get or create session ID from MCP-Session-ID header
114
- const sessionId = req.headers['mcp-session-id'] || `session_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
115
- // Check if we have an existing session
116
- let session = sessions.get(sessionId);
117
- if (!session) {
118
- console.log(`[${new Date().toISOString()}] Creating new session: ${sessionId}`);
119
- // Create a new server with the API key
120
- const server = createMcpServer(apiKey);
121
- // Create a new transport for this session
122
- const transport = new StreamableHTTPServerTransport({
123
- sessionIdGenerator: () => sessionId
124
- });
125
- // Set up session management callbacks
126
- transport.onsessioninitialized = (sid) => {
127
- console.log(`[${new Date().toISOString()}] Session initialized: ${sid}`);
128
- };
129
- // Set up cleanup on close
130
- transport.onclose = () => {
131
- console.log(`[${new Date().toISOString()}] Session closed: ${sessionId}`);
132
- sessions.delete(sessionId);
133
- };
134
- // Connect the transport to the server
135
- await server.connect(transport);
136
- // Store the session
137
- session = { server, transport, apiKey: apiKey };
138
- sessions.set(sessionId, session);
153
+ const sessionId = req.headers['mcp-session-id'] ||
154
+ `session_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
155
+ const collection = process.env.AIRWEAVE_COLLECTION || 'default';
156
+ const baseUrl = process.env.AIRWEAVE_BASE_URL || 'https://api.airweave.ai';
157
+ // Security: Extract client metadata for session binding
158
+ const clientIP = req.headers['x-forwarded-for']?.split(',')[0] ||
159
+ req.headers['x-real-ip'] ||
160
+ req.socket.remoteAddress ||
161
+ 'unknown';
162
+ const userAgent = req.headers['user-agent'] || 'unknown';
163
+ let session;
164
+ // Step 1: Check local cache (fastest path - same pod, same session)
165
+ session = localSessionCache.get(sessionId);
166
+ if (session) {
167
+ // Security: Validate API key hasn't changed
168
+ const apiKeyMatches = RedisSessionManager.validateApiKey(apiKey, session.data.apiKeyHash);
169
+ if (!apiKeyMatches) {
170
+ console.log(`[${new Date().toISOString()}] API key changed for session ${sessionId}, recreating...`);
171
+ // Close old session
172
+ session.transport.close();
173
+ localSessionCache.delete(sessionId);
174
+ // Create new session data with hash
175
+ const newSessionData = {
176
+ sessionId,
177
+ apiKeyHash: RedisSessionManager.hashApiKey(apiKey),
178
+ collection,
179
+ baseUrl,
180
+ createdAt: Date.now(),
181
+ lastAccessedAt: Date.now(),
182
+ clientIP,
183
+ userAgent
184
+ };
185
+ // Store in Redis
186
+ await sessionManager.setSession(newSessionData, true);
187
+ // Create new session objects
188
+ session = await createSessionObjects(newSessionData, apiKey);
189
+ localSessionCache.set(sessionId, session);
190
+ }
191
+ else {
192
+ // Security: Validate session binding
193
+ if (session.data.clientIP && session.data.clientIP !== clientIP) {
194
+ console.warn(`[${new Date().toISOString()}] Session hijacking attempt detected: IP mismatch for ${sessionId}`);
195
+ res.status(403).json({
196
+ jsonrpc: '2.0',
197
+ error: {
198
+ code: -32003,
199
+ message: 'Session validation failed: Client identity mismatch',
200
+ },
201
+ id: req.body.id || null
202
+ });
203
+ return;
204
+ }
205
+ }
139
206
  }
140
- else if (session.apiKey !== apiKey) {
141
- // API key changed - recreate session
142
- console.log(`[${new Date().toISOString()}] API key changed for session ${sessionId}, recreating...`);
143
- session.transport.close();
144
- sessions.delete(sessionId);
145
- // Create new session with new API key
146
- const server = createMcpServer(apiKey);
147
- const transport = new StreamableHTTPServerTransport({
148
- sessionIdGenerator: () => sessionId
149
- });
150
- await server.connect(transport);
151
- session = { server, transport, apiKey: apiKey };
152
- sessions.set(sessionId, session);
207
+ else {
208
+ // Step 2: Not in local cache - check Redis (different pod or first request)
209
+ const sessionData = await sessionManager.getSession(sessionId);
210
+ if (sessionData) {
211
+ // Session exists in Redis but not in this pod's cache
212
+ console.log(`[${new Date().toISOString()}] Restoring session from Redis: ${sessionId}`);
213
+ // Security: Validate API key matches
214
+ const apiKeyMatches = RedisSessionManager.validateApiKey(apiKey, sessionData.apiKeyHash);
215
+ if (!apiKeyMatches) {
216
+ console.log(`[${new Date().toISOString()}] API key mismatch for session ${sessionId}, recreating...`);
217
+ // Update session data with new API key hash
218
+ sessionData.apiKeyHash = RedisSessionManager.hashApiKey(apiKey);
219
+ sessionData.lastAccessedAt = Date.now();
220
+ sessionData.clientIP = clientIP;
221
+ sessionData.userAgent = userAgent;
222
+ await sessionManager.setSession(sessionData, false);
223
+ }
224
+ // Security: Validate session binding
225
+ if (sessionData.clientIP && sessionData.clientIP !== clientIP) {
226
+ console.warn(`[${new Date().toISOString()}] Session hijacking attempt detected: IP mismatch for ${sessionId}`);
227
+ res.status(403).json({
228
+ jsonrpc: '2.0',
229
+ error: {
230
+ code: -32003,
231
+ message: 'Session validation failed: Client identity mismatch',
232
+ },
233
+ id: req.body.id || null
234
+ });
235
+ return;
236
+ }
237
+ // Recreate server and transport from session data
238
+ session = await createSessionObjects(sessionData, apiKey);
239
+ localSessionCache.set(sessionId, session);
240
+ }
241
+ else {
242
+ // Step 3: New session - check rate limit first
243
+ console.log(`[${new Date().toISOString()}] Creating new session: ${sessionId}`);
244
+ // Security: Check rate limit
245
+ const rateLimit = await sessionManager.checkRateLimit(apiKey);
246
+ if (!rateLimit.allowed) {
247
+ console.warn(`[${new Date().toISOString()}] Rate limit exceeded for API key (${rateLimit.count} sessions/hour)`);
248
+ res.status(429).json({
249
+ jsonrpc: '2.0',
250
+ error: {
251
+ code: -32002,
252
+ message: 'Too many sessions created. Please try again later.',
253
+ data: {
254
+ limit: 100,
255
+ current: rateLimit.count,
256
+ retryAfter: 3600
257
+ }
258
+ },
259
+ id: req.body.id || null
260
+ });
261
+ return;
262
+ }
263
+ const newSessionData = {
264
+ sessionId,
265
+ apiKeyHash: RedisSessionManager.hashApiKey(apiKey),
266
+ collection,
267
+ baseUrl,
268
+ createdAt: Date.now(),
269
+ lastAccessedAt: Date.now(),
270
+ clientIP,
271
+ userAgent
272
+ };
273
+ // Store in Redis
274
+ await sessionManager.setSession(newSessionData, true);
275
+ // Create session objects
276
+ session = await createSessionObjects(newSessionData, apiKey);
277
+ localSessionCache.set(sessionId, session);
278
+ }
153
279
  }
154
280
  // Handle the request with the session's transport
155
281
  await session.transport.handleRequest(req, res, req.body);
@@ -169,7 +295,7 @@ app.post('/mcp', async (req, res) => {
169
295
  }
170
296
  });
171
297
  // DELETE endpoint for session termination
172
- app.delete('/mcp', (req, res) => {
298
+ app.delete('/mcp', async (req, res) => {
173
299
  const sessionId = req.headers['mcp-session-id'];
174
300
  if (!sessionId) {
175
301
  res.status(400).json({
@@ -182,17 +308,19 @@ app.delete('/mcp', (req, res) => {
182
308
  });
183
309
  return;
184
310
  }
185
- // Close the session if it exists
186
- const session = sessions.get(sessionId);
311
+ // Close the session if it exists locally
312
+ const session = localSessionCache.get(sessionId);
187
313
  if (session) {
188
314
  console.log(`[${new Date().toISOString()}] Terminating session: ${sessionId}`);
189
315
  session.transport.close();
190
- sessions.delete(sessionId);
316
+ localSessionCache.delete(sessionId);
191
317
  }
318
+ // Delete from Redis (works across all pods)
319
+ await sessionManager.deleteSession(sessionId);
192
320
  res.status(200).json({
193
321
  jsonrpc: '2.0',
194
322
  result: {
195
- message: session ? 'Session terminated successfully' : 'Session not found (may have already been closed)'
323
+ message: 'Session terminated successfully'
196
324
  },
197
325
  id: null
198
326
  });
@@ -211,21 +339,62 @@ app.use((error, req, res, next) => {
211
339
  });
212
340
  }
213
341
  });
214
- // Start server
215
- const PORT = process.env.PORT || 8080;
216
- app.listen(PORT, () => {
342
+ // Initialize and start server
343
+ async function startServer() {
344
+ const PORT = process.env.PORT || 8080;
217
345
  const collection = process.env.AIRWEAVE_COLLECTION || 'default';
218
346
  const baseUrl = process.env.AIRWEAVE_BASE_URL || 'https://api.airweave.ai';
219
- console.log(`🚀 Airweave MCP Search Server (Streamable HTTP) started`);
220
- console.log(`📡 Protocol: MCP 2025-03-26`);
221
- console.log(`🔗 Endpoint: http://localhost:${PORT}/mcp`);
222
- console.log(`🏥 Health: http://localhost:${PORT}/health`);
223
- console.log(`📋 Info: http://localhost:${PORT}/`);
224
- console.log(`📚 Collection: ${collection}`);
225
- console.log(`🌐 Base URL: ${baseUrl}`);
226
- console.log(`\n🔑 Authentication required: Provide your Airweave API key via:`);
227
- console.log(` - Authorization: Bearer <your-api-key>`);
228
- console.log(` - X-API-Key: <your-api-key>`);
229
- console.log(` - Query parameter: ?apiKey=your-key`);
230
- });
347
+ try {
348
+ // Connect to Redis
349
+ console.log('🔌 Connecting to Redis...');
350
+ await sessionManager.connect();
351
+ console.log('✅ Redis connected');
352
+ // Start HTTP server
353
+ const server = app.listen(PORT, () => {
354
+ console.log(`\n🚀 Airweave MCP Search Server (Streamable HTTP) started`);
355
+ console.log(`📡 Protocol: MCP 2025-03-26`);
356
+ console.log(`🔗 Endpoint: http://localhost:${PORT}/mcp`);
357
+ console.log(`🏥 Health: http://localhost:${PORT}/health`);
358
+ console.log(`📋 Info: http://localhost:${PORT}/`);
359
+ console.log(`📚 Collection: ${collection}`);
360
+ console.log(`🌐 Base URL: ${baseUrl}`);
361
+ console.log(`💾 Session Storage: Redis (stateless, horizontally scalable)`);
362
+ console.log(`\n🔑 Authentication required: Provide your Airweave API key via:`);
363
+ console.log(` - Authorization: Bearer <your-api-key>`);
364
+ console.log(` - X-API-Key: <your-api-key>`);
365
+ console.log(` - Query parameter: ?apiKey=your-key`);
366
+ });
367
+ // Graceful shutdown
368
+ const shutdown = async (signal) => {
369
+ console.log(`\n${signal} received. Shutting down gracefully...`);
370
+ // Close HTTP server
371
+ server.close(() => {
372
+ console.log('HTTP server closed');
373
+ });
374
+ // Close all local sessions
375
+ console.log(`Closing ${localSessionCache.size} local sessions...`);
376
+ for (const [sessionId, session] of localSessionCache.entries()) {
377
+ try {
378
+ session.transport.close();
379
+ }
380
+ catch (err) {
381
+ console.error(`Error closing session ${sessionId}:`, err);
382
+ }
383
+ }
384
+ localSessionCache.clear();
385
+ // Disconnect from Redis
386
+ await sessionManager.disconnect();
387
+ console.log('Redis disconnected');
388
+ process.exit(0);
389
+ };
390
+ process.on('SIGTERM', () => shutdown('SIGTERM'));
391
+ process.on('SIGINT', () => shutdown('SIGINT'));
392
+ }
393
+ catch (error) {
394
+ console.error('Failed to start server:', error);
395
+ process.exit(1);
396
+ }
397
+ }
398
+ // Start the server
399
+ startServer().catch(console.error);
231
400
  //# sourceMappingURL=index-http.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index-http.js","sourceRoot":"","sources":["../src/index-http.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index-http.js","sourceRoot":"","sources":["../src/index-http.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Redis-based session manager for MCP server
3
+ *
4
+ * Stores session metadata in Redis to enable stateless, horizontally-scalable deployments.
5
+ * Session state includes: API key hash, collections metadata, last access timestamp.
6
+ *
7
+ * Security measures:
8
+ * - API keys are hashed (SHA-256) before storage for defense-in-depth
9
+ * - Session TTL limits exposure window
10
+ * - Client binding (IP/User-Agent) prevents session hijacking
11
+ * - Comprehensive audit logging for security monitoring
12
+ *
13
+ * Note: We still need plaintext API keys at runtime to call Airweave API,
14
+ * but Redis compromise won't expose them.
15
+ */
16
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
17
+ import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
18
+ export interface SessionData {
19
+ sessionId: string;
20
+ apiKeyHash: string;
21
+ collection: string;
22
+ baseUrl: string;
23
+ createdAt: number;
24
+ lastAccessedAt: number;
25
+ clientIP?: string;
26
+ userAgent?: string;
27
+ }
28
+ export interface SessionMetadata {
29
+ clientIP?: string;
30
+ userAgent?: string;
31
+ }
32
+ export interface SessionWithTransport {
33
+ server: McpServer;
34
+ transport: StreamableHTTPServerTransport;
35
+ data: SessionData;
36
+ }
37
+ export declare class RedisSessionManager {
38
+ private redis;
39
+ private connected;
40
+ private readonly SESSION_PREFIX;
41
+ private readonly RATE_LIMIT_PREFIX;
42
+ private readonly DEFAULT_TTL;
43
+ private readonly RATE_LIMIT_WINDOW;
44
+ private readonly MAX_SESSIONS_PER_HOUR;
45
+ constructor(redisUrl?: string);
46
+ connect(): Promise<void>;
47
+ disconnect(): Promise<void>;
48
+ isConnected(): boolean;
49
+ private getKey;
50
+ private getRateLimitKey;
51
+ /**
52
+ * Hash an API key using SHA-256 for secure storage
53
+ * Note: This is defense-in-depth. We still need the plaintext key at runtime.
54
+ */
55
+ static hashApiKey(apiKey: string): string;
56
+ /**
57
+ * Validate that an API key matches the stored hash
58
+ */
59
+ static validateApiKey(apiKey: string, apiKeyHash: string): boolean;
60
+ /**
61
+ * Audit log for security monitoring
62
+ */
63
+ private auditLog;
64
+ /**
65
+ * Check rate limit for session creation
66
+ */
67
+ checkRateLimit(apiKey: string): Promise<{
68
+ allowed: boolean;
69
+ count: number;
70
+ }>;
71
+ /**
72
+ * Get session data from Redis
73
+ */
74
+ getSession(sessionId: string): Promise<SessionData | null>;
75
+ /**
76
+ * Create or update session in Redis
77
+ * Includes rate limiting check for new sessions
78
+ */
79
+ setSession(sessionData: SessionData, isNewSession?: boolean): Promise<void>;
80
+ /**
81
+ * Delete session from Redis
82
+ */
83
+ deleteSession(sessionId: string): Promise<void>;
84
+ /**
85
+ * Check if a session exists
86
+ */
87
+ sessionExists(sessionId: string): Promise<boolean>;
88
+ /**
89
+ * Get all session IDs (for debugging/monitoring)
90
+ */
91
+ getAllSessionIds(): Promise<string[]>;
92
+ /**
93
+ * Clean up expired sessions (manual cleanup, Redis TTL handles this automatically)
94
+ */
95
+ cleanupExpiredSessions(maxAge?: number): Promise<number>;
96
+ }
97
+ //# sourceMappingURL=redis-session-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redis-session-manager.d.ts","sourceRoot":"","sources":["../../src/session/redis-session-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,6BAA6B,EAAE,MAAM,oDAAoD,CAAC;AAGnG,MAAM,WAAW,WAAW;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IAEvB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,oBAAoB;IACjC,MAAM,EAAE,SAAS,CAAC;IAClB,SAAS,EAAE,6BAA6B,CAAC;IACzC,IAAI,EAAE,WAAW,CAAC;CACrB;AAED,qBAAa,mBAAmB;IAC5B,OAAO,CAAC,KAAK,CAAkB;IAC/B,OAAO,CAAC,SAAS,CAAkB;IACnC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAkB;IACjD,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAqB;IACvD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAQ;IACpC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAQ;IAC1C,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAO;gBAEjC,QAAQ,CAAC,EAAE,MAAM;IA+BvB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAMxB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAOjC,WAAW,IAAI,OAAO;IAItB,OAAO,CAAC,MAAM;IAId,OAAO,CAAC,eAAe;IAKvB;;;OAGG;IACH,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAIzC;;OAEG;IACH,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO;IAIlE;;OAEG;IACH,OAAO,CAAC,QAAQ;IAShB;;OAEG;IACG,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IA8BlF;;OAEG;IACG,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAgChE;;;OAGG;IACG,UAAU,CAAC,WAAW,EAAE,WAAW,EAAE,YAAY,GAAE,OAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAwBxF;;OAEG;IACG,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBrD;;OAEG;IACG,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAWxD;;OAEG;IACG,gBAAgB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAW3C;;OAEG;IACG,sBAAsB,CAAC,MAAM,GAAE,MAAgC,GAAG,OAAO,CAAC,MAAM,CAAC;CAwB1F"}
@@ -0,0 +1,254 @@
1
+ /**
2
+ * Redis-based session manager for MCP server
3
+ *
4
+ * Stores session metadata in Redis to enable stateless, horizontally-scalable deployments.
5
+ * Session state includes: API key hash, collections metadata, last access timestamp.
6
+ *
7
+ * Security measures:
8
+ * - API keys are hashed (SHA-256) before storage for defense-in-depth
9
+ * - Session TTL limits exposure window
10
+ * - Client binding (IP/User-Agent) prevents session hijacking
11
+ * - Comprehensive audit logging for security monitoring
12
+ *
13
+ * Note: We still need plaintext API keys at runtime to call Airweave API,
14
+ * but Redis compromise won't expose them.
15
+ */
16
+ import { createClient } from 'redis';
17
+ import { createHash } from 'crypto';
18
+ export class RedisSessionManager {
19
+ redis;
20
+ connected = false;
21
+ SESSION_PREFIX = 'mcp:session:';
22
+ RATE_LIMIT_PREFIX = 'mcp:rate_limit:';
23
+ DEFAULT_TTL = 1800; // 30 minutes (reduced from 1 hour for security)
24
+ RATE_LIMIT_WINDOW = 3600; // 1 hour
25
+ MAX_SESSIONS_PER_HOUR = 100; // Per API key
26
+ constructor(redisUrl) {
27
+ this.redis = createClient({
28
+ url: redisUrl || process.env.REDIS_URL || 'redis://localhost:6379',
29
+ socket: {
30
+ reconnectStrategy: (retries) => {
31
+ if (retries > 10) {
32
+ console.error('Redis: Max reconnection attempts reached');
33
+ return new Error('Max reconnection attempts reached');
34
+ }
35
+ const delay = Math.min(retries * 100, 3000);
36
+ console.log(`Redis: Reconnecting in ${delay}ms (attempt ${retries})`);
37
+ return delay;
38
+ }
39
+ }
40
+ });
41
+ this.redis.on('error', (err) => {
42
+ console.error('Redis Client Error:', err);
43
+ });
44
+ this.redis.on('connect', () => {
45
+ console.log('Redis: Connected');
46
+ this.connected = true;
47
+ });
48
+ this.redis.on('disconnect', () => {
49
+ console.log('Redis: Disconnected');
50
+ this.connected = false;
51
+ });
52
+ }
53
+ async connect() {
54
+ if (!this.connected) {
55
+ await this.redis.connect();
56
+ }
57
+ }
58
+ async disconnect() {
59
+ if (this.connected) {
60
+ await this.redis.quit();
61
+ this.connected = false;
62
+ }
63
+ }
64
+ isConnected() {
65
+ return this.connected;
66
+ }
67
+ getKey(sessionId) {
68
+ return `${this.SESSION_PREFIX}${sessionId}`;
69
+ }
70
+ getRateLimitKey(apiKeyHash) {
71
+ const hour = Math.floor(Date.now() / (1000 * 60 * 60));
72
+ return `${this.RATE_LIMIT_PREFIX}${apiKeyHash}:${hour}`;
73
+ }
74
+ /**
75
+ * Hash an API key using SHA-256 for secure storage
76
+ * Note: This is defense-in-depth. We still need the plaintext key at runtime.
77
+ */
78
+ static hashApiKey(apiKey) {
79
+ return createHash('sha256').update(apiKey).digest('hex');
80
+ }
81
+ /**
82
+ * Validate that an API key matches the stored hash
83
+ */
84
+ static validateApiKey(apiKey, apiKeyHash) {
85
+ return RedisSessionManager.hashApiKey(apiKey) === apiKeyHash;
86
+ }
87
+ /**
88
+ * Audit log for security monitoring
89
+ */
90
+ auditLog(operation, details) {
91
+ console.log(JSON.stringify({
92
+ timestamp: new Date().toISOString(),
93
+ service: 'mcp-redis-session',
94
+ operation,
95
+ ...details
96
+ }));
97
+ }
98
+ /**
99
+ * Check rate limit for session creation
100
+ */
101
+ async checkRateLimit(apiKey) {
102
+ try {
103
+ const apiKeyHash = RedisSessionManager.hashApiKey(apiKey);
104
+ const rateLimitKey = this.getRateLimitKey(apiKeyHash);
105
+ const count = await this.redis.incr(rateLimitKey);
106
+ // Set expiration on first increment
107
+ if (count === 1) {
108
+ await this.redis.expire(rateLimitKey, this.RATE_LIMIT_WINDOW);
109
+ }
110
+ const allowed = count <= this.MAX_SESSIONS_PER_HOUR;
111
+ if (!allowed) {
112
+ this.auditLog('rate_limit_exceeded', {
113
+ apiKeyHash: apiKeyHash ? apiKeyHash.substring(0, 16) + '...' : 'N/A',
114
+ count,
115
+ limit: this.MAX_SESSIONS_PER_HOUR
116
+ });
117
+ }
118
+ return { allowed, count };
119
+ }
120
+ catch (error) {
121
+ console.error('Error checking rate limit:', error);
122
+ // Fail open - allow the request if rate limiting fails
123
+ return { allowed: true, count: 0 };
124
+ }
125
+ }
126
+ /**
127
+ * Get session data from Redis
128
+ */
129
+ async getSession(sessionId) {
130
+ try {
131
+ const key = this.getKey(sessionId);
132
+ const data = await this.redis.get(key);
133
+ if (!data) {
134
+ this.auditLog('session_miss', { sessionId });
135
+ return null;
136
+ }
137
+ const sessionData = JSON.parse(data);
138
+ // Update last accessed time
139
+ sessionData.lastAccessedAt = Date.now();
140
+ await this.redis.set(key, JSON.stringify(sessionData), {
141
+ EX: this.DEFAULT_TTL
142
+ });
143
+ this.auditLog('session_accessed', {
144
+ sessionId,
145
+ apiKeyHash: sessionData.apiKeyHash ? sessionData.apiKeyHash.substring(0, 16) + '...' : 'N/A',
146
+ age: Date.now() - sessionData.createdAt
147
+ });
148
+ return sessionData;
149
+ }
150
+ catch (error) {
151
+ console.error(`Error getting session ${sessionId}:`, error);
152
+ this.auditLog('session_error', { sessionId, error: String(error) });
153
+ return null;
154
+ }
155
+ }
156
+ /**
157
+ * Create or update session in Redis
158
+ * Includes rate limiting check for new sessions
159
+ */
160
+ async setSession(sessionData, isNewSession = false) {
161
+ try {
162
+ const key = this.getKey(sessionData.sessionId);
163
+ await this.redis.set(key, JSON.stringify(sessionData), {
164
+ EX: this.DEFAULT_TTL
165
+ });
166
+ this.auditLog(isNewSession ? 'session_created' : 'session_updated', {
167
+ sessionId: sessionData.sessionId,
168
+ apiKeyHash: sessionData.apiKeyHash ? sessionData.apiKeyHash.substring(0, 16) + '...' : 'N/A',
169
+ clientIP: sessionData.clientIP || 'unknown',
170
+ hasBinding: !!(sessionData.clientIP && sessionData.userAgent)
171
+ });
172
+ }
173
+ catch (error) {
174
+ console.error(`Error setting session ${sessionData.sessionId}:`, error);
175
+ this.auditLog('session_error', {
176
+ sessionId: sessionData.sessionId,
177
+ error: String(error),
178
+ operation: 'set'
179
+ });
180
+ throw error;
181
+ }
182
+ }
183
+ /**
184
+ * Delete session from Redis
185
+ */
186
+ async deleteSession(sessionId) {
187
+ try {
188
+ const key = this.getKey(sessionId);
189
+ await this.redis.del(key);
190
+ this.auditLog('session_deleted', { sessionId });
191
+ }
192
+ catch (error) {
193
+ console.error(`Error deleting session ${sessionId}:`, error);
194
+ this.auditLog('session_error', {
195
+ sessionId,
196
+ error: String(error),
197
+ operation: 'delete'
198
+ });
199
+ }
200
+ }
201
+ /**
202
+ * Check if a session exists
203
+ */
204
+ async sessionExists(sessionId) {
205
+ try {
206
+ const key = this.getKey(sessionId);
207
+ const exists = await this.redis.exists(key);
208
+ return exists === 1;
209
+ }
210
+ catch (error) {
211
+ console.error(`Error checking session ${sessionId}:`, error);
212
+ return false;
213
+ }
214
+ }
215
+ /**
216
+ * Get all session IDs (for debugging/monitoring)
217
+ */
218
+ async getAllSessionIds() {
219
+ try {
220
+ const keys = await this.redis.keys(`${this.SESSION_PREFIX}*`);
221
+ return keys.map(key => key.replace(this.SESSION_PREFIX, ''));
222
+ }
223
+ catch (error) {
224
+ console.error('Error getting all session IDs:', error);
225
+ return [];
226
+ }
227
+ }
228
+ /**
229
+ * Clean up expired sessions (manual cleanup, Redis TTL handles this automatically)
230
+ */
231
+ async cleanupExpiredSessions(maxAge = this.DEFAULT_TTL * 1000) {
232
+ try {
233
+ const keys = await this.redis.keys(`${this.SESSION_PREFIX}*`);
234
+ let deleted = 0;
235
+ for (const key of keys) {
236
+ const data = await this.redis.get(key);
237
+ if (data) {
238
+ const sessionData = JSON.parse(data);
239
+ const age = Date.now() - sessionData.lastAccessedAt;
240
+ if (age > maxAge) {
241
+ await this.redis.del(key);
242
+ deleted++;
243
+ }
244
+ }
245
+ }
246
+ return deleted;
247
+ }
248
+ catch (error) {
249
+ console.error('Error cleaning up expired sessions:', error);
250
+ return 0;
251
+ }
252
+ }
253
+ }
254
+ //# sourceMappingURL=redis-session-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redis-session-manager.js","sourceRoot":"","sources":["../../src/session/redis-session-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,YAAY,EAAmB,MAAM,OAAO,CAAC;AAGtD,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAyBpC,MAAM,OAAO,mBAAmB;IACpB,KAAK,CAAkB;IACvB,SAAS,GAAY,KAAK,CAAC;IAClB,cAAc,GAAG,cAAc,CAAC;IAChC,iBAAiB,GAAG,iBAAiB,CAAC;IACtC,WAAW,GAAG,IAAI,CAAC,CAAC,gDAAgD;IACpE,iBAAiB,GAAG,IAAI,CAAC,CAAC,SAAS;IACnC,qBAAqB,GAAG,GAAG,CAAC,CAAC,cAAc;IAE5D,YAAY,QAAiB;QACzB,IAAI,CAAC,KAAK,GAAG,YAAY,CAAC;YACtB,GAAG,EAAE,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,wBAAwB;YAClE,MAAM,EAAE;gBACJ,iBAAiB,EAAE,CAAC,OAAO,EAAE,EAAE;oBAC3B,IAAI,OAAO,GAAG,EAAE,EAAE,CAAC;wBACf,OAAO,CAAC,KAAK,CAAC,0CAA0C,CAAC,CAAC;wBAC1D,OAAO,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;oBAC1D,CAAC;oBACD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,GAAG,GAAG,EAAE,IAAI,CAAC,CAAC;oBAC5C,OAAO,CAAC,GAAG,CAAC,0BAA0B,KAAK,eAAe,OAAO,GAAG,CAAC,CAAC;oBACtE,OAAO,KAAK,CAAC;gBACjB,CAAC;aACJ;SACJ,CAAC,CAAC;QAEH,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;YAC3B,OAAO,CAAC,KAAK,CAAC,qBAAqB,EAAE,GAAG,CAAC,CAAC;QAC9C,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;YAC1B,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;YAChC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QAC1B,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,EAAE,GAAG,EAAE;YAC7B,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;YACnC,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;QAC3B,CAAC,CAAC,CAAC;IACP,CAAC;IAED,KAAK,CAAC,OAAO;QACT,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YAClB,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;QAC/B,CAAC;IACL,CAAC;IAED,KAAK,CAAC,UAAU;QACZ,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACjB,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;YACxB,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;QAC3B,CAAC;IACL,CAAC;IAED,WAAW;QACP,OAAO,IAAI,CAAC,SAAS,CAAC;IAC1B,CAAC;IAEO,MAAM,CAAC,SAAiB;QAC5B,OAAO,GAAG,IAAI,CAAC,cAAc,GAAG,SAAS,EAAE,CAAC;IAChD,CAAC;IAEO,eAAe,CAAC,UAAkB;QACtC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;QACvD,OAAO,GAAG,IAAI,CAAC,iBAAiB,GAAG,UAAU,IAAI,IAAI,EAAE,CAAC;IAC5D,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,UAAU,CAAC,MAAc;QAC5B,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC7D,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,cAAc,CAAC,MAAc,EAAE,UAAkB;QACpD,OAAO,mBAAmB,CAAC,UAAU,CAAC,MAAM,CAAC,KAAK,UAAU,CAAC;IACjE,CAAC;IAED;;OAEG;IACK,QAAQ,CAAC,SAAiB,EAAE,OAA4B;QAC5D,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC;YACvB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,OAAO,EAAE,mBAAmB;YAC5B,SAAS;YACT,GAAG,OAAO;SACb,CAAC,CAAC,CAAC;IACR,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,cAAc,CAAC,MAAc;QAC/B,IAAI,CAAC;YACD,MAAM,UAAU,GAAG,mBAAmB,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;YAC1D,MAAM,YAAY,GAAG,IAAI,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC;YAEtD,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAElD,oCAAoC;YACpC,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;gBACd,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,YAAY,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAC;YAClE,CAAC;YAED,MAAM,OAAO,GAAG,KAAK,IAAI,IAAI,CAAC,qBAAqB,CAAC;YAEpD,IAAI,CAAC,OAAO,EAAE,CAAC;gBACX,IAAI,CAAC,QAAQ,CAAC,qBAAqB,EAAE;oBACjC,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK;oBACpE,KAAK;oBACL,KAAK,EAAE,IAAI,CAAC,qBAAqB;iBACpC,CAAC,CAAC;YACP,CAAC;YAED,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;QAC9B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,4BAA4B,EAAE,KAAK,CAAC,CAAC;YACnD,uDAAuD;YACvD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;QACvC,CAAC;IACL,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,UAAU,CAAC,SAAiB;QAC9B,IAAI,CAAC;YACD,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;YACnC,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAEvC,IAAI,CAAC,IAAI,EAAE,CAAC;gBACR,IAAI,CAAC,QAAQ,CAAC,cAAc,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;gBAC7C,OAAO,IAAI,CAAC;YAChB,CAAC;YAED,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAgB,CAAC;YAEpD,4BAA4B;YAC5B,WAAW,CAAC,cAAc,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YACxC,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,EAAE;gBACnD,EAAE,EAAE,IAAI,CAAC,WAAW;aACvB,CAAC,CAAC;YAEH,IAAI,CAAC,QAAQ,CAAC,kBAAkB,EAAE;gBAC9B,SAAS;gBACT,UAAU,EAAE,WAAW,CAAC,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK;gBAC5F,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,WAAW,CAAC,SAAS;aAC1C,CAAC,CAAC;YAEH,OAAO,WAAW,CAAC;QACvB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,yBAAyB,SAAS,GAAG,EAAE,KAAK,CAAC,CAAC;YAC5D,IAAI,CAAC,QAAQ,CAAC,eAAe,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YACpE,OAAO,IAAI,CAAC;QAChB,CAAC;IACL,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,UAAU,CAAC,WAAwB,EAAE,eAAwB,KAAK;QACpE,IAAI,CAAC;YACD,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;YAC/C,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,EAAE;gBACnD,EAAE,EAAE,IAAI,CAAC,WAAW;aACvB,CAAC,CAAC;YAEH,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,iBAAiB,EAAE;gBAChE,SAAS,EAAE,WAAW,CAAC,SAAS;gBAChC,UAAU,EAAE,WAAW,CAAC,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK;gBAC5F,QAAQ,EAAE,WAAW,CAAC,QAAQ,IAAI,SAAS;gBAC3C,UAAU,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,QAAQ,IAAI,WAAW,CAAC,SAAS,CAAC;aAChE,CAAC,CAAC;QACP,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,yBAAyB,WAAW,CAAC,SAAS,GAAG,EAAE,KAAK,CAAC,CAAC;YACxE,IAAI,CAAC,QAAQ,CAAC,eAAe,EAAE;gBAC3B,SAAS,EAAE,WAAW,CAAC,SAAS;gBAChC,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC;gBACpB,SAAS,EAAE,KAAK;aACnB,CAAC,CAAC;YACH,MAAM,KAAK,CAAC;QAChB,CAAC;IACL,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,aAAa,CAAC,SAAiB;QACjC,IAAI,CAAC;YACD,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;YACnC,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAE1B,IAAI,CAAC,QAAQ,CAAC,iBAAiB,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;QACpD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,0BAA0B,SAAS,GAAG,EAAE,KAAK,CAAC,CAAC;YAC7D,IAAI,CAAC,QAAQ,CAAC,eAAe,EAAE;gBAC3B,SAAS;gBACT,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC;gBACpB,SAAS,EAAE,QAAQ;aACtB,CAAC,CAAC;QACP,CAAC;IACL,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,aAAa,CAAC,SAAiB;QACjC,IAAI,CAAC;YACD,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;YACnC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC5C,OAAO,MAAM,KAAK,CAAC,CAAC;QACxB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,0BAA0B,SAAS,GAAG,EAAE,KAAK,CAAC,CAAC;YAC7D,OAAO,KAAK,CAAC;QACjB,CAAC;IACL,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,gBAAgB;QAClB,IAAI,CAAC;YACD,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,cAAc,GAAG,CAAC,CAAC;YAC9D,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC,CAAC;QACjE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,gCAAgC,EAAE,KAAK,CAAC,CAAC;YACvD,OAAO,EAAE,CAAC;QACd,CAAC;IACL,CAAC;IAGD;;OAEG;IACH,KAAK,CAAC,sBAAsB,CAAC,SAAiB,IAAI,CAAC,WAAW,GAAG,IAAI;QACjE,IAAI,CAAC;YACD,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,cAAc,GAAG,CAAC,CAAC;YAC9D,IAAI,OAAO,GAAG,CAAC,CAAC;YAEhB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;gBACrB,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gBACvC,IAAI,IAAI,EAAE,CAAC;oBACP,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAgB,CAAC;oBACpD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,WAAW,CAAC,cAAc,CAAC;oBAEpD,IAAI,GAAG,GAAG,MAAM,EAAE,CAAC;wBACf,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;wBAC1B,OAAO,EAAE,CAAC;oBACd,CAAC;gBACL,CAAC;YACL,CAAC;YAED,OAAO,OAAO,CAAC;QACnB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,qCAAqC,EAAE,KAAK,CAAC,CAAC;YAC5D,OAAO,CAAC,CAAC;QACb,CAAC;IACL,CAAC;CACJ"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "airweave-mcp-search",
3
- "version": "0.6.51",
3
+ "version": "0.6.53",
4
4
  "description": "MCP server for searching Airweave collections",
5
5
  "type": "module",
6
6
  "main": "build/index.js",
@@ -49,6 +49,7 @@
49
49
  "@airweave/sdk": "^0.6.0",
50
50
  "@modelcontextprotocol/sdk": "^1.12.0",
51
51
  "express": "^4.18.2",
52
+ "redis": "^4.6.13",
52
53
  "zod": "^3.23.8"
53
54
  },
54
55
  "devDependencies": {