mcp-perplexity-pro 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/README.md +638 -0
  2. package/bin/mcp-perplexity-pro +8 -0
  3. package/bin/mcp-perplexity-pro-stdio +9 -0
  4. package/dist/claude-code-bridge.d.ts +3 -0
  5. package/dist/claude-code-bridge.d.ts.map +1 -0
  6. package/dist/claude-code-bridge.js +111 -0
  7. package/dist/claude-code-bridge.js.map +1 -0
  8. package/dist/http-index.d.ts +3 -0
  9. package/dist/http-index.d.ts.map +1 -0
  10. package/dist/http-index.js +38 -0
  11. package/dist/http-index.js.map +1 -0
  12. package/dist/http-server.d.ts +33 -0
  13. package/dist/http-server.d.ts.map +1 -0
  14. package/dist/http-server.js +362 -0
  15. package/dist/http-server.js.map +1 -0
  16. package/dist/http-streaming-server.d.ts +4 -0
  17. package/dist/http-streaming-server.d.ts.map +1 -0
  18. package/dist/http-streaming-server.js +514 -0
  19. package/dist/http-streaming-server.js.map +1 -0
  20. package/dist/index.d.ts +3 -0
  21. package/dist/index.d.ts.map +1 -0
  22. package/dist/index.js +43 -0
  23. package/dist/index.js.map +1 -0
  24. package/dist/launcher.d.ts +3 -0
  25. package/dist/launcher.d.ts.map +1 -0
  26. package/dist/launcher.js +209 -0
  27. package/dist/launcher.js.map +1 -0
  28. package/dist/mcp-server.d.ts +5 -0
  29. package/dist/mcp-server.d.ts.map +1 -0
  30. package/dist/mcp-server.js +329 -0
  31. package/dist/mcp-server.js.map +1 -0
  32. package/dist/models.d.ts +45 -0
  33. package/dist/models.d.ts.map +1 -0
  34. package/dist/models.js +284 -0
  35. package/dist/models.js.map +1 -0
  36. package/dist/perplexity-api.d.ts +59 -0
  37. package/dist/perplexity-api.d.ts.map +1 -0
  38. package/dist/perplexity-api.js +455 -0
  39. package/dist/perplexity-api.js.map +1 -0
  40. package/dist/port-utils.d.ts +31 -0
  41. package/dist/port-utils.d.ts.map +1 -0
  42. package/dist/port-utils.js +114 -0
  43. package/dist/port-utils.js.map +1 -0
  44. package/dist/project-manager.d.ts +91 -0
  45. package/dist/project-manager.d.ts.map +1 -0
  46. package/dist/project-manager.js +422 -0
  47. package/dist/project-manager.js.map +1 -0
  48. package/dist/simple-streaming.d.ts +26 -0
  49. package/dist/simple-streaming.d.ts.map +1 -0
  50. package/dist/simple-streaming.js +75 -0
  51. package/dist/simple-streaming.js.map +1 -0
  52. package/dist/sse-index.d.ts +3 -0
  53. package/dist/sse-index.d.ts.map +1 -0
  54. package/dist/sse-index.js +38 -0
  55. package/dist/sse-index.js.map +1 -0
  56. package/dist/sse-server.d.ts +4 -0
  57. package/dist/sse-server.d.ts.map +1 -0
  58. package/dist/sse-server.js +208 -0
  59. package/dist/sse-server.js.map +1 -0
  60. package/dist/stdio-bridge.d.ts +21 -0
  61. package/dist/stdio-bridge.d.ts.map +1 -0
  62. package/dist/stdio-bridge.js +157 -0
  63. package/dist/stdio-bridge.js.map +1 -0
  64. package/dist/stdio-server.d.ts +7 -0
  65. package/dist/stdio-server.d.ts.map +1 -0
  66. package/dist/stdio-server.js +396 -0
  67. package/dist/stdio-server.js.map +1 -0
  68. package/dist/storage.d.ts +65 -0
  69. package/dist/storage.d.ts.map +1 -0
  70. package/dist/storage.js +328 -0
  71. package/dist/storage.js.map +1 -0
  72. package/dist/streaming-wrapper.d.ts +63 -0
  73. package/dist/streaming-wrapper.d.ts.map +1 -0
  74. package/dist/streaming-wrapper.js +452 -0
  75. package/dist/streaming-wrapper.js.map +1 -0
  76. package/dist/tools/async.d.ts +28 -0
  77. package/dist/tools/async.d.ts.map +1 -0
  78. package/dist/tools/async.js +167 -0
  79. package/dist/tools/async.js.map +1 -0
  80. package/dist/tools/chat.d.ts +29 -0
  81. package/dist/tools/chat.d.ts.map +1 -0
  82. package/dist/tools/chat.js +233 -0
  83. package/dist/tools/chat.js.map +1 -0
  84. package/dist/tools/projects.d.ts +19 -0
  85. package/dist/tools/projects.d.ts.map +1 -0
  86. package/dist/tools/projects.js +219 -0
  87. package/dist/tools/projects.js.map +1 -0
  88. package/dist/tools/query.d.ts +13 -0
  89. package/dist/tools/query.d.ts.map +1 -0
  90. package/dist/tools/query.js +178 -0
  91. package/dist/tools/query.js.map +1 -0
  92. package/dist/types.d.ts +330 -0
  93. package/dist/types.d.ts.map +1 -0
  94. package/dist/types.js +90 -0
  95. package/dist/types.js.map +1 -0
  96. package/package.json +89 -0
@@ -0,0 +1,455 @@
1
+ import fetch from 'node-fetch';
2
+ import { suggestFallbackModel } from './models.js';
3
+ // Perplexity API endpoints
4
+ const PERPLEXITY_BASE_URL = 'https://api.perplexity.ai';
5
+ const CHAT_COMPLETIONS_ENDPOINT = '/chat/completions';
6
+ const ASYNC_CHAT_COMPLETIONS_ENDPOINT = '/async/chat/completions';
7
+ export class PerplexityApiError extends Error {
8
+ status;
9
+ response;
10
+ constructor(message, status, response) {
11
+ super(message);
12
+ this.status = status;
13
+ this.response = response;
14
+ this.name = 'PerplexityApiError';
15
+ }
16
+ }
17
+ export class PerplexityApiClient {
18
+ apiKey;
19
+ baseUrl;
20
+ constructor(config) {
21
+ this.apiKey = config.api_key;
22
+ this.baseUrl = PERPLEXITY_BASE_URL;
23
+ }
24
+ /**
25
+ * Makes a request to the Perplexity API with proper error handling
26
+ */
27
+ async makeRequest(endpoint, body, method = 'POST') {
28
+ const url = `${this.baseUrl}${endpoint}`;
29
+ console.error(`Making request to: ${url}`);
30
+ console.error(`API key: ${this.apiKey ? this.apiKey.substring(0, 10) + '...' : 'MISSING'}`);
31
+ try {
32
+ const response = await fetch(url, {
33
+ method,
34
+ headers: {
35
+ Authorization: `Bearer ${this.apiKey}`,
36
+ 'Content-Type': 'application/json',
37
+ },
38
+ body: method === 'POST' ? JSON.stringify(body) : null,
39
+ });
40
+ // Check if response is JSON before parsing
41
+ const contentType = response.headers.get('content-type');
42
+ let data;
43
+ if (contentType?.includes('application/json')) {
44
+ data = await response.json();
45
+ }
46
+ else {
47
+ // If not JSON, get the text for better error messages
48
+ const text = await response.text();
49
+ data = { error: { message: `Non-JSON response: ${text.substring(0, 200)}...` } };
50
+ }
51
+ if (!response.ok) {
52
+ throw new PerplexityApiError(data.error?.message || `HTTP ${response.status}: ${response.statusText}`, response.status, data);
53
+ }
54
+ return data;
55
+ }
56
+ catch (error) {
57
+ if (error instanceof PerplexityApiError) {
58
+ throw error;
59
+ }
60
+ if (error instanceof Error) {
61
+ throw new PerplexityApiError(`Network error: ${error.message}`);
62
+ }
63
+ throw new PerplexityApiError('Unknown error occurred');
64
+ }
65
+ }
66
+ /**
67
+ * Sends a chat completion request to Perplexity
68
+ */
69
+ async chatCompletion(request) {
70
+ // Prepare the request body according to Perplexity API format
71
+ const requestBody = {
72
+ model: request.model,
73
+ messages: request.messages,
74
+ ...(request.max_tokens && { max_tokens: request.max_tokens }),
75
+ ...(request.temperature !== undefined && { temperature: request.temperature }),
76
+ ...(request.top_p !== undefined && { top_p: request.top_p }),
77
+ ...(request.search_domain_filter && { search_domain_filter: request.search_domain_filter }),
78
+ ...(request.return_images !== undefined && { return_images: request.return_images }),
79
+ ...(request.return_related_questions !== undefined && {
80
+ return_related_questions: request.return_related_questions,
81
+ }),
82
+ ...(request.search_recency_filter && {
83
+ search_recency_filter: request.search_recency_filter,
84
+ }),
85
+ ...(request.search_after_date_filter && {
86
+ search_after_date_filter: request.search_after_date_filter,
87
+ }),
88
+ ...(request.search_before_date_filter && {
89
+ search_before_date_filter: request.search_before_date_filter,
90
+ }),
91
+ ...(request.last_updated_after_filter && {
92
+ last_updated_after_filter: request.last_updated_after_filter,
93
+ }),
94
+ ...(request.last_updated_before_filter && {
95
+ last_updated_before_filter: request.last_updated_before_filter,
96
+ }),
97
+ ...(request.top_k !== undefined && { top_k: request.top_k }),
98
+ ...(request.stream !== undefined && { stream: request.stream }),
99
+ ...(request.presence_penalty !== undefined && { presence_penalty: request.presence_penalty }),
100
+ ...(request.frequency_penalty !== undefined && {
101
+ frequency_penalty: request.frequency_penalty,
102
+ }),
103
+ ...(request.response_format && { response_format: request.response_format }),
104
+ ...(request.disable_search !== undefined && { disable_search: request.disable_search }),
105
+ ...(request.enable_search_classifier !== undefined && {
106
+ enable_search_classifier: request.enable_search_classifier,
107
+ }),
108
+ ...(request.web_search_options && { web_search_options: request.web_search_options }),
109
+ };
110
+ return this.makeRequest(CHAT_COMPLETIONS_ENDPOINT, requestBody);
111
+ }
112
+ /**
113
+ * Sends a streaming chat completion request to Perplexity
114
+ */
115
+ async chatCompletionStream(request, callbacks) {
116
+ const url = `${this.baseUrl}${CHAT_COMPLETIONS_ENDPOINT}`;
117
+ // Force streaming mode
118
+ const requestBody = {
119
+ model: request.model,
120
+ messages: request.messages,
121
+ stream: true, // Force streaming
122
+ ...(request.max_tokens && { max_tokens: request.max_tokens }),
123
+ ...(request.temperature !== undefined && { temperature: request.temperature }),
124
+ ...(request.top_p !== undefined && { top_p: request.top_p }),
125
+ ...(request.search_domain_filter && { search_domain_filter: request.search_domain_filter }),
126
+ ...(request.return_images !== undefined && { return_images: request.return_images }),
127
+ ...(request.return_related_questions !== undefined && {
128
+ return_related_questions: request.return_related_questions,
129
+ }),
130
+ ...(request.search_recency_filter && {
131
+ search_recency_filter: request.search_recency_filter,
132
+ }),
133
+ ...(request.search_after_date_filter && {
134
+ search_after_date_filter: request.search_after_date_filter,
135
+ }),
136
+ ...(request.search_before_date_filter && {
137
+ search_before_date_filter: request.search_before_date_filter,
138
+ }),
139
+ ...(request.last_updated_after_filter && {
140
+ last_updated_after_filter: request.last_updated_after_filter,
141
+ }),
142
+ ...(request.last_updated_before_filter && {
143
+ last_updated_before_filter: request.last_updated_before_filter,
144
+ }),
145
+ ...(request.top_k !== undefined && { top_k: request.top_k }),
146
+ ...(request.presence_penalty !== undefined && { presence_penalty: request.presence_penalty }),
147
+ ...(request.frequency_penalty !== undefined && {
148
+ frequency_penalty: request.frequency_penalty,
149
+ }),
150
+ ...(request.response_format && { response_format: request.response_format }),
151
+ ...(request.disable_search !== undefined && { disable_search: request.disable_search }),
152
+ ...(request.enable_search_classifier !== undefined && {
153
+ enable_search_classifier: request.enable_search_classifier,
154
+ }),
155
+ ...(request.web_search_options && { web_search_options: request.web_search_options }),
156
+ };
157
+ try {
158
+ const response = await fetch(url, {
159
+ method: 'POST',
160
+ headers: {
161
+ Authorization: `Bearer ${this.apiKey}`,
162
+ 'Content-Type': 'application/json',
163
+ Accept: 'text/event-stream',
164
+ },
165
+ body: JSON.stringify(requestBody),
166
+ });
167
+ if (!response.ok) {
168
+ const errorText = await response.text();
169
+ throw new PerplexityApiError(`HTTP ${response.status}: ${response.statusText}`, response.status, { error: { message: errorText } });
170
+ }
171
+ if (!response.body) {
172
+ throw new PerplexityApiError('No response body received');
173
+ }
174
+ // In node-fetch v3, response.body is already a Node.js Readable stream
175
+ // Cast it to the correct type for TypeScript
176
+ const bodyStream = response.body;
177
+ return this.processStreamingResponse(bodyStream, callbacks);
178
+ }
179
+ catch (error) {
180
+ if (callbacks.onError) {
181
+ callbacks.onError(error instanceof Error ? error : new Error('Unknown streaming error'));
182
+ }
183
+ throw error;
184
+ }
185
+ }
186
+ /**
187
+ * Processes Server-Sent Events from Perplexity's streaming API
188
+ */
189
+ async processStreamingResponse(body, callbacks) {
190
+ return new Promise((resolve, reject) => {
191
+ let buffer = '';
192
+ let finalResponse = null;
193
+ let aggregatedContent = '';
194
+ let responseMetadata = {};
195
+ body.on('data', chunk => {
196
+ buffer += chunk.toString();
197
+ // Process complete lines
198
+ const lines = buffer.split('\n');
199
+ buffer = lines.pop() || ''; // Keep incomplete line in buffer
200
+ for (const line of lines) {
201
+ this.processSSELine(line, {
202
+ onChunk: chunk => {
203
+ // Aggregate content for final response
204
+ if (chunk.choices?.[0]?.delta?.content) {
205
+ aggregatedContent += chunk.choices[0].delta.content;
206
+ }
207
+ // Store metadata from first chunk
208
+ if (!responseMetadata.id) {
209
+ responseMetadata = {
210
+ id: chunk.id,
211
+ model: chunk.model,
212
+ created: chunk.created,
213
+ object: 'chat.completion',
214
+ };
215
+ }
216
+ // Forward chunk to callback
217
+ if (callbacks.onChunk) {
218
+ callbacks.onChunk(chunk);
219
+ }
220
+ },
221
+ onComplete: response => {
222
+ finalResponse = response;
223
+ },
224
+ onError: callbacks.onError || (() => { }),
225
+ });
226
+ }
227
+ });
228
+ body.on('end', () => {
229
+ // If we have a final response from [DONE], use it
230
+ if (finalResponse) {
231
+ if (callbacks.onComplete) {
232
+ callbacks.onComplete(finalResponse);
233
+ }
234
+ resolve(finalResponse);
235
+ }
236
+ else {
237
+ // Otherwise, construct final response from aggregated data
238
+ const constructedResponse = {
239
+ ...responseMetadata,
240
+ choices: [
241
+ {
242
+ index: 0,
243
+ finish_reason: 'stop',
244
+ message: {
245
+ role: 'assistant',
246
+ content: aggregatedContent,
247
+ },
248
+ },
249
+ ],
250
+ usage: {
251
+ prompt_tokens: 0,
252
+ completion_tokens: 0,
253
+ total_tokens: 0,
254
+ },
255
+ };
256
+ if (callbacks.onComplete) {
257
+ callbacks.onComplete(constructedResponse);
258
+ }
259
+ resolve(constructedResponse);
260
+ }
261
+ });
262
+ body.on('error', error => {
263
+ if (callbacks.onError) {
264
+ callbacks.onError(error);
265
+ }
266
+ reject(error);
267
+ });
268
+ });
269
+ }
270
+ /**
271
+ * Processes a single Server-Sent Event line
272
+ */
273
+ processSSELine(line, callbacks) {
274
+ if (!line.trim())
275
+ return;
276
+ // Handle SSE format: "data: {json}"
277
+ if (line.startsWith('data: ')) {
278
+ const data = line.slice(6).trim();
279
+ // Check for completion signal
280
+ if (data === '[DONE]') {
281
+ return;
282
+ }
283
+ try {
284
+ const chunk = JSON.parse(data);
285
+ if (callbacks.onChunk) {
286
+ callbacks.onChunk(chunk);
287
+ }
288
+ }
289
+ catch (error) {
290
+ console.warn('Failed to parse SSE chunk:', data, error);
291
+ }
292
+ }
293
+ }
294
+ /**
295
+ * Creates an async chat completion job
296
+ */
297
+ async createAsyncChatCompletion(request) {
298
+ const requestBody = {
299
+ request: {
300
+ model: request.model,
301
+ messages: request.messages,
302
+ ...(request.max_tokens && { max_tokens: request.max_tokens }),
303
+ ...(request.temperature !== undefined && { temperature: request.temperature }),
304
+ ...(request.top_p !== undefined && { top_p: request.top_p }),
305
+ ...(request.search_domain_filter && { search_domain_filter: request.search_domain_filter }),
306
+ ...(request.return_images !== undefined && { return_images: request.return_images }),
307
+ ...(request.return_related_questions !== undefined && {
308
+ return_related_questions: request.return_related_questions,
309
+ }),
310
+ ...(request.search_recency_filter && {
311
+ search_recency_filter: request.search_recency_filter,
312
+ }),
313
+ ...(request.search_after_date_filter && {
314
+ search_after_date_filter: request.search_after_date_filter,
315
+ }),
316
+ ...(request.search_before_date_filter && {
317
+ search_before_date_filter: request.search_before_date_filter,
318
+ }),
319
+ ...(request.last_updated_after_filter && {
320
+ last_updated_after_filter: request.last_updated_after_filter,
321
+ }),
322
+ ...(request.last_updated_before_filter && {
323
+ last_updated_before_filter: request.last_updated_before_filter,
324
+ }),
325
+ ...(request.top_k !== undefined && { top_k: request.top_k }),
326
+ ...(request.stream !== undefined && { stream: request.stream }),
327
+ ...(request.presence_penalty !== undefined && {
328
+ presence_penalty: request.presence_penalty,
329
+ }),
330
+ ...(request.frequency_penalty !== undefined && {
331
+ frequency_penalty: request.frequency_penalty,
332
+ }),
333
+ ...(request.response_format && { response_format: request.response_format }),
334
+ ...(request.disable_search !== undefined && { disable_search: request.disable_search }),
335
+ ...(request.enable_search_classifier !== undefined && {
336
+ enable_search_classifier: request.enable_search_classifier,
337
+ }),
338
+ ...(request.web_search_options && { web_search_options: request.web_search_options }),
339
+ },
340
+ };
341
+ return this.makeRequest(ASYNC_CHAT_COMPLETIONS_ENDPOINT, requestBody);
342
+ }
343
+ /**
344
+ * Alias for backward compatibility
345
+ */
346
+ async createAsyncChat(request) {
347
+ return this.createAsyncChatCompletion(request);
348
+ }
349
+ /**
350
+ * Lists async chat completion jobs
351
+ */
352
+ async listAsyncJobs(limit = 20, nextToken) {
353
+ const params = new URLSearchParams();
354
+ params.append('limit', limit.toString());
355
+ if (nextToken) {
356
+ params.append('next_token', encodeURIComponent(nextToken));
357
+ }
358
+ const endpoint = `${ASYNC_CHAT_COMPLETIONS_ENDPOINT}?${params.toString()}`;
359
+ return this.makeRequest(endpoint, null, 'GET');
360
+ }
361
+ /**
362
+ * Gets the status and result of an async job
363
+ */
364
+ async getAsyncJob(jobId) {
365
+ const endpoint = `${ASYNC_CHAT_COMPLETIONS_ENDPOINT}/${jobId}`;
366
+ return this.makeRequest(endpoint, null, 'GET');
367
+ }
368
+ /**
369
+ * Handles API errors and creates structured error responses
370
+ */
371
+ static handleError(error, context) {
372
+ if (error instanceof PerplexityApiError) {
373
+ // Rate limiting
374
+ if (error.status === 429) {
375
+ return {
376
+ error: {
377
+ type: 'rate_limit',
378
+ message: 'Rate limit exceeded',
379
+ details: {
380
+ suggestion: 'Wait before retrying or use async_perplexity for queuing',
381
+ retry_after: error.response?.headers?.['retry-after'] || 60,
382
+ ...(context?.model && {
383
+ fallback_model: suggestFallbackModel(context.model, 'rate_limit'),
384
+ }),
385
+ },
386
+ },
387
+ };
388
+ }
389
+ // Invalid model
390
+ if (error.status === 400 && error.message.toLowerCase().includes('model')) {
391
+ return {
392
+ error: {
393
+ type: 'invalid_model',
394
+ message: `Invalid model: ${context?.model || 'unknown'}`,
395
+ details: {
396
+ suggestion: 'Use a supported model: sonar, sonar-pro, sonar-reasoning, sonar-reasoning-pro, sonar-deep-research',
397
+ fallback_model: 'sonar-reasoning-pro',
398
+ },
399
+ },
400
+ };
401
+ }
402
+ // Authentication error
403
+ if (error.status === 401) {
404
+ return {
405
+ error: {
406
+ type: 'api_error',
407
+ message: 'Authentication failed - check your API key',
408
+ details: {
409
+ suggestion: 'Verify your Perplexity API key is correct and has sufficient credits',
410
+ },
411
+ },
412
+ };
413
+ }
414
+ // Server error
415
+ if (error.status && error.status >= 500) {
416
+ return {
417
+ error: {
418
+ type: 'api_error',
419
+ message: 'Perplexity API server error',
420
+ details: {
421
+ suggestion: 'Try again later or use a different model',
422
+ fallback_model: context?.model ? suggestFallbackModel(context.model) : 'sonar',
423
+ },
424
+ },
425
+ };
426
+ }
427
+ // General API error
428
+ return {
429
+ error: {
430
+ type: 'api_error',
431
+ message: error.message || 'Unknown API error',
432
+ details: {
433
+ suggestion: 'Check your request parameters and try again',
434
+ fallback_model: context?.model
435
+ ? suggestFallbackModel(context.model)
436
+ : 'sonar-reasoning-pro',
437
+ },
438
+ },
439
+ };
440
+ }
441
+ // Network or unknown error
442
+ return {
443
+ error: {
444
+ type: 'api_error',
445
+ message: error instanceof Error ? error.message : 'Unknown error occurred',
446
+ details: {
447
+ suggestion: 'Check your internet connection and try again',
448
+ },
449
+ },
450
+ };
451
+ }
452
+ }
453
+ // Export alias for backward compatibility
454
+ export { PerplexityApiClient as PerplexityAPI };
455
+ //# sourceMappingURL=perplexity-api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"perplexity-api.js","sourceRoot":"","sources":["../src/perplexity-api.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ export interface PortDiscoveryResult {
2
+ port: number;
3
+ isExistingServer: boolean;
4
+ healthStatus?: 'healthy' | 'unhealthy';
5
+ }
6
+ /**
7
+ * Checks if a port is available for binding
8
+ */
9
+ export declare function isPortAvailable(port: number): Promise<boolean>;
10
+ /**
11
+ * Checks if an MCP server is running on the specified port
12
+ */
13
+ export declare function checkMcpServerHealth(port: number): Promise<'healthy' | 'unhealthy' | 'not-running'>;
14
+ /**
15
+ * Discovers the best port to use for the MCP server
16
+ * Strategy:
17
+ * 1. Check if there's already a healthy MCP server running in the port range
18
+ * 2. If yes, return that port (shared server model)
19
+ * 3. If no, find the first available port in the range
20
+ * 4. If none available in range, throw an error
21
+ */
22
+ export declare function discoverMcpPort(preferredPort?: number): Promise<PortDiscoveryResult>;
23
+ /**
24
+ * Lists all ports in the MCP range and their status
25
+ */
26
+ export declare function scanMcpPortRange(): Promise<Array<{
27
+ port: number;
28
+ available: boolean;
29
+ mcpHealth: 'healthy' | 'unhealthy' | 'not-running';
30
+ }>>;
31
+ //# sourceMappingURL=port-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"port-utils.d.ts","sourceRoot":"","sources":["../src/port-utils.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,gBAAgB,EAAE,OAAO,CAAC;IAC1B,YAAY,CAAC,EAAE,SAAS,GAAG,WAAW,CAAC;CACxC;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAUpE;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,SAAS,GAAG,WAAW,GAAG,aAAa,CAAC,CAkBlD;AAED;;;;;;;GAOG;AACH,wBAAsB,eAAe,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC,CA0D1F;AAED;;GAEG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAC/C,KAAK,CAAC;IACJ,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,SAAS,GAAG,WAAW,GAAG,aAAa,CAAC;CACpD,CAAC,CACH,CAeA"}
@@ -0,0 +1,114 @@
1
+ import { createServer } from 'http';
2
+ // Port range for MCP server discovery (Claude Code uses 8124, Claude Desktop uses 8125)
3
+ const MCP_PORT_RANGE = { start: 8124, end: 8133 };
4
+ /**
5
+ * Checks if a port is available for binding
6
+ */
7
+ export async function isPortAvailable(port) {
8
+ return new Promise(resolve => {
9
+ const server = createServer();
10
+ server.listen(port, () => {
11
+ server.close(() => resolve(true));
12
+ });
13
+ server.on('error', () => resolve(false));
14
+ });
15
+ }
16
+ /**
17
+ * Checks if an MCP server is running on the specified port
18
+ */
19
+ export async function checkMcpServerHealth(port) {
20
+ try {
21
+ const response = await fetch(`http://localhost:${port}/health`, {
22
+ method: 'GET',
23
+ signal: AbortSignal.timeout(2000), // 2 second timeout
24
+ });
25
+ if (response.ok) {
26
+ const health = await response.json();
27
+ return health.status === 'healthy' ? 'healthy' : 'unhealthy';
28
+ }
29
+ else {
30
+ return 'unhealthy';
31
+ }
32
+ }
33
+ catch (error) {
34
+ // Port might be occupied by non-MCP service or not running
35
+ const available = await isPortAvailable(port);
36
+ return available ? 'not-running' : 'unhealthy';
37
+ }
38
+ }
39
+ /**
40
+ * Discovers the best port to use for the MCP server
41
+ * Strategy:
42
+ * 1. Check if there's already a healthy MCP server running in the port range
43
+ * 2. If yes, return that port (shared server model)
44
+ * 3. If no, find the first available port in the range
45
+ * 4. If none available in range, throw an error
46
+ */
47
+ export async function discoverMcpPort(preferredPort) {
48
+ const debugMode = process.env.MCP_DEBUG_MODE === 'true';
49
+ const debugLog = debugMode ? console.log : console.error;
50
+ debugLog(`Discovering MCP server port (preferred: ${preferredPort || 'none'})`);
51
+ // First, check if preferred port has a healthy MCP server
52
+ if (preferredPort) {
53
+ const health = await checkMcpServerHealth(preferredPort);
54
+ if (health === 'healthy') {
55
+ debugLog(`Found healthy MCP server on preferred port ${preferredPort}`);
56
+ return {
57
+ port: preferredPort,
58
+ isExistingServer: true,
59
+ healthStatus: 'healthy',
60
+ };
61
+ }
62
+ }
63
+ // Scan the entire port range for existing healthy MCP servers
64
+ for (let port = MCP_PORT_RANGE.start; port <= MCP_PORT_RANGE.end; port++) {
65
+ const health = await checkMcpServerHealth(port);
66
+ if (health === 'healthy') {
67
+ debugLog(`Found healthy MCP server on port ${port}`);
68
+ return {
69
+ port,
70
+ isExistingServer: true,
71
+ healthStatus: 'healthy',
72
+ };
73
+ }
74
+ }
75
+ // No existing healthy server found, find an available port
76
+ // Start with preferred port if specified and available
77
+ if (preferredPort && (await isPortAvailable(preferredPort))) {
78
+ debugLog(`Using preferred port ${preferredPort} (no existing server found)`);
79
+ return {
80
+ port: preferredPort,
81
+ isExistingServer: false,
82
+ };
83
+ }
84
+ // Find first available port in range
85
+ for (let port = MCP_PORT_RANGE.start; port <= MCP_PORT_RANGE.end; port++) {
86
+ if (await isPortAvailable(port)) {
87
+ debugLog(`Using available port ${port}`);
88
+ return {
89
+ port,
90
+ isExistingServer: false,
91
+ };
92
+ }
93
+ }
94
+ // No ports available in the range
95
+ throw new Error(`No available ports in MCP range ${MCP_PORT_RANGE.start}-${MCP_PORT_RANGE.end}. ` +
96
+ 'Please free up a port or use a different range.');
97
+ }
98
+ /**
99
+ * Lists all ports in the MCP range and their status
100
+ */
101
+ export async function scanMcpPortRange() {
102
+ const results = [];
103
+ for (let port = MCP_PORT_RANGE.start; port <= MCP_PORT_RANGE.end; port++) {
104
+ const available = await isPortAvailable(port);
105
+ const mcpHealth = available ? 'not-running' : await checkMcpServerHealth(port);
106
+ results.push({
107
+ port,
108
+ available,
109
+ mcpHealth,
110
+ });
111
+ }
112
+ return results;
113
+ }
114
+ //# sourceMappingURL=port-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"port-utils.js","sourceRoot":"","sources":["../src/port-utils.ts"],"names":[],"mappings":"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"}