@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.
- package/LICENSE +21 -0
- package/README.md +229 -0
- package/dist/errors/index.d.mts +114 -0
- package/dist/errors/index.d.ts +114 -0
- package/dist/errors/index.js +159 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/errors/index.mjs +146 -0
- package/dist/errors/index.mjs.map +1 -0
- package/dist/index.d.mts +6 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +524 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +495 -0
- package/dist/index.mjs.map +1 -0
- package/dist/logger/index.d.mts +34 -0
- package/dist/logger/index.d.ts +34 -0
- package/dist/logger/index.js +79 -0
- package/dist/logger/index.js.map +1 -0
- package/dist/logger/index.mjs +77 -0
- package/dist/logger/index.mjs.map +1 -0
- package/dist/server/index.d.mts +48 -0
- package/dist/server/index.d.ts +48 -0
- package/dist/server/index.js +239 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/index.mjs +236 -0
- package/dist/server/index.mjs.map +1 -0
- package/dist/telemetry/index.d.mts +64 -0
- package/dist/telemetry/index.d.ts +64 -0
- package/dist/telemetry/index.js +129 -0
- package/dist/telemetry/index.js.map +1 -0
- package/dist/telemetry/index.mjs +125 -0
- package/dist/telemetry/index.mjs.map +1 -0
- package/dist/validate/index.d.mts +51 -0
- package/dist/validate/index.d.ts +51 -0
- package/dist/validate/index.js +122 -0
- package/dist/validate/index.js.map +1 -0
- package/dist/validate/index.mjs +111 -0
- package/dist/validate/index.mjs.map +1 -0
- package/package.json +85 -0
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
// src/telemetry/index.ts
|
|
2
|
+
var SDK_VERSION = "0.2.0";
|
|
3
|
+
var DEFAULT_ENDPOINT = "https://api.openconductor.ai/functions/v1/telemetry";
|
|
4
|
+
var globalTelemetry = null;
|
|
5
|
+
function initTelemetry(config) {
|
|
6
|
+
globalTelemetry = new Telemetry(config);
|
|
7
|
+
return globalTelemetry;
|
|
8
|
+
}
|
|
9
|
+
function getTelemetry() {
|
|
10
|
+
return globalTelemetry;
|
|
11
|
+
}
|
|
12
|
+
var Telemetry = class {
|
|
13
|
+
config;
|
|
14
|
+
buffer = [];
|
|
15
|
+
flushTimer = null;
|
|
16
|
+
constructor(config) {
|
|
17
|
+
this.config = {
|
|
18
|
+
apiKey: config.apiKey,
|
|
19
|
+
serverName: config.serverName,
|
|
20
|
+
serverVersion: config.serverVersion,
|
|
21
|
+
endpoint: config.endpoint ?? DEFAULT_ENDPOINT,
|
|
22
|
+
batchSize: config.batchSize ?? 10,
|
|
23
|
+
flushInterval: config.flushInterval ?? 3e4,
|
|
24
|
+
debug: config.debug ?? false
|
|
25
|
+
};
|
|
26
|
+
this.flushTimer = setInterval(() => {
|
|
27
|
+
this.flush().catch(this.handleError.bind(this));
|
|
28
|
+
}, this.config.flushInterval);
|
|
29
|
+
if (typeof process !== "undefined") {
|
|
30
|
+
process.on("beforeExit", () => this.flush());
|
|
31
|
+
process.on("SIGINT", () => {
|
|
32
|
+
this.flush().finally(() => process.exit(0));
|
|
33
|
+
});
|
|
34
|
+
process.on("SIGTERM", () => {
|
|
35
|
+
this.flush().finally(() => process.exit(0));
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
this.log("Telemetry initialized", { serverName: config.serverName });
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Track a tool invocation
|
|
42
|
+
*/
|
|
43
|
+
trackToolCall(tool, duration, success, error) {
|
|
44
|
+
const metric = {
|
|
45
|
+
tool,
|
|
46
|
+
duration,
|
|
47
|
+
success,
|
|
48
|
+
...error && { error },
|
|
49
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
50
|
+
};
|
|
51
|
+
this.buffer.push(metric);
|
|
52
|
+
this.log("Metric tracked", { ...metric });
|
|
53
|
+
if (this.buffer.length >= this.config.batchSize) {
|
|
54
|
+
this.flush().catch(this.handleError.bind(this));
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Flush buffered metrics to OpenConductor
|
|
59
|
+
*/
|
|
60
|
+
async flush() {
|
|
61
|
+
if (this.buffer.length === 0) return;
|
|
62
|
+
const metrics = [...this.buffer];
|
|
63
|
+
this.buffer = [];
|
|
64
|
+
const batch = {
|
|
65
|
+
serverName: this.config.serverName,
|
|
66
|
+
serverVersion: this.config.serverVersion,
|
|
67
|
+
metrics,
|
|
68
|
+
meta: {
|
|
69
|
+
sdkVersion: SDK_VERSION,
|
|
70
|
+
nodeVersion: typeof process !== "undefined" ? process.version : "unknown",
|
|
71
|
+
platform: typeof process !== "undefined" ? process.platform : "unknown"
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
this.log("Flushing metrics", { count: metrics.length });
|
|
75
|
+
try {
|
|
76
|
+
const response = await fetch(this.config.endpoint, {
|
|
77
|
+
method: "POST",
|
|
78
|
+
headers: {
|
|
79
|
+
"Content-Type": "application/json",
|
|
80
|
+
"Authorization": `Bearer ${this.config.apiKey}`,
|
|
81
|
+
"X-OpenConductor-SDK": SDK_VERSION
|
|
82
|
+
},
|
|
83
|
+
body: JSON.stringify(batch)
|
|
84
|
+
});
|
|
85
|
+
if (!response.ok) {
|
|
86
|
+
throw new Error(`Telemetry flush failed: ${response.status} ${response.statusText}`);
|
|
87
|
+
}
|
|
88
|
+
this.log("Metrics flushed successfully", { count: metrics.length });
|
|
89
|
+
} catch (error) {
|
|
90
|
+
this.buffer.unshift(...metrics);
|
|
91
|
+
throw error;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Stop telemetry collection
|
|
96
|
+
*/
|
|
97
|
+
shutdown() {
|
|
98
|
+
if (this.flushTimer) {
|
|
99
|
+
clearInterval(this.flushTimer);
|
|
100
|
+
this.flushTimer = null;
|
|
101
|
+
}
|
|
102
|
+
this.flush().catch(this.handleError.bind(this));
|
|
103
|
+
this.log("Telemetry shutdown");
|
|
104
|
+
}
|
|
105
|
+
log(message, data) {
|
|
106
|
+
if (this.config.debug) {
|
|
107
|
+
console.debug(JSON.stringify({
|
|
108
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
109
|
+
level: "debug",
|
|
110
|
+
service: "openconductor-telemetry",
|
|
111
|
+
message,
|
|
112
|
+
...data
|
|
113
|
+
}));
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
handleError(error) {
|
|
117
|
+
if (this.config.debug) {
|
|
118
|
+
console.error("[OpenConductor Telemetry Error]", error);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
export { Telemetry, getTelemetry, initTelemetry };
|
|
124
|
+
//# sourceMappingURL=index.mjs.map
|
|
125
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/telemetry/index.ts"],"names":[],"mappings":";AAoCA,IAAM,WAAA,GAAc,OAAA;AACpB,IAAM,gBAAA,GAAmB,qDAAA;AAEzB,IAAI,eAAA,GAAoC,IAAA;AAMjC,SAAS,cAAc,MAAA,EAAoC;AAChE,EAAA,eAAA,GAAkB,IAAI,UAAU,MAAM,CAAA;AACtC,EAAA,OAAO,eAAA;AACT;AAKO,SAAS,YAAA,GAAiC;AAC/C,EAAA,OAAO,eAAA;AACT;AAGO,IAAM,YAAN,MAAgB;AAAA,EACb,MAAA;AAAA,EACA,SAAuB,EAAC;AAAA,EACxB,UAAA,GAAoD,IAAA;AAAA,EAE5D,YAAY,MAAA,EAAyB;AACnC,IAAA,IAAA,CAAK,MAAA,GAAS;AAAA,MACZ,QAAQ,MAAA,CAAO,MAAA;AAAA,MACf,YAAY,MAAA,CAAO,UAAA;AAAA,MACnB,eAAe,MAAA,CAAO,aAAA;AAAA,MACtB,QAAA,EAAU,OAAO,QAAA,IAAY,gBAAA;AAAA,MAC7B,SAAA,EAAW,OAAO,SAAA,IAAa,EAAA;AAAA,MAC/B,aAAA,EAAe,OAAO,aAAA,IAAiB,GAAA;AAAA,MACvC,KAAA,EAAO,OAAO,KAAA,IAAS;AAAA,KACzB;AAGA,IAAA,IAAA,CAAK,UAAA,GAAa,YAAY,MAAM;AAClC,MAAA,IAAA,CAAK,OAAM,CAAE,KAAA,CAAM,KAAK,WAAA,CAAY,IAAA,CAAK,IAAI,CAAC,CAAA;AAAA,IAChD,CAAA,EAAG,IAAA,CAAK,MAAA,CAAO,aAAa,CAAA;AAG5B,IAAA,IAAI,OAAO,YAAY,WAAA,EAAa;AAClC,MAAA,OAAA,CAAQ,EAAA,CAAG,YAAA,EAAc,MAAM,IAAA,CAAK,OAAO,CAAA;AAC3C,MAAA,OAAA,CAAQ,EAAA,CAAG,UAAU,MAAM;AACzB,QAAA,IAAA,CAAK,OAAM,CAAE,OAAA,CAAQ,MAAM,OAAA,CAAQ,IAAA,CAAK,CAAC,CAAC,CAAA;AAAA,MAC5C,CAAC,CAAA;AACD,MAAA,OAAA,CAAQ,EAAA,CAAG,WAAW,MAAM;AAC1B,QAAA,IAAA,CAAK,OAAM,CAAE,OAAA,CAAQ,MAAM,OAAA,CAAQ,IAAA,CAAK,CAAC,CAAC,CAAA;AAAA,MAC5C,CAAC,CAAA;AAAA,IACH;AAEA,IAAA,IAAA,CAAK,IAAI,uBAAA,EAAyB,EAAE,UAAA,EAAY,MAAA,CAAO,YAAY,CAAA;AAAA,EACrE;AAAA;AAAA;AAAA;AAAA,EAKA,aAAA,CACE,IAAA,EACA,QAAA,EACA,OAAA,EACA,KAAA,EACM;AACN,IAAA,MAAM,MAAA,GAAqB;AAAA,MACzB,IAAA;AAAA,MACA,QAAA;AAAA,MACA,OAAA;AAAA,MACA,GAAI,KAAA,IAAS,EAAE,KAAA,EAAM;AAAA,MACrB,SAAA,EAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA;AAAY,KACpC;AAEA,IAAA,IAAA,CAAK,MAAA,CAAO,KAAK,MAAM,CAAA;AACvB,IAAA,IAAA,CAAK,GAAA,CAAI,gBAAA,EAAkB,EAAE,GAAG,QAAQ,CAAA;AAGxC,IAAA,IAAI,IAAA,CAAK,MAAA,CAAO,MAAA,IAAU,IAAA,CAAK,OAAO,SAAA,EAAW;AAC/C,MAAA,IAAA,CAAK,OAAM,CAAE,KAAA,CAAM,KAAK,WAAA,CAAY,IAAA,CAAK,IAAI,CAAC,CAAA;AAAA,IAChD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,KAAA,GAAuB;AAC3B,IAAA,IAAI,IAAA,CAAK,MAAA,CAAO,MAAA,KAAW,CAAA,EAAG;AAE9B,IAAA,MAAM,OAAA,GAAU,CAAC,GAAG,IAAA,CAAK,MAAM,CAAA;AAC/B,IAAA,IAAA,CAAK,SAAS,EAAC;AAEf,IAAA,MAAM,KAAA,GAAwB;AAAA,MAC5B,UAAA,EAAY,KAAK,MAAA,CAAO,UAAA;AAAA,MACxB,aAAA,EAAe,KAAK,MAAA,CAAO,aAAA;AAAA,MAC3B,OAAA;AAAA,MACA,IAAA,EAAM;AAAA,QACJ,UAAA,EAAY,WAAA;AAAA,QACZ,WAAA,EAAa,OAAO,OAAA,KAAY,WAAA,GAAc,QAAQ,OAAA,GAAU,SAAA;AAAA,QAChE,QAAA,EAAU,OAAO,OAAA,KAAY,WAAA,GAAc,QAAQ,QAAA,GAAW;AAAA;AAChE,KACF;AAEA,IAAA,IAAA,CAAK,IAAI,kBAAA,EAAoB,EAAE,KAAA,EAAO,OAAA,CAAQ,QAAQ,CAAA;AAEtD,IAAA,IAAI;AACF,MAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,IAAA,CAAK,OAAO,QAAA,EAAU;AAAA,QACjD,MAAA,EAAQ,MAAA;AAAA,QACR,OAAA,EAAS;AAAA,UACP,cAAA,EAAgB,kBAAA;AAAA,UAChB,eAAA,EAAiB,CAAA,OAAA,EAAU,IAAA,CAAK,MAAA,CAAO,MAAM,CAAA,CAAA;AAAA,UAC7C,qBAAA,EAAuB;AAAA,SACzB;AAAA,QACA,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,KAAK;AAAA,OAC3B,CAAA;AAED,MAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,QAAA,MAAM,IAAI,MAAM,CAAA,wBAAA,EAA2B,QAAA,CAAS,MAAM,CAAA,CAAA,EAAI,QAAA,CAAS,UAAU,CAAA,CAAE,CAAA;AAAA,MACrF;AAEA,MAAA,IAAA,CAAK,IAAI,8BAAA,EAAgC,EAAE,KAAA,EAAO,OAAA,CAAQ,QAAQ,CAAA;AAAA,IACpE,SAAS,KAAA,EAAO;AAEd,MAAA,IAAA,CAAK,MAAA,CAAO,OAAA,CAAQ,GAAG,OAAO,CAAA;AAC9B,MAAA,MAAM,KAAA;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,QAAA,GAAiB;AACf,IAAA,IAAI,KAAK,UAAA,EAAY;AACnB,MAAA,aAAA,CAAc,KAAK,UAAU,CAAA;AAC7B,MAAA,IAAA,CAAK,UAAA,GAAa,IAAA;AAAA,IACpB;AACA,IAAA,IAAA,CAAK,OAAM,CAAE,KAAA,CAAM,KAAK,WAAA,CAAY,IAAA,CAAK,IAAI,CAAC,CAAA;AAC9C,IAAA,IAAA,CAAK,IAAI,oBAAoB,CAAA;AAAA,EAC/B;AAAA,EAEQ,GAAA,CAAI,SAAiB,IAAA,EAAsC;AACjE,IAAA,IAAI,IAAA,CAAK,OAAO,KAAA,EAAO;AACrB,MAAA,OAAA,CAAQ,KAAA,CAAM,KAAK,SAAA,CAAU;AAAA,QAC3B,SAAA,EAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAAA,QAClC,KAAA,EAAO,OAAA;AAAA,QACP,OAAA,EAAS,yBAAA;AAAA,QACT,OAAA;AAAA,QACA,GAAG;AAAA,OACJ,CAAC,CAAA;AAAA,IACJ;AAAA,EACF;AAAA,EAEQ,YAAY,KAAA,EAAsB;AACxC,IAAA,IAAI,IAAA,CAAK,OAAO,KAAA,EAAO;AACrB,MAAA,OAAA,CAAQ,KAAA,CAAM,mCAAmC,KAAK,CAAA;AAAA,IACxD;AAAA,EACF;AACF","file":"index.mjs","sourcesContent":["export interface TelemetryConfig {\n /** Your OpenConductor API key */\n apiKey: string\n /** Server name for identification */\n serverName: string\n /** Server version */\n serverVersion?: string\n /** Custom endpoint (default: OpenConductor production) */\n endpoint?: string\n /** Batch size before flushing (default: 10) */\n batchSize?: number\n /** Flush interval in ms (default: 30000) */\n flushInterval?: number\n /** Enable debug logging (default: false) */\n debug?: boolean\n}\n\nexport interface ToolMetric {\n tool: string\n duration: number\n success: boolean\n error?: string\n timestamp: string\n}\n\nexport interface TelemetryBatch {\n serverName: string\n serverVersion?: string\n metrics: ToolMetric[]\n meta: {\n sdkVersion: string\n nodeVersion: string\n platform: string\n }\n}\n\nconst SDK_VERSION = '0.2.0'\nconst DEFAULT_ENDPOINT = 'https://api.openconductor.ai/functions/v1/telemetry'\n\nlet globalTelemetry: Telemetry | null = null\n\n/**\n * Initialize telemetry for your MCP server\n * Call this once at startup with your OpenConductor API key\n */\nexport function initTelemetry(config: TelemetryConfig): Telemetry {\n globalTelemetry = new Telemetry(config)\n return globalTelemetry\n}\n\n/**\n * Get the global telemetry instance (if initialized)\n */\nexport function getTelemetry(): Telemetry | null {\n return globalTelemetry\n}\n\n\nexport class Telemetry {\n private config: Required<Omit<TelemetryConfig, 'serverVersion'>> & Pick<TelemetryConfig, 'serverVersion'>\n private buffer: ToolMetric[] = []\n private flushTimer: ReturnType<typeof setInterval> | null = null\n\n constructor(config: TelemetryConfig) {\n this.config = {\n apiKey: config.apiKey,\n serverName: config.serverName,\n serverVersion: config.serverVersion,\n endpoint: config.endpoint ?? DEFAULT_ENDPOINT,\n batchSize: config.batchSize ?? 10,\n flushInterval: config.flushInterval ?? 30000,\n debug: config.debug ?? false,\n }\n\n // Start periodic flush\n this.flushTimer = setInterval(() => {\n this.flush().catch(this.handleError.bind(this))\n }, this.config.flushInterval)\n\n // Flush on process exit\n if (typeof process !== 'undefined') {\n process.on('beforeExit', () => this.flush())\n process.on('SIGINT', () => {\n this.flush().finally(() => process.exit(0))\n })\n process.on('SIGTERM', () => {\n this.flush().finally(() => process.exit(0))\n })\n }\n\n this.log('Telemetry initialized', { serverName: config.serverName })\n }\n\n /**\n * Track a tool invocation\n */\n trackToolCall(\n tool: string,\n duration: number,\n success: boolean,\n error?: string\n ): void {\n const metric: ToolMetric = {\n tool,\n duration,\n success,\n ...(error && { error }),\n timestamp: new Date().toISOString(),\n }\n\n this.buffer.push(metric)\n this.log('Metric tracked', { ...metric })\n\n // Auto-flush if buffer is full\n if (this.buffer.length >= this.config.batchSize) {\n this.flush().catch(this.handleError.bind(this))\n }\n }\n\n /**\n * Flush buffered metrics to OpenConductor\n */\n async flush(): Promise<void> {\n if (this.buffer.length === 0) return\n\n const metrics = [...this.buffer]\n this.buffer = []\n\n const batch: TelemetryBatch = {\n serverName: this.config.serverName,\n serverVersion: this.config.serverVersion,\n metrics,\n meta: {\n sdkVersion: SDK_VERSION,\n nodeVersion: typeof process !== 'undefined' ? process.version : 'unknown',\n platform: typeof process !== 'undefined' ? process.platform : 'unknown',\n },\n }\n\n this.log('Flushing metrics', { count: metrics.length })\n\n try {\n const response = await fetch(this.config.endpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${this.config.apiKey}`,\n 'X-OpenConductor-SDK': SDK_VERSION,\n },\n body: JSON.stringify(batch),\n })\n\n if (!response.ok) {\n throw new Error(`Telemetry flush failed: ${response.status} ${response.statusText}`)\n }\n\n this.log('Metrics flushed successfully', { count: metrics.length })\n } catch (error) {\n // Put metrics back in buffer on failure\n this.buffer.unshift(...metrics)\n throw error\n }\n }\n\n /**\n * Stop telemetry collection\n */\n shutdown(): void {\n if (this.flushTimer) {\n clearInterval(this.flushTimer)\n this.flushTimer = null\n }\n this.flush().catch(this.handleError.bind(this))\n this.log('Telemetry shutdown')\n }\n\n private log(message: string, data?: Record<string, unknown>): void {\n if (this.config.debug) {\n console.debug(JSON.stringify({\n timestamp: new Date().toISOString(),\n level: 'debug',\n service: 'openconductor-telemetry',\n message,\n ...data,\n }))\n }\n }\n\n private handleError(error: unknown): void {\n if (this.config.debug) {\n console.error('[OpenConductor Telemetry Error]', error)\n }\n }\n}\n"]}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { ZodSchema, ZodError, z } from 'zod';
|
|
2
|
+
export { ZodError, ZodSchema, ZodTypeDef, z } from 'zod';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Options for input validation
|
|
6
|
+
*/
|
|
7
|
+
interface ValidateOptions {
|
|
8
|
+
/** Strip unknown keys from objects (default: true) */
|
|
9
|
+
stripUnknown?: boolean;
|
|
10
|
+
/** Custom error formatter */
|
|
11
|
+
formatError?: (error: ZodError) => string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Validates input against a Zod schema
|
|
15
|
+
* Throws ValidationError on failure with detailed field info
|
|
16
|
+
*/
|
|
17
|
+
declare function validate<T>(schema: ZodSchema<T>, input: unknown, options?: ValidateOptions): T;
|
|
18
|
+
/**
|
|
19
|
+
* Creates a validated tool handler
|
|
20
|
+
* Wraps your handler function with automatic input validation
|
|
21
|
+
*/
|
|
22
|
+
declare function validateInput<TInput, TOutput>(schema: ZodSchema<TInput>, handler: (input: TInput) => TOutput | Promise<TOutput>, options?: ValidateOptions): (input: unknown) => Promise<TOutput>;
|
|
23
|
+
/**
|
|
24
|
+
* Common schema patterns for MCP tools
|
|
25
|
+
*/
|
|
26
|
+
declare const schemas: {
|
|
27
|
+
/** Non-empty string */
|
|
28
|
+
nonEmptyString: z.ZodString;
|
|
29
|
+
/** Positive integer */
|
|
30
|
+
positiveInt: z.ZodNumber;
|
|
31
|
+
/** Pagination limit (1-100, default 10) */
|
|
32
|
+
limit: z.ZodDefault<z.ZodNumber>;
|
|
33
|
+
/** Pagination offset (>= 0, default 0) */
|
|
34
|
+
offset: z.ZodDefault<z.ZodNumber>;
|
|
35
|
+
/** URL string */
|
|
36
|
+
url: z.ZodString;
|
|
37
|
+
/** Email string */
|
|
38
|
+
email: z.ZodString;
|
|
39
|
+
/** UUID string */
|
|
40
|
+
uuid: z.ZodString;
|
|
41
|
+
/** ISO date string */
|
|
42
|
+
isoDate: z.ZodString;
|
|
43
|
+
/** Boolean with string coercion ('true'/'false' -> boolean) */
|
|
44
|
+
booleanish: z.ZodUnion<[z.ZodBoolean, z.ZodEffects<z.ZodEnum<["true", "false"]>, boolean, "true" | "false">]>;
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* Type helper to infer schema type
|
|
48
|
+
*/
|
|
49
|
+
type Infer<T extends ZodSchema> = z.infer<T>;
|
|
50
|
+
|
|
51
|
+
export { type Infer, type ValidateOptions, schemas, validate, validateInput };
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { ZodSchema, ZodError, z } from 'zod';
|
|
2
|
+
export { ZodError, ZodSchema, ZodTypeDef, z } from 'zod';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Options for input validation
|
|
6
|
+
*/
|
|
7
|
+
interface ValidateOptions {
|
|
8
|
+
/** Strip unknown keys from objects (default: true) */
|
|
9
|
+
stripUnknown?: boolean;
|
|
10
|
+
/** Custom error formatter */
|
|
11
|
+
formatError?: (error: ZodError) => string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Validates input against a Zod schema
|
|
15
|
+
* Throws ValidationError on failure with detailed field info
|
|
16
|
+
*/
|
|
17
|
+
declare function validate<T>(schema: ZodSchema<T>, input: unknown, options?: ValidateOptions): T;
|
|
18
|
+
/**
|
|
19
|
+
* Creates a validated tool handler
|
|
20
|
+
* Wraps your handler function with automatic input validation
|
|
21
|
+
*/
|
|
22
|
+
declare function validateInput<TInput, TOutput>(schema: ZodSchema<TInput>, handler: (input: TInput) => TOutput | Promise<TOutput>, options?: ValidateOptions): (input: unknown) => Promise<TOutput>;
|
|
23
|
+
/**
|
|
24
|
+
* Common schema patterns for MCP tools
|
|
25
|
+
*/
|
|
26
|
+
declare const schemas: {
|
|
27
|
+
/** Non-empty string */
|
|
28
|
+
nonEmptyString: z.ZodString;
|
|
29
|
+
/** Positive integer */
|
|
30
|
+
positiveInt: z.ZodNumber;
|
|
31
|
+
/** Pagination limit (1-100, default 10) */
|
|
32
|
+
limit: z.ZodDefault<z.ZodNumber>;
|
|
33
|
+
/** Pagination offset (>= 0, default 0) */
|
|
34
|
+
offset: z.ZodDefault<z.ZodNumber>;
|
|
35
|
+
/** URL string */
|
|
36
|
+
url: z.ZodString;
|
|
37
|
+
/** Email string */
|
|
38
|
+
email: z.ZodString;
|
|
39
|
+
/** UUID string */
|
|
40
|
+
uuid: z.ZodString;
|
|
41
|
+
/** ISO date string */
|
|
42
|
+
isoDate: z.ZodString;
|
|
43
|
+
/** Boolean with string coercion ('true'/'false' -> boolean) */
|
|
44
|
+
booleanish: z.ZodUnion<[z.ZodBoolean, z.ZodEffects<z.ZodEnum<["true", "false"]>, boolean, "true" | "false">]>;
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* Type helper to infer schema type
|
|
48
|
+
*/
|
|
49
|
+
type Infer<T extends ZodSchema> = z.infer<T>;
|
|
50
|
+
|
|
51
|
+
export { type Infer, type ValidateOptions, schemas, validate, validateInput };
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var zod = require('zod');
|
|
4
|
+
|
|
5
|
+
// src/validate/index.ts
|
|
6
|
+
|
|
7
|
+
// src/errors/codes.ts
|
|
8
|
+
var ErrorCodes = {
|
|
9
|
+
INVALID_PARAMS: -32602};
|
|
10
|
+
|
|
11
|
+
// src/errors/index.ts
|
|
12
|
+
var MCPError = class extends Error {
|
|
13
|
+
code;
|
|
14
|
+
data;
|
|
15
|
+
constructor(code, message, data) {
|
|
16
|
+
super(message);
|
|
17
|
+
this.name = "MCPError";
|
|
18
|
+
this.code = code;
|
|
19
|
+
this.data = data;
|
|
20
|
+
if (Error.captureStackTrace) {
|
|
21
|
+
Error.captureStackTrace(this, this.constructor);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Returns JSON-RPC 2.0 formatted error object
|
|
26
|
+
*/
|
|
27
|
+
toJSON() {
|
|
28
|
+
return {
|
|
29
|
+
code: this.code,
|
|
30
|
+
message: this.message,
|
|
31
|
+
...this.data && { data: this.data }
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Create error response for JSON-RPC
|
|
36
|
+
*/
|
|
37
|
+
toResponse(id = null) {
|
|
38
|
+
return {
|
|
39
|
+
jsonrpc: "2.0",
|
|
40
|
+
id,
|
|
41
|
+
error: this.toJSON()
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
var ValidationError = class extends MCPError {
|
|
46
|
+
constructor(field, reason, value) {
|
|
47
|
+
super(ErrorCodes.INVALID_PARAMS, `Validation failed for '${field}': ${reason}`, {
|
|
48
|
+
field,
|
|
49
|
+
reason,
|
|
50
|
+
...value !== void 0 && { value }
|
|
51
|
+
});
|
|
52
|
+
this.name = "ValidationError";
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
// src/validate/index.ts
|
|
57
|
+
function validate(schema, input, options = {}) {
|
|
58
|
+
const { stripUnknown = true } = options;
|
|
59
|
+
const result = stripUnknown ? schema.safeParse(input) : schema instanceof zod.z.ZodObject ? schema.strict().safeParse(input) : schema.safeParse(input);
|
|
60
|
+
if (!result.success) {
|
|
61
|
+
const firstError = result.error.errors[0];
|
|
62
|
+
const field = firstError.path.join(".") || "input";
|
|
63
|
+
const reason = firstError.message;
|
|
64
|
+
throw new ValidationError(
|
|
65
|
+
field,
|
|
66
|
+
reason,
|
|
67
|
+
firstError.path.length > 0 ? getNestedValue(input, firstError.path) : input
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
return result.data;
|
|
71
|
+
}
|
|
72
|
+
function validateInput(schema, handler, options = {}) {
|
|
73
|
+
return async (input) => {
|
|
74
|
+
const validated = validate(schema, input, options);
|
|
75
|
+
return handler(validated);
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
function getNestedValue(obj, path) {
|
|
79
|
+
let current = obj;
|
|
80
|
+
for (const key of path) {
|
|
81
|
+
if (current === null || current === void 0) return void 0;
|
|
82
|
+
current = current[key];
|
|
83
|
+
}
|
|
84
|
+
return current;
|
|
85
|
+
}
|
|
86
|
+
var schemas = {
|
|
87
|
+
/** Non-empty string */
|
|
88
|
+
nonEmptyString: zod.z.string().min(1, "Cannot be empty"),
|
|
89
|
+
/** Positive integer */
|
|
90
|
+
positiveInt: zod.z.number().int().positive(),
|
|
91
|
+
/** Pagination limit (1-100, default 10) */
|
|
92
|
+
limit: zod.z.number().int().min(1).max(100).default(10),
|
|
93
|
+
/** Pagination offset (>= 0, default 0) */
|
|
94
|
+
offset: zod.z.number().int().min(0).default(0),
|
|
95
|
+
/** URL string */
|
|
96
|
+
url: zod.z.string().url(),
|
|
97
|
+
/** Email string */
|
|
98
|
+
email: zod.z.string().email(),
|
|
99
|
+
/** UUID string */
|
|
100
|
+
uuid: zod.z.string().uuid(),
|
|
101
|
+
/** ISO date string */
|
|
102
|
+
isoDate: zod.z.string().datetime(),
|
|
103
|
+
/** Boolean with string coercion ('true'/'false' -> boolean) */
|
|
104
|
+
booleanish: zod.z.union([
|
|
105
|
+
zod.z.boolean(),
|
|
106
|
+
zod.z.enum(["true", "false"]).transform((v) => v === "true")
|
|
107
|
+
])
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
Object.defineProperty(exports, "ZodError", {
|
|
111
|
+
enumerable: true,
|
|
112
|
+
get: function () { return zod.ZodError; }
|
|
113
|
+
});
|
|
114
|
+
Object.defineProperty(exports, "z", {
|
|
115
|
+
enumerable: true,
|
|
116
|
+
get: function () { return zod.z; }
|
|
117
|
+
});
|
|
118
|
+
exports.schemas = schemas;
|
|
119
|
+
exports.validate = validate;
|
|
120
|
+
exports.validateInput = validateInput;
|
|
121
|
+
//# sourceMappingURL=index.js.map
|
|
122
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/errors/codes.ts","../../src/errors/index.ts","../../src/validate/index.ts"],"names":["z"],"mappings":"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","file":"index.js","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","import { z, ZodError, type ZodSchema, type ZodTypeDef, type SafeParseReturnType } from 'zod'\nimport { ValidationError } from '../errors'\n\n// Re-export zod for convenience\nexport { z, ZodError, type ZodSchema }\nexport type { ZodTypeDef }\n\n/**\n * Options for input validation\n */\nexport interface ValidateOptions {\n /** Strip unknown keys from objects (default: true) */\n stripUnknown?: boolean\n /** Custom error formatter */\n formatError?: (error: ZodError) => string\n}\n\n/**\n * Validates input against a Zod schema\n * Throws ValidationError on failure with detailed field info\n */\nexport function validate<T>(\n schema: ZodSchema<T>,\n input: unknown,\n options: ValidateOptions = {}\n): T {\n const { stripUnknown = true } = options\n\n const result = (\n stripUnknown\n ? schema.safeParse(input)\n : schema instanceof z.ZodObject\n ? schema.strict().safeParse(input)\n : schema.safeParse(input)\n ) as SafeParseReturnType<unknown, T>\n\n if (!result.success) {\n const firstError = result.error.errors[0]\n const field = firstError.path.join('.') || 'input'\n const reason = firstError.message\n throw new ValidationError(field, reason, firstError.path.length > 0 \n ? getNestedValue(input, firstError.path) \n : input\n )\n }\n\n return result.data\n}\n\n/**\n * Creates a validated tool handler\n * Wraps your handler function with automatic input validation\n */\nexport function validateInput<TInput, TOutput>(\n schema: ZodSchema<TInput>,\n handler: (input: TInput) => TOutput | Promise<TOutput>,\n options: ValidateOptions = {}\n): (input: unknown) => Promise<TOutput> {\n return async (input: unknown) => {\n const validated = validate(schema, input, options)\n return handler(validated)\n }\n}\n\n\n/**\n * Helper to extract nested value from object by path\n */\nfunction getNestedValue(obj: unknown, path: (string | number)[]): unknown {\n let current = obj\n for (const key of path) {\n if (current === null || current === undefined) return undefined\n current = (current as Record<string | number, unknown>)[key]\n }\n return current\n}\n\n/**\n * Common schema patterns for MCP tools\n */\nexport const schemas = {\n /** Non-empty string */\n nonEmptyString: z.string().min(1, 'Cannot be empty'),\n \n /** Positive integer */\n positiveInt: z.number().int().positive(),\n \n /** Pagination limit (1-100, default 10) */\n limit: z.number().int().min(1).max(100).default(10),\n \n /** Pagination offset (>= 0, default 0) */\n offset: z.number().int().min(0).default(0),\n \n /** URL string */\n url: z.string().url(),\n \n /** Email string */\n email: z.string().email(),\n \n /** UUID string */\n uuid: z.string().uuid(),\n \n /** ISO date string */\n isoDate: z.string().datetime(),\n \n /** Boolean with string coercion ('true'/'false' -> boolean) */\n booleanish: z.union([\n z.boolean(),\n z.enum(['true', 'false']).transform(v => v === 'true'),\n ]),\n}\n\n/**\n * Type helper to infer schema type\n */\nexport type Infer<T extends ZodSchema> = z.infer<T>\n"]}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export { ZodError, z } from 'zod';
|
|
3
|
+
|
|
4
|
+
// src/validate/index.ts
|
|
5
|
+
|
|
6
|
+
// src/errors/codes.ts
|
|
7
|
+
var ErrorCodes = {
|
|
8
|
+
INVALID_PARAMS: -32602};
|
|
9
|
+
|
|
10
|
+
// src/errors/index.ts
|
|
11
|
+
var MCPError = class extends Error {
|
|
12
|
+
code;
|
|
13
|
+
data;
|
|
14
|
+
constructor(code, message, data) {
|
|
15
|
+
super(message);
|
|
16
|
+
this.name = "MCPError";
|
|
17
|
+
this.code = code;
|
|
18
|
+
this.data = data;
|
|
19
|
+
if (Error.captureStackTrace) {
|
|
20
|
+
Error.captureStackTrace(this, this.constructor);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Returns JSON-RPC 2.0 formatted error object
|
|
25
|
+
*/
|
|
26
|
+
toJSON() {
|
|
27
|
+
return {
|
|
28
|
+
code: this.code,
|
|
29
|
+
message: this.message,
|
|
30
|
+
...this.data && { data: this.data }
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Create error response for JSON-RPC
|
|
35
|
+
*/
|
|
36
|
+
toResponse(id = null) {
|
|
37
|
+
return {
|
|
38
|
+
jsonrpc: "2.0",
|
|
39
|
+
id,
|
|
40
|
+
error: this.toJSON()
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
var ValidationError = class extends MCPError {
|
|
45
|
+
constructor(field, reason, value) {
|
|
46
|
+
super(ErrorCodes.INVALID_PARAMS, `Validation failed for '${field}': ${reason}`, {
|
|
47
|
+
field,
|
|
48
|
+
reason,
|
|
49
|
+
...value !== void 0 && { value }
|
|
50
|
+
});
|
|
51
|
+
this.name = "ValidationError";
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
// src/validate/index.ts
|
|
56
|
+
function validate(schema, input, options = {}) {
|
|
57
|
+
const { stripUnknown = true } = options;
|
|
58
|
+
const result = stripUnknown ? schema.safeParse(input) : schema instanceof z.ZodObject ? schema.strict().safeParse(input) : schema.safeParse(input);
|
|
59
|
+
if (!result.success) {
|
|
60
|
+
const firstError = result.error.errors[0];
|
|
61
|
+
const field = firstError.path.join(".") || "input";
|
|
62
|
+
const reason = firstError.message;
|
|
63
|
+
throw new ValidationError(
|
|
64
|
+
field,
|
|
65
|
+
reason,
|
|
66
|
+
firstError.path.length > 0 ? getNestedValue(input, firstError.path) : input
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
return result.data;
|
|
70
|
+
}
|
|
71
|
+
function validateInput(schema, handler, options = {}) {
|
|
72
|
+
return async (input) => {
|
|
73
|
+
const validated = validate(schema, input, options);
|
|
74
|
+
return handler(validated);
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
function getNestedValue(obj, path) {
|
|
78
|
+
let current = obj;
|
|
79
|
+
for (const key of path) {
|
|
80
|
+
if (current === null || current === void 0) return void 0;
|
|
81
|
+
current = current[key];
|
|
82
|
+
}
|
|
83
|
+
return current;
|
|
84
|
+
}
|
|
85
|
+
var schemas = {
|
|
86
|
+
/** Non-empty string */
|
|
87
|
+
nonEmptyString: z.string().min(1, "Cannot be empty"),
|
|
88
|
+
/** Positive integer */
|
|
89
|
+
positiveInt: z.number().int().positive(),
|
|
90
|
+
/** Pagination limit (1-100, default 10) */
|
|
91
|
+
limit: z.number().int().min(1).max(100).default(10),
|
|
92
|
+
/** Pagination offset (>= 0, default 0) */
|
|
93
|
+
offset: z.number().int().min(0).default(0),
|
|
94
|
+
/** URL string */
|
|
95
|
+
url: z.string().url(),
|
|
96
|
+
/** Email string */
|
|
97
|
+
email: z.string().email(),
|
|
98
|
+
/** UUID string */
|
|
99
|
+
uuid: z.string().uuid(),
|
|
100
|
+
/** ISO date string */
|
|
101
|
+
isoDate: z.string().datetime(),
|
|
102
|
+
/** Boolean with string coercion ('true'/'false' -> boolean) */
|
|
103
|
+
booleanish: z.union([
|
|
104
|
+
z.boolean(),
|
|
105
|
+
z.enum(["true", "false"]).transform((v) => v === "true")
|
|
106
|
+
])
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
export { schemas, validate, validateInput };
|
|
110
|
+
//# sourceMappingURL=index.mjs.map
|
|
111
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/errors/codes.ts","../../src/errors/index.ts","../../src/validate/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","import { z, ZodError, type ZodSchema, type ZodTypeDef, type SafeParseReturnType } from 'zod'\nimport { ValidationError } from '../errors'\n\n// Re-export zod for convenience\nexport { z, ZodError, type ZodSchema }\nexport type { ZodTypeDef }\n\n/**\n * Options for input validation\n */\nexport interface ValidateOptions {\n /** Strip unknown keys from objects (default: true) */\n stripUnknown?: boolean\n /** Custom error formatter */\n formatError?: (error: ZodError) => string\n}\n\n/**\n * Validates input against a Zod schema\n * Throws ValidationError on failure with detailed field info\n */\nexport function validate<T>(\n schema: ZodSchema<T>,\n input: unknown,\n options: ValidateOptions = {}\n): T {\n const { stripUnknown = true } = options\n\n const result = (\n stripUnknown\n ? schema.safeParse(input)\n : schema instanceof z.ZodObject\n ? schema.strict().safeParse(input)\n : schema.safeParse(input)\n ) as SafeParseReturnType<unknown, T>\n\n if (!result.success) {\n const firstError = result.error.errors[0]\n const field = firstError.path.join('.') || 'input'\n const reason = firstError.message\n throw new ValidationError(field, reason, firstError.path.length > 0 \n ? getNestedValue(input, firstError.path) \n : input\n )\n }\n\n return result.data\n}\n\n/**\n * Creates a validated tool handler\n * Wraps your handler function with automatic input validation\n */\nexport function validateInput<TInput, TOutput>(\n schema: ZodSchema<TInput>,\n handler: (input: TInput) => TOutput | Promise<TOutput>,\n options: ValidateOptions = {}\n): (input: unknown) => Promise<TOutput> {\n return async (input: unknown) => {\n const validated = validate(schema, input, options)\n return handler(validated)\n }\n}\n\n\n/**\n * Helper to extract nested value from object by path\n */\nfunction getNestedValue(obj: unknown, path: (string | number)[]): unknown {\n let current = obj\n for (const key of path) {\n if (current === null || current === undefined) return undefined\n current = (current as Record<string | number, unknown>)[key]\n }\n return current\n}\n\n/**\n * Common schema patterns for MCP tools\n */\nexport const schemas = {\n /** Non-empty string */\n nonEmptyString: z.string().min(1, 'Cannot be empty'),\n \n /** Positive integer */\n positiveInt: z.number().int().positive(),\n \n /** Pagination limit (1-100, default 10) */\n limit: z.number().int().min(1).max(100).default(10),\n \n /** Pagination offset (>= 0, default 0) */\n offset: z.number().int().min(0).default(0),\n \n /** URL string */\n url: z.string().url(),\n \n /** Email string */\n email: z.string().email(),\n \n /** UUID string */\n uuid: z.string().uuid(),\n \n /** ISO date string */\n isoDate: z.string().datetime(),\n \n /** Boolean with string coercion ('true'/'false' -> boolean) */\n booleanish: z.union([\n z.boolean(),\n z.enum(['true', 'false']).transform(v => v === 'true'),\n ]),\n}\n\n/**\n * Type helper to infer schema type\n */\nexport type Infer<T extends ZodSchema> = z.infer<T>\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@openconductor/mcp-sdk",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "The standard SDK for building MCP servers — error handling, validation, logging, and telemetry out of the box",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"module": "dist/index.mjs",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.mjs",
|
|
12
|
+
"require": "./dist/index.js"
|
|
13
|
+
},
|
|
14
|
+
"./errors": {
|
|
15
|
+
"types": "./dist/errors/index.d.ts",
|
|
16
|
+
"import": "./dist/errors/index.mjs",
|
|
17
|
+
"require": "./dist/errors/index.js"
|
|
18
|
+
},
|
|
19
|
+
"./validate": {
|
|
20
|
+
"types": "./dist/validate/index.d.ts",
|
|
21
|
+
"import": "./dist/validate/index.mjs",
|
|
22
|
+
"require": "./dist/validate/index.js"
|
|
23
|
+
},
|
|
24
|
+
"./logger": {
|
|
25
|
+
"types": "./dist/logger/index.d.ts",
|
|
26
|
+
"import": "./dist/logger/index.mjs",
|
|
27
|
+
"require": "./dist/logger/index.js"
|
|
28
|
+
},
|
|
29
|
+
"./server": {
|
|
30
|
+
"types": "./dist/server/index.d.ts",
|
|
31
|
+
"import": "./dist/server/index.mjs",
|
|
32
|
+
"require": "./dist/server/index.js"
|
|
33
|
+
},
|
|
34
|
+
"./telemetry": {
|
|
35
|
+
"types": "./dist/telemetry/index.d.ts",
|
|
36
|
+
"import": "./dist/telemetry/index.mjs",
|
|
37
|
+
"require": "./dist/telemetry/index.js"
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
"files": [
|
|
41
|
+
"dist",
|
|
42
|
+
"README.md",
|
|
43
|
+
"LICENSE"
|
|
44
|
+
],
|
|
45
|
+
"scripts": {
|
|
46
|
+
"build": "tsup",
|
|
47
|
+
"dev": "tsup --watch",
|
|
48
|
+
"test": "vitest",
|
|
49
|
+
"lint": "eslint src/",
|
|
50
|
+
"prepublishOnly": "npm run build"
|
|
51
|
+
},
|
|
52
|
+
"keywords": [
|
|
53
|
+
"mcp",
|
|
54
|
+
"model-context-protocol",
|
|
55
|
+
"ai",
|
|
56
|
+
"agents",
|
|
57
|
+
"llm",
|
|
58
|
+
"sdk",
|
|
59
|
+
"openconductor",
|
|
60
|
+
"validation",
|
|
61
|
+
"telemetry"
|
|
62
|
+
],
|
|
63
|
+
"author": "OpenConductor <hello@openconductor.dev>",
|
|
64
|
+
"license": "MIT",
|
|
65
|
+
"repository": {
|
|
66
|
+
"type": "git",
|
|
67
|
+
"url": "https://github.com/openconductor/mcp-sdk.git"
|
|
68
|
+
},
|
|
69
|
+
"homepage": "https://openconductor.dev",
|
|
70
|
+
"bugs": {
|
|
71
|
+
"url": "https://github.com/openconductor/mcp-sdk/issues"
|
|
72
|
+
},
|
|
73
|
+
"dependencies": {
|
|
74
|
+
"zod": "^3.23.8"
|
|
75
|
+
},
|
|
76
|
+
"devDependencies": {
|
|
77
|
+
"@types/node": "^20.11.0",
|
|
78
|
+
"tsup": "^8.0.1",
|
|
79
|
+
"typescript": "^5.3.3",
|
|
80
|
+
"vitest": "^4.0.17"
|
|
81
|
+
},
|
|
82
|
+
"engines": {
|
|
83
|
+
"node": ">=18.0.0"
|
|
84
|
+
}
|
|
85
|
+
}
|