latitude-mcp-server 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 (51) hide show
  1. package/.releaserc.json +34 -0
  2. package/README.md +687 -0
  3. package/dist/cli/index.d.ts +7 -0
  4. package/dist/cli/index.js +43 -0
  5. package/dist/cli/latitude.cli.d.ts +10 -0
  6. package/dist/cli/latitude.cli.js +286 -0
  7. package/dist/controllers/latitude.controller.d.ts +115 -0
  8. package/dist/controllers/latitude.controller.js +287 -0
  9. package/dist/index.d.ts +6 -0
  10. package/dist/index.js +166 -0
  11. package/dist/resources/latitude.resource.d.ts +12 -0
  12. package/dist/resources/latitude.resource.js +145 -0
  13. package/dist/services/vendor.latitude.service.d.ts +49 -0
  14. package/dist/services/vendor.latitude.service.js +294 -0
  15. package/dist/tools/latitude.tool.d.ts +6 -0
  16. package/dist/tools/latitude.tool.js +517 -0
  17. package/dist/types/common.types.d.ts +20 -0
  18. package/dist/types/common.types.js +7 -0
  19. package/dist/types/latitude.types.d.ts +487 -0
  20. package/dist/types/latitude.types.js +311 -0
  21. package/dist/utils/cli.test.util.d.ts +34 -0
  22. package/dist/utils/cli.test.util.js +143 -0
  23. package/dist/utils/config.util.d.ts +43 -0
  24. package/dist/utils/config.util.js +145 -0
  25. package/dist/utils/config.util.test.d.ts +1 -0
  26. package/dist/utils/constants.util.d.ts +26 -0
  27. package/dist/utils/constants.util.js +29 -0
  28. package/dist/utils/error-handler.util.d.ts +54 -0
  29. package/dist/utils/error-handler.util.js +202 -0
  30. package/dist/utils/error-handler.util.test.d.ts +1 -0
  31. package/dist/utils/error.util.d.ts +73 -0
  32. package/dist/utils/error.util.js +174 -0
  33. package/dist/utils/error.util.test.d.ts +1 -0
  34. package/dist/utils/formatter.util.d.ts +36 -0
  35. package/dist/utils/formatter.util.js +116 -0
  36. package/dist/utils/jest.setup.d.ts +5 -0
  37. package/dist/utils/jest.setup.js +36 -0
  38. package/dist/utils/jq.util.d.ts +34 -0
  39. package/dist/utils/jq.util.js +87 -0
  40. package/dist/utils/logger.util.d.ts +78 -0
  41. package/dist/utils/logger.util.js +344 -0
  42. package/dist/utils/toon.util.d.ts +15 -0
  43. package/dist/utils/toon.util.js +65 -0
  44. package/dist/utils/transport.util.d.ts +49 -0
  45. package/dist/utils/transport.util.js +162 -0
  46. package/eslint.config.mjs +46 -0
  47. package/openapi.json +12592 -0
  48. package/package.json +118 -0
  49. package/scripts/ensure-executable.js +38 -0
  50. package/scripts/package.json +3 -0
  51. package/scripts/update-version.js +204 -0
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Application constants
3
+ *
4
+ * This file contains constants used throughout the application.
5
+ * Centralizing these values makes them easier to maintain and update.
6
+ */
7
+ /**
8
+ * Current application version
9
+ * This should match the version in package.json
10
+ */
11
+ export declare const VERSION = "1.0.0";
12
+ /**
13
+ * Package name with scope
14
+ * Used for initialization and identification
15
+ */
16
+ export declare const PACKAGE_NAME = "@anthropic/latitude-mcp-server";
17
+ /**
18
+ * CLI command name
19
+ * Used for binary name and CLI help text
20
+ */
21
+ export declare const CLI_NAME = "latitude-mcp";
22
+ /**
23
+ * Latitude API configuration
24
+ */
25
+ export declare const LATITUDE_BASE_URL = "https://gateway.latitude.so";
26
+ export declare const LATITUDE_API_VERSION = "v3";
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ /**
3
+ * Application constants
4
+ *
5
+ * This file contains constants used throughout the application.
6
+ * Centralizing these values makes them easier to maintain and update.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.LATITUDE_API_VERSION = exports.LATITUDE_BASE_URL = exports.CLI_NAME = exports.PACKAGE_NAME = exports.VERSION = void 0;
10
+ /**
11
+ * Current application version
12
+ * This should match the version in package.json
13
+ */
14
+ exports.VERSION = '1.0.0';
15
+ /**
16
+ * Package name with scope
17
+ * Used for initialization and identification
18
+ */
19
+ exports.PACKAGE_NAME = '@anthropic/latitude-mcp-server';
20
+ /**
21
+ * CLI command name
22
+ * Used for binary name and CLI help text
23
+ */
24
+ exports.CLI_NAME = 'latitude-mcp';
25
+ /**
26
+ * Latitude API configuration
27
+ */
28
+ exports.LATITUDE_BASE_URL = 'https://gateway.latitude.so';
29
+ exports.LATITUDE_API_VERSION = 'v3';
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Standard error codes for consistent handling
3
+ */
4
+ export declare enum ErrorCode {
5
+ NOT_FOUND = "NOT_FOUND",
6
+ INVALID_CURSOR = "INVALID_CURSOR",
7
+ ACCESS_DENIED = "ACCESS_DENIED",
8
+ VALIDATION_ERROR = "VALIDATION_ERROR",
9
+ UNEXPECTED_ERROR = "UNEXPECTED_ERROR",
10
+ NETWORK_ERROR = "NETWORK_ERROR",
11
+ RATE_LIMIT_ERROR = "RATE_LIMIT_ERROR"
12
+ }
13
+ /**
14
+ * Context information for error handling
15
+ */
16
+ export interface ErrorContext {
17
+ /**
18
+ * Source of the error (e.g., file path and function)
19
+ */
20
+ source?: string;
21
+ /**
22
+ * Type of entity being processed (e.g., 'IP Address', 'User')
23
+ */
24
+ entityType?: string;
25
+ /**
26
+ * Identifier of the entity being processed
27
+ */
28
+ entityId?: string | Record<string, string>;
29
+ /**
30
+ * Operation being performed (e.g., 'retrieving', 'searching')
31
+ */
32
+ operation?: string;
33
+ /**
34
+ * Additional information for debugging
35
+ */
36
+ additionalInfo?: Record<string, unknown>;
37
+ }
38
+ /**
39
+ * Helper function to create a consistent error context object
40
+ * @param entityType Type of entity being processed
41
+ * @param operation Operation being performed
42
+ * @param source Source of the error (typically file path and function)
43
+ * @param entityId Optional identifier of the entity
44
+ * @param additionalInfo Optional additional information for debugging
45
+ * @returns A formatted ErrorContext object
46
+ */
47
+ export declare function buildErrorContext(entityType: string, operation: string, source: string, entityId?: string | Record<string, string>, additionalInfo?: Record<string, unknown>): ErrorContext;
48
+ /**
49
+ * Handle controller errors consistently
50
+ * @param error The error to handle
51
+ * @param context Context information for better error messages
52
+ * @returns Never returns, always throws an error
53
+ */
54
+ export declare function handleControllerError(error: unknown, context?: ErrorContext): never;
@@ -0,0 +1,202 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ErrorCode = void 0;
4
+ exports.buildErrorContext = buildErrorContext;
5
+ exports.handleControllerError = handleControllerError;
6
+ const error_util_js_1 = require("./error.util.js");
7
+ const logger_util_js_1 = require("./logger.util.js");
8
+ /**
9
+ * Standard error codes for consistent handling
10
+ */
11
+ var ErrorCode;
12
+ (function (ErrorCode) {
13
+ ErrorCode["NOT_FOUND"] = "NOT_FOUND";
14
+ ErrorCode["INVALID_CURSOR"] = "INVALID_CURSOR";
15
+ ErrorCode["ACCESS_DENIED"] = "ACCESS_DENIED";
16
+ ErrorCode["VALIDATION_ERROR"] = "VALIDATION_ERROR";
17
+ ErrorCode["UNEXPECTED_ERROR"] = "UNEXPECTED_ERROR";
18
+ ErrorCode["NETWORK_ERROR"] = "NETWORK_ERROR";
19
+ ErrorCode["RATE_LIMIT_ERROR"] = "RATE_LIMIT_ERROR";
20
+ })(ErrorCode || (exports.ErrorCode = ErrorCode = {}));
21
+ /**
22
+ * Helper function to create a consistent error context object
23
+ * @param entityType Type of entity being processed
24
+ * @param operation Operation being performed
25
+ * @param source Source of the error (typically file path and function)
26
+ * @param entityId Optional identifier of the entity
27
+ * @param additionalInfo Optional additional information for debugging
28
+ * @returns A formatted ErrorContext object
29
+ */
30
+ function buildErrorContext(entityType, operation, source, entityId, additionalInfo) {
31
+ return {
32
+ entityType,
33
+ operation,
34
+ source,
35
+ ...(entityId && { entityId }),
36
+ ...(additionalInfo && { additionalInfo }),
37
+ };
38
+ }
39
+ /**
40
+ * Detect specific error types from raw errors
41
+ * @param error The error to analyze
42
+ * @param context Context information for better error detection
43
+ * @returns Object containing the error code and status code
44
+ */
45
+ function detectErrorType(error, context = {}) {
46
+ const methodLogger = logger_util_js_1.Logger.forContext('utils/error-handler.util.ts', 'detectErrorType');
47
+ methodLogger.debug(`Detecting error type`, { error, context });
48
+ const errorMessage = error instanceof Error ? error.message : String(error);
49
+ const statusCode = error instanceof Error && 'statusCode' in error
50
+ ? error.statusCode
51
+ : undefined;
52
+ // Network error detection
53
+ if (errorMessage.includes('network error') ||
54
+ errorMessage.includes('fetch failed') ||
55
+ errorMessage.includes('ECONNREFUSED') ||
56
+ errorMessage.includes('ENOTFOUND') ||
57
+ errorMessage.includes('Failed to fetch') ||
58
+ errorMessage.includes('Network request failed')) {
59
+ return { code: ErrorCode.NETWORK_ERROR, statusCode: 500 };
60
+ }
61
+ // Rate limiting detection
62
+ if (errorMessage.includes('rate limit') ||
63
+ errorMessage.includes('too many requests') ||
64
+ statusCode === 429) {
65
+ return { code: ErrorCode.RATE_LIMIT_ERROR, statusCode: 429 };
66
+ }
67
+ // Not Found detection
68
+ if (errorMessage.includes('not found') ||
69
+ errorMessage.includes('does not exist') ||
70
+ statusCode === 404) {
71
+ return { code: ErrorCode.NOT_FOUND, statusCode: 404 };
72
+ }
73
+ // Access Denied detection
74
+ if (errorMessage.includes('access') ||
75
+ errorMessage.includes('permission') ||
76
+ errorMessage.includes('authorize') ||
77
+ errorMessage.includes('authentication') ||
78
+ statusCode === 401 ||
79
+ statusCode === 403) {
80
+ return { code: ErrorCode.ACCESS_DENIED, statusCode: statusCode || 403 };
81
+ }
82
+ // Invalid Cursor detection
83
+ if ((errorMessage.includes('cursor') ||
84
+ errorMessage.includes('startAt') ||
85
+ errorMessage.includes('page')) &&
86
+ (errorMessage.includes('invalid') || errorMessage.includes('not valid'))) {
87
+ return { code: ErrorCode.INVALID_CURSOR, statusCode: 400 };
88
+ }
89
+ // Validation Error detection
90
+ if (errorMessage.includes('validation') ||
91
+ errorMessage.includes('invalid') ||
92
+ errorMessage.includes('required') ||
93
+ statusCode === 400 ||
94
+ statusCode === 422) {
95
+ return {
96
+ code: ErrorCode.VALIDATION_ERROR,
97
+ statusCode: statusCode || 400,
98
+ };
99
+ }
100
+ // Default to unexpected error
101
+ return {
102
+ code: ErrorCode.UNEXPECTED_ERROR,
103
+ statusCode: statusCode || 500,
104
+ };
105
+ }
106
+ /**
107
+ * Create user-friendly error messages based on error type and context
108
+ * @param code The error code
109
+ * @param context Context information for better error messages
110
+ * @param originalMessage The original error message
111
+ * @returns User-friendly error message
112
+ */
113
+ function createUserFriendlyErrorMessage(code, context = {}, originalMessage) {
114
+ const methodLogger = logger_util_js_1.Logger.forContext('utils/error-handler.util.ts', 'createUserFriendlyErrorMessage');
115
+ const { entityType, entityId, operation } = context;
116
+ // Format entity ID for display
117
+ let entityIdStr = '';
118
+ if (entityId) {
119
+ if (typeof entityId === 'string') {
120
+ entityIdStr = entityId;
121
+ }
122
+ else {
123
+ // Handle object entityId
124
+ entityIdStr = Object.values(entityId).join('/');
125
+ }
126
+ }
127
+ // Determine entity display name
128
+ const entity = entityType
129
+ ? `${entityType}${entityIdStr ? ` ${entityIdStr}` : ''}`
130
+ : 'Resource';
131
+ let message = '';
132
+ switch (code) {
133
+ case ErrorCode.NOT_FOUND:
134
+ message = `${entity} not found${entityIdStr ? `: ${entityIdStr}` : ''}. Verify the ID is correct and that you have access to this ${entityType?.toLowerCase() || 'resource'}.`;
135
+ break;
136
+ case ErrorCode.ACCESS_DENIED:
137
+ message = `Access denied for ${entity.toLowerCase()}${entityIdStr ? ` ${entityIdStr}` : ''}. Verify your credentials and permissions.`;
138
+ break;
139
+ case ErrorCode.INVALID_CURSOR:
140
+ message = `Invalid pagination cursor. Use the exact cursor string returned from previous results.`;
141
+ break;
142
+ case ErrorCode.VALIDATION_ERROR:
143
+ message =
144
+ originalMessage ||
145
+ `Invalid data provided for ${operation || 'operation'} ${entity.toLowerCase()}.`;
146
+ break;
147
+ case ErrorCode.NETWORK_ERROR:
148
+ message = `Network error while ${operation || 'connecting to'} the service. Please check your internet connection and try again.`;
149
+ break;
150
+ case ErrorCode.RATE_LIMIT_ERROR:
151
+ message = `Rate limit exceeded. Please wait a moment and try again, or reduce the frequency of requests.`;
152
+ break;
153
+ default:
154
+ message = `An unexpected error occurred while ${operation || 'processing'} ${entity.toLowerCase()}.`;
155
+ }
156
+ // Include original message details if available and appropriate
157
+ if (originalMessage &&
158
+ code !== ErrorCode.NOT_FOUND &&
159
+ code !== ErrorCode.ACCESS_DENIED) {
160
+ message += ` Error details: ${originalMessage}`;
161
+ }
162
+ methodLogger.debug(`Created user-friendly message: ${message}`, {
163
+ code,
164
+ context,
165
+ });
166
+ return message;
167
+ }
168
+ /**
169
+ * Handle controller errors consistently
170
+ * @param error The error to handle
171
+ * @param context Context information for better error messages
172
+ * @returns Never returns, always throws an error
173
+ */
174
+ function handleControllerError(error, context = {}) {
175
+ const methodLogger = logger_util_js_1.Logger.forContext('utils/error-handler.util.ts', 'handleControllerError');
176
+ // Extract error details
177
+ const errorMessage = error instanceof Error ? error.message : String(error);
178
+ const statusCode = error instanceof Error && 'statusCode' in error
179
+ ? error.statusCode
180
+ : undefined;
181
+ // Detect error type using utility
182
+ const { code, statusCode: detectedStatus } = detectErrorType(error, context);
183
+ // Combine detected status with explicit status
184
+ const finalStatusCode = statusCode || detectedStatus;
185
+ // Format entity information for logging
186
+ const { entityType, entityId, operation } = context;
187
+ const entity = entityType || 'resource';
188
+ const entityIdStr = entityId
189
+ ? typeof entityId === 'string'
190
+ ? entityId
191
+ : JSON.stringify(entityId)
192
+ : '';
193
+ const actionStr = operation || 'processing';
194
+ // Log detailed error information
195
+ methodLogger.error(`Error ${actionStr} ${entity}${entityIdStr ? `: ${entityIdStr}` : ''}: ${errorMessage}`, error);
196
+ // Create user-friendly error message for the response
197
+ const message = code === ErrorCode.VALIDATION_ERROR
198
+ ? errorMessage
199
+ : createUserFriendlyErrorMessage(code, context, errorMessage);
200
+ // Throw an appropriate API error with the user-friendly message
201
+ throw (0, error_util_js_1.createApiError)(message, finalStatusCode, error);
202
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Error types for classification
3
+ */
4
+ export declare enum ErrorType {
5
+ AUTH_MISSING = "AUTH_MISSING",
6
+ AUTH_INVALID = "AUTH_INVALID",
7
+ API_ERROR = "API_ERROR",
8
+ UNEXPECTED_ERROR = "UNEXPECTED_ERROR"
9
+ }
10
+ /**
11
+ * Custom error class with type classification
12
+ */
13
+ export declare class McpError extends Error {
14
+ type: ErrorType;
15
+ statusCode?: number;
16
+ originalError?: unknown;
17
+ constructor(message: string, type: ErrorType, statusCode?: number, originalError?: unknown);
18
+ }
19
+ /**
20
+ * Create an authentication missing error
21
+ */
22
+ export declare function createAuthMissingError(message?: string): McpError;
23
+ /**
24
+ * Create an authentication invalid error
25
+ */
26
+ export declare function createAuthInvalidError(message?: string): McpError;
27
+ /**
28
+ * Create an API error
29
+ */
30
+ export declare function createApiError(message: string, statusCode?: number, originalError?: unknown): McpError;
31
+ /**
32
+ * Create an unexpected error
33
+ */
34
+ export declare function createUnexpectedError(message?: string, originalError?: unknown): McpError;
35
+ /**
36
+ * Ensure an error is an McpError
37
+ */
38
+ export declare function ensureMcpError(error: unknown): McpError;
39
+ /**
40
+ * Get the deepest original error from an error chain
41
+ * @param error The error to extract the original cause from
42
+ * @returns The deepest original error or the error itself
43
+ */
44
+ export declare function getDeepOriginalError(error: unknown): unknown;
45
+ /**
46
+ * Format error for MCP tool response
47
+ */
48
+ export declare function formatErrorForMcpTool(error: unknown): {
49
+ content: Array<{
50
+ type: 'text';
51
+ text: string;
52
+ }>;
53
+ metadata?: {
54
+ errorType: ErrorType;
55
+ statusCode?: number;
56
+ errorDetails?: unknown;
57
+ };
58
+ };
59
+ /**
60
+ * Format error for MCP resource response
61
+ */
62
+ export declare function formatErrorForMcpResource(error: unknown, uri: string): {
63
+ contents: Array<{
64
+ uri: string;
65
+ text: string;
66
+ mimeType: string;
67
+ description?: string;
68
+ }>;
69
+ };
70
+ /**
71
+ * Handle error in CLI context with improved user feedback
72
+ */
73
+ export declare function handleCliError(error: unknown): never;
@@ -0,0 +1,174 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.McpError = exports.ErrorType = void 0;
4
+ exports.createAuthMissingError = createAuthMissingError;
5
+ exports.createAuthInvalidError = createAuthInvalidError;
6
+ exports.createApiError = createApiError;
7
+ exports.createUnexpectedError = createUnexpectedError;
8
+ exports.ensureMcpError = ensureMcpError;
9
+ exports.getDeepOriginalError = getDeepOriginalError;
10
+ exports.formatErrorForMcpTool = formatErrorForMcpTool;
11
+ exports.formatErrorForMcpResource = formatErrorForMcpResource;
12
+ exports.handleCliError = handleCliError;
13
+ const logger_util_js_1 = require("./logger.util.js");
14
+ /**
15
+ * Error types for classification
16
+ */
17
+ var ErrorType;
18
+ (function (ErrorType) {
19
+ ErrorType["AUTH_MISSING"] = "AUTH_MISSING";
20
+ ErrorType["AUTH_INVALID"] = "AUTH_INVALID";
21
+ ErrorType["API_ERROR"] = "API_ERROR";
22
+ ErrorType["UNEXPECTED_ERROR"] = "UNEXPECTED_ERROR";
23
+ })(ErrorType || (exports.ErrorType = ErrorType = {}));
24
+ /**
25
+ * Custom error class with type classification
26
+ */
27
+ class McpError extends Error {
28
+ constructor(message, type, statusCode, originalError) {
29
+ super(message);
30
+ this.name = 'McpError';
31
+ this.type = type;
32
+ this.statusCode = statusCode;
33
+ this.originalError = originalError;
34
+ }
35
+ }
36
+ exports.McpError = McpError;
37
+ /**
38
+ * Create an authentication missing error
39
+ */
40
+ function createAuthMissingError(message = 'Authentication credentials are missing') {
41
+ return new McpError(message, ErrorType.AUTH_MISSING);
42
+ }
43
+ /**
44
+ * Create an authentication invalid error
45
+ */
46
+ function createAuthInvalidError(message = 'Authentication credentials are invalid') {
47
+ return new McpError(message, ErrorType.AUTH_INVALID, 401);
48
+ }
49
+ /**
50
+ * Create an API error
51
+ */
52
+ function createApiError(message, statusCode, originalError) {
53
+ return new McpError(message, ErrorType.API_ERROR, statusCode, originalError);
54
+ }
55
+ /**
56
+ * Create an unexpected error
57
+ */
58
+ function createUnexpectedError(message = 'An unexpected error occurred', originalError) {
59
+ return new McpError(message, ErrorType.UNEXPECTED_ERROR, undefined, originalError);
60
+ }
61
+ /**
62
+ * Ensure an error is an McpError
63
+ */
64
+ function ensureMcpError(error) {
65
+ if (error instanceof McpError) {
66
+ return error;
67
+ }
68
+ if (error instanceof Error) {
69
+ return createUnexpectedError(error.message, error);
70
+ }
71
+ return createUnexpectedError(String(error));
72
+ }
73
+ /**
74
+ * Get the deepest original error from an error chain
75
+ * @param error The error to extract the original cause from
76
+ * @returns The deepest original error or the error itself
77
+ */
78
+ function getDeepOriginalError(error) {
79
+ if (!error) {
80
+ return error;
81
+ }
82
+ let current = error;
83
+ let depth = 0;
84
+ const maxDepth = 10; // Prevent infinite recursion
85
+ while (depth < maxDepth &&
86
+ current instanceof Error &&
87
+ 'originalError' in current &&
88
+ current.originalError) {
89
+ current = current.originalError;
90
+ depth++;
91
+ }
92
+ return current;
93
+ }
94
+ /**
95
+ * Format error for MCP tool response
96
+ */
97
+ function formatErrorForMcpTool(error) {
98
+ const methodLogger = logger_util_js_1.Logger.forContext('utils/error.util.ts', 'formatErrorForMcpTool');
99
+ const mcpError = ensureMcpError(error);
100
+ methodLogger.error(`${mcpError.type} error`, mcpError);
101
+ // Get the deep original error for additional context
102
+ const originalError = getDeepOriginalError(mcpError.originalError);
103
+ // Safely extract details from the original error
104
+ const errorDetails = originalError instanceof Error
105
+ ? { message: originalError.message }
106
+ : originalError;
107
+ return {
108
+ content: [
109
+ {
110
+ type: 'text',
111
+ text: `Error: ${mcpError.message}`,
112
+ },
113
+ ],
114
+ metadata: {
115
+ errorType: mcpError.type,
116
+ statusCode: mcpError.statusCode,
117
+ errorDetails,
118
+ },
119
+ };
120
+ }
121
+ /**
122
+ * Format error for MCP resource response
123
+ */
124
+ function formatErrorForMcpResource(error, uri) {
125
+ const methodLogger = logger_util_js_1.Logger.forContext('utils/error.util.ts', 'formatErrorForMcpResource');
126
+ const mcpError = ensureMcpError(error);
127
+ methodLogger.error(`${mcpError.type} error`, mcpError);
128
+ return {
129
+ contents: [
130
+ {
131
+ uri,
132
+ text: `Error: ${mcpError.message}`,
133
+ mimeType: 'text/plain',
134
+ description: `Error: ${mcpError.type}`,
135
+ },
136
+ ],
137
+ };
138
+ }
139
+ /**
140
+ * Handle error in CLI context with improved user feedback
141
+ */
142
+ function handleCliError(error) {
143
+ const methodLogger = logger_util_js_1.Logger.forContext('utils/error.util.ts', 'handleCliError');
144
+ const mcpError = ensureMcpError(error);
145
+ methodLogger.error(`${mcpError.type} error`, mcpError);
146
+ // Get the deep original error for more context
147
+ const originalError = getDeepOriginalError(mcpError.originalError);
148
+ // Print the error message
149
+ console.error(`Error: ${mcpError.message}`);
150
+ // Provide helpful context based on error type
151
+ if (mcpError.type === ErrorType.AUTH_MISSING) {
152
+ console.error('\nTip: Make sure to set up your API token in the configuration file or environment variables.');
153
+ }
154
+ else if (mcpError.type === ErrorType.AUTH_INVALID) {
155
+ console.error('\nTip: Check that your API token is correct and has not expired.');
156
+ }
157
+ else if (mcpError.type === ErrorType.API_ERROR) {
158
+ if (mcpError.statusCode === 429) {
159
+ console.error('\nTip: You may have exceeded your API rate limits. Try again later or upgrade your API plan.');
160
+ }
161
+ // Add API error context if available
162
+ if (originalError && typeof originalError === 'object') {
163
+ const origErr = originalError;
164
+ if (origErr.message) {
165
+ console.error(`\nAPI error: ${String(origErr.message)}`);
166
+ }
167
+ }
168
+ }
169
+ // Display DEBUG tip
170
+ if (process.env.DEBUG !== 'mcp:*') {
171
+ console.error('\nFor more detailed error information, run with DEBUG=mcp:* environment variable.');
172
+ }
173
+ process.exit(1);
174
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Standardized formatting utilities for consistent output across all CLI and Tool interfaces.
3
+ * These functions should be used by all formatters to ensure consistent formatting.
4
+ */
5
+ /**
6
+ * Format a date in a standardized way: YYYY-MM-DD HH:MM:SS UTC
7
+ * @param dateString - ISO date string or Date object
8
+ * @returns Formatted date string
9
+ */
10
+ export declare function formatDate(dateString?: string | Date): string;
11
+ /**
12
+ * Format a URL as a markdown link
13
+ * @param url - URL to format
14
+ * @param title - Link title
15
+ * @returns Formatted markdown link
16
+ */
17
+ export declare function formatUrl(url?: string, title?: string): string;
18
+ /**
19
+ * Format a heading with consistent style
20
+ * @param text - Heading text
21
+ * @param level - Heading level (1-6)
22
+ * @returns Formatted heading
23
+ */
24
+ export declare function formatHeading(text: string, level?: number): string;
25
+ /**
26
+ * Format a list of key-value pairs as a bullet list
27
+ * @param items - Object with key-value pairs
28
+ * @param keyFormatter - Optional function to format keys
29
+ * @returns Formatted bullet list
30
+ */
31
+ export declare function formatBulletList(items: Record<string, unknown>, keyFormatter?: (key: string) => string): string;
32
+ /**
33
+ * Format a separator line
34
+ * @returns Separator line
35
+ */
36
+ export declare function formatSeparator(): string;