@mcp-z/cli 1.0.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.
Files changed (126) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +166 -0
  3. package/bin/cli.js +5 -0
  4. package/dist/cjs/cli.d.cts +1 -0
  5. package/dist/cjs/cli.d.ts +1 -0
  6. package/dist/cjs/cli.js +576 -0
  7. package/dist/cjs/cli.js.map +1 -0
  8. package/dist/cjs/commands/call-tool.d.cts +26 -0
  9. package/dist/cjs/commands/call-tool.d.ts +26 -0
  10. package/dist/cjs/commands/call-tool.js +362 -0
  11. package/dist/cjs/commands/call-tool.js.map +1 -0
  12. package/dist/cjs/commands/get-prompt.d.cts +26 -0
  13. package/dist/cjs/commands/get-prompt.d.ts +26 -0
  14. package/dist/cjs/commands/get-prompt.js +335 -0
  15. package/dist/cjs/commands/get-prompt.js.map +1 -0
  16. package/dist/cjs/commands/inspect.d.cts +35 -0
  17. package/dist/cjs/commands/inspect.d.ts +35 -0
  18. package/dist/cjs/commands/inspect.js +896 -0
  19. package/dist/cjs/commands/inspect.js.map +1 -0
  20. package/dist/cjs/commands/manifest/env-prompting.d.cts +21 -0
  21. package/dist/cjs/commands/manifest/env-prompting.d.ts +21 -0
  22. package/dist/cjs/commands/manifest/env-prompting.js +657 -0
  23. package/dist/cjs/commands/manifest/env-prompting.js.map +1 -0
  24. package/dist/cjs/commands/manifest/generate.d.cts +124 -0
  25. package/dist/cjs/commands/manifest/generate.d.ts +124 -0
  26. package/dist/cjs/commands/manifest/generate.js +2541 -0
  27. package/dist/cjs/commands/manifest/generate.js.map +1 -0
  28. package/dist/cjs/commands/manifest/index.d.cts +2 -0
  29. package/dist/cjs/commands/manifest/index.d.ts +2 -0
  30. package/dist/cjs/commands/manifest/index.js +229 -0
  31. package/dist/cjs/commands/manifest/index.js.map +1 -0
  32. package/dist/cjs/commands/manifest/metadata-reader.d.cts +71 -0
  33. package/dist/cjs/commands/manifest/metadata-reader.d.ts +71 -0
  34. package/dist/cjs/commands/manifest/metadata-reader.js +441 -0
  35. package/dist/cjs/commands/manifest/metadata-reader.js.map +1 -0
  36. package/dist/cjs/commands/manifest/validate.d.cts +1 -0
  37. package/dist/cjs/commands/manifest/validate.d.ts +1 -0
  38. package/dist/cjs/commands/manifest/validate.js +525 -0
  39. package/dist/cjs/commands/manifest/validate.js.map +1 -0
  40. package/dist/cjs/commands/read-resource.d.cts +24 -0
  41. package/dist/cjs/commands/read-resource.d.ts +24 -0
  42. package/dist/cjs/commands/read-resource.js +311 -0
  43. package/dist/cjs/commands/read-resource.js.map +1 -0
  44. package/dist/cjs/commands/search.d.cts +31 -0
  45. package/dist/cjs/commands/search.d.ts +31 -0
  46. package/dist/cjs/commands/search.js +464 -0
  47. package/dist/cjs/commands/search.js.map +1 -0
  48. package/dist/cjs/commands/up.d.cts +49 -0
  49. package/dist/cjs/commands/up.d.ts +49 -0
  50. package/dist/cjs/commands/up.js +235 -0
  51. package/dist/cjs/commands/up.js.map +1 -0
  52. package/dist/cjs/index.d.cts +7 -0
  53. package/dist/cjs/index.d.ts +7 -0
  54. package/dist/cjs/index.js +85 -0
  55. package/dist/cjs/index.js.map +1 -0
  56. package/dist/cjs/lib/find-config.d.cts +14 -0
  57. package/dist/cjs/lib/find-config.d.ts +14 -0
  58. package/dist/cjs/lib/find-config.js +93 -0
  59. package/dist/cjs/lib/find-config.js.map +1 -0
  60. package/dist/cjs/lib/json-schema.d.cts +18 -0
  61. package/dist/cjs/lib/json-schema.d.ts +18 -0
  62. package/dist/cjs/lib/json-schema.js +306 -0
  63. package/dist/cjs/lib/json-schema.js.map +1 -0
  64. package/dist/cjs/lib/resolve-server-config.d.cts +50 -0
  65. package/dist/cjs/lib/resolve-server-config.d.ts +50 -0
  66. package/dist/cjs/lib/resolve-server-config.js +214 -0
  67. package/dist/cjs/lib/resolve-server-config.js.map +1 -0
  68. package/dist/cjs/package.json +1 -0
  69. package/dist/cjs/types.d.cts +21 -0
  70. package/dist/cjs/types.d.ts +21 -0
  71. package/dist/cjs/types.js +32 -0
  72. package/dist/cjs/types.js.map +1 -0
  73. package/dist/esm/cli.d.ts +1 -0
  74. package/dist/esm/cli.js +129 -0
  75. package/dist/esm/cli.js.map +1 -0
  76. package/dist/esm/commands/call-tool.d.ts +26 -0
  77. package/dist/esm/commands/call-tool.js +151 -0
  78. package/dist/esm/commands/call-tool.js.map +1 -0
  79. package/dist/esm/commands/get-prompt.d.ts +26 -0
  80. package/dist/esm/commands/get-prompt.js +118 -0
  81. package/dist/esm/commands/get-prompt.js.map +1 -0
  82. package/dist/esm/commands/inspect.d.ts +35 -0
  83. package/dist/esm/commands/inspect.js +438 -0
  84. package/dist/esm/commands/inspect.js.map +1 -0
  85. package/dist/esm/commands/manifest/env-prompting.d.ts +21 -0
  86. package/dist/esm/commands/manifest/env-prompting.js +213 -0
  87. package/dist/esm/commands/manifest/env-prompting.js.map +1 -0
  88. package/dist/esm/commands/manifest/generate.d.ts +124 -0
  89. package/dist/esm/commands/manifest/generate.js +1087 -0
  90. package/dist/esm/commands/manifest/generate.js.map +1 -0
  91. package/dist/esm/commands/manifest/index.d.ts +2 -0
  92. package/dist/esm/commands/manifest/index.js +23 -0
  93. package/dist/esm/commands/manifest/index.js.map +1 -0
  94. package/dist/esm/commands/manifest/metadata-reader.d.ts +71 -0
  95. package/dist/esm/commands/manifest/metadata-reader.js +143 -0
  96. package/dist/esm/commands/manifest/metadata-reader.js.map +1 -0
  97. package/dist/esm/commands/manifest/validate.d.ts +1 -0
  98. package/dist/esm/commands/manifest/validate.js +167 -0
  99. package/dist/esm/commands/manifest/validate.js.map +1 -0
  100. package/dist/esm/commands/read-resource.d.ts +24 -0
  101. package/dist/esm/commands/read-resource.js +95 -0
  102. package/dist/esm/commands/read-resource.js.map +1 -0
  103. package/dist/esm/commands/search.d.ts +31 -0
  104. package/dist/esm/commands/search.js +145 -0
  105. package/dist/esm/commands/search.js.map +1 -0
  106. package/dist/esm/commands/up.d.ts +49 -0
  107. package/dist/esm/commands/up.js +74 -0
  108. package/dist/esm/commands/up.js.map +1 -0
  109. package/dist/esm/index.d.ts +7 -0
  110. package/dist/esm/index.js +11 -0
  111. package/dist/esm/index.js.map +1 -0
  112. package/dist/esm/lib/find-config.d.ts +14 -0
  113. package/dist/esm/lib/find-config.js +42 -0
  114. package/dist/esm/lib/find-config.js.map +1 -0
  115. package/dist/esm/lib/json-schema.d.ts +18 -0
  116. package/dist/esm/lib/json-schema.js +66 -0
  117. package/dist/esm/lib/json-schema.js.map +1 -0
  118. package/dist/esm/lib/resolve-server-config.d.ts +50 -0
  119. package/dist/esm/lib/resolve-server-config.js +154 -0
  120. package/dist/esm/lib/resolve-server-config.js.map +1 -0
  121. package/dist/esm/package.json +1 -0
  122. package/dist/esm/types.d.ts +21 -0
  123. package/dist/esm/types.js +11 -0
  124. package/dist/esm/types.js.map +1 -0
  125. package/package.json +99 -0
  126. package/schemas/server.schema.json +489 -0
@@ -0,0 +1,438 @@
1
+ /**
2
+ * inspect.ts
3
+ *
4
+ * Inspect MCP servers: explore tools, resources, prompts, and health status.
5
+ * Supports stdio (spawned) and http (remote) servers per MCP spec.
6
+ */ import { createServerRegistry } from '@mcp-z/client';
7
+ import * as fs from 'fs';
8
+ import * as path from 'path';
9
+ import { findConfigPath } from '../lib/find-config.js';
10
+ import { isHttpServer } from '../types.js';
11
+ const MAX_DESCRIPTION = 100;
12
+ /**
13
+ * Main inspect command implementation.
14
+ *
15
+ * @param opts - Inspect options from CLI flags
16
+ *
17
+ * @example
18
+ * // Show summary of .mcp.json servers (spawns servers)
19
+ * await inspectCommand({});
20
+ *
21
+ * @example
22
+ * // Show all tools from echo server (spawns server)
23
+ * await inspectCommand({ servers: 'echo', tools: true });
24
+ *
25
+ * @example
26
+ * // Connect to running servers (attach mode)
27
+ * await inspectCommand({ config: 'http-servers.json', attach: true, health: true });
28
+ */ export async function inspectCommand(opts = {}) {
29
+ let registry;
30
+ try {
31
+ var _ref, _raw_mcpServers;
32
+ const configPath = findConfigPath(opts.config);
33
+ const raw = JSON.parse(fs.readFileSync(configPath, 'utf8'));
34
+ const servers = (_ref = (_raw_mcpServers = raw.mcpServers) !== null && _raw_mcpServers !== void 0 ? _raw_mcpServers : raw.servers) !== null && _ref !== void 0 ? _ref : raw;
35
+ const configDir = path.dirname(configPath);
36
+ const serverNames = Object.keys(servers || {});
37
+ const serversToInspect = filterServers(serverNames, opts.servers);
38
+ // Create registry (spawns stdio servers, registers HTTP servers)
39
+ // In attach mode, don't spawn - just register for connection
40
+ registry = createServerRegistry(servers, {
41
+ cwd: configDir,
42
+ dialects: opts.attach ? [] : [
43
+ 'servers',
44
+ 'start'
45
+ ]
46
+ });
47
+ const serverInfos = [];
48
+ for (const serverName of serversToInspect){
49
+ const info = await inspectServer(serverName, servers, registry, opts);
50
+ serverInfos.push(info);
51
+ }
52
+ // 5. Output results
53
+ if (opts.json) {
54
+ outputJSON(serverInfos);
55
+ } else {
56
+ outputPretty(serverInfos, opts);
57
+ }
58
+ } finally{
59
+ // 6. Cleanup - registry.close() handles all clients and servers
60
+ if (registry) {
61
+ try {
62
+ await registry.close();
63
+ } catch (_) {
64
+ // Ignore close errors
65
+ }
66
+ }
67
+ }
68
+ }
69
+ /**
70
+ * Filter servers based on --servers flag.
71
+ */ function filterServers(allServers, serversFlag) {
72
+ if (!serversFlag) {
73
+ return allServers;
74
+ }
75
+ const requested = serversFlag.split(',').map((s)=>s.trim());
76
+ const missing = requested.filter((s)=>!allServers.includes(s));
77
+ if (missing.length > 0) {
78
+ throw new Error(`Server(s) not found in config: ${missing.join(', ')}\n\nAvailable servers: ${allServers.join(', ')}`);
79
+ }
80
+ return requested;
81
+ }
82
+ /**
83
+ * Inspect a single server: collect tools, resources, prompts, health.
84
+ */ async function inspectServer(serverName, servers, registry, opts) {
85
+ const start = Date.now();
86
+ try {
87
+ // Connect to server via registry
88
+ const serverConfig = servers === null || servers === void 0 ? void 0 : servers[serverName];
89
+ if (!serverConfig) {
90
+ throw new Error(`Server ${serverName} not found in config`);
91
+ }
92
+ if (!isHttpServer(serverConfig) && !serverConfig.command) {
93
+ throw new Error(`Stdio server ${serverName} missing required "command" field`);
94
+ }
95
+ const client = await registry.connect(serverName);
96
+ // Collect content based on flags
97
+ const needsTools = opts.tools || shouldShowSummary(opts);
98
+ const needsResources = opts.resources || shouldShowSummary(opts);
99
+ const needsPrompts = opts.prompts || shouldShowSummary(opts);
100
+ // Handle each capability independently - servers may not implement all methods
101
+ const [toolsResult, resourcesResult, promptsResult] = await Promise.all([
102
+ needsTools ? client.listTools().catch(()=>null) : Promise.resolve(null),
103
+ needsResources ? client.listResources().catch(()=>null) : Promise.resolve(null),
104
+ needsPrompts ? client.listPrompts().catch(()=>null) : Promise.resolve(null)
105
+ ]);
106
+ const startupTime = Date.now() - start;
107
+ return {
108
+ name: serverName,
109
+ status: 'ready',
110
+ startupTime,
111
+ error: undefined,
112
+ tools: (toolsResult === null || toolsResult === void 0 ? void 0 : toolsResult.tools) ? toolsResult.tools.map((t)=>({
113
+ name: t.name,
114
+ description: t.description,
115
+ inputSchema: t.inputSchema
116
+ })) : undefined,
117
+ resources: (resourcesResult === null || resourcesResult === void 0 ? void 0 : resourcesResult.resources) ? resourcesResult.resources.map((r)=>({
118
+ uri: r.uri,
119
+ name: r.name,
120
+ description: r.description,
121
+ mimeType: r.mimeType
122
+ })) : undefined,
123
+ prompts: (promptsResult === null || promptsResult === void 0 ? void 0 : promptsResult.prompts) ? promptsResult.prompts.map((p)=>({
124
+ name: p.name,
125
+ description: p.description,
126
+ arguments: p.arguments
127
+ })) : undefined
128
+ };
129
+ } catch (error) {
130
+ // Format error message with context
131
+ let errorMessage = error instanceof Error ? error.message : String(error);
132
+ // For fetch errors, dig into the cause for more details
133
+ if (error instanceof Error && error.message === 'fetch failed' && 'cause' in error) {
134
+ const cause = error.cause;
135
+ if ((cause === null || cause === void 0 ? void 0 : cause.code) === 'ECONNREFUSED') {
136
+ const serverConfig = servers === null || servers === void 0 ? void 0 : servers[serverName];
137
+ const url = serverConfig && 'url' in serverConfig ? serverConfig.url : undefined;
138
+ errorMessage = url ? `Connection refused (server not running at ${url})` : 'Connection refused (server not running)';
139
+ } else if (cause === null || cause === void 0 ? void 0 : cause.message) {
140
+ errorMessage = `${error.message}: ${cause.message}`;
141
+ }
142
+ }
143
+ return {
144
+ name: serverName,
145
+ status: 'failed',
146
+ startupTime: undefined,
147
+ error: errorMessage,
148
+ tools: undefined,
149
+ resources: undefined,
150
+ prompts: undefined
151
+ };
152
+ }
153
+ }
154
+ /**
155
+ * Determine if we should show summary (no specific content flags).
156
+ */ function shouldShowSummary(opts) {
157
+ return !opts.tools && !opts.resources && !opts.prompts && !opts.health;
158
+ }
159
+ /**
160
+ * Truncate description to max length with ellipsis.
161
+ */ function truncateDescription(desc, _maxLength = MAX_DESCRIPTION) {
162
+ return desc;
163
+ // if (!desc || desc.length <= maxLength) {
164
+ // return desc;
165
+ // }
166
+ // return `${desc.slice(0, maxLength - 3)}...`;
167
+ }
168
+ /**
169
+ * Render verbose details for a tool (parameters with types and descriptions)
170
+ */ function renderToolVerbose(tool, indent) {
171
+ // Description is already shown inline, so skip it here
172
+ const schema = tool.inputSchema;
173
+ if (!schema || !schema.properties) {
174
+ return;
175
+ }
176
+ const properties = schema.properties;
177
+ const required = schema.required || [];
178
+ // Separate required and optional parameters
179
+ const requiredParams = [];
180
+ const optionalParams = [];
181
+ for (const [name, _prop] of Object.entries(properties)){
182
+ if (required.includes(name)) {
183
+ requiredParams.push(name);
184
+ } else {
185
+ optionalParams.push(name);
186
+ }
187
+ }
188
+ // Show required parameters
189
+ if (requiredParams.length > 0) {
190
+ console.log(`${indent}Required Parameters:`);
191
+ for (const name of requiredParams){
192
+ renderParameter(name, properties[name], `${indent} `);
193
+ }
194
+ console.log('');
195
+ }
196
+ // Show optional parameters
197
+ if (optionalParams.length > 0) {
198
+ console.log(`${indent}Optional Parameters:`);
199
+ for (const name of optionalParams){
200
+ renderParameter(name, properties[name], `${indent} `);
201
+ }
202
+ console.log('');
203
+ }
204
+ }
205
+ /**
206
+ * Render verbose details for a resource
207
+ */ function renderResourceVerbose(resource, indent) {
208
+ // Description is already shown inline, so only show URI and MIME type
209
+ if (resource.uri) {
210
+ console.log(`${indent}URI: ${resource.uri}`);
211
+ }
212
+ if (resource.mimeType) {
213
+ console.log(`${indent}MIME Type: ${resource.mimeType}`);
214
+ }
215
+ if (resource.uri || resource.mimeType) {
216
+ console.log('');
217
+ }
218
+ }
219
+ /**
220
+ * Render verbose details for a prompt
221
+ */ function renderPromptVerbose(prompt, indent) {
222
+ // Description is already shown inline, so only show arguments
223
+ if (prompt.arguments && Array.isArray(prompt.arguments) && prompt.arguments.length > 0) {
224
+ console.log(`${indent}Arguments:`);
225
+ for (const arg of prompt.arguments){
226
+ const argObj = arg;
227
+ const name = argObj.name || 'unknown';
228
+ const description = argObj.description || '';
229
+ const required = argObj.required ? ' (required)' : ' (optional)';
230
+ const desc = description ? ` - ${description}` : '';
231
+ console.log(`${indent} ${name}${required}${desc}`);
232
+ }
233
+ console.log('');
234
+ }
235
+ }
236
+ /**
237
+ * Render a single parameter with type and description
238
+ */ function renderParameter(name, prop, indent) {
239
+ const p = prop;
240
+ const type = getParameterType(prop);
241
+ const constraints = getParameterConstraints(prop);
242
+ const typeInfo = constraints ? `(${type}) ${constraints}` : `(${type})`;
243
+ const desc = p.description ? ` - ${p.description}` : '';
244
+ console.log(`${indent}${name} ${typeInfo}${desc}`);
245
+ // Show enum options on separate line if present
246
+ if (p.enum && Array.isArray(p.enum)) {
247
+ console.log(`${indent} Options: ${p.enum.join(', ')}`);
248
+ }
249
+ }
250
+ /**
251
+ * Get human-readable type from JSON Schema property
252
+ */ function getParameterType(prop) {
253
+ const p = prop;
254
+ if (p.type) {
255
+ if (Array.isArray(p.type)) {
256
+ return p.type.join(' | ');
257
+ }
258
+ if (p.type === 'array' && p.items) {
259
+ const itemType = p.items.type || 'any';
260
+ return `array of ${itemType}`;
261
+ }
262
+ return p.type;
263
+ }
264
+ if (p.anyOf) {
265
+ return p.anyOf.map((s)=>s.type || 'any').join(' | ');
266
+ }
267
+ if (p.enum) {
268
+ return 'enum';
269
+ }
270
+ return 'any';
271
+ }
272
+ /**
273
+ * Get parameter constraints (default, min, max, etc.)
274
+ */ function getParameterConstraints(prop) {
275
+ const p = prop;
276
+ const constraints = [];
277
+ if (p.default !== undefined) {
278
+ const defaultValue = typeof p.default === 'string' ? `"${p.default}"` : String(p.default);
279
+ constraints.push(`default: ${defaultValue}`);
280
+ }
281
+ if (p.minimum !== undefined) {
282
+ constraints.push(`min: ${p.minimum}`);
283
+ }
284
+ if (p.maximum !== undefined) {
285
+ constraints.push(`max: ${p.maximum}`);
286
+ }
287
+ if (p.minLength !== undefined) {
288
+ constraints.push(`minLength: ${p.minLength}`);
289
+ }
290
+ if (p.maxLength !== undefined) {
291
+ constraints.push(`maxLength: ${p.maxLength}`);
292
+ }
293
+ if (p.minItems !== undefined) {
294
+ constraints.push(`minItems: ${p.minItems}`);
295
+ }
296
+ if (p.maxItems !== undefined) {
297
+ constraints.push(`maxItems: ${p.maxItems}`);
298
+ }
299
+ return constraints.length > 0 ? `[${constraints.join(', ')}]` : '';
300
+ }
301
+ /**
302
+ * Output results as JSON.
303
+ */ function outputJSON(serverInfos) {
304
+ const output = {
305
+ servers: serverInfos.reduce((acc, info)=>{
306
+ acc[info.name] = {
307
+ status: info.status,
308
+ startupTime: info.startupTime ? `${(info.startupTime / 1000).toFixed(1)}s` : undefined,
309
+ error: info.error,
310
+ tools: info.tools,
311
+ resources: info.resources,
312
+ prompts: info.prompts
313
+ };
314
+ return acc;
315
+ }, {})
316
+ };
317
+ console.log(JSON.stringify(output, null, 2));
318
+ }
319
+ /**
320
+ * Output results in human-readable format.
321
+ */ function outputPretty(serverInfos, opts) {
322
+ const showSummary = shouldShowSummary(opts);
323
+ for (const info of serverInfos){
324
+ // Summary mode
325
+ if (showSummary) {
326
+ if (info.status === 'ready') {
327
+ var _info_tools, _info_resources, _info_prompts;
328
+ const toolCount = ((_info_tools = info.tools) === null || _info_tools === void 0 ? void 0 : _info_tools.length) || 0;
329
+ const resourceCount = ((_info_resources = info.resources) === null || _info_resources === void 0 ? void 0 : _info_resources.length) || 0;
330
+ const promptCount = ((_info_prompts = info.prompts) === null || _info_prompts === void 0 ? void 0 : _info_prompts.length) || 0;
331
+ const time = info.startupTime ? `(${(info.startupTime / 1000).toFixed(1)}s)` : '';
332
+ console.log(`šŸ“¦ ${info.name}: ${time}`);
333
+ // Show detailed list of tools
334
+ console.log(`tools: ${toolCount}`);
335
+ if (info.tools && info.tools.length > 0) {
336
+ for(let i = 0; i < info.tools.length; i++){
337
+ const tool = info.tools[i];
338
+ if (!tool) continue; // Array indexing can return undefined with noUncheckedIndexedAccess
339
+ const desc = tool.description ? ` - ${opts.verbose ? tool.description : truncateDescription(tool.description)}` : '';
340
+ console.log(`${i + 1}. ${tool.name}${desc}`);
341
+ if (opts.verbose) {
342
+ renderToolVerbose(tool, ' ');
343
+ }
344
+ }
345
+ }
346
+ // Show detailed list of resources
347
+ console.log(`resources: ${resourceCount}`);
348
+ if (info.resources && info.resources.length > 0) {
349
+ for(let i = 0; i < info.resources.length; i++){
350
+ const resource = info.resources[i];
351
+ if (!resource) continue; // Array indexing can return undefined with noUncheckedIndexedAccess
352
+ const desc = resource.description ? ` - ${opts.verbose ? resource.description : truncateDescription(resource.description)}` : '';
353
+ console.log(`${i + 1}. ${resource.name}${desc}`);
354
+ if (opts.verbose) {
355
+ renderResourceVerbose(resource, ' ');
356
+ }
357
+ }
358
+ }
359
+ // Show detailed list of prompts
360
+ console.log(`prompts: ${promptCount}`);
361
+ if (info.prompts && info.prompts.length > 0) {
362
+ for(let i = 0; i < info.prompts.length; i++){
363
+ const prompt = info.prompts[i];
364
+ if (!prompt) continue; // Array indexing can return undefined with noUncheckedIndexedAccess
365
+ const desc = prompt.description ? ` - ${opts.verbose ? prompt.description : truncateDescription(prompt.description)}` : '';
366
+ console.log(`${i + 1}. ${prompt.name}${desc}`);
367
+ if (opts.verbose) {
368
+ renderPromptVerbose(prompt, ' ');
369
+ }
370
+ }
371
+ }
372
+ } else {
373
+ console.log(`šŸ“¦ ${info.name}: āœ— failed - ${info.error}`);
374
+ }
375
+ continue;
376
+ }
377
+ // Health mode
378
+ if (opts.health) {
379
+ if (info.status === 'ready') {
380
+ const time = info.startupTime ? `(${(info.startupTime / 1000).toFixed(1)}s)` : '';
381
+ console.log(`āœ“ ${info.name} - ready ${time}`);
382
+ } else {
383
+ console.log(`āœ— ${info.name} - failed`);
384
+ console.log(` Error: ${info.error}`);
385
+ }
386
+ continue;
387
+ }
388
+ // Tools mode
389
+ if (opts.tools) {
390
+ var _info_tools1;
391
+ console.log(`\nšŸ“¦ ${info.name} (${((_info_tools1 = info.tools) === null || _info_tools1 === void 0 ? void 0 : _info_tools1.length) || 0} tools)`);
392
+ if (info.tools && info.tools.length > 0) {
393
+ for(let i = 0; i < info.tools.length; i++){
394
+ const tool = info.tools[i];
395
+ if (!tool) continue; // Array indexing can return undefined with noUncheckedIndexedAccess
396
+ const desc = tool.description ? ` - ${opts.verbose ? tool.description : truncateDescription(tool.description)}` : '';
397
+ console.log(` ${i + 1}. ${tool.name}${desc}`);
398
+ if (opts.verbose) {
399
+ renderToolVerbose(tool, ' ');
400
+ }
401
+ }
402
+ }
403
+ }
404
+ // Resources mode
405
+ if (opts.resources) {
406
+ var _info_resources1;
407
+ console.log(`\nšŸ“¦ ${info.name} (${((_info_resources1 = info.resources) === null || _info_resources1 === void 0 ? void 0 : _info_resources1.length) || 0} resources)`);
408
+ if (info.resources && info.resources.length > 0) {
409
+ for(let i = 0; i < info.resources.length; i++){
410
+ const resource = info.resources[i];
411
+ if (!resource) continue; // Array indexing can return undefined with noUncheckedIndexedAccess
412
+ const desc = resource.description ? ` - ${opts.verbose ? resource.description : truncateDescription(resource.description)}` : '';
413
+ console.log(` ${i + 1}. ${resource.name}${desc}`);
414
+ if (opts.verbose) {
415
+ renderResourceVerbose(resource, ' ');
416
+ }
417
+ }
418
+ }
419
+ }
420
+ // Prompts mode
421
+ if (opts.prompts) {
422
+ var _info_prompts1;
423
+ console.log(`\nšŸ“¦ ${info.name} (${((_info_prompts1 = info.prompts) === null || _info_prompts1 === void 0 ? void 0 : _info_prompts1.length) || 0} prompts)`);
424
+ if (info.prompts && info.prompts.length > 0) {
425
+ for(let i = 0; i < info.prompts.length; i++){
426
+ const prompt = info.prompts[i];
427
+ if (!prompt) continue; // Array indexing can return undefined with noUncheckedIndexedAccess
428
+ const desc = prompt.description ? ` - ${opts.verbose ? prompt.description : truncateDescription(prompt.description)}` : '';
429
+ console.log(` ${i + 1}. ${prompt.name}${desc}`);
430
+ if (opts.verbose) {
431
+ renderPromptVerbose(prompt, ' ');
432
+ }
433
+ }
434
+ }
435
+ }
436
+ }
437
+ console.log('');
438
+ }
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/Users/kevin/Dev/Projects/ai/mcp-z/cli/src/commands/inspect.ts"],"sourcesContent":["/**\n * inspect.ts\n *\n * Inspect MCP servers: explore tools, resources, prompts, and health status.\n * Supports stdio (spawned) and http (remote) servers per MCP spec.\n */\n\nimport { createServerRegistry, type PromptArgument, type ServerRegistry, type ServersConfig } from '@mcp-z/client';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport { findConfigPath } from '../lib/find-config.ts';\nimport { isHttpServer, type ServerConfig } from '../types.ts';\n\nconst MAX_DESCRIPTION = 100;\n\nexport interface InspectOptions {\n config?: string; // --config custom.json\n servers?: string; // --servers echo-server-1,echo-server-2 (comma-separated)\n tools?: boolean; // --tools\n resources?: boolean; // --resources\n prompts?: boolean; // --prompts\n health?: boolean; // --health\n json?: boolean; // --json\n verbose?: boolean; // --verbose\n attach?: boolean; // --attach (connect to running servers instead of spawning)\n}\n\ninterface ServerInfo {\n name: string;\n status: 'ready' | 'failed';\n startupTime: number | undefined;\n error: string | undefined;\n tools: ToolInfo[] | undefined;\n resources: ResourceInfo[] | undefined;\n prompts: PromptInfo[] | undefined;\n}\n\ninterface ToolInfo {\n name: string;\n description: string | undefined;\n inputSchema: unknown;\n}\n\ninterface ResourceInfo {\n uri: string;\n name: string;\n description: string | undefined;\n mimeType: string | undefined;\n}\n\ninterface PromptInfo {\n name: string;\n description: string | undefined;\n arguments: PromptArgument[] | undefined;\n}\n\n/**\n * Main inspect command implementation.\n *\n * @param opts - Inspect options from CLI flags\n *\n * @example\n * // Show summary of .mcp.json servers (spawns servers)\n * await inspectCommand({});\n *\n * @example\n * // Show all tools from echo server (spawns server)\n * await inspectCommand({ servers: 'echo', tools: true });\n *\n * @example\n * // Connect to running servers (attach mode)\n * await inspectCommand({ config: 'http-servers.json', attach: true, health: true });\n */\nexport async function inspectCommand(opts: InspectOptions = {}): Promise<void> {\n let registry: ServerRegistry | undefined;\n\n try {\n const configPath = findConfigPath(opts.config);\n const raw = JSON.parse(fs.readFileSync(configPath, 'utf8'));\n const servers = raw.mcpServers ?? raw.servers ?? raw;\n const configDir = path.dirname(configPath);\n const serverNames = Object.keys(servers || {});\n const serversToInspect = filterServers(serverNames, opts.servers);\n\n // Create registry (spawns stdio servers, registers HTTP servers)\n // In attach mode, don't spawn - just register for connection\n registry = createServerRegistry(servers, {\n cwd: configDir,\n dialects: opts.attach ? [] : ['servers', 'start'], // Empty dialects = no spawning\n });\n\n const serverInfos: ServerInfo[] = [];\n for (const serverName of serversToInspect) {\n const info = await inspectServer(serverName, servers, registry, opts);\n serverInfos.push(info);\n }\n\n // 5. Output results\n if (opts.json) {\n outputJSON(serverInfos);\n } else {\n outputPretty(serverInfos, opts);\n }\n } finally {\n // 6. Cleanup - registry.close() handles all clients and servers\n if (registry) {\n try {\n await registry.close();\n } catch (_) {\n // Ignore close errors\n }\n }\n }\n}\n\n/**\n * Filter servers based on --servers flag.\n */\nfunction filterServers(allServers: string[], serversFlag?: string): string[] {\n if (!serversFlag) {\n return allServers;\n }\n\n const requested = serversFlag.split(',').map((s) => s.trim());\n const missing = requested.filter((s) => !allServers.includes(s));\n\n if (missing.length > 0) {\n throw new Error(`Server(s) not found in config: ${missing.join(', ')}\\n\\nAvailable servers: ${allServers.join(', ')}`);\n }\n\n return requested;\n}\n\n/**\n * Inspect a single server: collect tools, resources, prompts, health.\n */\nasync function inspectServer(serverName: string, servers: ServersConfig, registry: ServerRegistry, opts: InspectOptions): Promise<ServerInfo> {\n const start = Date.now();\n\n try {\n // Connect to server via registry\n const serverConfig = servers?.[serverName];\n if (!serverConfig) {\n throw new Error(`Server ${serverName} not found in config`);\n }\n\n if (!isHttpServer(serverConfig as ServerConfig) && !serverConfig.command) {\n throw new Error(`Stdio server ${serverName} missing required \"command\" field`);\n }\n\n const client = await registry.connect(serverName);\n\n // Collect content based on flags\n const needsTools = opts.tools || shouldShowSummary(opts);\n const needsResources = opts.resources || shouldShowSummary(opts);\n const needsPrompts = opts.prompts || shouldShowSummary(opts);\n\n // Handle each capability independently - servers may not implement all methods\n const [toolsResult, resourcesResult, promptsResult] = await Promise.all([needsTools ? client.listTools().catch(() => null) : Promise.resolve(null), needsResources ? client.listResources().catch(() => null) : Promise.resolve(null), needsPrompts ? client.listPrompts().catch(() => null) : Promise.resolve(null)]);\n\n const startupTime = Date.now() - start;\n\n return {\n name: serverName,\n status: 'ready',\n startupTime,\n error: undefined,\n tools: toolsResult?.tools\n ? toolsResult.tools.map((t) => ({\n name: t.name,\n description: t.description,\n inputSchema: t.inputSchema,\n }))\n : undefined,\n resources: resourcesResult?.resources\n ? resourcesResult.resources.map((r) => ({\n uri: r.uri,\n name: r.name,\n description: r.description,\n mimeType: r.mimeType,\n }))\n : undefined,\n prompts: promptsResult?.prompts\n ? promptsResult.prompts.map((p) => ({\n name: p.name,\n description: p.description,\n arguments: p.arguments,\n }))\n : undefined,\n };\n } catch (error) {\n // Format error message with context\n let errorMessage = error instanceof Error ? error.message : String(error);\n\n // For fetch errors, dig into the cause for more details\n if (error instanceof Error && error.message === 'fetch failed' && 'cause' in error) {\n const cause = error.cause as { code?: string; message?: string } | undefined;\n if (cause?.code === 'ECONNREFUSED') {\n const serverConfig = servers?.[serverName];\n const url = serverConfig && 'url' in serverConfig ? serverConfig.url : undefined;\n errorMessage = url ? `Connection refused (server not running at ${url})` : 'Connection refused (server not running)';\n } else if (cause?.message) {\n errorMessage = `${error.message}: ${cause.message}`;\n }\n }\n\n return {\n name: serverName,\n status: 'failed',\n startupTime: undefined,\n error: errorMessage,\n tools: undefined,\n resources: undefined,\n prompts: undefined,\n };\n }\n}\n\n/**\n * Determine if we should show summary (no specific content flags).\n */\nfunction shouldShowSummary(opts: InspectOptions): boolean {\n return !opts.tools && !opts.resources && !opts.prompts && !opts.health;\n}\n\n/**\n * Truncate description to max length with ellipsis.\n */\nfunction truncateDescription(desc: string, _maxLength = MAX_DESCRIPTION): string {\n return desc;\n // if (!desc || desc.length <= maxLength) {\n // return desc;\n // }\n // return `${desc.slice(0, maxLength - 3)}...`;\n}\n\n/**\n * Render verbose details for a tool (parameters with types and descriptions)\n */\nfunction renderToolVerbose(tool: ToolInfo, indent: string): void {\n // Description is already shown inline, so skip it here\n const schema = tool.inputSchema as { properties?: Record<string, unknown>; required?: string[] } | undefined;\n if (!schema || !schema.properties) {\n return;\n }\n\n const properties = schema.properties;\n const required = schema.required || [];\n\n // Separate required and optional parameters\n const requiredParams: string[] = [];\n const optionalParams: string[] = [];\n\n for (const [name, _prop] of Object.entries(properties)) {\n if (required.includes(name)) {\n requiredParams.push(name);\n } else {\n optionalParams.push(name);\n }\n }\n\n // Show required parameters\n if (requiredParams.length > 0) {\n console.log(`${indent}Required Parameters:`);\n for (const name of requiredParams) {\n renderParameter(name, properties[name], `${indent} `);\n }\n console.log('');\n }\n\n // Show optional parameters\n if (optionalParams.length > 0) {\n console.log(`${indent}Optional Parameters:`);\n for (const name of optionalParams) {\n renderParameter(name, properties[name], `${indent} `);\n }\n console.log('');\n }\n}\n\n/**\n * Render verbose details for a resource\n */\nfunction renderResourceVerbose(resource: ResourceInfo, indent: string): void {\n // Description is already shown inline, so only show URI and MIME type\n if (resource.uri) {\n console.log(`${indent}URI: ${resource.uri}`);\n }\n if (resource.mimeType) {\n console.log(`${indent}MIME Type: ${resource.mimeType}`);\n }\n if (resource.uri || resource.mimeType) {\n console.log('');\n }\n}\n\n/**\n * Render verbose details for a prompt\n */\nfunction renderPromptVerbose(prompt: PromptInfo, indent: string): void {\n // Description is already shown inline, so only show arguments\n if (prompt.arguments && Array.isArray(prompt.arguments) && prompt.arguments.length > 0) {\n console.log(`${indent}Arguments:`);\n for (const arg of prompt.arguments) {\n const argObj = arg as { name?: string; description?: string; required?: boolean };\n const name = argObj.name || 'unknown';\n const description = argObj.description || '';\n const required = argObj.required ? ' (required)' : ' (optional)';\n const desc = description ? ` - ${description}` : '';\n console.log(`${indent} ${name}${required}${desc}`);\n }\n console.log('');\n }\n}\n\n/**\n * Render a single parameter with type and description\n */\nfunction renderParameter(name: string, prop: unknown, indent: string): void {\n const p = prop as { description?: string; enum?: unknown[] };\n const type = getParameterType(prop);\n const constraints = getParameterConstraints(prop);\n const typeInfo = constraints ? `(${type}) ${constraints}` : `(${type})`;\n const desc = p.description ? ` - ${p.description}` : '';\n\n console.log(`${indent}${name} ${typeInfo}${desc}`);\n\n // Show enum options on separate line if present\n if (p.enum && Array.isArray(p.enum)) {\n console.log(`${indent} Options: ${p.enum.join(', ')}`);\n }\n}\n\n/**\n * Get human-readable type from JSON Schema property\n */\nfunction getParameterType(prop: unknown): string {\n const p = prop as { type?: string | string[]; items?: { type?: string }; anyOf?: Array<{ type?: string }>; enum?: unknown[] };\n if (p.type) {\n if (Array.isArray(p.type)) {\n return p.type.join(' | ');\n }\n if (p.type === 'array' && p.items) {\n const itemType = p.items.type || 'any';\n return `array of ${itemType}`;\n }\n return p.type;\n }\n\n if (p.anyOf) {\n return p.anyOf.map((s) => s.type || 'any').join(' | ');\n }\n\n if (p.enum) {\n return 'enum';\n }\n\n return 'any';\n}\n\n/**\n * Get parameter constraints (default, min, max, etc.)\n */\nfunction getParameterConstraints(prop: unknown): string {\n const p = prop as {\n default?: unknown;\n minimum?: number;\n maximum?: number;\n minLength?: number;\n maxLength?: number;\n minItems?: number;\n maxItems?: number;\n };\n const constraints: string[] = [];\n\n if (p.default !== undefined) {\n const defaultValue = typeof p.default === 'string' ? `\"${p.default}\"` : String(p.default);\n constraints.push(`default: ${defaultValue}`);\n }\n\n if (p.minimum !== undefined) {\n constraints.push(`min: ${p.minimum}`);\n }\n\n if (p.maximum !== undefined) {\n constraints.push(`max: ${p.maximum}`);\n }\n\n if (p.minLength !== undefined) {\n constraints.push(`minLength: ${p.minLength}`);\n }\n\n if (p.maxLength !== undefined) {\n constraints.push(`maxLength: ${p.maxLength}`);\n }\n\n if (p.minItems !== undefined) {\n constraints.push(`minItems: ${p.minItems}`);\n }\n\n if (p.maxItems !== undefined) {\n constraints.push(`maxItems: ${p.maxItems}`);\n }\n\n return constraints.length > 0 ? `[${constraints.join(', ')}]` : '';\n}\n\n/**\n * Output results as JSON.\n */\nfunction outputJSON(serverInfos: ServerInfo[]): void {\n const output = {\n servers: serverInfos.reduce(\n (acc, info) => {\n acc[info.name] = {\n status: info.status,\n startupTime: info.startupTime ? `${(info.startupTime / 1000).toFixed(1)}s` : undefined,\n error: info.error,\n tools: info.tools,\n resources: info.resources,\n prompts: info.prompts,\n };\n return acc;\n },\n {} as Record<string, unknown>\n ),\n };\n\n console.log(JSON.stringify(output, null, 2));\n}\n\n/**\n * Output results in human-readable format.\n */\nfunction outputPretty(serverInfos: ServerInfo[], opts: InspectOptions): void {\n const showSummary = shouldShowSummary(opts);\n\n for (const info of serverInfos) {\n // Summary mode\n if (showSummary) {\n if (info.status === 'ready') {\n const toolCount = info.tools?.length || 0;\n const resourceCount = info.resources?.length || 0;\n const promptCount = info.prompts?.length || 0;\n const time = info.startupTime ? `(${(info.startupTime / 1000).toFixed(1)}s)` : '';\n console.log(`šŸ“¦ ${info.name}: ${time}`);\n\n // Show detailed list of tools\n console.log(`tools: ${toolCount}`);\n if (info.tools && info.tools.length > 0) {\n for (let i = 0; i < info.tools.length; i++) {\n const tool = info.tools[i];\n if (!tool) continue; // Array indexing can return undefined with noUncheckedIndexedAccess\n const desc = tool.description ? ` - ${opts.verbose ? tool.description : truncateDescription(tool.description)}` : '';\n console.log(`${i + 1}. ${tool.name}${desc}`);\n if (opts.verbose) {\n renderToolVerbose(tool, ' ');\n }\n }\n }\n\n // Show detailed list of resources\n console.log(`resources: ${resourceCount}`);\n if (info.resources && info.resources.length > 0) {\n for (let i = 0; i < info.resources.length; i++) {\n const resource = info.resources[i];\n if (!resource) continue; // Array indexing can return undefined with noUncheckedIndexedAccess\n const desc = resource.description ? ` - ${opts.verbose ? resource.description : truncateDescription(resource.description)}` : '';\n console.log(`${i + 1}. ${resource.name}${desc}`);\n if (opts.verbose) {\n renderResourceVerbose(resource, ' ');\n }\n }\n }\n\n // Show detailed list of prompts\n console.log(`prompts: ${promptCount}`);\n if (info.prompts && info.prompts.length > 0) {\n for (let i = 0; i < info.prompts.length; i++) {\n const prompt = info.prompts[i];\n if (!prompt) continue; // Array indexing can return undefined with noUncheckedIndexedAccess\n const desc = prompt.description ? ` - ${opts.verbose ? prompt.description : truncateDescription(prompt.description)}` : '';\n console.log(`${i + 1}. ${prompt.name}${desc}`);\n if (opts.verbose) {\n renderPromptVerbose(prompt, ' ');\n }\n }\n }\n } else {\n console.log(`šŸ“¦ ${info.name}: āœ— failed - ${info.error}`);\n }\n continue;\n }\n\n // Health mode\n if (opts.health) {\n if (info.status === 'ready') {\n const time = info.startupTime ? `(${(info.startupTime / 1000).toFixed(1)}s)` : '';\n console.log(`āœ“ ${info.name} - ready ${time}`);\n } else {\n console.log(`āœ— ${info.name} - failed`);\n console.log(` Error: ${info.error}`);\n }\n continue;\n }\n\n // Tools mode\n if (opts.tools) {\n console.log(`\\nšŸ“¦ ${info.name} (${info.tools?.length || 0} tools)`);\n if (info.tools && info.tools.length > 0) {\n for (let i = 0; i < info.tools.length; i++) {\n const tool = info.tools[i];\n if (!tool) continue; // Array indexing can return undefined with noUncheckedIndexedAccess\n const desc = tool.description ? ` - ${opts.verbose ? tool.description : truncateDescription(tool.description)}` : '';\n console.log(` ${i + 1}. ${tool.name}${desc}`);\n if (opts.verbose) {\n renderToolVerbose(tool, ' ');\n }\n }\n }\n }\n\n // Resources mode\n if (opts.resources) {\n console.log(`\\nšŸ“¦ ${info.name} (${info.resources?.length || 0} resources)`);\n if (info.resources && info.resources.length > 0) {\n for (let i = 0; i < info.resources.length; i++) {\n const resource = info.resources[i];\n if (!resource) continue; // Array indexing can return undefined with noUncheckedIndexedAccess\n const desc = resource.description ? ` - ${opts.verbose ? resource.description : truncateDescription(resource.description)}` : '';\n console.log(` ${i + 1}. ${resource.name}${desc}`);\n if (opts.verbose) {\n renderResourceVerbose(resource, ' ');\n }\n }\n }\n }\n\n // Prompts mode\n if (opts.prompts) {\n console.log(`\\nšŸ“¦ ${info.name} (${info.prompts?.length || 0} prompts)`);\n if (info.prompts && info.prompts.length > 0) {\n for (let i = 0; i < info.prompts.length; i++) {\n const prompt = info.prompts[i];\n if (!prompt) continue; // Array indexing can return undefined with noUncheckedIndexedAccess\n const desc = prompt.description ? ` - ${opts.verbose ? prompt.description : truncateDescription(prompt.description)}` : '';\n console.log(` ${i + 1}. ${prompt.name}${desc}`);\n if (opts.verbose) {\n renderPromptVerbose(prompt, ' ');\n }\n }\n }\n }\n }\n\n console.log('');\n}\n"],"names":["createServerRegistry","fs","path","findConfigPath","isHttpServer","MAX_DESCRIPTION","inspectCommand","opts","registry","raw","configPath","config","JSON","parse","readFileSync","servers","mcpServers","configDir","dirname","serverNames","Object","keys","serversToInspect","filterServers","cwd","dialects","attach","serverInfos","serverName","info","inspectServer","push","json","outputJSON","outputPretty","close","_","allServers","serversFlag","requested","split","map","s","trim","missing","filter","includes","length","Error","join","start","Date","now","serverConfig","command","client","connect","needsTools","tools","shouldShowSummary","needsResources","resources","needsPrompts","prompts","toolsResult","resourcesResult","promptsResult","Promise","all","listTools","catch","resolve","listResources","listPrompts","startupTime","name","status","error","undefined","t","description","inputSchema","r","uri","mimeType","p","arguments","errorMessage","message","String","cause","code","url","health","truncateDescription","desc","_maxLength","renderToolVerbose","tool","indent","schema","properties","required","requiredParams","optionalParams","_prop","entries","console","log","renderParameter","renderResourceVerbose","resource","renderPromptVerbose","prompt","Array","isArray","arg","argObj","prop","type","getParameterType","constraints","getParameterConstraints","typeInfo","enum","items","itemType","anyOf","default","defaultValue","minimum","maximum","minLength","maxLength","minItems","maxItems","output","reduce","acc","toFixed","stringify","showSummary","toolCount","resourceCount","promptCount","time","i","verbose"],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import type { EnvVarMetadata } from './metadata-reader.js';
2
+ /**
3
+ * Substitute template variables in a string
4
+ * Replaces any {VARIABLE_NAME} with the corresponding value from the variables map
5
+ * Variable names are case-insensitive
6
+ */
7
+ export declare function substituteTemplateVars(template: string | undefined, variables?: Record<string, string>): string | undefined;
8
+ /**
9
+ * Prompt user for environment variables with support for:
10
+ * - Environment variable detection with partial redaction
11
+ * - Interactive prompts for required fields
12
+ * - Choice-based selection
13
+ * - Password input for secrets
14
+ * - Default values
15
+ * - Non-interactive mode (-y flag)
16
+ * - Dynamic placeholders via template variable substitution
17
+ */
18
+ export declare function promptForEnvVars(serverName: string, envVars: EnvVarMetadata[], options?: {
19
+ yes?: boolean;
20
+ templateVars?: Record<string, string>;
21
+ }): Promise<Record<string, string>>;