mcp-ts-template 1.1.6 ā 1.1.7
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 +1 -1
- package/dist/config/index.js +1 -1
- package/dist/mcp-client/client.js +0 -1
- package/dist/mcp-server/transports/httpTransport.js +4 -2
- package/dist/utils/internal/errorHandler.d.ts +123 -41
- package/dist/utils/internal/errorHandler.js +151 -131
- package/dist/utils/internal/logger.js +15 -5
- package/dist/utils/internal/requestContext.d.ts +49 -17
- package/dist/utils/internal/requestContext.js +42 -22
- package/dist/utils/metrics/tokenCounter.js +0 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
[](https://www.typescriptlang.org/)
|
|
4
4
|
[](https://github.com/modelcontextprotocol/typescript-sdk)
|
|
5
5
|
[](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/docs/specification/2025-03-26/changelog.mdx)
|
|
6
|
-
[](./CHANGELOG.md)
|
|
7
7
|
[](https://opensource.org/licenses/Apache-2.0)
|
|
8
8
|
[](https://github.com/cyanheads/mcp-ts-template/issues)
|
|
9
9
|
[](https://github.com/cyanheads/mcp-ts-template)
|
package/dist/config/index.js
CHANGED
|
@@ -17,7 +17,7 @@ try {
|
|
|
17
17
|
catch (error) {
|
|
18
18
|
// Silently use default pkg info if reading fails.
|
|
19
19
|
// Consider adding logging here if robust error handling is needed.
|
|
20
|
-
if (process.stdout.isTTY) {
|
|
20
|
+
if (process.stdout.isTTY) { // Guarded console.error
|
|
21
21
|
console.error("Warning: Could not read package.json for default config values.", error);
|
|
22
22
|
}
|
|
23
23
|
}
|
|
@@ -163,7 +163,6 @@ export async function connectMcpClient(serverName, parentContext) {
|
|
|
163
163
|
operation: `connecting to MCP server ${serverName}`,
|
|
164
164
|
context: operationContext,
|
|
165
165
|
errorCode: BaseErrorCode.INTERNAL_ERROR, // Use INTERNAL_ERROR as fallback for connection issues
|
|
166
|
-
rethrow: true, // Rethrow the McpError for the caller to handle
|
|
167
166
|
});
|
|
168
167
|
}
|
|
169
168
|
/**
|
|
@@ -401,8 +401,10 @@ export async function startHttpTransport(createServerInstanceFn, context) {
|
|
|
401
401
|
// Determine protocol for logging (basic assumption based on HSTS possibility)
|
|
402
402
|
const protocol = config.environment === 'production' ? 'https' : 'http';
|
|
403
403
|
const serverAddress = `${protocol}://${config.mcpHttpHost}:${actualPort}${MCP_ENDPOINT_PATH}`;
|
|
404
|
-
// Use console.log for prominent startup message.
|
|
405
|
-
|
|
404
|
+
// Use console.log for prominent startup message only if TTY.
|
|
405
|
+
if (process.stdout.isTTY) {
|
|
406
|
+
console.log(`\nš MCP Server running in HTTP mode at: ${serverAddress}\n (MCP Spec: 2025-03-26 Streamable HTTP Transport)\n`);
|
|
407
|
+
}
|
|
406
408
|
}
|
|
407
409
|
catch (err) {
|
|
408
410
|
logger.fatal('HTTP server failed to start after multiple port retries.', { ...transportContext, error: err instanceof Error ? err.message : String(err) });
|
|
@@ -1,90 +1,172 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file errorHandler.ts
|
|
3
|
+
* @description This module provides utilities for creating and managing request contexts.
|
|
4
|
+
* A request context is a data structure associated with a specific request or operation,
|
|
5
|
+
* carrying a unique ID, timestamp, and other relevant information for logging, tracing,
|
|
6
|
+
* and processing.
|
|
7
|
+
*/
|
|
1
8
|
import { BaseErrorCode } from '../../types-global/errors.js';
|
|
2
9
|
/**
|
|
3
|
-
*
|
|
10
|
+
* @interface ErrorContext
|
|
11
|
+
* @description Defines a generic structure for providing context with errors.
|
|
12
|
+
* This context can include identifiers like `requestId` or any other relevant
|
|
13
|
+
* key-value pairs that aid in debugging or understanding the error's circumstances.
|
|
4
14
|
*/
|
|
5
15
|
export interface ErrorContext {
|
|
6
|
-
/**
|
|
16
|
+
/**
|
|
17
|
+
* A unique identifier for the request or operation during which the error occurred.
|
|
18
|
+
* Useful for tracing errors through logs and distributed systems.
|
|
19
|
+
* @type {string}
|
|
20
|
+
* @optional
|
|
21
|
+
*/
|
|
7
22
|
requestId?: string;
|
|
8
|
-
/**
|
|
23
|
+
/**
|
|
24
|
+
* Allows for arbitrary additional context information.
|
|
25
|
+
* Keys are strings, and values can be of any type.
|
|
26
|
+
*/
|
|
9
27
|
[key: string]: unknown;
|
|
10
28
|
}
|
|
11
29
|
/**
|
|
12
|
-
*
|
|
30
|
+
* @interface ErrorHandlerOptions
|
|
31
|
+
* @description Configuration options for the `ErrorHandler.handleError` method.
|
|
32
|
+
* These options control how an error is processed, logged, and whether it's rethrown.
|
|
13
33
|
*/
|
|
14
34
|
export interface ErrorHandlerOptions {
|
|
15
|
-
/**
|
|
35
|
+
/**
|
|
36
|
+
* The context of the operation that caused the error.
|
|
37
|
+
* This can include `requestId` and other relevant debugging information.
|
|
38
|
+
* @type {ErrorContext}
|
|
39
|
+
* @optional
|
|
40
|
+
*/
|
|
16
41
|
context?: ErrorContext;
|
|
17
|
-
/**
|
|
42
|
+
/**
|
|
43
|
+
* A descriptive name of the operation being performed when the error occurred.
|
|
44
|
+
* This helps in identifying the source or nature of the error in logs.
|
|
45
|
+
* Example: "UserLogin", "ProcessPayment", "FetchUserProfile".
|
|
46
|
+
* @type {string}
|
|
47
|
+
* @required
|
|
48
|
+
*/
|
|
18
49
|
operation: string;
|
|
19
|
-
/**
|
|
50
|
+
/**
|
|
51
|
+
* The input data or parameters that were being processed when the error occurred.
|
|
52
|
+
* This input will be sanitized before logging to prevent sensitive data exposure.
|
|
53
|
+
* @type {unknown}
|
|
54
|
+
* @optional
|
|
55
|
+
*/
|
|
20
56
|
input?: unknown;
|
|
21
|
-
/**
|
|
57
|
+
/**
|
|
58
|
+
* If true, the (potentially transformed) error will be rethrown after handling.
|
|
59
|
+
* Defaults to `false`.
|
|
60
|
+
* @type {boolean}
|
|
61
|
+
* @optional
|
|
62
|
+
*/
|
|
22
63
|
rethrow?: boolean;
|
|
23
|
-
/**
|
|
64
|
+
/**
|
|
65
|
+
* A specific `BaseErrorCode` to assign to the error, overriding any
|
|
66
|
+
* automatically determined error code.
|
|
67
|
+
* @type {BaseErrorCode}
|
|
68
|
+
* @optional
|
|
69
|
+
*/
|
|
24
70
|
errorCode?: BaseErrorCode;
|
|
25
|
-
/**
|
|
71
|
+
/**
|
|
72
|
+
* A custom function to map or transform the original error into a new `Error` instance.
|
|
73
|
+
* If provided, this function is used instead of the default `McpError` creation.
|
|
74
|
+
* @param {unknown} error - The original error that occurred.
|
|
75
|
+
* @returns {Error} The transformed error.
|
|
76
|
+
* @optional
|
|
77
|
+
*/
|
|
26
78
|
errorMapper?: (error: unknown) => Error;
|
|
27
|
-
/**
|
|
79
|
+
/**
|
|
80
|
+
* If true, stack traces will be included in the logs.
|
|
81
|
+
* Defaults to `true`.
|
|
82
|
+
* @type {boolean}
|
|
83
|
+
* @optional
|
|
84
|
+
*/
|
|
28
85
|
includeStack?: boolean;
|
|
29
|
-
/**
|
|
86
|
+
/**
|
|
87
|
+
* If true, indicates that the error is critical and might require immediate attention
|
|
88
|
+
* or could lead to system instability. This is primarily for logging and alerting.
|
|
89
|
+
* Defaults to `false`.
|
|
90
|
+
* @type {boolean}
|
|
91
|
+
* @optional
|
|
92
|
+
*/
|
|
30
93
|
critical?: boolean;
|
|
31
94
|
}
|
|
32
95
|
/**
|
|
33
|
-
*
|
|
96
|
+
* @interface BaseErrorMapping
|
|
97
|
+
* @description Defines a basic rule for mapping errors based on patterns.
|
|
98
|
+
* Used internally by `COMMON_ERROR_PATTERNS` and as a base for `ErrorMapping`.
|
|
34
99
|
*/
|
|
35
100
|
export interface BaseErrorMapping {
|
|
36
|
-
/**
|
|
101
|
+
/**
|
|
102
|
+
* A string or regular expression to match against the error message.
|
|
103
|
+
* If a string is provided, it's typically used for substring matching (case-insensitive).
|
|
104
|
+
* @type {string | RegExp}
|
|
105
|
+
* @required
|
|
106
|
+
*/
|
|
37
107
|
pattern: string | RegExp;
|
|
38
|
-
/**
|
|
108
|
+
/**
|
|
109
|
+
* The `BaseErrorCode` to assign if the pattern matches.
|
|
110
|
+
* @type {BaseErrorCode}
|
|
111
|
+
* @required
|
|
112
|
+
*/
|
|
39
113
|
errorCode: BaseErrorCode;
|
|
40
|
-
/**
|
|
114
|
+
/**
|
|
115
|
+
* An optional custom message template for the mapped error.
|
|
116
|
+
* (Note: This property is defined but not directly used by `ErrorHandler.determineErrorCode`
|
|
117
|
+
* which focuses on `errorCode`. It's more relevant for custom mapping logic.)
|
|
118
|
+
* @type {string}
|
|
119
|
+
* @optional
|
|
120
|
+
*/
|
|
41
121
|
messageTemplate?: string;
|
|
42
122
|
}
|
|
43
123
|
/**
|
|
44
|
-
*
|
|
124
|
+
* @interface ErrorMapping
|
|
125
|
+
* @template T - The type of `Error` this mapping will produce, defaults to `Error`.
|
|
126
|
+
* @description Extends `BaseErrorMapping` to include a factory function for creating
|
|
127
|
+
* specific error instances and additional context for the mapping.
|
|
128
|
+
* Used by `ErrorHandler.mapError`.
|
|
45
129
|
*/
|
|
46
130
|
export interface ErrorMapping<T extends Error = Error> extends BaseErrorMapping {
|
|
47
|
-
/**
|
|
131
|
+
/**
|
|
132
|
+
* A factory function that creates and returns an instance of the mapped error type `T`.
|
|
133
|
+
* @param {unknown} error - The original error that occurred.
|
|
134
|
+
* @param {Record<string, unknown>} [context] - Optional additional context provided in the mapping rule.
|
|
135
|
+
* @returns {T} The newly created error instance.
|
|
136
|
+
* @required
|
|
137
|
+
*/
|
|
48
138
|
factory: (error: unknown, context?: Record<string, unknown>) => T;
|
|
49
|
-
/**
|
|
139
|
+
/**
|
|
140
|
+
* Additional static context to be merged or passed to the `factory` function
|
|
141
|
+
* when this mapping rule is applied.
|
|
142
|
+
* @type {Record<string, unknown>}
|
|
143
|
+
* @optional
|
|
144
|
+
*/
|
|
50
145
|
additionalContext?: Record<string, unknown>;
|
|
51
146
|
}
|
|
52
147
|
/**
|
|
53
|
-
*
|
|
148
|
+
* @class ErrorHandler
|
|
149
|
+
* @description A utility class providing static methods for comprehensive error handling.
|
|
54
150
|
*/
|
|
55
151
|
export declare class ErrorHandler {
|
|
56
152
|
/**
|
|
57
|
-
*
|
|
58
|
-
* @param error The error to classify
|
|
59
|
-
* @returns The appropriate error code
|
|
153
|
+
* Determines an appropriate `BaseErrorCode` for a given error.
|
|
60
154
|
*/
|
|
61
155
|
static determineErrorCode(error: unknown): BaseErrorCode;
|
|
62
156
|
/**
|
|
63
|
-
*
|
|
64
|
-
* @param error The error that occurred
|
|
65
|
-
* @param options Error handling options
|
|
66
|
-
* @returns The transformed error
|
|
157
|
+
* Handles an error with consistent logging and optional transformation.
|
|
67
158
|
*/
|
|
68
159
|
static handleError(error: unknown, options: ErrorHandlerOptions): Error;
|
|
69
160
|
/**
|
|
70
|
-
*
|
|
71
|
-
* @param error The error to map
|
|
72
|
-
* @param mappings Array of pattern and factory mappings
|
|
73
|
-
* @param defaultFactory Default factory function if no pattern matches
|
|
74
|
-
* @returns The mapped error
|
|
161
|
+
* Maps an error to a specific error type `T` based on a list of `ErrorMapping` rules.
|
|
75
162
|
*/
|
|
76
|
-
static mapError<T extends Error>(error: unknown, mappings: ErrorMapping<T
|
|
163
|
+
static mapError<T extends Error>(error: unknown, mappings: ReadonlyArray<ErrorMapping<T>>, defaultFactory?: (error: unknown, context?: Record<string, unknown>) => T): T | Error;
|
|
77
164
|
/**
|
|
78
|
-
*
|
|
79
|
-
* @param error The error to format
|
|
80
|
-
* @returns Formatted error object
|
|
165
|
+
* Formats an error into a consistent object structure, typically for API responses.
|
|
81
166
|
*/
|
|
82
167
|
static formatError(error: unknown): Record<string, unknown>;
|
|
83
168
|
/**
|
|
84
|
-
* Safely
|
|
85
|
-
* @param fn Function to execute
|
|
86
|
-
* @param options Error handling options
|
|
87
|
-
* @returns The result of the function or error
|
|
169
|
+
* Safely executes a function and handles any errors using `ErrorHandler.handleError`.
|
|
88
170
|
*/
|
|
89
|
-
static tryCatch<T>(fn: () => Promise<T> | T, options: ErrorHandlerOptions): Promise<T>;
|
|
171
|
+
static tryCatch<T>(fn: () => Promise<T> | T, options: Omit<ErrorHandlerOptions, 'rethrow'>): Promise<T>;
|
|
90
172
|
}
|
|
@@ -1,8 +1,18 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* @file errorHandler.ts
|
|
3
|
+
* @description This module provides utilities for creating and managing request contexts.
|
|
4
|
+
* A request context is a data structure associated with a specific request or operation,
|
|
5
|
+
* carrying a unique ID, timestamp, and other relevant information for logging, tracing,
|
|
6
|
+
* and processing.
|
|
7
|
+
*/
|
|
8
|
+
import { BaseErrorCode, McpError } from '../../types-global/errors.js';
|
|
9
|
+
import { sanitizeInputForLogging } from '../index.js';
|
|
2
10
|
import { logger } from './logger.js';
|
|
3
|
-
import { sanitizeInputForLogging } from '../index.js'; // Import from main barrel file
|
|
4
11
|
/**
|
|
5
|
-
*
|
|
12
|
+
* @constant ERROR_TYPE_MAPPINGS
|
|
13
|
+
* @description Maps standard JavaScript error constructor names to `BaseErrorCode` values.
|
|
14
|
+
* This allows for quick classification of common built-in error types.
|
|
15
|
+
* @readonly
|
|
6
16
|
*/
|
|
7
17
|
const ERROR_TYPE_MAPPINGS = {
|
|
8
18
|
'SyntaxError': BaseErrorCode.VALIDATION_ERROR,
|
|
@@ -10,235 +20,245 @@ const ERROR_TYPE_MAPPINGS = {
|
|
|
10
20
|
'ReferenceError': BaseErrorCode.INTERNAL_ERROR,
|
|
11
21
|
'RangeError': BaseErrorCode.VALIDATION_ERROR,
|
|
12
22
|
'URIError': BaseErrorCode.VALIDATION_ERROR,
|
|
13
|
-
'EvalError': BaseErrorCode.INTERNAL_ERROR
|
|
23
|
+
'EvalError': BaseErrorCode.INTERNAL_ERROR,
|
|
14
24
|
};
|
|
15
25
|
/**
|
|
16
|
-
*
|
|
26
|
+
* @constant COMMON_ERROR_PATTERNS
|
|
27
|
+
* @description An array of `BaseErrorMapping` rules used to automatically classify
|
|
28
|
+
* errors based on keywords or patterns found in their messages or names.
|
|
29
|
+
* These patterns are typically case-insensitive.
|
|
30
|
+
* **IMPORTANT**: The order of patterns matters. More specific patterns should generally come
|
|
31
|
+
* before more generic ones if there's a possibility of overlap, as the first match is used.
|
|
32
|
+
* @readonly
|
|
17
33
|
*/
|
|
18
34
|
const COMMON_ERROR_PATTERNS = [
|
|
19
|
-
// Authentication related errors
|
|
20
35
|
{ pattern: /auth|unauthorized|unauthenticated|not.*logged.*in|invalid.*token|expired.*token/i, errorCode: BaseErrorCode.UNAUTHORIZED },
|
|
21
|
-
// Permission related errors
|
|
22
36
|
{ pattern: /permission|forbidden|access.*denied|not.*allowed/i, errorCode: BaseErrorCode.FORBIDDEN },
|
|
23
|
-
// Not found errors
|
|
24
37
|
{ pattern: /not.*found|missing|no.*such|doesn't.*exist|couldn't.*find/i, errorCode: BaseErrorCode.NOT_FOUND },
|
|
25
|
-
|
|
26
|
-
{ pattern: /invalid|validation|malformed|bad request|wrong format/i, errorCode: BaseErrorCode.VALIDATION_ERROR },
|
|
27
|
-
// Conflict errors
|
|
38
|
+
{ pattern: /invalid|validation|malformed|bad request|wrong format|missing.*required/i, errorCode: BaseErrorCode.VALIDATION_ERROR },
|
|
28
39
|
{ pattern: /conflict|already.*exists|duplicate|unique.*constraint/i, errorCode: BaseErrorCode.CONFLICT },
|
|
29
|
-
// Rate limiting
|
|
30
40
|
{ pattern: /rate.*limit|too.*many.*requests|throttled/i, errorCode: BaseErrorCode.RATE_LIMITED },
|
|
31
|
-
// Timeout errors
|
|
32
41
|
{ pattern: /timeout|timed.*out|deadline.*exceeded/i, errorCode: BaseErrorCode.TIMEOUT },
|
|
33
|
-
|
|
34
|
-
{ pattern: /service.*unavailable|bad.*gateway|gateway.*timeout/i, errorCode: BaseErrorCode.SERVICE_UNAVAILABLE }
|
|
42
|
+
{ pattern: /service.*unavailable|bad.*gateway|gateway.*timeout|upstream.*error/i, errorCode: BaseErrorCode.SERVICE_UNAVAILABLE },
|
|
35
43
|
];
|
|
36
44
|
/**
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
* @
|
|
45
|
+
* Creates a "safe" RegExp for testing error messages.
|
|
46
|
+
* Ensures case-insensitivity if not already specified and removes the global flag.
|
|
47
|
+
* @param pattern - The string or RegExp pattern.
|
|
48
|
+
* @returns A new RegExp instance.
|
|
49
|
+
*/
|
|
50
|
+
function createSafeRegex(pattern) {
|
|
51
|
+
if (pattern instanceof RegExp) {
|
|
52
|
+
let flags = pattern.flags.replace('g', ''); // Remove global flag
|
|
53
|
+
if (!flags.includes('i')) {
|
|
54
|
+
flags += 'i'; // Add case-insensitive if not present
|
|
55
|
+
}
|
|
56
|
+
return new RegExp(pattern.source, flags);
|
|
57
|
+
}
|
|
58
|
+
return new RegExp(pattern, 'i'); // Default to case-insensitive for string patterns
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Retrieves a descriptive name for an error object or value.
|
|
62
|
+
* Handles various types including `Error` instances, `null`, `undefined`, and other primitives/objects.
|
|
63
|
+
*
|
|
64
|
+
* @param error - The error object or value.
|
|
65
|
+
* @returns A string representing the error's name or type.
|
|
40
66
|
*/
|
|
41
67
|
function getErrorName(error) {
|
|
42
68
|
if (error instanceof Error) {
|
|
43
69
|
return error.name || 'Error';
|
|
44
70
|
}
|
|
45
71
|
if (error === null) {
|
|
46
|
-
return '
|
|
72
|
+
return 'NullValueEncountered';
|
|
47
73
|
}
|
|
48
74
|
if (error === undefined) {
|
|
49
|
-
return '
|
|
75
|
+
return 'UndefinedValueEncountered';
|
|
50
76
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
77
|
+
if (typeof error === 'object' && error !== null && error.constructor && typeof error.constructor.name === 'string' && error.constructor.name !== 'Object') {
|
|
78
|
+
return `${error.constructor.name}Encountered`;
|
|
79
|
+
}
|
|
80
|
+
return `${typeof error}Encountered`;
|
|
54
81
|
}
|
|
55
82
|
/**
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
83
|
+
* Extracts a message string from an error object or value.
|
|
84
|
+
* Handles `Error` instances, primitives, and converts other types to a string representation.
|
|
85
|
+
*
|
|
86
|
+
* @param error - The error object or value.
|
|
87
|
+
* @returns The error message string.
|
|
59
88
|
*/
|
|
60
89
|
function getErrorMessage(error) {
|
|
61
90
|
if (error instanceof Error) {
|
|
62
91
|
return error.message;
|
|
63
92
|
}
|
|
64
93
|
if (error === null) {
|
|
65
|
-
return 'Null error
|
|
94
|
+
return 'Null value encountered as error';
|
|
66
95
|
}
|
|
67
96
|
if (error === undefined) {
|
|
68
|
-
return 'Undefined error
|
|
97
|
+
return 'Undefined value encountered as error';
|
|
98
|
+
}
|
|
99
|
+
if (typeof error === 'string') {
|
|
100
|
+
return error;
|
|
101
|
+
}
|
|
102
|
+
try {
|
|
103
|
+
const str = String(error);
|
|
104
|
+
if (str === '[object Object]' && error !== null) {
|
|
105
|
+
try {
|
|
106
|
+
return `Non-Error object encountered: ${JSON.stringify(error)}`;
|
|
107
|
+
}
|
|
108
|
+
catch (stringifyError) {
|
|
109
|
+
return `Unstringifyable non-Error object encountered (constructor: ${error.constructor?.name || 'Unknown'})`;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return str;
|
|
113
|
+
}
|
|
114
|
+
catch (e) {
|
|
115
|
+
return `Error converting error to string: ${e instanceof Error ? e.message : 'Unknown conversion error'}`;
|
|
69
116
|
}
|
|
70
|
-
return typeof error === 'string'
|
|
71
|
-
? error
|
|
72
|
-
: String(error);
|
|
73
117
|
}
|
|
74
118
|
/**
|
|
75
|
-
*
|
|
119
|
+
* @class ErrorHandler
|
|
120
|
+
* @description A utility class providing static methods for comprehensive error handling.
|
|
76
121
|
*/
|
|
77
122
|
export class ErrorHandler {
|
|
78
123
|
/**
|
|
79
|
-
*
|
|
80
|
-
* @param error The error to classify
|
|
81
|
-
* @returns The appropriate error code
|
|
124
|
+
* Determines an appropriate `BaseErrorCode` for a given error.
|
|
82
125
|
*/
|
|
83
126
|
static determineErrorCode(error) {
|
|
84
|
-
// If it's already an McpError, use its code
|
|
85
127
|
if (error instanceof McpError) {
|
|
86
128
|
return error.code;
|
|
87
129
|
}
|
|
88
130
|
const errorName = getErrorName(error);
|
|
89
131
|
const errorMessage = getErrorMessage(error);
|
|
90
|
-
// Check if the error type has a direct mapping
|
|
91
132
|
if (errorName in ERROR_TYPE_MAPPINGS) {
|
|
92
133
|
return ERROR_TYPE_MAPPINGS[errorName];
|
|
93
134
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
const regex = pattern.pattern instanceof RegExp
|
|
97
|
-
? pattern.pattern
|
|
98
|
-
: new RegExp(pattern.pattern, 'i');
|
|
135
|
+
for (const mapping of COMMON_ERROR_PATTERNS) {
|
|
136
|
+
const regex = createSafeRegex(mapping.pattern);
|
|
99
137
|
if (regex.test(errorMessage) || regex.test(errorName)) {
|
|
100
|
-
return
|
|
138
|
+
return mapping.errorCode;
|
|
101
139
|
}
|
|
102
140
|
}
|
|
103
|
-
// Default to internal error if no pattern matches
|
|
104
141
|
return BaseErrorCode.INTERNAL_ERROR;
|
|
105
142
|
}
|
|
106
143
|
/**
|
|
107
|
-
*
|
|
108
|
-
* @param error The error that occurred
|
|
109
|
-
* @param options Error handling options
|
|
110
|
-
* @returns The transformed error
|
|
144
|
+
* Handles an error with consistent logging and optional transformation.
|
|
111
145
|
*/
|
|
112
146
|
static handleError(error, options) {
|
|
113
|
-
const { context, operation, input, rethrow = false, errorCode: explicitErrorCode, includeStack = true, critical = false } = options;
|
|
114
|
-
|
|
147
|
+
const { context = {}, operation, input, rethrow = false, errorCode: explicitErrorCode, includeStack = true, critical = false, errorMapper, } = options;
|
|
148
|
+
const sanitizedInput = input !== undefined ? sanitizeInputForLogging(input) : undefined;
|
|
149
|
+
const originalErrorName = getErrorName(error);
|
|
150
|
+
const originalErrorMessage = getErrorMessage(error);
|
|
151
|
+
const originalStack = error instanceof Error ? error.stack : undefined;
|
|
152
|
+
let finalError;
|
|
153
|
+
let loggedErrorCode;
|
|
154
|
+
// Consolidate details for McpError and logging
|
|
155
|
+
const errorDetailsSeed = error instanceof McpError && typeof error.details === 'object' && error.details !== null
|
|
156
|
+
? { ...error.details } // Clone to avoid mutating original
|
|
157
|
+
: {};
|
|
158
|
+
const consolidatedDetails = {
|
|
159
|
+
...errorDetailsSeed,
|
|
160
|
+
...context, // Operation context takes precedence over seed details if keys overlap
|
|
161
|
+
originalErrorName,
|
|
162
|
+
originalMessage: originalErrorMessage,
|
|
163
|
+
};
|
|
164
|
+
if (originalStack && !(error instanceof McpError && error.details?.originalStack)) { // Avoid duplicating if already there
|
|
165
|
+
consolidatedDetails.originalStack = originalStack;
|
|
166
|
+
}
|
|
115
167
|
if (error instanceof McpError) {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
error.details = { ...existingDetails, ...context };
|
|
168
|
+
loggedErrorCode = error.code;
|
|
169
|
+
finalError = errorMapper ? errorMapper(error) : new McpError(error.code, error.message, consolidatedDetails);
|
|
170
|
+
if (finalError instanceof McpError && !finalError.details) {
|
|
171
|
+
finalError.details = consolidatedDetails;
|
|
121
172
|
}
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
...context
|
|
130
|
-
});
|
|
131
|
-
if (rethrow) {
|
|
132
|
-
throw error;
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
loggedErrorCode = explicitErrorCode || ErrorHandler.determineErrorCode(error);
|
|
176
|
+
const message = `Error in ${operation}: ${originalErrorMessage}`;
|
|
177
|
+
finalError = errorMapper ? errorMapper(error) : new McpError(loggedErrorCode, message, consolidatedDetails);
|
|
178
|
+
if (finalError instanceof McpError && !finalError.details) {
|
|
179
|
+
finalError.details = consolidatedDetails;
|
|
133
180
|
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
//
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
181
|
+
}
|
|
182
|
+
// Preserve original stack if the finalError is a new Error instance and original was an Error
|
|
183
|
+
if (finalError !== error && error instanceof Error && finalError instanceof Error && !finalError.stack && error.stack) {
|
|
184
|
+
finalError.stack = error.stack;
|
|
185
|
+
}
|
|
186
|
+
// Prepare log payload
|
|
187
|
+
const logPayload = {
|
|
188
|
+
operation,
|
|
189
|
+
requestId: context.requestId,
|
|
143
190
|
input: sanitizedInput,
|
|
144
|
-
requestId: context?.requestId,
|
|
145
|
-
stack: includeStack && error instanceof Error ? error.stack : undefined,
|
|
146
191
|
critical,
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
// Transform to appropriate error type
|
|
154
|
-
let transformedError;
|
|
155
|
-
if (options.errorMapper) {
|
|
156
|
-
transformedError = options.errorMapper(error);
|
|
192
|
+
errorCode: loggedErrorCode,
|
|
193
|
+
originalErrorType: originalErrorName, // Retain for clarity
|
|
194
|
+
finalErrorType: getErrorName(finalError),
|
|
195
|
+
};
|
|
196
|
+
if (finalError instanceof McpError && finalError.details) {
|
|
197
|
+
logPayload.errorDetails = finalError.details;
|
|
157
198
|
}
|
|
158
199
|
else {
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
originalError: getErrorName(error),
|
|
162
|
-
...context
|
|
163
|
-
});
|
|
200
|
+
// For non-McpError or McpError without details, use the consolidatedDetails we built
|
|
201
|
+
logPayload.errorDetails = consolidatedDetails;
|
|
164
202
|
}
|
|
165
|
-
|
|
203
|
+
if (includeStack && finalError instanceof Error && finalError.stack) {
|
|
204
|
+
logPayload.stack = finalError.stack;
|
|
205
|
+
}
|
|
206
|
+
else if (includeStack && originalStack && !logPayload.stack) { // Fallback to original stack if finalError lost it
|
|
207
|
+
logPayload.stack = originalStack;
|
|
208
|
+
}
|
|
209
|
+
logger.error(`Error in ${operation}: ${finalError.message || originalErrorMessage}`, logPayload);
|
|
166
210
|
if (rethrow) {
|
|
167
|
-
throw
|
|
211
|
+
throw finalError;
|
|
168
212
|
}
|
|
169
|
-
|
|
170
|
-
return transformedError;
|
|
213
|
+
return finalError;
|
|
171
214
|
}
|
|
172
215
|
/**
|
|
173
|
-
*
|
|
174
|
-
* @param error The error to map
|
|
175
|
-
* @param mappings Array of pattern and factory mappings
|
|
176
|
-
* @param defaultFactory Default factory function if no pattern matches
|
|
177
|
-
* @returns The mapped error
|
|
216
|
+
* Maps an error to a specific error type `T` based on a list of `ErrorMapping` rules.
|
|
178
217
|
*/
|
|
179
218
|
static mapError(error, mappings, defaultFactory) {
|
|
180
|
-
// If it's already the target type and we have a default factory to check against, return it
|
|
181
|
-
if (defaultFactory && error instanceof Error) {
|
|
182
|
-
const defaultInstance = defaultFactory(error);
|
|
183
|
-
if (error.constructor === defaultInstance.constructor) {
|
|
184
|
-
return error;
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
219
|
const errorMessage = getErrorMessage(error);
|
|
188
|
-
|
|
220
|
+
const errorName = getErrorName(error);
|
|
189
221
|
for (const mapping of mappings) {
|
|
190
|
-
const
|
|
191
|
-
|
|
192
|
-
: errorMessage.includes(mapping.pattern);
|
|
193
|
-
if (matches) {
|
|
222
|
+
const regex = createSafeRegex(mapping.pattern);
|
|
223
|
+
if (regex.test(errorMessage) || regex.test(errorName)) {
|
|
194
224
|
return mapping.factory(error, mapping.additionalContext);
|
|
195
225
|
}
|
|
196
226
|
}
|
|
197
|
-
// Return default or original error
|
|
198
227
|
if (defaultFactory) {
|
|
199
228
|
return defaultFactory(error);
|
|
200
229
|
}
|
|
201
|
-
return error instanceof Error
|
|
202
|
-
? error
|
|
203
|
-
: new Error(String(error));
|
|
230
|
+
return error instanceof Error ? error : new Error(String(error));
|
|
204
231
|
}
|
|
205
|
-
// Removed createErrorMapper method for simplification
|
|
206
232
|
/**
|
|
207
|
-
*
|
|
208
|
-
* @param error The error to format
|
|
209
|
-
* @returns Formatted error object
|
|
233
|
+
* Formats an error into a consistent object structure, typically for API responses.
|
|
210
234
|
*/
|
|
211
235
|
static formatError(error) {
|
|
212
236
|
if (error instanceof McpError) {
|
|
213
237
|
return {
|
|
214
238
|
code: error.code,
|
|
215
239
|
message: error.message,
|
|
216
|
-
|
|
217
|
-
details: typeof error.details === 'object' && error.details !== null ? error.details : {}
|
|
240
|
+
details: typeof error.details === 'object' && error.details !== null ? error.details : {},
|
|
218
241
|
};
|
|
219
242
|
}
|
|
220
243
|
if (error instanceof Error) {
|
|
221
244
|
return {
|
|
222
245
|
code: ErrorHandler.determineErrorCode(error),
|
|
223
246
|
message: error.message,
|
|
224
|
-
details: { errorType: error.name }
|
|
247
|
+
details: { errorType: error.name || 'Error' },
|
|
225
248
|
};
|
|
226
249
|
}
|
|
227
250
|
return {
|
|
228
251
|
code: BaseErrorCode.UNKNOWN_ERROR,
|
|
229
|
-
message:
|
|
230
|
-
details: { errorType:
|
|
252
|
+
message: getErrorMessage(error),
|
|
253
|
+
details: { errorType: getErrorName(error) },
|
|
231
254
|
};
|
|
232
255
|
}
|
|
233
256
|
/**
|
|
234
|
-
* Safely
|
|
235
|
-
* @param fn Function to execute
|
|
236
|
-
* @param options Error handling options
|
|
237
|
-
* @returns The result of the function or error
|
|
257
|
+
* Safely executes a function and handles any errors using `ErrorHandler.handleError`.
|
|
238
258
|
*/
|
|
239
259
|
static async tryCatch(fn, options) {
|
|
240
260
|
try {
|
|
241
|
-
return await fn();
|
|
261
|
+
return await Promise.resolve(fn());
|
|
242
262
|
}
|
|
243
263
|
catch (error) {
|
|
244
264
|
throw ErrorHandler.handleError(error, { ...options, rethrow: true });
|
|
@@ -31,8 +31,12 @@ const logsDir = path.join(projectRoot, 'logs');
|
|
|
31
31
|
const resolvedLogsDir = path.resolve(logsDir);
|
|
32
32
|
const isLogsDirSafe = resolvedLogsDir === projectRoot || resolvedLogsDir.startsWith(projectRoot + path.sep);
|
|
33
33
|
if (!isLogsDirSafe) {
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
if (process.stdout.isTTY) {
|
|
35
|
+
// Use console.error here as logger might not be initialized or safe, but only if TTY
|
|
36
|
+
console.error(`FATAL: logs directory "${resolvedLogsDir}" is outside project root "${projectRoot}". File logging disabled.`);
|
|
37
|
+
}
|
|
38
|
+
// If not TTY, this critical error will be logged to a file if possible by the initialized logger later,
|
|
39
|
+
// or an MCP notification if configured. Suppressing direct console output here for stdio clients.
|
|
36
40
|
}
|
|
37
41
|
/**
|
|
38
42
|
* Singleton Logger wrapping Winston, adapted for MCP.
|
|
@@ -51,10 +55,11 @@ class Logger {
|
|
|
51
55
|
*/
|
|
52
56
|
async initialize(level = 'info') {
|
|
53
57
|
if (this.initialized) {
|
|
54
|
-
// Avoid console.warn in stdio mode, this will be logged via this.info later if needed.
|
|
55
58
|
if (process.stdout.isTTY) {
|
|
59
|
+
// This warning is only relevant for interactive sessions.
|
|
56
60
|
console.warn('Logger already initialized.');
|
|
57
61
|
}
|
|
62
|
+
// If already initialized, subsequent info log will indicate this.
|
|
58
63
|
return;
|
|
59
64
|
}
|
|
60
65
|
this.currentMcpLevel = level;
|
|
@@ -71,7 +76,10 @@ class Logger {
|
|
|
71
76
|
}
|
|
72
77
|
}
|
|
73
78
|
catch (err) {
|
|
74
|
-
|
|
79
|
+
if (process.stdout.isTTY) {
|
|
80
|
+
console.error(`Error creating logs directory at ${resolvedLogsDir}: ${err.message}. File logging disabled.`);
|
|
81
|
+
}
|
|
82
|
+
// This error will be logged to file/MCP by the logger instance if it initializes successfully.
|
|
75
83
|
}
|
|
76
84
|
}
|
|
77
85
|
// Common format for files
|
|
@@ -149,7 +157,9 @@ class Logger {
|
|
|
149
157
|
*/
|
|
150
158
|
setLevel(newLevel) {
|
|
151
159
|
if (!this.ensureInitialized()) {
|
|
152
|
-
|
|
160
|
+
if (process.stdout.isTTY) {
|
|
161
|
+
console.error("Cannot set level: Logger not initialized.");
|
|
162
|
+
}
|
|
153
163
|
return;
|
|
154
164
|
}
|
|
155
165
|
if (!(newLevel in mcpLevelSeverity)) {
|
|
@@ -1,47 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file requestContext.ts
|
|
3
|
+
* @description Utilities for creating and managing request contexts.
|
|
4
|
+
* A request context is an object carrying a unique ID, timestamp, and other
|
|
5
|
+
* relevant data for logging, tracing, and processing.
|
|
6
|
+
*/
|
|
1
7
|
/**
|
|
2
8
|
* Defines the structure for context information associated with a request or operation.
|
|
3
9
|
*/
|
|
4
10
|
export interface RequestContext {
|
|
5
|
-
/**
|
|
11
|
+
/**
|
|
12
|
+
* Unique ID for the context instance.
|
|
13
|
+
* Used for log correlation and request tracing.
|
|
14
|
+
*/
|
|
6
15
|
requestId: string;
|
|
7
|
-
/**
|
|
16
|
+
/**
|
|
17
|
+
* ISO 8601 timestamp indicating when the context was created.
|
|
18
|
+
*/
|
|
8
19
|
timestamp: string;
|
|
9
|
-
/**
|
|
10
|
-
|
|
20
|
+
/**
|
|
21
|
+
* Allows arbitrary key-value pairs for specific context needs.
|
|
22
|
+
* Using `unknown` promotes type-safe access.
|
|
23
|
+
* Consumers must type-check/assert when accessing extended properties.
|
|
24
|
+
*/
|
|
25
|
+
[key: string]: unknown;
|
|
11
26
|
}
|
|
12
27
|
/**
|
|
13
|
-
* Configuration interface for request context
|
|
28
|
+
* Configuration interface for the request context service.
|
|
29
|
+
* Extensible for future configuration.
|
|
30
|
+
* Placeholder for potential service-wide settings.
|
|
14
31
|
*/
|
|
15
32
|
export interface ContextConfig {
|
|
16
|
-
/** Custom configuration properties */
|
|
33
|
+
/** Custom configuration properties. Allows for arbitrary key-value pairs. */
|
|
17
34
|
[key: string]: unknown;
|
|
18
35
|
}
|
|
19
36
|
/**
|
|
20
|
-
*
|
|
37
|
+
* Represents a broader operation context, optionally including
|
|
38
|
+
* a `RequestContext` and custom properties.
|
|
39
|
+
* Often used to pass contextual information for an operation or task.
|
|
21
40
|
*/
|
|
22
41
|
export interface OperationContext {
|
|
23
|
-
/**
|
|
42
|
+
/** Optional request context data, adhering to the `RequestContext` structure. */
|
|
24
43
|
requestContext?: RequestContext;
|
|
25
|
-
/**
|
|
44
|
+
/** Allows for additional, custom properties specific to the operation. */
|
|
26
45
|
[key: string]: unknown;
|
|
27
46
|
}
|
|
47
|
+
/**
|
|
48
|
+
* Primary export for request context functionalities.
|
|
49
|
+
* Provides methods to create and manage request contexts.
|
|
50
|
+
*/
|
|
28
51
|
export declare const requestContextService: {
|
|
52
|
+
/**
|
|
53
|
+
* Internal configuration store.
|
|
54
|
+
* Initialized empty, updatable via `configure`.
|
|
55
|
+
*/
|
|
29
56
|
config: ContextConfig;
|
|
30
57
|
/**
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
* @
|
|
58
|
+
* Configures the service with new settings, merging with existing config.
|
|
59
|
+
*
|
|
60
|
+
* @param config - A partial `ContextConfig` object containing settings to update.
|
|
61
|
+
* @returns A shallow copy of the updated configuration.
|
|
34
62
|
*/
|
|
35
63
|
configure(config: Partial<ContextConfig>): ContextConfig;
|
|
36
64
|
/**
|
|
37
|
-
*
|
|
38
|
-
*
|
|
65
|
+
* Retrieves a shallow copy of the current service configuration.
|
|
66
|
+
*
|
|
67
|
+
* @returns A shallow copy of the current `ContextConfig`.
|
|
39
68
|
*/
|
|
40
69
|
getConfig(): ContextConfig;
|
|
41
70
|
/**
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
71
|
+
* Creates a new request context with a unique `requestId` and `timestamp`.
|
|
72
|
+
* Custom properties can be added via `additionalContext`.
|
|
73
|
+
*
|
|
74
|
+
* @param additionalContext - An optional record of key-value pairs to be
|
|
75
|
+
* included in the request context. Defaults to an empty object.
|
|
76
|
+
* @returns A `RequestContext` object.
|
|
45
77
|
*/
|
|
46
78
|
createRequestContext(additionalContext?: Record<string, unknown>): RequestContext;
|
|
47
79
|
};
|
|
@@ -1,48 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file requestContext.ts
|
|
3
|
+
* @description Utilities for creating and managing request contexts.
|
|
4
|
+
* A request context is an object carrying a unique ID, timestamp, and other
|
|
5
|
+
* relevant data for logging, tracing, and processing.
|
|
6
|
+
*/
|
|
1
7
|
import { logger } from './logger.js';
|
|
2
8
|
// Import utils from the main barrel file (generateUUID from ../security/idGenerator.js)
|
|
3
9
|
import { generateUUID } from '../index.js';
|
|
4
|
-
|
|
10
|
+
/**
|
|
11
|
+
* Service instance for managing request context operations.
|
|
12
|
+
* Singleton-like object to configure the service and create contexts.
|
|
13
|
+
*/
|
|
5
14
|
const requestContextServiceInstance = {
|
|
15
|
+
/**
|
|
16
|
+
* Internal configuration store.
|
|
17
|
+
* Initialized empty, updatable via `configure`.
|
|
18
|
+
*/
|
|
6
19
|
config: {},
|
|
7
20
|
/**
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* @
|
|
21
|
+
* Configures the service with new settings, merging with existing config.
|
|
22
|
+
*
|
|
23
|
+
* @param config - A partial `ContextConfig` object containing settings to update.
|
|
24
|
+
* @returns A shallow copy of the updated configuration.
|
|
11
25
|
*/
|
|
12
26
|
configure(config) {
|
|
13
27
|
this.config = {
|
|
14
28
|
...this.config,
|
|
15
|
-
...config
|
|
29
|
+
...config,
|
|
16
30
|
};
|
|
17
|
-
logger.debug('
|
|
18
|
-
return { ...this.config };
|
|
31
|
+
logger.debug('RequestContextService configuration updated', { newConfig: this.config });
|
|
32
|
+
return { ...this.config }; // Return a copy to prevent direct mutation
|
|
19
33
|
},
|
|
20
34
|
/**
|
|
21
|
-
*
|
|
22
|
-
*
|
|
35
|
+
* Retrieves a shallow copy of the current service configuration.
|
|
36
|
+
*
|
|
37
|
+
* @returns A shallow copy of the current `ContextConfig`.
|
|
23
38
|
*/
|
|
24
39
|
getConfig() {
|
|
25
|
-
return { ...this.config };
|
|
40
|
+
return { ...this.config }; // Return a copy
|
|
26
41
|
},
|
|
27
42
|
/**
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
43
|
+
* Creates a new request context with a unique `requestId` and `timestamp`.
|
|
44
|
+
* Custom properties can be added via `additionalContext`.
|
|
45
|
+
*
|
|
46
|
+
* @param additionalContext - An optional record of key-value pairs to be
|
|
47
|
+
* included in the request context. Defaults to an empty object.
|
|
48
|
+
* @returns A `RequestContext` object.
|
|
31
49
|
*/
|
|
32
50
|
createRequestContext(additionalContext = {}) {
|
|
33
|
-
const requestId = generateUUID();
|
|
51
|
+
const requestId = generateUUID();
|
|
34
52
|
const timestamp = new Date().toISOString();
|
|
35
|
-
|
|
53
|
+
const context = {
|
|
36
54
|
requestId,
|
|
37
55
|
timestamp,
|
|
38
|
-
...additionalContext
|
|
56
|
+
...additionalContext,
|
|
39
57
|
};
|
|
58
|
+
// logger.debug('Request context created', { requestId }); // Optional: log context creation
|
|
59
|
+
return context;
|
|
40
60
|
},
|
|
41
|
-
// generateSecureRandomString function removed as it was unused and redundant
|
|
61
|
+
// generateSecureRandomString function was previously here but removed as it was unused and redundant.
|
|
62
|
+
// Its functionality, if needed for secure random strings, should be sourced from a dedicated crypto/security module.
|
|
42
63
|
};
|
|
43
|
-
|
|
64
|
+
/**
|
|
65
|
+
* Primary export for request context functionalities.
|
|
66
|
+
* Provides methods to create and manage request contexts.
|
|
67
|
+
*/
|
|
44
68
|
export const requestContextService = requestContextServiceInstance;
|
|
45
|
-
// Removed delegate functions and default export for simplicity.
|
|
46
|
-
// Users should import and use `requestContextService` directly.
|
|
47
|
-
// e.g., import { requestContextService } from './requestContext.js';
|
|
48
|
-
// requestContextService.createRequestContext();
|
|
@@ -31,7 +31,6 @@ export async function countTokens(text, context) {
|
|
|
31
31
|
context: context,
|
|
32
32
|
input: { textSample: text.substring(0, 50) + '...' }, // Log sanitized input
|
|
33
33
|
errorCode: BaseErrorCode.INTERNAL_ERROR, // Use INTERNAL_ERROR for external lib issues
|
|
34
|
-
rethrow: true // Rethrow as McpError
|
|
35
34
|
// Removed onErrorReturn as we now rethrow
|
|
36
35
|
});
|
|
37
36
|
}
|
|
@@ -118,7 +117,6 @@ context) {
|
|
|
118
117
|
context: context,
|
|
119
118
|
input: { messageCount: messages.length }, // Log sanitized input
|
|
120
119
|
errorCode: BaseErrorCode.INTERNAL_ERROR, // Use INTERNAL_ERROR
|
|
121
|
-
rethrow: true // Rethrow as McpError
|
|
122
120
|
// Removed onErrorReturn
|
|
123
121
|
});
|
|
124
122
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mcp-ts-template",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.7",
|
|
4
4
|
"description": "TypeScript template for building Model Context Protocol (MCP) servers & clients. Features production-ready utilities, stdio/HTTP transports (with JWT auth), examples, and type safety. Ideal starting point for creating MCP-based applications.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"files": [
|