@slbdn/mcp-tester 1.1.0 → 1.3.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,249 @@
1
+ /**
2
+ * Input validation utilities for MCPClient.
3
+ *
4
+ * Validates all user-facing inputs and throws descriptive `MCPClientError`
5
+ * with actionable messages when validation fails.
6
+ */
7
+ import { MCPClientError } from './errors.js';
8
+ /**
9
+ * Validate `start()` config — command is required and must be a non-empty string.
10
+ */
11
+ export function validateServerConfig(config) {
12
+ if (config === null || config === undefined) {
13
+ throw new MCPClientError('Server config is required. Pass an object with at least { command: "node" }.', 'MCP_INVALID_CONFIG');
14
+ }
15
+ if (typeof config !== 'object' || Array.isArray(config)) {
16
+ throw new MCPClientError(`Server config must be an object, got ${typeof config}.` +
17
+ ' Example: { command: "node", args: ["./server.js"] }', 'MCP_INVALID_CONFIG');
18
+ }
19
+ const cfg = config;
20
+ // command
21
+ if (!('command' in cfg) || cfg.command === undefined || cfg.command === null) {
22
+ throw new MCPClientError('Server config.command is required.' +
23
+ ' Specify the executable to run, e.g. { command: "node", args: ["./server.js"] }.', 'MCP_INVALID_CONFIG');
24
+ }
25
+ if (typeof cfg.command !== 'string') {
26
+ throw new MCPClientError(`Server config.command must be a string, got ${typeof cfg.command}.` +
27
+ ' Example: "node", "python", "npx"', 'MCP_INVALID_CONFIG');
28
+ }
29
+ if (cfg.command.trim() === '') {
30
+ throw new MCPClientError('Server config.command cannot be empty.' +
31
+ ' Specify the executable to run, e.g. "node", "python", "npx".', 'MCP_INVALID_CONFIG');
32
+ }
33
+ // args (optional)
34
+ if ('args' in cfg && cfg.args !== undefined) {
35
+ if (!Array.isArray(cfg.args)) {
36
+ throw new MCPClientError(`Server config.args must be an array of strings, got ${typeof cfg.args}.` +
37
+ ' Example: ["./server.js", "--port", "3000"]', 'MCP_INVALID_CONFIG');
38
+ }
39
+ for (let i = 0; i < cfg.args.length; i++) {
40
+ if (typeof cfg.args[i] !== 'string') {
41
+ throw new MCPClientError(`Server config.args[${i}] must be a string, got ${typeof cfg.args[i]}.` +
42
+ ` Full args: ${JSON.stringify(cfg.args)}`, 'MCP_INVALID_CONFIG');
43
+ }
44
+ }
45
+ }
46
+ // env (optional)
47
+ if ('env' in cfg && cfg.env !== undefined) {
48
+ if (typeof cfg.env !== 'object' || cfg.env === null || Array.isArray(cfg.env)) {
49
+ throw new MCPClientError(`Server config.env must be an object, got ${typeof cfg.env}.` +
50
+ ' Example: { NODE_ENV: "production", API_KEY: "..." }', 'MCP_INVALID_CONFIG');
51
+ }
52
+ const envKeys = Object.keys(cfg.env);
53
+ for (const key of envKeys) {
54
+ const val = cfg.env[key];
55
+ if (val !== undefined && typeof val !== 'string') {
56
+ throw new MCPClientError(`Server config.env["${key}"] must be a string or undefined, got ${typeof val}.` +
57
+ ' Environment variable values must be strings.', 'MCP_INVALID_CONFIG');
58
+ }
59
+ }
60
+ }
61
+ // startupDelay (optional)
62
+ if ('startupDelay' in cfg && cfg.startupDelay !== undefined) {
63
+ if (typeof cfg.startupDelay !== 'number' || isNaN(cfg.startupDelay)) {
64
+ throw new MCPClientError(`Server config.startupDelay must be a number, got ${typeof cfg.startupDelay}.` +
65
+ ' Example: 500 (milliseconds)', 'MCP_INVALID_CONFIG');
66
+ }
67
+ if (cfg.startupDelay < 0) {
68
+ throw new MCPClientError(`Server config.startupDelay must be non-negative, got ${cfg.startupDelay}.`, 'MCP_INVALID_CONFIG');
69
+ }
70
+ }
71
+ }
72
+ /**
73
+ * Validate `callTool()` options — tool name is required.
74
+ */
75
+ export function validateToolCallOptions(options) {
76
+ if (options === null || options === undefined) {
77
+ throw new MCPClientError('Tool call options are required. Pass { name: "tool-name", arguments: {} }.', 'MCP_INVALID_TOOL_CALL');
78
+ }
79
+ if (typeof options !== 'object' || Array.isArray(options)) {
80
+ throw new MCPClientError(`Tool call options must be an object, got ${typeof options}.`, 'MCP_INVALID_TOOL_CALL');
81
+ }
82
+ const opts = options;
83
+ // name
84
+ if (!('name' in opts) || opts.name === undefined || opts.name === null) {
85
+ throw new MCPClientError('Tool name is required. Pass { name: "tool-name" }.', 'MCP_INVALID_TOOL_CALL');
86
+ }
87
+ if (typeof opts.name !== 'string') {
88
+ throw new MCPClientError(`Tool name must be a string, got ${typeof opts.name}.`, 'MCP_INVALID_TOOL_CALL');
89
+ }
90
+ if (opts.name.trim() === '') {
91
+ throw new MCPClientError('Tool name cannot be empty. Specify the tool to call, e.g. { name: "echo" }.', 'MCP_INVALID_TOOL_CALL');
92
+ }
93
+ // arguments (optional)
94
+ if ('arguments' in opts && opts.arguments !== undefined) {
95
+ if (typeof opts.arguments !== 'object' ||
96
+ opts.arguments === null ||
97
+ Array.isArray(opts.arguments)) {
98
+ throw new MCPClientError(`Tool arguments must be an object, got ${typeof opts.arguments}.` +
99
+ ' Example: { message: "hello" }', 'MCP_INVALID_TOOL_CALL');
100
+ }
101
+ }
102
+ // timeout (optional)
103
+ if ('timeout' in opts && opts.timeout !== undefined) {
104
+ if (typeof opts.timeout !== 'number' || isNaN(opts.timeout)) {
105
+ throw new MCPClientError(`Tool call timeout must be a number, got ${typeof opts.timeout}.`, 'MCP_INVALID_TOOL_CALL');
106
+ }
107
+ if (opts.timeout <= 0) {
108
+ throw new MCPClientError(`Tool call timeout must be positive, got ${opts.timeout}.`, 'MCP_INVALID_TOOL_CALL');
109
+ }
110
+ }
111
+ // retries (optional)
112
+ if ('retries' in opts && opts.retries !== undefined) {
113
+ if (typeof opts.retries !== 'number' || isNaN(opts.retries)) {
114
+ throw new MCPClientError(`Tool call retries must be a number, got ${typeof opts.retries}.`, 'MCP_INVALID_TOOL_CALL');
115
+ }
116
+ if (opts.retries < 0) {
117
+ throw new MCPClientError(`Tool call retries must be non-negative, got ${opts.retries}.`, 'MCP_INVALID_TOOL_CALL');
118
+ }
119
+ }
120
+ }
121
+ /**
122
+ * Validate a resource URI — must be a non-empty string.
123
+ */
124
+ export function validateResourceUri(uri) {
125
+ if (uri === undefined || uri === null) {
126
+ throw new MCPClientError('Resource URI is required. Pass a URI string, e.g. "config://settings".', 'MCP_INVALID_RESOURCE_URI');
127
+ }
128
+ if (typeof uri !== 'string') {
129
+ throw new MCPClientError(`Resource URI must be a string, got ${typeof uri}.` +
130
+ ' Example: "config://settings", "file:///path/to/resource"', 'MCP_INVALID_RESOURCE_URI');
131
+ }
132
+ if (uri.trim() === '') {
133
+ throw new MCPClientError('Resource URI cannot be empty.' + ' Example: "config://settings", "file:///path/to/resource"', 'MCP_INVALID_RESOURCE_URI');
134
+ }
135
+ }
136
+ /**
137
+ * Validate prompt name — must be a non-empty string.
138
+ */
139
+ export function validatePromptName(name) {
140
+ if (name === undefined || name === null) {
141
+ throw new MCPClientError('Prompt name is required. Pass a prompt name string, e.g. "greet".', 'MCP_INVALID_PROMPT');
142
+ }
143
+ if (typeof name !== 'string') {
144
+ throw new MCPClientError(`Prompt name must be a string, got ${typeof name}. Example: "greet", "summarize"`, 'MCP_INVALID_PROMPT');
145
+ }
146
+ if (name.trim() === '') {
147
+ throw new MCPClientError('Prompt name cannot be empty. Example: "greet", "summarize"', 'MCP_INVALID_PROMPT');
148
+ }
149
+ }
150
+ /**
151
+ * Validate prompt arguments — must be an object with string values if provided.
152
+ */
153
+ export function validatePromptArgs(args) {
154
+ if (args === undefined || args === null) {
155
+ return; // Optional
156
+ }
157
+ if (typeof args !== 'object' || Array.isArray(args)) {
158
+ throw new MCPClientError(`Prompt arguments must be an object, got ${typeof args}.` + ' Example: { name: "Alice" }', 'MCP_INVALID_PROMPT');
159
+ }
160
+ const obj = args;
161
+ for (const key of Object.keys(obj)) {
162
+ if (typeof obj[key] !== 'string') {
163
+ throw new MCPClientError(`Prompt argument "${key}" must be a string, got ${typeof obj[key]}.` +
164
+ ' All prompt argument values must be strings.', 'MCP_INVALID_PROMPT');
165
+ }
166
+ }
167
+ }
168
+ /**
169
+ * Validate sampling request params.
170
+ */
171
+ export function validateSamplingRequest(request) {
172
+ if (request === null || request === undefined) {
173
+ throw new MCPClientError('Sampling request is required.' + ' Pass { messages: [...], maxTokens: 100 }.', 'MCP_INVALID_SAMPLING');
174
+ }
175
+ if (typeof request !== 'object' || Array.isArray(request)) {
176
+ throw new MCPClientError(`Sampling request must be an object, got ${typeof request}.`, 'MCP_INVALID_SAMPLING');
177
+ }
178
+ const req = request;
179
+ if (!('messages' in req) || !Array.isArray(req.messages)) {
180
+ throw new MCPClientError('Sampling request must include a "messages" array.' +
181
+ ' Example: { messages: [{ role: "user", content: { type: "text", text: "Hello" } }], maxTokens: 100 }', 'MCP_INVALID_SAMPLING');
182
+ }
183
+ if (req.messages.length === 0) {
184
+ throw new MCPClientError('Sampling request "messages" array cannot be empty.' + ' Include at least one message.', 'MCP_INVALID_SAMPLING');
185
+ }
186
+ }
187
+ /**
188
+ * Validate client constructor options.
189
+ */
190
+ export function validateClientOptions(options) {
191
+ if (options === undefined || options === null) {
192
+ return;
193
+ }
194
+ if (typeof options !== 'object' || Array.isArray(options)) {
195
+ throw new MCPClientError(`Client options must be an object, got ${typeof options}.`, 'MCP_INVALID_OPTIONS');
196
+ }
197
+ const opts = options;
198
+ // name (optional string)
199
+ if ('name' in opts && opts.name !== undefined && typeof opts.name !== 'string') {
200
+ throw new MCPClientError(`Client option "name" must be a string, got ${typeof opts.name}.`, 'MCP_INVALID_OPTIONS');
201
+ }
202
+ // version (optional string)
203
+ if ('version' in opts && opts.version !== undefined && typeof opts.version !== 'string') {
204
+ throw new MCPClientError(`Client option "version" must be a string, got ${typeof opts.version}.`, 'MCP_INVALID_OPTIONS');
205
+ }
206
+ // timeout (optional positive number)
207
+ if ('timeout' in opts && opts.timeout !== undefined) {
208
+ if (typeof opts.timeout !== 'number' || isNaN(opts.timeout)) {
209
+ throw new MCPClientError(`Client option "timeout" must be a number, got ${typeof opts.timeout}.`, 'MCP_INVALID_OPTIONS');
210
+ }
211
+ if (opts.timeout <= 0) {
212
+ throw new MCPClientError(`Client option "timeout" must be positive, got ${opts.timeout}.`, 'MCP_INVALID_OPTIONS');
213
+ }
214
+ }
215
+ // retries (optional non-negative number)
216
+ if ('retries' in opts && opts.retries !== undefined) {
217
+ if (typeof opts.retries !== 'number' || isNaN(opts.retries)) {
218
+ throw new MCPClientError(`Client option "retries" must be a number, got ${typeof opts.retries}.`, 'MCP_INVALID_OPTIONS');
219
+ }
220
+ if (opts.retries < 0) {
221
+ throw new MCPClientError(`Client option "retries" must be non-negative, got ${opts.retries}.`, 'MCP_INVALID_OPTIONS');
222
+ }
223
+ }
224
+ // retryDelay (optional non-negative number)
225
+ if ('retryDelay' in opts && opts.retryDelay !== undefined) {
226
+ if (typeof opts.retryDelay !== 'number' || isNaN(opts.retryDelay)) {
227
+ throw new MCPClientError(`Client option "retryDelay" must be a number, got ${typeof opts.retryDelay}.`, 'MCP_INVALID_OPTIONS');
228
+ }
229
+ if (opts.retryDelay < 0) {
230
+ throw new MCPClientError(`Client option "retryDelay" must be non-negative, got ${opts.retryDelay}.`, 'MCP_INVALID_OPTIONS');
231
+ }
232
+ }
233
+ // startupDelay (optional non-negative number)
234
+ if ('startupDelay' in opts && opts.startupDelay !== undefined) {
235
+ if (typeof opts.startupDelay !== 'number' || isNaN(opts.startupDelay)) {
236
+ throw new MCPClientError(`Client option "startupDelay" must be a number, got ${typeof opts.startupDelay}.`, 'MCP_INVALID_OPTIONS');
237
+ }
238
+ if (opts.startupDelay < 0) {
239
+ throw new MCPClientError(`Client option "startupDelay" must be non-negative, got ${opts.startupDelay}.`, 'MCP_INVALID_OPTIONS');
240
+ }
241
+ }
242
+ // enableProtocolLogging (optional boolean)
243
+ if ('enableProtocolLogging' in opts &&
244
+ opts.enableProtocolLogging !== undefined &&
245
+ typeof opts.enableProtocolLogging !== 'boolean') {
246
+ throw new MCPClientError(`Client option "enableProtocolLogging" must be a boolean, got ${typeof opts.enableProtocolLogging}.`, 'MCP_INVALID_OPTIONS');
247
+ }
248
+ }
249
+ //# sourceMappingURL=validation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@slbdn/mcp-tester",
3
- "version": "1.1.0",
3
+ "version": "1.3.0",
4
4
  "description": "Minimal MCP client implementation for CI/CD testing of MCP servers",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -29,10 +29,12 @@
29
29
  ],
30
30
  "scripts": {
31
31
  "build": "tsc",
32
+ "dev": "tsc --watch",
32
33
  "docs": "typedoc",
33
34
  "test": "jest",
34
35
  "test:watch": "jest --watch",
35
36
  "test:coverage": "jest --coverage",
37
+ "benchmark": "npx tsx src/__tests__/benchmarks.ts 2>/dev/null",
36
38
  "lint": "eslint src --ext .ts",
37
39
  "format": "prettier --write \"src/**/*.ts\"",
38
40
  "format:check": "prettier --check \"src/**/*.ts\"",
@@ -82,15 +84,17 @@
82
84
  "devDependencies": {
83
85
  "@modelcontextprotocol/server-everything": "^2026.1.26",
84
86
  "@types/jest": "^29.5.0",
85
- "@types/node": "^20.0.0",
86
- "@typescript-eslint/eslint-plugin": "^8.58.0",
87
- "@typescript-eslint/parser": "^8.58.0",
87
+ "@types/node": "^20.19.41",
88
+ "@typescript-eslint/eslint-plugin": "^8.60.0",
89
+ "@typescript-eslint/parser": "^8.60.0",
88
90
  "eslint": "^8.56.0",
91
+ "fast-check": "^4.8.0",
89
92
  "husky": "^9.1.7",
90
93
  "jest": "^29.7.0",
94
+ "jest-html-reporters": "^3.1.7",
91
95
  "lint-staged": "^16.4.0",
92
- "prettier": "^3.8.1",
93
- "ts-jest": "^29.4.9",
96
+ "prettier": "^3.8.3",
97
+ "ts-jest": "^29.4.11",
94
98
  "typedoc": "^0.28.19",
95
99
  "typedoc-plugin-markdown": "^4.11.0",
96
100
  "typescript": "^5.3.0"