@slbdn/mcp-tester 1.0.1 → 1.1.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,75 @@
1
+ /**
2
+ * Standalone assertion utilities for MCP tool/resource/prompt testing.
3
+ *
4
+ * Works with any test runner — just throws descriptive errors on failure.
5
+ * Designed for the `runTest(name, fn)` pattern:
6
+ *
7
+ * await runTest("Get constant: c", async () => {
8
+ * const result = await client.callTool({ name: "get_constant", arguments: { name: "c" } });
9
+ * assertToolText(result, "299792458");
10
+ * });
11
+ *
12
+ * @module assert
13
+ */
14
+ import type { CallToolResult, ReadResourceResult, GetPromptResult } from '@modelcontextprotocol/sdk/types.js';
15
+ /** Thrown when an assertion fails. */
16
+ export declare class AssertionError extends Error {
17
+ constructor(message: string);
18
+ }
19
+ /** Assert that `actual === expected` (strict equality). */
20
+ export declare function equal<T>(actual: T, expected: T, msg?: string): void;
21
+ /** Assert that `actual !== expected`. */
22
+ export declare function notEqual<T>(actual: T, expected: T, msg?: string): void;
23
+ /** Assert that `actual` is deeply equal to `expected`. */
24
+ export declare function deepEqual(actual: unknown, expected: unknown, msg?: string): void;
25
+ /** Assert that `value` is truthy. */
26
+ export declare function ok(value: unknown, msg?: string): void;
27
+ /** Assert that `value` is falsy. */
28
+ export declare function notOk(value: unknown, msg?: string): void;
29
+ /** Assert that `fn` throws an error. Returns the error for further assertions. */
30
+ export declare function throws(fn: () => Promise<unknown>, msg?: string): Promise<Error>;
31
+ /** Assert that `fn` does NOT throw. */
32
+ export declare function doesNotThrow(fn: () => Promise<unknown>, msg?: string): Promise<void>;
33
+ /** Assert that `actual === expected` (numbers). */
34
+ export declare function equalNum(actual: number, expected: number, msg?: string): void;
35
+ /** Assert `actual > expected`. */
36
+ export declare function greaterThan(actual: number, expected: number, msg?: string): void;
37
+ /** Assert `actual >= expected`. */
38
+ export declare function atLeast(actual: number, expected: number, msg?: string): void;
39
+ /** Assert `actual < expected`. */
40
+ export declare function lessThan(actual: number, expected: number, msg?: string): void;
41
+ /** Assert `value` is within `epsilon` of `expected`. */
42
+ export declare function closeTo(actual: number, expected: number, epsilon?: number, msg?: string): void;
43
+ /** Assert that `str` contains `substring`. */
44
+ export declare function contains(str: string, substring: string, msg?: string): void;
45
+ /** Assert that `str` does NOT contain `substring`. */
46
+ export declare function notContains(str: string, substring: string, msg?: string): void;
47
+ /** Assert that `str` matches `regex`. */
48
+ export declare function matches(str: string, regex: RegExp, msg?: string): void;
49
+ /** Assert tool result text equals expected string exactly. If expected omitted, just checks for text content. */
50
+ export declare function toolTextEquals(result: CallToolResult, expected?: string, msg?: string): void;
51
+ /** Assert tool result text contains expected substring. */
52
+ export declare function toolTextContains(result: CallToolResult, substring: string, msg?: string): void;
53
+ /** Assert tool result text, parsed as number, equals expected. */
54
+ export declare function toolNumEquals(result: CallToolResult, expected: number, msg?: string): void;
55
+ /** Assert tool result text, parsed as number, is within epsilon of expected. */
56
+ export declare function toolNumCloseTo(result: CallToolResult, expected: number, epsilon?: number, msg?: string): void;
57
+ /** Assert tool result text, parsed as JSON, deeply equals expected. */
58
+ export declare function toolJsonEquals<T = unknown>(result: CallToolResult, expected: T, msg?: string): void;
59
+ /** Assert tool returned an error (isError flag or error in text). */
60
+ export declare function toolIsError(result: CallToolResult, msg?: string): void;
61
+ /** Assert tool did NOT return an error. */
62
+ export declare function toolIsOk(result: CallToolResult, msg?: string): void;
63
+ /** Assert tool result has at least `minItems` content items. */
64
+ export declare function toolHasContent(result: CallToolResult, minItems?: number, msg?: string): void;
65
+ /** Assert tool result contains an image content item. */
66
+ export declare function toolHasImage(result: CallToolResult, msg?: string): void;
67
+ /** Assert resource result has content. */
68
+ export declare function resourceHasContent(result: ReadResourceResult, minItems?: number, msg?: string): void;
69
+ /** Assert resource result text contains substring. */
70
+ export declare function resourceTextContains(result: ReadResourceResult, substring: string, msg?: string): void;
71
+ /** Assert prompt result has messages. */
72
+ export declare function promptHasMessages(result: GetPromptResult, minMessages?: number, msg?: string): void;
73
+ /** Assert prompt result text contains substring. */
74
+ export declare function promptTextContains(result: GetPromptResult, substring: string, msg?: string): void;
75
+ //# sourceMappingURL=assert.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assert.d.ts","sourceRoot":"","sources":["../src/assert.ts"],"names":[],"mappings":"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"}
package/dist/assert.js ADDED
@@ -0,0 +1,250 @@
1
+ /**
2
+ * Standalone assertion utilities for MCP tool/resource/prompt testing.
3
+ *
4
+ * Works with any test runner — just throws descriptive errors on failure.
5
+ * Designed for the `runTest(name, fn)` pattern:
6
+ *
7
+ * await runTest("Get constant: c", async () => {
8
+ * const result = await client.callTool({ name: "get_constant", arguments: { name: "c" } });
9
+ * assertToolText(result, "299792458");
10
+ * });
11
+ *
12
+ * @module assert
13
+ */
14
+ // ─── Helpers ────────────────────────────────────────────────────────────────
15
+ function extractText(result) {
16
+ const item = result.content[0];
17
+ if (item && 'text' in item)
18
+ return item.text;
19
+ throw new AssertionError(`Tool result has no text content. Got: ${JSON.stringify(result.content[0])}`);
20
+ }
21
+ function fail(message) {
22
+ throw new AssertionError(message);
23
+ }
24
+ // ─── Error Class ────────────────────────────────────────────────────────────
25
+ /** Thrown when an assertion fails. */
26
+ export class AssertionError extends Error {
27
+ constructor(message) {
28
+ super(message);
29
+ this.name = 'AssertionError';
30
+ }
31
+ }
32
+ // ─── Value Assertions ───────────────────────────────────────────────────────
33
+ /** Assert that `actual === expected` (strict equality). */
34
+ export function equal(actual, expected, msg) {
35
+ if (actual !== expected) {
36
+ fail(msg ?? `Expected ${JSON.stringify(expected)}, got ${JSON.stringify(actual)}`);
37
+ }
38
+ }
39
+ /** Assert that `actual !== expected`. */
40
+ export function notEqual(actual, expected, msg) {
41
+ if (actual === expected) {
42
+ fail(msg ?? `Expected value to NOT equal ${JSON.stringify(expected)}`);
43
+ }
44
+ }
45
+ /** Assert that `actual` is deeply equal to `expected`. */
46
+ export function deepEqual(actual, expected, msg) {
47
+ if (JSON.stringify(actual) !== JSON.stringify(expected)) {
48
+ fail(msg ??
49
+ `Expected deep equality:\n actual: ${JSON.stringify(actual)}\n expected: ${JSON.stringify(expected)}`);
50
+ }
51
+ }
52
+ /** Assert that `value` is truthy. */
53
+ export function ok(value, msg) {
54
+ if (!value) {
55
+ fail(msg ?? `Expected truthy value, got ${JSON.stringify(value)}`);
56
+ }
57
+ }
58
+ /** Assert that `value` is falsy. */
59
+ export function notOk(value, msg) {
60
+ if (value) {
61
+ fail(msg ?? `Expected falsy value, got ${JSON.stringify(value)}`);
62
+ }
63
+ }
64
+ /** Assert that `fn` throws an error. Returns the error for further assertions. */
65
+ export async function throws(fn, msg) {
66
+ try {
67
+ await fn();
68
+ fail(msg ?? 'Expected function to throw, but it did not');
69
+ }
70
+ catch (error) {
71
+ if (error instanceof AssertionError)
72
+ throw error;
73
+ return error;
74
+ }
75
+ }
76
+ /** Assert that `fn` does NOT throw. */
77
+ export async function doesNotThrow(fn, msg) {
78
+ try {
79
+ await fn();
80
+ }
81
+ catch (error) {
82
+ fail(msg ?? `Expected function NOT to throw, but it threw: ${error}`);
83
+ }
84
+ }
85
+ // ─── Numeric Assertions ─────────────────────────────────────────────────────
86
+ /** Assert that `actual === expected` (numbers). */
87
+ export function equalNum(actual, expected, msg) {
88
+ if (actual !== expected) {
89
+ fail(msg ?? `Expected ${expected}, got ${actual}`);
90
+ }
91
+ }
92
+ /** Assert `actual > expected`. */
93
+ export function greaterThan(actual, expected, msg) {
94
+ if (actual <= expected) {
95
+ fail(msg ?? `Expected ${actual} > ${expected}`);
96
+ }
97
+ }
98
+ /** Assert `actual >= expected`. */
99
+ export function atLeast(actual, expected, msg) {
100
+ if (actual < expected) {
101
+ fail(msg ?? `Expected ${actual} >= ${expected}`);
102
+ }
103
+ }
104
+ /** Assert `actual < expected`. */
105
+ export function lessThan(actual, expected, msg) {
106
+ if (actual >= expected) {
107
+ fail(msg ?? `Expected ${actual} < ${expected}`);
108
+ }
109
+ }
110
+ /** Assert `value` is within `epsilon` of `expected`. */
111
+ export function closeTo(actual, expected, epsilon = 0.001, msg) {
112
+ if (Math.abs(actual - expected) > epsilon) {
113
+ fail(msg ?? `Expected ${actual} to be within ${epsilon} of ${expected}`);
114
+ }
115
+ }
116
+ // ─── String Assertions ──────────────────────────────────────────────────────
117
+ /** Assert that `str` contains `substring`. */
118
+ export function contains(str, substring, msg) {
119
+ if (!str.includes(substring)) {
120
+ fail(msg ?? `Expected string to contain "${substring}". Got: "${str}"`);
121
+ }
122
+ }
123
+ /** Assert that `str` does NOT contain `substring`. */
124
+ export function notContains(str, substring, msg) {
125
+ if (str.includes(substring)) {
126
+ fail(msg ?? `Expected string to NOT contain "${substring}". Got: "${str}"`);
127
+ }
128
+ }
129
+ /** Assert that `str` matches `regex`. */
130
+ export function matches(str, regex, msg) {
131
+ if (!regex.test(str)) {
132
+ fail(msg ?? `Expected string to match ${regex}. Got: "${str}"`);
133
+ }
134
+ }
135
+ // ─── MCP Tool Assertions ────────────────────────────────────────────────────
136
+ /** Assert tool result text equals expected string exactly. If expected omitted, just checks for text content. */
137
+ export function toolTextEquals(result, expected, msg) {
138
+ const text = extractText(result);
139
+ if (text === undefined) {
140
+ fail(msg ?? 'Expected tool result to have text content');
141
+ }
142
+ if (expected !== undefined && text !== expected) {
143
+ fail(msg ?? `Expected tool text "${expected}", got "${text}"`);
144
+ }
145
+ }
146
+ /** Assert tool result text contains expected substring. */
147
+ export function toolTextContains(result, substring, msg) {
148
+ const text = extractText(result);
149
+ if (!text.includes(substring)) {
150
+ fail(msg ?? `Expected tool text to contain "${substring}". Got: "${text}"`);
151
+ }
152
+ }
153
+ /** Assert tool result text, parsed as number, equals expected. */
154
+ export function toolNumEquals(result, expected, msg) {
155
+ const text = extractText(result);
156
+ const actual = parseFloat(text);
157
+ if (Number.isNaN(actual)) {
158
+ fail(msg ?? `Expected tool text to be a number. Got: "${text}"`);
159
+ }
160
+ if (actual !== expected) {
161
+ fail(msg ?? `Expected tool result ${expected}, got ${actual}`);
162
+ }
163
+ }
164
+ /** Assert tool result text, parsed as number, is within epsilon of expected. */
165
+ export function toolNumCloseTo(result, expected, epsilon = 0.001, msg) {
166
+ const text = extractText(result);
167
+ const actual = parseFloat(text);
168
+ if (Number.isNaN(actual)) {
169
+ fail(msg ?? `Expected tool text to be a number. Got: "${text}"`);
170
+ }
171
+ if (Math.abs(actual - expected) > epsilon) {
172
+ fail(msg ?? `Expected tool result within ${epsilon} of ${expected}, got ${actual}`);
173
+ }
174
+ }
175
+ /** Assert tool result text, parsed as JSON, deeply equals expected. */
176
+ export function toolJsonEquals(result, expected, msg) {
177
+ const text = extractText(result);
178
+ let parsed;
179
+ try {
180
+ parsed = JSON.parse(text);
181
+ }
182
+ catch {
183
+ fail(msg ?? `Expected tool text to be valid JSON. Got: "${text}"`);
184
+ }
185
+ if (JSON.stringify(parsed) !== JSON.stringify(expected)) {
186
+ fail(msg ?? `Expected tool JSON ${JSON.stringify(expected)}, got ${JSON.stringify(parsed)}`);
187
+ }
188
+ }
189
+ /** Assert tool returned an error (isError flag or error in text). */
190
+ export function toolIsError(result, msg) {
191
+ if (!result.isError && !extractText(result).toLowerCase().includes('error')) {
192
+ fail(msg ?? 'Expected tool result to be an error');
193
+ }
194
+ }
195
+ /** Assert tool did NOT return an error. */
196
+ export function toolIsOk(result, msg) {
197
+ if (result.isError) {
198
+ fail(msg ?? `Expected tool result to be successful, but got error: ${extractText(result)}`);
199
+ }
200
+ }
201
+ /** Assert tool result has at least `minItems` content items. */
202
+ export function toolHasContent(result, minItems = 1, msg) {
203
+ if (result.content.length < minItems) {
204
+ fail(msg ?? `Expected at least ${minItems} content items, got ${result.content.length}`);
205
+ }
206
+ }
207
+ /** Assert tool result contains an image content item. */
208
+ export function toolHasImage(result, msg) {
209
+ const hasImage = result.content.some((item) => item.type === 'image');
210
+ if (!hasImage) {
211
+ fail(msg ?? 'Expected tool result to contain an image');
212
+ }
213
+ }
214
+ // ─── MCP Resource Assertions ────────────────────────────────────────────────
215
+ /** Assert resource result has content. */
216
+ export function resourceHasContent(result, minItems = 1, msg) {
217
+ if (result.contents.length < minItems) {
218
+ fail(msg ?? `Expected at least ${minItems} resource contents, got ${result.contents.length}`);
219
+ }
220
+ }
221
+ /** Assert resource result text contains substring. */
222
+ export function resourceTextContains(result, substring, msg) {
223
+ const item = result.contents[0];
224
+ if (!item || !('text' in item)) {
225
+ fail(msg ?? 'Resource result has no text content');
226
+ }
227
+ const text = item.text;
228
+ if (!text.includes(substring)) {
229
+ fail(msg ?? `Expected resource text to contain "${substring}". Got: "${text}"`);
230
+ }
231
+ }
232
+ // ─── MCP Prompt Assertions ──────────────────────────────────────────────────
233
+ /** Assert prompt result has messages. */
234
+ export function promptHasMessages(result, minMessages = 1, msg) {
235
+ if (result.messages.length < minMessages) {
236
+ fail(msg ?? `Expected at least ${minMessages} prompt messages, got ${result.messages.length}`);
237
+ }
238
+ }
239
+ /** Assert prompt result text contains substring. */
240
+ export function promptTextContains(result, substring, msg) {
241
+ const item = result.messages[0]?.content;
242
+ if (!item || !('text' in item)) {
243
+ fail(msg ?? 'Prompt message has no text content');
244
+ }
245
+ const text = item.text;
246
+ if (!text.includes(substring)) {
247
+ fail(msg ?? `Expected prompt text to contain "${substring}". Got: "${text}"`);
248
+ }
249
+ }
250
+ //# sourceMappingURL=assert.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assert.js","sourceRoot":"","sources":["../src/assert.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":""}
@@ -0,0 +1,311 @@
1
+ #!/usr/bin/env node
2
+ // CLI entry point - run with: node dist/cli/index.js
3
+ import { Command } from 'commander';
4
+ import { MCPClient } from '../client/MCPClient.js';
5
+ import { MCPConnectionError, MCPTimeoutError, MCPServerError } from '../utils/errors.js';
6
+ const program = new Command();
7
+ program
8
+ .name('mcp-tester')
9
+ .description('CLI tool for testing MCP servers')
10
+ .version('1.0.0', '-V, --version');
11
+ // Global options - use string type since commander passes strings
12
+ program
13
+ .option('-t, --timeout <ms>', 'Request timeout in milliseconds', '30000')
14
+ .option('-v, --verbose', 'Enable verbose output')
15
+ .option('-l, --log-level <level>', 'Log level (debug|info|warn|error)', 'info');
16
+ // Test command - connects and verifies server is working
17
+ program
18
+ .command('test')
19
+ .description('Test MCP server connection and list available capabilities')
20
+ .argument('<command>', 'Command to run the MCP server (e.g., "node", "python")')
21
+ .argument('[args...]', 'Arguments for the server command')
22
+ .action(async (command, args, opts) => {
23
+ const client = new MCPClient({
24
+ name: 'mcp-tester-cli',
25
+ version: '1.0.0',
26
+ timeout: parseInt(String(opts['timeout'] || '30000')),
27
+ logLevel: (opts['verbose'] ? 'debug' : String(opts['logLevel'] || 'info')),
28
+ });
29
+ try {
30
+ console.log(`šŸ”Œ Connecting to MCP server...`);
31
+ console.log(` Command: ${command} ${args.join(' ')}`);
32
+ await client.start({
33
+ command,
34
+ args,
35
+ });
36
+ console.log(`āœ… Connected successfully\n`);
37
+ // Test tools
38
+ console.log(`šŸ› ļø Tools:`);
39
+ const tools = await client.listTools();
40
+ if (tools.length === 0) {
41
+ console.log(' (none)');
42
+ }
43
+ else {
44
+ tools.forEach((tool) => {
45
+ console.log(` • ${tool.name}: ${tool.description}`);
46
+ });
47
+ }
48
+ console.log();
49
+ // Test resources
50
+ console.log(`šŸ“„ Resources:`);
51
+ const resources = await client.listResources();
52
+ if (resources.length === 0) {
53
+ console.log(' (none)');
54
+ }
55
+ else {
56
+ resources.forEach((resource) => {
57
+ console.log(` • ${resource.uri}: ${resource.description || resource.name}`);
58
+ });
59
+ }
60
+ console.log();
61
+ // Test prompts
62
+ console.log(`šŸ’¬ Prompts:`);
63
+ const prompts = await client.listPrompts();
64
+ if (prompts.length === 0) {
65
+ console.log(' (none)');
66
+ }
67
+ else {
68
+ prompts.forEach((prompt) => {
69
+ console.log(` • ${prompt.name}: ${prompt.description}`);
70
+ });
71
+ }
72
+ console.log();
73
+ console.log(`āœ… Server test completed successfully!`);
74
+ console.log(` Tools: ${tools.length} | Resources: ${resources.length} | Prompts: ${prompts.length}`);
75
+ }
76
+ catch (error) {
77
+ console.error(`āŒ Error: ${error instanceof Error ? error.message : String(error)}`);
78
+ if (error instanceof MCPConnectionError) {
79
+ console.error(' → Server failed to start. Check command and server process.');
80
+ }
81
+ else if (error instanceof MCPTimeoutError) {
82
+ console.error(` → Request timed out after ${opts['timeout']}ms`);
83
+ }
84
+ else if (error instanceof MCPServerError) {
85
+ console.error(' → Server returned an error');
86
+ }
87
+ process.exit(1);
88
+ }
89
+ finally {
90
+ await client.stop();
91
+ }
92
+ });
93
+ // List tools command
94
+ program
95
+ .command('list-tools')
96
+ .alias('lt')
97
+ .description('List all available tools from the MCP server')
98
+ .argument('<command>', 'Command to run the MCP server')
99
+ .argument('[args...]', 'Arguments for the server command')
100
+ .option('--json', 'Output as JSON')
101
+ .action(async (command, args, opts) => {
102
+ const client = new MCPClient({
103
+ name: 'mcp-tester-cli',
104
+ version: '1.0.0',
105
+ timeout: parseInt(String(opts['timeout'] || '30000')),
106
+ logLevel: opts['verbose'] ? 'debug' : 'info',
107
+ });
108
+ try {
109
+ await client.start({ command, args });
110
+ const tools = await client.listTools();
111
+ if (opts['json']) {
112
+ console.log(JSON.stringify({ tools }, null, 2));
113
+ }
114
+ else {
115
+ console.log(`šŸ› ļø Available tools (${tools.length}):\n`);
116
+ tools.forEach((tool) => {
117
+ console.log(` ${tool.name}`);
118
+ console.log(` Description: ${tool.description}`);
119
+ if (tool.inputSchema?.properties) {
120
+ const props = Object.keys(tool.inputSchema.properties);
121
+ console.log(` Parameters: ${props.join(', ') || '(none)'}`);
122
+ }
123
+ console.log();
124
+ });
125
+ }
126
+ }
127
+ catch (error) {
128
+ console.error(`āŒ Error: ${error instanceof Error ? error.message : String(error)}`);
129
+ process.exit(1);
130
+ }
131
+ finally {
132
+ await client.stop();
133
+ }
134
+ });
135
+ // Call tool command
136
+ program
137
+ .command('call-tool')
138
+ .alias('ct')
139
+ .description('Call a tool on the MCP server')
140
+ .argument('<tool-name>', 'Name of the tool to call')
141
+ .argument('<command>', 'Command to run the MCP server')
142
+ .argument('[args...]', 'Arguments for the server command')
143
+ .option('--params <json>', 'Tool parameters as JSON string')
144
+ .option('--json', 'Output as JSON')
145
+ .action(async (toolName, command, serverArgs, opts) => {
146
+ const client = new MCPClient({
147
+ name: 'mcp-tester-cli',
148
+ version: '1.0.0',
149
+ timeout: parseInt(String(opts['timeout'] || '30000')),
150
+ logLevel: opts['verbose'] ? 'debug' : 'info',
151
+ });
152
+ let toolArgs = {};
153
+ if (opts['params']) {
154
+ try {
155
+ toolArgs = JSON.parse(String(opts['params']));
156
+ }
157
+ catch {
158
+ console.error('āŒ Invalid JSON for --params');
159
+ process.exit(1);
160
+ }
161
+ }
162
+ try {
163
+ await client.start({ command, args: serverArgs });
164
+ if (!opts['json']) {
165
+ console.log(`šŸ”§ Calling tool: ${toolName}`);
166
+ if (Object.keys(toolArgs).length > 0) {
167
+ console.log(` Parameters: ${JSON.stringify(toolArgs)}`);
168
+ }
169
+ }
170
+ const result = await client.callTool({
171
+ name: toolName,
172
+ arguments: toolArgs,
173
+ });
174
+ if (opts['json']) {
175
+ console.log(JSON.stringify(result, null, 2));
176
+ }
177
+ else {
178
+ console.log('\nāœ… Result:');
179
+ result.content.forEach((item) => {
180
+ if ('text' in item) {
181
+ console.log(` ${item.text}`);
182
+ }
183
+ else if ('data' in item) {
184
+ console.log(` ${JSON.stringify(item.data)}`);
185
+ }
186
+ });
187
+ }
188
+ }
189
+ catch (error) {
190
+ console.error(`āŒ Error: ${error instanceof Error ? error.message : String(error)}`);
191
+ process.exit(1);
192
+ }
193
+ finally {
194
+ await client.stop();
195
+ }
196
+ });
197
+ // Read resource command
198
+ program
199
+ .command('read-resource')
200
+ .alias('rr')
201
+ .description('Read a resource from the MCP server')
202
+ .argument('<uri>', 'URI of the resource to read')
203
+ .argument('<command>', 'Command to run the MCP server')
204
+ .argument('[args...]', 'Arguments for the server command')
205
+ .option('--json', 'Output as JSON')
206
+ .action(async (uri, command, serverArgs, opts) => {
207
+ const client = new MCPClient({
208
+ name: 'mcp-tester-cli',
209
+ version: '1.0.0',
210
+ timeout: parseInt(String(opts['timeout'] || '30000')),
211
+ logLevel: opts['verbose'] ? 'debug' : 'info',
212
+ });
213
+ try {
214
+ await client.start({ command, args: serverArgs });
215
+ if (!opts['json']) {
216
+ console.log(`šŸ“– Reading resource: ${uri}`);
217
+ }
218
+ const result = await client.readResource(uri);
219
+ if (opts['json']) {
220
+ console.log(JSON.stringify(result, null, 2));
221
+ }
222
+ else {
223
+ result.contents.forEach((item) => {
224
+ if ('text' in item) {
225
+ console.log('\nšŸ“„ Content:');
226
+ console.log(` ${item.text}`);
227
+ }
228
+ });
229
+ }
230
+ }
231
+ catch (error) {
232
+ console.error(`āŒ Error: ${error instanceof Error ? error.message : String(error)}`);
233
+ process.exit(1);
234
+ }
235
+ finally {
236
+ await client.stop();
237
+ }
238
+ });
239
+ // Get prompt command
240
+ program
241
+ .command('get-prompt')
242
+ .alias('gp')
243
+ .description('Get a prompt from the MCP server')
244
+ .argument('<name>', 'Name of the prompt')
245
+ .argument('<command>', 'Command to run the MCP server')
246
+ .argument('[args...]', 'Arguments for the server command')
247
+ .option('--args <json>', 'Prompt arguments as JSON string')
248
+ .option('--json', 'Output as JSON')
249
+ .action(async (promptName, command, serverArgs, opts) => {
250
+ const client = new MCPClient({
251
+ name: 'mcp-tester-cli',
252
+ version: '1.0.0',
253
+ timeout: parseInt(String(opts['timeout'] || '30000')),
254
+ logLevel: opts['verbose'] ? 'debug' : 'info',
255
+ });
256
+ let promptArgs = {};
257
+ if (opts['args']) {
258
+ try {
259
+ promptArgs = JSON.parse(String(opts['args']));
260
+ }
261
+ catch {
262
+ console.error('āŒ Invalid JSON for --args');
263
+ process.exit(1);
264
+ }
265
+ }
266
+ try {
267
+ await client.start({ command, args: serverArgs });
268
+ if (!opts['json']) {
269
+ console.log(`šŸ’¬ Getting prompt: ${promptName}`);
270
+ }
271
+ const result = await client.getPrompt(promptName, promptArgs);
272
+ if (opts['json']) {
273
+ console.log(JSON.stringify(result, null, 2));
274
+ }
275
+ else {
276
+ console.log('\nšŸ“ Messages:');
277
+ result.messages.forEach((msg) => {
278
+ console.log(` [${msg.role}]`);
279
+ if ('text' in msg.content) {
280
+ console.log(` ${msg.content.text}`);
281
+ }
282
+ });
283
+ }
284
+ }
285
+ catch (error) {
286
+ console.error(`āŒ Error: ${error instanceof Error ? error.message : String(error)}`);
287
+ process.exit(1);
288
+ }
289
+ finally {
290
+ await client.stop();
291
+ }
292
+ });
293
+ // Add custom help with examples using Commander's built-in help system
294
+ program.addHelpText('after', `
295
+ Examples:
296
+ mcp-tester test node ./server.js
297
+ mcp-tester list-tools node ./server.js --json
298
+ mcp-tester call-tool echo node ./server.js --params '{"message":"Hello"}'
299
+ mcp-tester read-resource text://example node ./server.js
300
+ mcp-tester get-prompt greet node ./server.js --args '{"name":"World"}'
301
+ mcp-tester lt node ./server.js # short alias for list-tools
302
+ mcp-tester ct echo node ./server.js --params '{}' # short alias for call-tool
303
+ `);
304
+ // Show help when invoked with no arguments
305
+ const args = process.argv.slice(2);
306
+ if (args.length === 0) {
307
+ program.outputHelp();
308
+ process.exit(0);
309
+ }
310
+ program.parse();
311
+ //# sourceMappingURL=index.js.map