@openconductor/mcp-sdk 0.2.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.
@@ -0,0 +1,146 @@
1
+ // src/errors/codes.ts
2
+ var ErrorCodes = {
3
+ // JSON-RPC 2.0 Standard Errors
4
+ PARSE_ERROR: -32700,
5
+ INVALID_REQUEST: -32600,
6
+ METHOD_NOT_FOUND: -32601,
7
+ INVALID_PARAMS: -32602,
8
+ INTERNAL_ERROR: -32603,
9
+ // MCP-Specific Errors (-32000 to -32099 reserved for implementation)
10
+ TOOL_NOT_FOUND: -32001,
11
+ TOOL_EXECUTION_ERROR: -32002,
12
+ RESOURCE_NOT_FOUND: -32003,
13
+ AUTHENTICATION_ERROR: -32004,
14
+ AUTHORIZATION_ERROR: -32005,
15
+ RATE_LIMIT_ERROR: -32006,
16
+ TIMEOUT_ERROR: -32007,
17
+ VALIDATION_ERROR: -32008,
18
+ DEPENDENCY_ERROR: -32009,
19
+ CONFIGURATION_ERROR: -32010
20
+ };
21
+
22
+ // src/errors/index.ts
23
+ var MCPError = class extends Error {
24
+ code;
25
+ data;
26
+ constructor(code, message, data) {
27
+ super(message);
28
+ this.name = "MCPError";
29
+ this.code = code;
30
+ this.data = data;
31
+ if (Error.captureStackTrace) {
32
+ Error.captureStackTrace(this, this.constructor);
33
+ }
34
+ }
35
+ /**
36
+ * Returns JSON-RPC 2.0 formatted error object
37
+ */
38
+ toJSON() {
39
+ return {
40
+ code: this.code,
41
+ message: this.message,
42
+ ...this.data && { data: this.data }
43
+ };
44
+ }
45
+ /**
46
+ * Create error response for JSON-RPC
47
+ */
48
+ toResponse(id = null) {
49
+ return {
50
+ jsonrpc: "2.0",
51
+ id,
52
+ error: this.toJSON()
53
+ };
54
+ }
55
+ };
56
+ var ValidationError = class extends MCPError {
57
+ constructor(field, reason, value) {
58
+ super(ErrorCodes.INVALID_PARAMS, `Validation failed for '${field}': ${reason}`, {
59
+ field,
60
+ reason,
61
+ ...value !== void 0 && { value }
62
+ });
63
+ this.name = "ValidationError";
64
+ }
65
+ };
66
+ var ToolNotFoundError = class extends MCPError {
67
+ constructor(toolName) {
68
+ super(ErrorCodes.TOOL_NOT_FOUND, `Tool '${toolName}' not found`, {
69
+ tool: toolName
70
+ });
71
+ this.name = "ToolNotFoundError";
72
+ }
73
+ };
74
+ var ToolExecutionError = class extends MCPError {
75
+ constructor(toolName, reason, cause) {
76
+ super(ErrorCodes.TOOL_EXECUTION_ERROR, `Tool '${toolName}' failed: ${reason}`, {
77
+ tool: toolName,
78
+ reason,
79
+ ...cause && { cause: cause.message }
80
+ });
81
+ this.name = "ToolExecutionError";
82
+ }
83
+ };
84
+ var ResourceNotFoundError = class extends MCPError {
85
+ constructor(resourceUri) {
86
+ super(ErrorCodes.RESOURCE_NOT_FOUND, `Resource '${resourceUri}' not found`, {
87
+ uri: resourceUri
88
+ });
89
+ this.name = "ResourceNotFoundError";
90
+ }
91
+ };
92
+ var AuthenticationError = class extends MCPError {
93
+ constructor(reason = "Authentication required") {
94
+ super(ErrorCodes.AUTHENTICATION_ERROR, reason);
95
+ this.name = "AuthenticationError";
96
+ }
97
+ };
98
+ var AuthorizationError = class extends MCPError {
99
+ constructor(action, resource) {
100
+ const msg = resource ? `Not authorized to ${action} on '${resource}'` : `Not authorized to ${action}`;
101
+ super(ErrorCodes.AUTHORIZATION_ERROR, msg, {
102
+ action,
103
+ ...resource && { resource }
104
+ });
105
+ this.name = "AuthorizationError";
106
+ }
107
+ };
108
+ var RateLimitError = class extends MCPError {
109
+ constructor(retryAfterMs) {
110
+ super(ErrorCodes.RATE_LIMIT_ERROR, "Rate limit exceeded", {
111
+ ...retryAfterMs && { retryAfterMs }
112
+ });
113
+ this.name = "RateLimitError";
114
+ }
115
+ };
116
+ var TimeoutError = class extends MCPError {
117
+ constructor(operation, timeoutMs) {
118
+ super(ErrorCodes.TIMEOUT_ERROR, `Operation '${operation}' timed out after ${timeoutMs}ms`, {
119
+ operation,
120
+ timeoutMs
121
+ });
122
+ this.name = "TimeoutError";
123
+ }
124
+ };
125
+ var DependencyError = class extends MCPError {
126
+ constructor(dependency, reason) {
127
+ super(ErrorCodes.DEPENDENCY_ERROR, `Dependency '${dependency}' unavailable: ${reason}`, {
128
+ dependency,
129
+ reason
130
+ });
131
+ this.name = "DependencyError";
132
+ }
133
+ };
134
+ var ConfigurationError = class extends MCPError {
135
+ constructor(setting, reason) {
136
+ super(ErrorCodes.CONFIGURATION_ERROR, `Invalid configuration '${setting}': ${reason}`, {
137
+ setting,
138
+ reason
139
+ });
140
+ this.name = "ConfigurationError";
141
+ }
142
+ };
143
+
144
+ export { AuthenticationError, AuthorizationError, ConfigurationError, DependencyError, ErrorCodes, MCPError, RateLimitError, ResourceNotFoundError, TimeoutError, ToolExecutionError, ToolNotFoundError, ValidationError };
145
+ //# sourceMappingURL=index.mjs.map
146
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/errors/codes.ts","../../src/errors/index.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * JSON-RPC 2.0 Standard Error Codes\n * https://www.jsonrpc.org/specification#error_object\n */\nexport const ErrorCodes = {\n // JSON-RPC 2.0 Standard Errors\n PARSE_ERROR: -32700,\n INVALID_REQUEST: -32600,\n METHOD_NOT_FOUND: -32601,\n INVALID_PARAMS: -32602,\n INTERNAL_ERROR: -32603,\n\n // MCP-Specific Errors (-32000 to -32099 reserved for implementation)\n TOOL_NOT_FOUND: -32001,\n TOOL_EXECUTION_ERROR: -32002,\n RESOURCE_NOT_FOUND: -32003,\n AUTHENTICATION_ERROR: -32004,\n AUTHORIZATION_ERROR: -32005,\n RATE_LIMIT_ERROR: -32006,\n TIMEOUT_ERROR: -32007,\n VALIDATION_ERROR: -32008,\n DEPENDENCY_ERROR: -32009,\n CONFIGURATION_ERROR: -32010,\n} as const\n\nexport type ErrorCode = (typeof ErrorCodes)[keyof typeof ErrorCodes]\n","import { ErrorCodes, type ErrorCode } from './codes'\n\nexport { ErrorCodes, type ErrorCode } from './codes'\n\n/**\n * Base error class for MCP servers\n * Formats errors according to JSON-RPC 2.0 specification\n */\nexport class MCPError extends Error {\n public readonly code: ErrorCode\n public readonly data?: Record<string, unknown>\n\n constructor(\n code: ErrorCode,\n message: string,\n data?: Record<string, unknown>\n ) {\n super(message)\n this.name = 'MCPError'\n this.code = code\n this.data = data\n\n // Maintains proper stack trace in V8 environments\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor)\n }\n }\n\n /**\n * Returns JSON-RPC 2.0 formatted error object\n */\n toJSON() {\n return {\n code: this.code,\n message: this.message,\n ...(this.data && { data: this.data }),\n }\n }\n\n /**\n * Create error response for JSON-RPC\n */\n toResponse(id: string | number | null = null) {\n return {\n jsonrpc: '2.0' as const,\n id,\n error: this.toJSON(),\n }\n }\n}\n\n/**\n * Thrown when tool input validation fails\n */\nexport class ValidationError extends MCPError {\n constructor(field: string, reason: string, value?: unknown) {\n super(ErrorCodes.INVALID_PARAMS, `Validation failed for '${field}': ${reason}`, {\n field,\n reason,\n ...(value !== undefined && { value }),\n })\n this.name = 'ValidationError'\n }\n}\n\n/**\n * Thrown when a requested tool doesn't exist\n */\nexport class ToolNotFoundError extends MCPError {\n constructor(toolName: string) {\n super(ErrorCodes.TOOL_NOT_FOUND, `Tool '${toolName}' not found`, {\n tool: toolName,\n })\n this.name = 'ToolNotFoundError'\n }\n}\n\n/**\n * Thrown when tool execution fails\n */\nexport class ToolExecutionError extends MCPError {\n constructor(toolName: string, reason: string, cause?: Error) {\n super(ErrorCodes.TOOL_EXECUTION_ERROR, `Tool '${toolName}' failed: ${reason}`, {\n tool: toolName,\n reason,\n ...(cause && { cause: cause.message }),\n })\n this.name = 'ToolExecutionError'\n }\n}\n\n/**\n * Thrown when a requested resource doesn't exist\n */\nexport class ResourceNotFoundError extends MCPError {\n constructor(resourceUri: string) {\n super(ErrorCodes.RESOURCE_NOT_FOUND, `Resource '${resourceUri}' not found`, {\n uri: resourceUri,\n })\n this.name = 'ResourceNotFoundError'\n }\n}\n\n/**\n * Thrown when authentication fails\n */\nexport class AuthenticationError extends MCPError {\n constructor(reason: string = 'Authentication required') {\n super(ErrorCodes.AUTHENTICATION_ERROR, reason)\n this.name = 'AuthenticationError'\n }\n}\n\n/**\n * Thrown when authorization fails (authenticated but not permitted)\n */\nexport class AuthorizationError extends MCPError {\n constructor(action: string, resource?: string) {\n const msg = resource\n ? `Not authorized to ${action} on '${resource}'`\n : `Not authorized to ${action}`\n super(ErrorCodes.AUTHORIZATION_ERROR, msg, {\n action,\n ...(resource && { resource }),\n })\n this.name = 'AuthorizationError'\n }\n}\n\n/**\n * Thrown when rate limits are exceeded\n */\nexport class RateLimitError extends MCPError {\n constructor(retryAfterMs?: number) {\n super(ErrorCodes.RATE_LIMIT_ERROR, 'Rate limit exceeded', {\n ...(retryAfterMs && { retryAfterMs }),\n })\n this.name = 'RateLimitError'\n }\n}\n\n/**\n * Thrown when an operation times out\n */\nexport class TimeoutError extends MCPError {\n constructor(operation: string, timeoutMs: number) {\n super(ErrorCodes.TIMEOUT_ERROR, `Operation '${operation}' timed out after ${timeoutMs}ms`, {\n operation,\n timeoutMs,\n })\n this.name = 'TimeoutError'\n }\n}\n\n/**\n * Thrown when a required dependency is unavailable\n */\nexport class DependencyError extends MCPError {\n constructor(dependency: string, reason: string) {\n super(ErrorCodes.DEPENDENCY_ERROR, `Dependency '${dependency}' unavailable: ${reason}`, {\n dependency,\n reason,\n })\n this.name = 'DependencyError'\n }\n}\n\n/**\n * Thrown when server configuration is invalid\n */\nexport class ConfigurationError extends MCPError {\n constructor(setting: string, reason: string) {\n super(ErrorCodes.CONFIGURATION_ERROR, `Invalid configuration '${setting}': ${reason}`, {\n setting,\n reason,\n })\n this.name = 'ConfigurationError'\n }\n}\n"]}
@@ -0,0 +1,6 @@
1
+ export { AuthenticationError, AuthorizationError, ConfigurationError, DependencyError, ErrorCode, ErrorCodes, MCPError, RateLimitError, ResourceNotFoundError, TimeoutError, ToolExecutionError, ToolNotFoundError, ValidationError } from './errors/index.mjs';
2
+ export { Infer, ValidateOptions, schemas, validate, validateInput } from './validate/index.mjs';
3
+ export { LogEntry, LogLevel, Logger, LoggerOptions, createLogger } from './logger/index.mjs';
4
+ export { HealthCheckInfo, HealthCheckResponse, ToolContext, WrapToolOptions, createHealthCheck, wrapTool } from './server/index.mjs';
5
+ export { Telemetry, TelemetryBatch, TelemetryConfig, ToolMetric, getTelemetry, initTelemetry } from './telemetry/index.mjs';
6
+ export { ZodError, ZodSchema, z } from 'zod';
@@ -0,0 +1,6 @@
1
+ export { AuthenticationError, AuthorizationError, ConfigurationError, DependencyError, ErrorCode, ErrorCodes, MCPError, RateLimitError, ResourceNotFoundError, TimeoutError, ToolExecutionError, ToolNotFoundError, ValidationError } from './errors/index.js';
2
+ export { Infer, ValidateOptions, schemas, validate, validateInput } from './validate/index.js';
3
+ export { LogEntry, LogLevel, Logger, LoggerOptions, createLogger } from './logger/index.js';
4
+ export { HealthCheckInfo, HealthCheckResponse, ToolContext, WrapToolOptions, createHealthCheck, wrapTool } from './server/index.js';
5
+ export { Telemetry, TelemetryBatch, TelemetryConfig, ToolMetric, getTelemetry, initTelemetry } from './telemetry/index.js';
6
+ export { ZodError, ZodSchema, z } from 'zod';
package/dist/index.js ADDED
@@ -0,0 +1,524 @@
1
+ 'use strict';
2
+
3
+ var zod = require('zod');
4
+
5
+ // src/errors/codes.ts
6
+ var ErrorCodes = {
7
+ // JSON-RPC 2.0 Standard Errors
8
+ PARSE_ERROR: -32700,
9
+ INVALID_REQUEST: -32600,
10
+ METHOD_NOT_FOUND: -32601,
11
+ INVALID_PARAMS: -32602,
12
+ INTERNAL_ERROR: -32603,
13
+ // MCP-Specific Errors (-32000 to -32099 reserved for implementation)
14
+ TOOL_NOT_FOUND: -32001,
15
+ TOOL_EXECUTION_ERROR: -32002,
16
+ RESOURCE_NOT_FOUND: -32003,
17
+ AUTHENTICATION_ERROR: -32004,
18
+ AUTHORIZATION_ERROR: -32005,
19
+ RATE_LIMIT_ERROR: -32006,
20
+ TIMEOUT_ERROR: -32007,
21
+ VALIDATION_ERROR: -32008,
22
+ DEPENDENCY_ERROR: -32009,
23
+ CONFIGURATION_ERROR: -32010
24
+ };
25
+
26
+ // src/errors/index.ts
27
+ var MCPError = class extends Error {
28
+ code;
29
+ data;
30
+ constructor(code, message, data) {
31
+ super(message);
32
+ this.name = "MCPError";
33
+ this.code = code;
34
+ this.data = data;
35
+ if (Error.captureStackTrace) {
36
+ Error.captureStackTrace(this, this.constructor);
37
+ }
38
+ }
39
+ /**
40
+ * Returns JSON-RPC 2.0 formatted error object
41
+ */
42
+ toJSON() {
43
+ return {
44
+ code: this.code,
45
+ message: this.message,
46
+ ...this.data && { data: this.data }
47
+ };
48
+ }
49
+ /**
50
+ * Create error response for JSON-RPC
51
+ */
52
+ toResponse(id = null) {
53
+ return {
54
+ jsonrpc: "2.0",
55
+ id,
56
+ error: this.toJSON()
57
+ };
58
+ }
59
+ };
60
+ var ValidationError = class extends MCPError {
61
+ constructor(field, reason, value) {
62
+ super(ErrorCodes.INVALID_PARAMS, `Validation failed for '${field}': ${reason}`, {
63
+ field,
64
+ reason,
65
+ ...value !== void 0 && { value }
66
+ });
67
+ this.name = "ValidationError";
68
+ }
69
+ };
70
+ var ToolNotFoundError = class extends MCPError {
71
+ constructor(toolName) {
72
+ super(ErrorCodes.TOOL_NOT_FOUND, `Tool '${toolName}' not found`, {
73
+ tool: toolName
74
+ });
75
+ this.name = "ToolNotFoundError";
76
+ }
77
+ };
78
+ var ToolExecutionError = class extends MCPError {
79
+ constructor(toolName, reason, cause) {
80
+ super(ErrorCodes.TOOL_EXECUTION_ERROR, `Tool '${toolName}' failed: ${reason}`, {
81
+ tool: toolName,
82
+ reason,
83
+ ...cause && { cause: cause.message }
84
+ });
85
+ this.name = "ToolExecutionError";
86
+ }
87
+ };
88
+ var ResourceNotFoundError = class extends MCPError {
89
+ constructor(resourceUri) {
90
+ super(ErrorCodes.RESOURCE_NOT_FOUND, `Resource '${resourceUri}' not found`, {
91
+ uri: resourceUri
92
+ });
93
+ this.name = "ResourceNotFoundError";
94
+ }
95
+ };
96
+ var AuthenticationError = class extends MCPError {
97
+ constructor(reason = "Authentication required") {
98
+ super(ErrorCodes.AUTHENTICATION_ERROR, reason);
99
+ this.name = "AuthenticationError";
100
+ }
101
+ };
102
+ var AuthorizationError = class extends MCPError {
103
+ constructor(action, resource) {
104
+ const msg = resource ? `Not authorized to ${action} on '${resource}'` : `Not authorized to ${action}`;
105
+ super(ErrorCodes.AUTHORIZATION_ERROR, msg, {
106
+ action,
107
+ ...resource && { resource }
108
+ });
109
+ this.name = "AuthorizationError";
110
+ }
111
+ };
112
+ var RateLimitError = class extends MCPError {
113
+ constructor(retryAfterMs) {
114
+ super(ErrorCodes.RATE_LIMIT_ERROR, "Rate limit exceeded", {
115
+ ...retryAfterMs && { retryAfterMs }
116
+ });
117
+ this.name = "RateLimitError";
118
+ }
119
+ };
120
+ var TimeoutError = class extends MCPError {
121
+ constructor(operation, timeoutMs) {
122
+ super(ErrorCodes.TIMEOUT_ERROR, `Operation '${operation}' timed out after ${timeoutMs}ms`, {
123
+ operation,
124
+ timeoutMs
125
+ });
126
+ this.name = "TimeoutError";
127
+ }
128
+ };
129
+ var DependencyError = class extends MCPError {
130
+ constructor(dependency, reason) {
131
+ super(ErrorCodes.DEPENDENCY_ERROR, `Dependency '${dependency}' unavailable: ${reason}`, {
132
+ dependency,
133
+ reason
134
+ });
135
+ this.name = "DependencyError";
136
+ }
137
+ };
138
+ var ConfigurationError = class extends MCPError {
139
+ constructor(setting, reason) {
140
+ super(ErrorCodes.CONFIGURATION_ERROR, `Invalid configuration '${setting}': ${reason}`, {
141
+ setting,
142
+ reason
143
+ });
144
+ this.name = "ConfigurationError";
145
+ }
146
+ };
147
+ function validate(schema, input, options = {}) {
148
+ const { stripUnknown = true } = options;
149
+ const result = stripUnknown ? schema.safeParse(input) : schema instanceof zod.z.ZodObject ? schema.strict().safeParse(input) : schema.safeParse(input);
150
+ if (!result.success) {
151
+ const firstError = result.error.errors[0];
152
+ const field = firstError.path.join(".") || "input";
153
+ const reason = firstError.message;
154
+ throw new ValidationError(
155
+ field,
156
+ reason,
157
+ firstError.path.length > 0 ? getNestedValue(input, firstError.path) : input
158
+ );
159
+ }
160
+ return result.data;
161
+ }
162
+ function validateInput(schema, handler, options = {}) {
163
+ return async (input) => {
164
+ const validated = validate(schema, input, options);
165
+ return handler(validated);
166
+ };
167
+ }
168
+ function getNestedValue(obj, path) {
169
+ let current = obj;
170
+ for (const key of path) {
171
+ if (current === null || current === void 0) return void 0;
172
+ current = current[key];
173
+ }
174
+ return current;
175
+ }
176
+ var schemas = {
177
+ /** Non-empty string */
178
+ nonEmptyString: zod.z.string().min(1, "Cannot be empty"),
179
+ /** Positive integer */
180
+ positiveInt: zod.z.number().int().positive(),
181
+ /** Pagination limit (1-100, default 10) */
182
+ limit: zod.z.number().int().min(1).max(100).default(10),
183
+ /** Pagination offset (>= 0, default 0) */
184
+ offset: zod.z.number().int().min(0).default(0),
185
+ /** URL string */
186
+ url: zod.z.string().url(),
187
+ /** Email string */
188
+ email: zod.z.string().email(),
189
+ /** UUID string */
190
+ uuid: zod.z.string().uuid(),
191
+ /** ISO date string */
192
+ isoDate: zod.z.string().datetime(),
193
+ /** Boolean with string coercion ('true'/'false' -> boolean) */
194
+ booleanish: zod.z.union([
195
+ zod.z.boolean(),
196
+ zod.z.enum(["true", "false"]).transform((v) => v === "true")
197
+ ])
198
+ };
199
+
200
+ // src/logger/index.ts
201
+ var LEVEL_PRIORITY = {
202
+ debug: 0,
203
+ info: 1,
204
+ warn: 2,
205
+ error: 3
206
+ };
207
+ function createLogger(service, options = {}) {
208
+ const {
209
+ level: minLevel = "info",
210
+ timestamps = true,
211
+ pretty = false
212
+ } = options;
213
+ const shouldLog = (level) => {
214
+ return LEVEL_PRIORITY[level] >= LEVEL_PRIORITY[minLevel];
215
+ };
216
+ const formatEntry = (entry) => {
217
+ return pretty ? JSON.stringify(entry, null, 2) : JSON.stringify(entry);
218
+ };
219
+ const log = (level, message, data) => {
220
+ if (!shouldLog(level)) return;
221
+ const entry = {
222
+ ...timestamps && { timestamp: (/* @__PURE__ */ new Date()).toISOString() },
223
+ level,
224
+ service,
225
+ message,
226
+ ...data
227
+ };
228
+ if (options.output) {
229
+ options.output(entry);
230
+ } else {
231
+ const formatted = formatEntry(entry);
232
+ switch (level) {
233
+ case "debug":
234
+ console.debug(formatted);
235
+ break;
236
+ case "info":
237
+ console.info(formatted);
238
+ break;
239
+ case "warn":
240
+ console.warn(formatted);
241
+ break;
242
+ case "error":
243
+ console.error(formatted);
244
+ break;
245
+ }
246
+ }
247
+ return entry;
248
+ };
249
+ return {
250
+ debug: (message, data) => log("debug", message, data),
251
+ info: (message, data) => log("info", message, data),
252
+ warn: (message, data) => log("warn", message, data),
253
+ error: (message, data) => log("error", message, data),
254
+ /**
255
+ * Create a child logger with additional context
256
+ */
257
+ child: (context) => {
258
+ return createLogger(service, {
259
+ ...options,
260
+ output: (entry) => {
261
+ const merged = { ...entry, ...context };
262
+ if (options.output) {
263
+ options.output(merged);
264
+ } else {
265
+ const formatted = pretty ? JSON.stringify(merged, null, 2) : JSON.stringify(merged);
266
+ console[entry.level](formatted);
267
+ }
268
+ }
269
+ });
270
+ }
271
+ };
272
+ }
273
+
274
+ // src/telemetry/index.ts
275
+ var SDK_VERSION = "0.2.0";
276
+ var DEFAULT_ENDPOINT = "https://api.openconductor.ai/functions/v1/telemetry";
277
+ var globalTelemetry = null;
278
+ function initTelemetry(config) {
279
+ globalTelemetry = new Telemetry(config);
280
+ return globalTelemetry;
281
+ }
282
+ function getTelemetry() {
283
+ return globalTelemetry;
284
+ }
285
+ var Telemetry = class {
286
+ config;
287
+ buffer = [];
288
+ flushTimer = null;
289
+ constructor(config) {
290
+ this.config = {
291
+ apiKey: config.apiKey,
292
+ serverName: config.serverName,
293
+ serverVersion: config.serverVersion,
294
+ endpoint: config.endpoint ?? DEFAULT_ENDPOINT,
295
+ batchSize: config.batchSize ?? 10,
296
+ flushInterval: config.flushInterval ?? 3e4,
297
+ debug: config.debug ?? false
298
+ };
299
+ this.flushTimer = setInterval(() => {
300
+ this.flush().catch(this.handleError.bind(this));
301
+ }, this.config.flushInterval);
302
+ if (typeof process !== "undefined") {
303
+ process.on("beforeExit", () => this.flush());
304
+ process.on("SIGINT", () => {
305
+ this.flush().finally(() => process.exit(0));
306
+ });
307
+ process.on("SIGTERM", () => {
308
+ this.flush().finally(() => process.exit(0));
309
+ });
310
+ }
311
+ this.log("Telemetry initialized", { serverName: config.serverName });
312
+ }
313
+ /**
314
+ * Track a tool invocation
315
+ */
316
+ trackToolCall(tool, duration, success, error) {
317
+ const metric = {
318
+ tool,
319
+ duration,
320
+ success,
321
+ ...error && { error },
322
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
323
+ };
324
+ this.buffer.push(metric);
325
+ this.log("Metric tracked", { ...metric });
326
+ if (this.buffer.length >= this.config.batchSize) {
327
+ this.flush().catch(this.handleError.bind(this));
328
+ }
329
+ }
330
+ /**
331
+ * Flush buffered metrics to OpenConductor
332
+ */
333
+ async flush() {
334
+ if (this.buffer.length === 0) return;
335
+ const metrics = [...this.buffer];
336
+ this.buffer = [];
337
+ const batch = {
338
+ serverName: this.config.serverName,
339
+ serverVersion: this.config.serverVersion,
340
+ metrics,
341
+ meta: {
342
+ sdkVersion: SDK_VERSION,
343
+ nodeVersion: typeof process !== "undefined" ? process.version : "unknown",
344
+ platform: typeof process !== "undefined" ? process.platform : "unknown"
345
+ }
346
+ };
347
+ this.log("Flushing metrics", { count: metrics.length });
348
+ try {
349
+ const response = await fetch(this.config.endpoint, {
350
+ method: "POST",
351
+ headers: {
352
+ "Content-Type": "application/json",
353
+ "Authorization": `Bearer ${this.config.apiKey}`,
354
+ "X-OpenConductor-SDK": SDK_VERSION
355
+ },
356
+ body: JSON.stringify(batch)
357
+ });
358
+ if (!response.ok) {
359
+ throw new Error(`Telemetry flush failed: ${response.status} ${response.statusText}`);
360
+ }
361
+ this.log("Metrics flushed successfully", { count: metrics.length });
362
+ } catch (error) {
363
+ this.buffer.unshift(...metrics);
364
+ throw error;
365
+ }
366
+ }
367
+ /**
368
+ * Stop telemetry collection
369
+ */
370
+ shutdown() {
371
+ if (this.flushTimer) {
372
+ clearInterval(this.flushTimer);
373
+ this.flushTimer = null;
374
+ }
375
+ this.flush().catch(this.handleError.bind(this));
376
+ this.log("Telemetry shutdown");
377
+ }
378
+ log(message, data) {
379
+ if (this.config.debug) {
380
+ console.debug(JSON.stringify({
381
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
382
+ level: "debug",
383
+ service: "openconductor-telemetry",
384
+ message,
385
+ ...data
386
+ }));
387
+ }
388
+ }
389
+ handleError(error) {
390
+ if (this.config.debug) {
391
+ console.error("[OpenConductor Telemetry Error]", error);
392
+ }
393
+ }
394
+ };
395
+
396
+ // src/server/index.ts
397
+ function createHealthCheck(info) {
398
+ return async () => {
399
+ const checks = {};
400
+ let allHealthy = true;
401
+ if (info.checks) {
402
+ for (const [name, check] of Object.entries(info.checks)) {
403
+ try {
404
+ checks[name] = await check();
405
+ if (!checks[name]) allHealthy = false;
406
+ } catch {
407
+ checks[name] = false;
408
+ allHealthy = false;
409
+ }
410
+ }
411
+ }
412
+ return {
413
+ status: allHealthy ? "healthy" : "degraded",
414
+ name: info.name,
415
+ version: info.version,
416
+ ...info.description && { description: info.description },
417
+ ...info.uptime && { uptime: info.uptime() },
418
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
419
+ ...Object.keys(checks).length > 0 && { checks }
420
+ };
421
+ };
422
+ }
423
+ function wrapTool(handler, options) {
424
+ const {
425
+ name,
426
+ timeout = 3e4,
427
+ telemetry: enableTelemetry = true
428
+ } = options;
429
+ const baseLogger = options.logger ?? createLogger(name);
430
+ return async (input) => {
431
+ const callId = generateCallId();
432
+ const startTime = Date.now();
433
+ const log = baseLogger.child({ callId });
434
+ const ctx = { callId, name, startTime, log };
435
+ log.info("Tool invoked", { tool: name, input: sanitizeInput(input) });
436
+ try {
437
+ const timeoutPromise = new Promise((_, reject) => {
438
+ setTimeout(() => {
439
+ reject(new TimeoutError(name, timeout));
440
+ }, timeout);
441
+ });
442
+ const result = await Promise.race([
443
+ Promise.resolve(handler(input, ctx)),
444
+ timeoutPromise
445
+ ]);
446
+ const duration = Date.now() - startTime;
447
+ log.info("Tool completed", { tool: name, duration });
448
+ if (enableTelemetry) {
449
+ const tel = getTelemetry();
450
+ tel?.trackToolCall(name, duration, true);
451
+ }
452
+ return result;
453
+ } catch (error) {
454
+ const duration = Date.now() - startTime;
455
+ const errorMessage = error instanceof Error ? error.message : String(error);
456
+ log.error("Tool failed", {
457
+ tool: name,
458
+ duration,
459
+ error: errorMessage,
460
+ stack: error instanceof Error ? error.stack : void 0
461
+ });
462
+ if (enableTelemetry) {
463
+ const tel = getTelemetry();
464
+ tel?.trackToolCall(name, duration, false, errorMessage);
465
+ }
466
+ if (error instanceof MCPError) {
467
+ throw error;
468
+ }
469
+ throw new ToolExecutionError(
470
+ name,
471
+ errorMessage,
472
+ error instanceof Error ? error : void 0
473
+ );
474
+ }
475
+ };
476
+ }
477
+ function generateCallId() {
478
+ return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
479
+ }
480
+ function sanitizeInput(input) {
481
+ if (typeof input !== "object" || input === null) return input;
482
+ const sensitiveKeys = ["password", "token", "secret", "key", "auth", "credential"];
483
+ const sanitized = {};
484
+ for (const [key, value] of Object.entries(input)) {
485
+ if (sensitiveKeys.some((k) => key.toLowerCase().includes(k))) {
486
+ sanitized[key] = "[REDACTED]";
487
+ } else {
488
+ sanitized[key] = value;
489
+ }
490
+ }
491
+ return sanitized;
492
+ }
493
+
494
+ Object.defineProperty(exports, "ZodError", {
495
+ enumerable: true,
496
+ get: function () { return zod.ZodError; }
497
+ });
498
+ Object.defineProperty(exports, "z", {
499
+ enumerable: true,
500
+ get: function () { return zod.z; }
501
+ });
502
+ exports.AuthenticationError = AuthenticationError;
503
+ exports.AuthorizationError = AuthorizationError;
504
+ exports.ConfigurationError = ConfigurationError;
505
+ exports.DependencyError = DependencyError;
506
+ exports.ErrorCodes = ErrorCodes;
507
+ exports.MCPError = MCPError;
508
+ exports.RateLimitError = RateLimitError;
509
+ exports.ResourceNotFoundError = ResourceNotFoundError;
510
+ exports.Telemetry = Telemetry;
511
+ exports.TimeoutError = TimeoutError;
512
+ exports.ToolExecutionError = ToolExecutionError;
513
+ exports.ToolNotFoundError = ToolNotFoundError;
514
+ exports.ValidationError = ValidationError;
515
+ exports.createHealthCheck = createHealthCheck;
516
+ exports.createLogger = createLogger;
517
+ exports.getTelemetry = getTelemetry;
518
+ exports.initTelemetry = initTelemetry;
519
+ exports.schemas = schemas;
520
+ exports.validate = validate;
521
+ exports.validateInput = validateInput;
522
+ exports.wrapTool = wrapTool;
523
+ //# sourceMappingURL=index.js.map
524
+ //# sourceMappingURL=index.js.map