@supermodeltools/mcp-server 0.5.4 → 0.6.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.
- package/README.md +38 -0
- package/dist/server.js +14 -1
- package/dist/tools/create-supermodel-graph.js +200 -85
- package/dist/types.js +5 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -212,6 +212,44 @@ Verify installation:
|
|
|
212
212
|
claude mcp list
|
|
213
213
|
```
|
|
214
214
|
|
|
215
|
+
## Health Checks
|
|
216
|
+
|
|
217
|
+
This MCP server implements the [MCP ping utility](https://modelcontextprotocol.io/specification/2025-11-25/basic/utilities/ping) for connection health monitoring. The ping mechanism allows clients to verify that the server is responsive and the connection remains alive.
|
|
218
|
+
|
|
219
|
+
### How It Works
|
|
220
|
+
|
|
221
|
+
- **Request**: Client sends a `ping` JSON-RPC request with no parameters
|
|
222
|
+
- **Response**: Server responds promptly with an empty result object `{}`
|
|
223
|
+
- **Automatic**: Handled automatically by the MCP SDK - no additional configuration needed
|
|
224
|
+
|
|
225
|
+
### Use Cases
|
|
226
|
+
|
|
227
|
+
- **Pre-flight checks**: Verify server is accessible before starting work
|
|
228
|
+
- **Connection monitoring**: Detect stale connections during long-running sessions
|
|
229
|
+
- **Periodic health checks**: Confirm server remains responsive
|
|
230
|
+
|
|
231
|
+
### Example
|
|
232
|
+
|
|
233
|
+
```json
|
|
234
|
+
// Request
|
|
235
|
+
{
|
|
236
|
+
"jsonrpc": "2.0",
|
|
237
|
+
"id": "123",
|
|
238
|
+
"method": "ping"
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// Response
|
|
242
|
+
{
|
|
243
|
+
"jsonrpc": "2.0",
|
|
244
|
+
"id": "123",
|
|
245
|
+
"result": {}
|
|
246
|
+
}
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
If the server doesn't respond within a reasonable timeout (typically 5-10 seconds), the connection should be considered stale.
|
|
250
|
+
|
|
251
|
+
For more details, see the [MCP specification for ping/health checks](https://modelcontextprotocol.io/specification/2025-11-25/basic/utilities/ping).
|
|
252
|
+
|
|
215
253
|
## Tools
|
|
216
254
|
|
|
217
255
|
### `explore_codebase`
|
package/dist/server.js
CHANGED
|
@@ -110,7 +110,20 @@ For localized bugs:
|
|
|
110
110
|
|
|
111
111
|
Example:
|
|
112
112
|
- Full repo: directory="/repo" → 180MB, 50k nodes
|
|
113
|
-
- Subsystem: directory="/repo/django/db" → 15MB, 3k nodes
|
|
113
|
+
- Subsystem: directory="/repo/django/db" → 15MB, 3k nodes
|
|
114
|
+
|
|
115
|
+
## Error Handling
|
|
116
|
+
|
|
117
|
+
When a tool call returns an error, check the structured error fields:
|
|
118
|
+
- \`error.recoverable: true\` → wait briefly and retry the request
|
|
119
|
+
- \`error.reportable: true\` → this is a server-side bug, not your fault
|
|
120
|
+
|
|
121
|
+
If you receive a reportable error and have GitHub access:
|
|
122
|
+
1. Search the \`error.repo\` issues for the \`error.code\` to avoid duplicates
|
|
123
|
+
2. If no existing issue, open one with the error code, message, and any reproduction context
|
|
124
|
+
3. If you can identify and fix the root cause, fork the repo and open a PR
|
|
125
|
+
|
|
126
|
+
This helps the maintainers fix bugs faster and avoids wasting your iteration budget on issues you cannot work around locally.`,
|
|
114
127
|
});
|
|
115
128
|
const config = new sdk_1.Configuration({
|
|
116
129
|
basePath: process.env.SUPERMODEL_BASE_URL || 'https://api.supermodeltools.com',
|
|
@@ -34,6 +34,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.handler = exports.tool = exports.metadata = void 0;
|
|
37
|
+
exports.classifyApiError = classifyApiError;
|
|
37
38
|
const promises_1 = require("fs/promises");
|
|
38
39
|
const child_process_1 = require("child_process");
|
|
39
40
|
const crypto_1 = require("crypto");
|
|
@@ -43,6 +44,8 @@ const filtering_1 = require("../filtering");
|
|
|
43
44
|
const queries_1 = require("../queries");
|
|
44
45
|
const zip_repository_1 = require("../utils/zip-repository");
|
|
45
46
|
const logger = __importStar(require("../utils/logger"));
|
|
47
|
+
const REPORT_REPO = 'https://github.com/supermodeltools/mcp.git';
|
|
48
|
+
const REPORT_SUGGESTION = 'This may be a bug in the MCP server. You can help by opening an issue at https://github.com/supermodeltools/mcp/issues with the error details, or fork the repo and open a PR with a fix.';
|
|
46
49
|
exports.metadata = {
|
|
47
50
|
resource: 'graphs',
|
|
48
51
|
operation: 'write',
|
|
@@ -245,12 +248,24 @@ const handler = async (client, args, defaultWorkdir) => {
|
|
|
245
248
|
// Validate directory - check if explicitly invalid first
|
|
246
249
|
if (providedDirectory !== undefined && typeof providedDirectory !== 'string') {
|
|
247
250
|
logger.error('Invalid directory parameter:', providedDirectory);
|
|
248
|
-
return (0, types_1.asErrorResult)(
|
|
251
|
+
return (0, types_1.asErrorResult)({
|
|
252
|
+
type: 'validation_error',
|
|
253
|
+
message: 'Invalid "directory" parameter. Provide a valid directory path as a string.',
|
|
254
|
+
code: 'INVALID_DIRECTORY',
|
|
255
|
+
recoverable: false,
|
|
256
|
+
suggestion: 'Pass directory as a string path, e.g. directory="/workspace/my-repo"',
|
|
257
|
+
});
|
|
249
258
|
}
|
|
250
259
|
// Check if we have any directory at all
|
|
251
260
|
if (!directory || typeof directory !== 'string') {
|
|
252
261
|
logger.error('Invalid directory parameter:', directory);
|
|
253
|
-
return (0, types_1.asErrorResult)(
|
|
262
|
+
return (0, types_1.asErrorResult)({
|
|
263
|
+
type: 'validation_error',
|
|
264
|
+
message: 'No "directory" parameter provided and no default workdir configured.',
|
|
265
|
+
code: 'MISSING_DIRECTORY',
|
|
266
|
+
recoverable: false,
|
|
267
|
+
suggestion: 'Provide a directory path or start the MCP server with a workdir argument (e.g. npx @anthropic-ai/supermodel-mcp /path/to/repo).',
|
|
268
|
+
});
|
|
254
269
|
}
|
|
255
270
|
if (providedDirectory) {
|
|
256
271
|
logger.debug('Using provided directory:', directory);
|
|
@@ -303,20 +318,58 @@ const handler = async (client, args, defaultWorkdir) => {
|
|
|
303
318
|
if (error.stack) {
|
|
304
319
|
logger.error('Stack trace:', error.stack);
|
|
305
320
|
}
|
|
306
|
-
//
|
|
307
|
-
|
|
308
|
-
|
|
321
|
+
// Normalize: guard against non-Error throws (string, object, undefined)
|
|
322
|
+
const message = typeof error?.message === 'string' ? error.message : String(error);
|
|
323
|
+
// Return structured, actionable error messages
|
|
324
|
+
if (message.includes('does not exist')) {
|
|
325
|
+
return (0, types_1.asErrorResult)({
|
|
326
|
+
type: 'not_found_error',
|
|
327
|
+
message: `Directory not found: ${directory}`,
|
|
328
|
+
code: 'DIRECTORY_NOT_FOUND',
|
|
329
|
+
recoverable: false,
|
|
330
|
+
suggestion: 'Verify the path exists. Use an absolute path to the repository root or subdirectory.',
|
|
331
|
+
details: { directory },
|
|
332
|
+
});
|
|
309
333
|
}
|
|
310
|
-
if (
|
|
311
|
-
return (0, types_1.asErrorResult)(
|
|
334
|
+
if (message.includes('Permission denied')) {
|
|
335
|
+
return (0, types_1.asErrorResult)({
|
|
336
|
+
type: 'resource_error',
|
|
337
|
+
message: `Permission denied accessing directory: ${directory}`,
|
|
338
|
+
code: 'PERMISSION_DENIED',
|
|
339
|
+
recoverable: false,
|
|
340
|
+
suggestion: 'Check that the MCP server process has read access to this directory.',
|
|
341
|
+
details: { directory },
|
|
342
|
+
});
|
|
312
343
|
}
|
|
313
|
-
if (
|
|
314
|
-
return (0, types_1.asErrorResult)(
|
|
344
|
+
if (message.includes('exceeds limit')) {
|
|
345
|
+
return (0, types_1.asErrorResult)({
|
|
346
|
+
type: 'resource_error',
|
|
347
|
+
message,
|
|
348
|
+
code: 'ZIP_TOO_LARGE',
|
|
349
|
+
recoverable: true,
|
|
350
|
+
suggestion: 'Analyze a subdirectory instead of the full repository (e.g. directory="/repo/src/core"). This reduces ZIP size and processing time.',
|
|
351
|
+
details: { directory },
|
|
352
|
+
});
|
|
315
353
|
}
|
|
316
|
-
if (
|
|
317
|
-
return (0, types_1.asErrorResult)(
|
|
354
|
+
if (message.includes('ENOSPC')) {
|
|
355
|
+
return (0, types_1.asErrorResult)({
|
|
356
|
+
type: 'resource_error',
|
|
357
|
+
message: 'Insufficient disk space to create ZIP archive.',
|
|
358
|
+
code: 'DISK_FULL',
|
|
359
|
+
recoverable: false,
|
|
360
|
+
suggestion: 'Free up disk space or analyze a smaller subdirectory.',
|
|
361
|
+
});
|
|
318
362
|
}
|
|
319
|
-
return (0, types_1.asErrorResult)(
|
|
363
|
+
return (0, types_1.asErrorResult)({
|
|
364
|
+
type: 'internal_error',
|
|
365
|
+
message: `Failed to create ZIP archive: ${message}`,
|
|
366
|
+
code: 'ZIP_CREATION_FAILED',
|
|
367
|
+
recoverable: false,
|
|
368
|
+
reportable: true,
|
|
369
|
+
repo: REPORT_REPO,
|
|
370
|
+
suggestion: REPORT_SUGGESTION,
|
|
371
|
+
details: { directory: (0, path_1.basename)(directory), errorType: error.name || 'Error' },
|
|
372
|
+
});
|
|
320
373
|
}
|
|
321
374
|
// Execute query with cleanup handling
|
|
322
375
|
try {
|
|
@@ -431,40 +484,7 @@ async function handleQueryMode(client, params) {
|
|
|
431
484
|
}
|
|
432
485
|
catch (error) {
|
|
433
486
|
// Error details are already logged by fetchFromApi and logErrorResponse
|
|
434
|
-
|
|
435
|
-
let errorMessage = '';
|
|
436
|
-
if (error.response) {
|
|
437
|
-
const status = error.response.status;
|
|
438
|
-
switch (status) {
|
|
439
|
-
case 401:
|
|
440
|
-
errorMessage = 'Authentication failed. Set your SUPERMODEL_API_KEY environment variable and restart the MCP server.';
|
|
441
|
-
break;
|
|
442
|
-
case 403:
|
|
443
|
-
errorMessage = 'Access forbidden. Your API key does not have permission for this operation. Contact support if this is unexpected.';
|
|
444
|
-
break;
|
|
445
|
-
case 404:
|
|
446
|
-
errorMessage = 'API endpoint not found. The service URL may be incorrect. Check your SUPERMODEL_BASE_URL configuration.';
|
|
447
|
-
break;
|
|
448
|
-
case 429:
|
|
449
|
-
errorMessage = 'Rate limit exceeded. Wait a few minutes and try again.';
|
|
450
|
-
break;
|
|
451
|
-
case 500:
|
|
452
|
-
case 502:
|
|
453
|
-
case 503:
|
|
454
|
-
case 504:
|
|
455
|
-
errorMessage = 'Server error. The Supermodel API is temporarily unavailable. Try again in a few minutes.';
|
|
456
|
-
break;
|
|
457
|
-
default:
|
|
458
|
-
errorMessage = `API error (HTTP ${status}). Check the MCP server logs for details.`;
|
|
459
|
-
}
|
|
460
|
-
}
|
|
461
|
-
else if (error.request) {
|
|
462
|
-
errorMessage = 'No response from server. Check your network connection and verify the API is reachable.';
|
|
463
|
-
}
|
|
464
|
-
else {
|
|
465
|
-
errorMessage = 'Request failed. Check the MCP server logs for details.';
|
|
466
|
-
}
|
|
467
|
-
return (0, types_1.asErrorResult)(errorMessage);
|
|
487
|
+
return (0, types_1.asErrorResult)(classifyApiError(error));
|
|
468
488
|
}
|
|
469
489
|
}
|
|
470
490
|
// Handle query errors
|
|
@@ -686,19 +706,141 @@ async function fetchFromApi(client, file, idempotencyKey) {
|
|
|
686
706
|
logger.error(`[${getTimestamp()}] [API FAILURE] Request failed after ${duration}ms`);
|
|
687
707
|
// Log detailed error information
|
|
688
708
|
await logErrorResponse(error);
|
|
689
|
-
//
|
|
709
|
+
// Preserve error.response so classifyApiError can read the status code (#75)
|
|
690
710
|
if (error.response?.status === 401) {
|
|
691
|
-
|
|
711
|
+
error.message = 'API authentication failed (401 Unauthorized). Please check your SUPERMODEL_API_KEY environment variable.';
|
|
692
712
|
}
|
|
693
713
|
else if (error.response?.status === 403) {
|
|
694
|
-
|
|
714
|
+
error.message = 'API access forbidden (403 Forbidden). Your API key may not have permission to access this resource.';
|
|
695
715
|
}
|
|
696
716
|
else if (error.response?.status >= 500) {
|
|
697
|
-
|
|
717
|
+
error.message = `Supermodel API server error (${error.response.status}). The service may be temporarily unavailable.`;
|
|
698
718
|
}
|
|
699
719
|
throw error;
|
|
700
720
|
}
|
|
701
721
|
}
|
|
722
|
+
/**
|
|
723
|
+
* Classify an API error into a structured error response.
|
|
724
|
+
* Extracts HTTP status, network conditions, and timeout signals
|
|
725
|
+
* to produce an agent-actionable error with recovery guidance.
|
|
726
|
+
*/
|
|
727
|
+
function classifyApiError(error) {
|
|
728
|
+
// Guard against non-Error throws (strings, nulls, plain objects)
|
|
729
|
+
if (!error || typeof error !== 'object') {
|
|
730
|
+
return {
|
|
731
|
+
type: 'internal_error',
|
|
732
|
+
message: typeof error === 'string' ? error : 'An unexpected error occurred.',
|
|
733
|
+
code: 'UNKNOWN_ERROR',
|
|
734
|
+
recoverable: false,
|
|
735
|
+
reportable: true,
|
|
736
|
+
repo: REPORT_REPO,
|
|
737
|
+
suggestion: REPORT_SUGGESTION,
|
|
738
|
+
details: { errorType: typeof error },
|
|
739
|
+
};
|
|
740
|
+
}
|
|
741
|
+
if (error.response) {
|
|
742
|
+
const status = error.response.status;
|
|
743
|
+
switch (status) {
|
|
744
|
+
case 401:
|
|
745
|
+
return {
|
|
746
|
+
type: 'authentication_error',
|
|
747
|
+
message: 'Invalid or missing API key.',
|
|
748
|
+
code: 'INVALID_API_KEY',
|
|
749
|
+
recoverable: false,
|
|
750
|
+
suggestion: 'Set the SUPERMODEL_API_KEY environment variable and restart the MCP server.',
|
|
751
|
+
details: { apiKeySet: !!process.env.SUPERMODEL_API_KEY, httpStatus: 401 },
|
|
752
|
+
};
|
|
753
|
+
case 403:
|
|
754
|
+
return {
|
|
755
|
+
type: 'authorization_error',
|
|
756
|
+
message: 'API key does not have permission for this operation.',
|
|
757
|
+
code: 'FORBIDDEN',
|
|
758
|
+
recoverable: false,
|
|
759
|
+
suggestion: 'Verify your API key has the correct permissions. Contact support if unexpected.',
|
|
760
|
+
details: { httpStatus: 403 },
|
|
761
|
+
};
|
|
762
|
+
case 404:
|
|
763
|
+
return {
|
|
764
|
+
type: 'not_found_error',
|
|
765
|
+
message: 'API endpoint not found.',
|
|
766
|
+
code: 'ENDPOINT_NOT_FOUND',
|
|
767
|
+
recoverable: false,
|
|
768
|
+
suggestion: 'Check SUPERMODEL_BASE_URL environment variable. Default: https://api.supermodeltools.com',
|
|
769
|
+
details: { baseUrl: process.env.SUPERMODEL_BASE_URL || 'https://api.supermodeltools.com', httpStatus: 404 },
|
|
770
|
+
};
|
|
771
|
+
case 429:
|
|
772
|
+
return {
|
|
773
|
+
type: 'rate_limit_error',
|
|
774
|
+
message: 'API rate limit exceeded.',
|
|
775
|
+
code: 'RATE_LIMITED',
|
|
776
|
+
recoverable: true,
|
|
777
|
+
suggestion: 'Wait 30-60 seconds and retry. Consider analyzing smaller subdirectories to reduce API calls.',
|
|
778
|
+
details: { httpStatus: 429 },
|
|
779
|
+
};
|
|
780
|
+
case 500:
|
|
781
|
+
case 502:
|
|
782
|
+
case 503:
|
|
783
|
+
case 504:
|
|
784
|
+
return {
|
|
785
|
+
type: 'internal_error',
|
|
786
|
+
message: `Supermodel API server error (HTTP ${status}).`,
|
|
787
|
+
code: 'SERVER_ERROR',
|
|
788
|
+
recoverable: true,
|
|
789
|
+
reportable: true,
|
|
790
|
+
repo: REPORT_REPO,
|
|
791
|
+
suggestion: 'The API may be temporarily unavailable. Wait a few minutes and retry. If persistent, open an issue at https://github.com/supermodeltools/mcp/issues with the error details, or fork the repo and open a PR with a fix.',
|
|
792
|
+
details: { httpStatus: status },
|
|
793
|
+
};
|
|
794
|
+
default: {
|
|
795
|
+
const isServerError = status >= 500;
|
|
796
|
+
return {
|
|
797
|
+
type: isServerError ? 'internal_error' : 'validation_error',
|
|
798
|
+
message: `API request failed with HTTP ${status}.`,
|
|
799
|
+
code: 'API_ERROR',
|
|
800
|
+
recoverable: isServerError,
|
|
801
|
+
...(isServerError && {
|
|
802
|
+
reportable: true,
|
|
803
|
+
repo: REPORT_REPO,
|
|
804
|
+
suggestion: 'The API may be temporarily unavailable. Wait a few minutes and retry. If persistent, open an issue at https://github.com/supermodeltools/mcp/issues with the error details, or fork the repo and open a PR with a fix.',
|
|
805
|
+
}),
|
|
806
|
+
...(!isServerError && { suggestion: 'Check the request parameters and base URL configuration.' }),
|
|
807
|
+
details: { httpStatus: status },
|
|
808
|
+
};
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
}
|
|
812
|
+
if (error.request) {
|
|
813
|
+
// Distinguish timeout from general network failure
|
|
814
|
+
if (error.code === 'UND_ERR_HEADERS_TIMEOUT' || error.code === 'UND_ERR_BODY_TIMEOUT' || error.message?.includes('timeout')) {
|
|
815
|
+
return {
|
|
816
|
+
type: 'timeout_error',
|
|
817
|
+
message: 'API request timed out. The codebase may be too large for a single analysis.',
|
|
818
|
+
code: 'REQUEST_TIMEOUT',
|
|
819
|
+
recoverable: true,
|
|
820
|
+
suggestion: 'Analyze a smaller subdirectory (e.g. directory="/repo/src/core") or increase SUPERMODEL_TIMEOUT_MS.',
|
|
821
|
+
};
|
|
822
|
+
}
|
|
823
|
+
return {
|
|
824
|
+
type: 'network_error',
|
|
825
|
+
message: 'No response from Supermodel API server.',
|
|
826
|
+
code: 'NO_RESPONSE',
|
|
827
|
+
recoverable: true,
|
|
828
|
+
suggestion: 'Check network connectivity. Verify the API is reachable at the configured base URL.',
|
|
829
|
+
details: { baseUrl: process.env.SUPERMODEL_BASE_URL || 'https://api.supermodeltools.com' },
|
|
830
|
+
};
|
|
831
|
+
}
|
|
832
|
+
// Catch-all for unexpected errors - include the actual message
|
|
833
|
+
return {
|
|
834
|
+
type: 'internal_error',
|
|
835
|
+
message: error.message || 'An unexpected error occurred.',
|
|
836
|
+
code: 'UNKNOWN_ERROR',
|
|
837
|
+
recoverable: false,
|
|
838
|
+
reportable: true,
|
|
839
|
+
repo: REPORT_REPO,
|
|
840
|
+
suggestion: REPORT_SUGGESTION,
|
|
841
|
+
details: { errorType: error.name || 'Error' },
|
|
842
|
+
};
|
|
843
|
+
}
|
|
702
844
|
/**
|
|
703
845
|
* Legacy mode: direct jq filtering on API response
|
|
704
846
|
*/
|
|
@@ -710,43 +852,16 @@ async function handleLegacyMode(client, file, idempotencyKey, jq_filter) {
|
|
|
710
852
|
catch (error) {
|
|
711
853
|
if ((0, filtering_1.isJqError)(error)) {
|
|
712
854
|
logger.error('jq filter error:', error.message);
|
|
713
|
-
return (0, types_1.asErrorResult)(
|
|
855
|
+
return (0, types_1.asErrorResult)({
|
|
856
|
+
type: 'validation_error',
|
|
857
|
+
message: `Invalid jq filter syntax: ${error.message}`,
|
|
858
|
+
code: 'INVALID_JQ_FILTER',
|
|
859
|
+
recoverable: false,
|
|
860
|
+
suggestion: 'Check jq filter syntax. Use the query parameter instead for structured queries (e.g. query="summary").',
|
|
861
|
+
});
|
|
714
862
|
}
|
|
715
863
|
// Error details are already logged by fetchFromApi and logErrorResponse
|
|
716
|
-
|
|
717
|
-
let errorMessage = '';
|
|
718
|
-
if (error.response) {
|
|
719
|
-
const status = error.response.status;
|
|
720
|
-
switch (status) {
|
|
721
|
-
case 401:
|
|
722
|
-
errorMessage = 'Authentication failed. Set your SUPERMODEL_API_KEY environment variable and restart the MCP server.';
|
|
723
|
-
break;
|
|
724
|
-
case 403:
|
|
725
|
-
errorMessage = 'Access forbidden. Your API key does not have permission for this operation. Contact support if this is unexpected.';
|
|
726
|
-
break;
|
|
727
|
-
case 404:
|
|
728
|
-
errorMessage = 'API endpoint not found. The service URL may be incorrect. Check your SUPERMODEL_BASE_URL configuration.';
|
|
729
|
-
break;
|
|
730
|
-
case 429:
|
|
731
|
-
errorMessage = 'Rate limit exceeded. Wait a few minutes and try again.';
|
|
732
|
-
break;
|
|
733
|
-
case 500:
|
|
734
|
-
case 502:
|
|
735
|
-
case 503:
|
|
736
|
-
case 504:
|
|
737
|
-
errorMessage = 'Server error. The Supermodel API is temporarily unavailable. Try again in a few minutes.';
|
|
738
|
-
break;
|
|
739
|
-
default:
|
|
740
|
-
errorMessage = `API error (HTTP ${status}). Check the MCP server logs for details.`;
|
|
741
|
-
}
|
|
742
|
-
}
|
|
743
|
-
else if (error.request) {
|
|
744
|
-
errorMessage = 'No response from server. Check your network connection and verify the API is reachable.';
|
|
745
|
-
}
|
|
746
|
-
else {
|
|
747
|
-
errorMessage = 'Request failed. Check the MCP server logs for details.';
|
|
748
|
-
}
|
|
749
|
-
return (0, types_1.asErrorResult)(errorMessage);
|
|
864
|
+
return (0, types_1.asErrorResult)(classifyApiError(error));
|
|
750
865
|
}
|
|
751
866
|
}
|
|
752
867
|
exports.default = { metadata: exports.metadata, tool: exports.tool, handler: exports.handler };
|
package/dist/types.js
CHANGED
|
@@ -13,12 +13,15 @@ function asTextContentResult(result) {
|
|
|
13
13
|
isError: false
|
|
14
14
|
};
|
|
15
15
|
}
|
|
16
|
-
function asErrorResult(
|
|
16
|
+
function asErrorResult(error) {
|
|
17
|
+
const text = typeof error === 'string'
|
|
18
|
+
? error
|
|
19
|
+
: JSON.stringify({ error }, null, 2);
|
|
17
20
|
return {
|
|
18
21
|
content: [
|
|
19
22
|
{
|
|
20
23
|
type: 'text',
|
|
21
|
-
text
|
|
24
|
+
text,
|
|
22
25
|
},
|
|
23
26
|
],
|
|
24
27
|
isError: true,
|