@defai.digital/ax-cli 3.2.0 ā 3.4.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/.ax-cli/memory.json +8 -1
- package/README.md +118 -2
- package/config/models.yaml +13 -0
- package/config/settings.yaml +6 -0
- package/dist/agent/context-manager.d.ts +5 -5
- package/dist/agent/context-manager.js +19 -9
- package/dist/agent/context-manager.js.map +1 -1
- package/dist/agent/dependency-resolver.js +2 -1
- package/dist/agent/dependency-resolver.js.map +1 -1
- package/dist/agent/llm-agent.d.ts +3 -2
- package/dist/agent/llm-agent.js +64 -58
- package/dist/agent/llm-agent.js.map +1 -1
- package/dist/agent/subagent.js +2 -1
- package/dist/agent/subagent.js.map +1 -1
- package/dist/analyzers/architecture/anti-pattern-detectors/god-object-detector.d.ts +29 -0
- package/dist/analyzers/architecture/anti-pattern-detectors/god-object-detector.js +103 -0
- package/dist/analyzers/architecture/anti-pattern-detectors/god-object-detector.js.map +1 -0
- package/dist/analyzers/architecture/architecture-analyzer.d.ts +58 -0
- package/dist/analyzers/architecture/architecture-analyzer.js +276 -0
- package/dist/analyzers/architecture/architecture-analyzer.js.map +1 -0
- package/dist/analyzers/architecture/index.d.ts +12 -0
- package/dist/analyzers/architecture/index.js +14 -0
- package/dist/analyzers/architecture/index.js.map +1 -0
- package/dist/analyzers/architecture/pattern-detectors/base-detector.d.ts +27 -0
- package/dist/analyzers/architecture/pattern-detectors/base-detector.js +31 -0
- package/dist/analyzers/architecture/pattern-detectors/base-detector.js.map +1 -0
- package/dist/analyzers/architecture/pattern-detectors/clean-architecture-detector.d.ts +11 -0
- package/dist/analyzers/architecture/pattern-detectors/clean-architecture-detector.js +57 -0
- package/dist/analyzers/architecture/pattern-detectors/clean-architecture-detector.js.map +1 -0
- package/dist/analyzers/architecture/pattern-detectors/mvc-detector.d.ts +11 -0
- package/dist/analyzers/architecture/pattern-detectors/mvc-detector.js +43 -0
- package/dist/analyzers/architecture/pattern-detectors/mvc-detector.js.map +1 -0
- package/dist/analyzers/architecture/pattern-detectors/repository-detector.d.ts +11 -0
- package/dist/analyzers/architecture/pattern-detectors/repository-detector.js +49 -0
- package/dist/analyzers/architecture/pattern-detectors/repository-detector.js.map +1 -0
- package/dist/analyzers/architecture/project-structure-scanner.d.ts +54 -0
- package/dist/analyzers/architecture/project-structure-scanner.js +200 -0
- package/dist/analyzers/architecture/project-structure-scanner.js.map +1 -0
- package/dist/analyzers/best-practices/base-rule.d.ts +45 -0
- package/dist/analyzers/best-practices/base-rule.js +45 -0
- package/dist/analyzers/best-practices/base-rule.js.map +1 -0
- package/dist/analyzers/best-practices/best-practice-validator.d.ts +35 -0
- package/dist/analyzers/best-practices/best-practice-validator.js +181 -0
- package/dist/analyzers/best-practices/best-practice-validator.js.map +1 -0
- package/dist/analyzers/best-practices/rules/index.d.ts +7 -0
- package/dist/analyzers/best-practices/rules/index.js +56 -0
- package/dist/analyzers/best-practices/rules/index.js.map +1 -0
- package/dist/analyzers/best-practices/rules/typescript/consistent-naming.d.ts +17 -0
- package/dist/analyzers/best-practices/rules/typescript/consistent-naming.js +41 -0
- package/dist/analyzers/best-practices/rules/typescript/consistent-naming.js.map +1 -0
- package/dist/analyzers/best-practices/rules/typescript/function-complexity.d.ts +27 -0
- package/dist/analyzers/best-practices/rules/typescript/function-complexity.js +76 -0
- package/dist/analyzers/best-practices/rules/typescript/function-complexity.js.map +1 -0
- package/dist/analyzers/best-practices/rules/typescript/index.d.ts +15 -0
- package/dist/analyzers/best-practices/rules/typescript/index.js +16 -0
- package/dist/analyzers/best-practices/rules/typescript/index.js.map +1 -0
- package/dist/analyzers/best-practices/rules/typescript/max-file-length.d.ts +18 -0
- package/dist/analyzers/best-practices/rules/typescript/max-file-length.js +25 -0
- package/dist/analyzers/best-practices/rules/typescript/max-file-length.js.map +1 -0
- package/dist/analyzers/best-practices/rules/typescript/no-any-type.d.ts +17 -0
- package/dist/analyzers/best-practices/rules/typescript/no-any-type.js +27 -0
- package/dist/analyzers/best-practices/rules/typescript/no-any-type.js.map +1 -0
- package/dist/analyzers/best-practices/rules/typescript/no-implicit-any.d.ts +18 -0
- package/dist/analyzers/best-practices/rules/typescript/no-implicit-any.js +39 -0
- package/dist/analyzers/best-practices/rules/typescript/no-implicit-any.js.map +1 -0
- package/dist/analyzers/best-practices/rules/typescript/no-magic-numbers.d.ts +17 -0
- package/dist/analyzers/best-practices/rules/typescript/no-magic-numbers.js +32 -0
- package/dist/analyzers/best-practices/rules/typescript/no-magic-numbers.js.map +1 -0
- package/dist/analyzers/best-practices/rules/typescript/no-unused-vars.d.ts +17 -0
- package/dist/analyzers/best-practices/rules/typescript/no-unused-vars.js +36 -0
- package/dist/analyzers/best-practices/rules/typescript/no-unused-vars.js.map +1 -0
- package/dist/analyzers/best-practices/rules/typescript/prefer-const.d.ts +17 -0
- package/dist/analyzers/best-practices/rules/typescript/prefer-const.js +33 -0
- package/dist/analyzers/best-practices/rules/typescript/prefer-const.js.map +1 -0
- package/dist/analyzers/best-practices/rules/typescript/prefer-readonly.d.ts +17 -0
- package/dist/analyzers/best-practices/rules/typescript/prefer-readonly.js +34 -0
- package/dist/analyzers/best-practices/rules/typescript/prefer-readonly.js.map +1 -0
- package/dist/analyzers/best-practices/rules/typescript/proper-error-handling.d.ts +17 -0
- package/dist/analyzers/best-practices/rules/typescript/proper-error-handling.js +27 -0
- package/dist/analyzers/best-practices/rules/typescript/proper-error-handling.js.map +1 -0
- package/dist/analyzers/best-practices/types.d.ts +86 -0
- package/dist/analyzers/best-practices/types.js +7 -0
- package/dist/analyzers/best-practices/types.js.map +1 -0
- package/dist/analyzers/cache/analysis-cache.d.ts +41 -0
- package/dist/analyzers/cache/analysis-cache.js +84 -0
- package/dist/analyzers/cache/analysis-cache.js.map +1 -0
- package/dist/analyzers/errors.d.ts +51 -0
- package/dist/analyzers/errors.js +79 -0
- package/dist/analyzers/errors.js.map +1 -0
- package/dist/commands/doctor.js +3 -2
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/frontend.d.ts +9 -0
- package/dist/commands/frontend.js +645 -0
- package/dist/commands/frontend.js.map +1 -0
- package/dist/commands/mcp.js +652 -3
- package/dist/commands/mcp.js.map +1 -1
- package/dist/commands/models.js +2 -2
- package/dist/commands/models.js.map +1 -1
- package/dist/commands/setup.js +100 -41
- package/dist/commands/setup.js.map +1 -1
- package/dist/constants.d.ts +4 -0
- package/dist/constants.js +4 -0
- package/dist/constants.js.map +1 -1
- package/dist/hooks/use-enhanced-input.js +16 -3
- package/dist/hooks/use-enhanced-input.js.map +1 -1
- package/dist/hooks/use-input-handler.js +9 -4
- package/dist/hooks/use-input-handler.js.map +1 -1
- package/dist/index.js +5 -2
- package/dist/index.js.map +1 -1
- package/dist/llm/client.d.ts +1 -0
- package/dist/llm/tools.js +86 -0
- package/dist/llm/tools.js.map +1 -1
- package/dist/llm/types.d.ts +49 -22
- package/dist/llm/types.js +12 -8
- package/dist/llm/types.js.map +1 -1
- package/dist/mcp/client.d.ts +5 -0
- package/dist/mcp/client.js +55 -0
- package/dist/mcp/client.js.map +1 -1
- package/dist/mcp/config.d.ts +1 -1
- package/dist/mcp/config.js +2 -2
- package/dist/mcp/config.js.map +1 -1
- package/dist/mcp/health.d.ts +120 -0
- package/dist/mcp/health.js +267 -0
- package/dist/mcp/health.js.map +1 -0
- package/dist/mcp/reconnection.d.ts +93 -0
- package/dist/mcp/reconnection.js +216 -0
- package/dist/mcp/reconnection.js.map +1 -0
- package/dist/mcp/registry.d.ts +71 -0
- package/dist/mcp/registry.js +257 -0
- package/dist/mcp/registry.js.map +1 -0
- package/dist/mcp/resources.d.ts +53 -0
- package/dist/mcp/resources.js +135 -0
- package/dist/mcp/resources.js.map +1 -0
- package/dist/mcp/templates.d.ts +52 -0
- package/dist/mcp/templates.js +624 -0
- package/dist/mcp/templates.js.map +1 -0
- package/dist/mcp/validation.d.ts +25 -0
- package/dist/mcp/validation.js +209 -0
- package/dist/mcp/validation.js.map +1 -0
- package/dist/memory/context-generator.js +1 -2
- package/dist/memory/context-generator.js.map +1 -1
- package/dist/planner/types.d.ts +2 -2
- package/dist/schemas/api-schemas.d.ts +2 -1
- package/dist/schemas/api-schemas.js +6 -4
- package/dist/schemas/api-schemas.js.map +1 -1
- package/dist/schemas/index.d.ts +4 -4
- package/dist/schemas/tool-schemas.d.ts +2 -2
- package/dist/schemas/yaml-schemas.d.ts +15 -0
- package/dist/schemas/yaml-schemas.js +3 -0
- package/dist/schemas/yaml-schemas.js.map +1 -1
- package/dist/sdk/index.d.ts +138 -0
- package/dist/sdk/index.js +173 -0
- package/dist/sdk/index.js.map +1 -0
- package/dist/sdk/types.d.ts +53 -0
- package/dist/sdk/types.js +8 -0
- package/dist/sdk/types.js.map +1 -0
- package/dist/tools/analysis-tools/architecture-tool.d.ts +46 -0
- package/dist/tools/analysis-tools/architecture-tool.js +124 -0
- package/dist/tools/analysis-tools/architecture-tool.js.map +1 -0
- package/dist/tools/analysis-tools/validation-tool.d.ts +51 -0
- package/dist/tools/analysis-tools/validation-tool.js +121 -0
- package/dist/tools/analysis-tools/validation-tool.js.map +1 -0
- package/dist/tools/bash.js +25 -10
- package/dist/tools/bash.js.map +1 -1
- package/dist/tools/web-search/cache.d.ts +62 -0
- package/dist/tools/web-search/cache.js +105 -0
- package/dist/tools/web-search/cache.js.map +1 -0
- package/dist/tools/web-search/engines/brave.d.ts +16 -0
- package/dist/tools/web-search/engines/brave.js +99 -0
- package/dist/tools/web-search/engines/brave.js.map +1 -0
- package/dist/tools/web-search/engines/crates.d.ts +19 -0
- package/dist/tools/web-search/engines/crates.js +87 -0
- package/dist/tools/web-search/engines/crates.js.map +1 -0
- package/dist/tools/web-search/engines/npm.d.ts +18 -0
- package/dist/tools/web-search/engines/npm.js +86 -0
- package/dist/tools/web-search/engines/npm.js.map +1 -0
- package/dist/tools/web-search/engines/pypi.d.ts +18 -0
- package/dist/tools/web-search/engines/pypi.js +75 -0
- package/dist/tools/web-search/engines/pypi.js.map +1 -0
- package/dist/tools/web-search/engines/tavily.d.ts +17 -0
- package/dist/tools/web-search/engines/tavily.js +73 -0
- package/dist/tools/web-search/engines/tavily.js.map +1 -0
- package/dist/tools/web-search/index.d.ts +13 -0
- package/dist/tools/web-search/index.js +13 -0
- package/dist/tools/web-search/index.js.map +1 -0
- package/dist/tools/web-search/router.d.ts +36 -0
- package/dist/tools/web-search/router.js +280 -0
- package/dist/tools/web-search/router.js.map +1 -0
- package/dist/tools/web-search/types.d.ts +45 -0
- package/dist/tools/web-search/types.js +6 -0
- package/dist/tools/web-search/types.js.map +1 -0
- package/dist/tools/web-search/web-search-tool.d.ts +51 -0
- package/dist/tools/web-search/web-search-tool.js +256 -0
- package/dist/tools/web-search/web-search-tool.js.map +1 -0
- package/dist/types/analysis.d.ts +177 -0
- package/dist/types/analysis.js +8 -0
- package/dist/types/analysis.js.map +1 -0
- package/dist/ui/components/api-key-input.js +2 -2
- package/dist/ui/components/api-key-input.js.map +1 -1
- package/dist/ui/components/chat-history.js +14 -7
- package/dist/ui/components/chat-history.js.map +1 -1
- package/dist/ui/components/chat-input.js +12 -7
- package/dist/ui/components/chat-input.js.map +1 -1
- package/dist/ui/components/chat-interface.js +75 -54
- package/dist/ui/components/chat-interface.js.map +1 -1
- package/dist/ui/components/keyboard-hints.js +5 -4
- package/dist/ui/components/keyboard-hints.js.map +1 -1
- package/dist/ui/components/quick-actions.js +1 -0
- package/dist/ui/components/quick-actions.js.map +1 -1
- package/dist/ui/components/reasoning-display.js +14 -4
- package/dist/ui/components/reasoning-display.js.map +1 -1
- package/dist/ui/components/status-bar.d.ts +1 -0
- package/dist/ui/components/status-bar.js +37 -39
- package/dist/ui/components/status-bar.js.map +1 -1
- package/dist/ui/components/toast-notification.d.ts +29 -0
- package/dist/ui/components/toast-notification.js +17 -3
- package/dist/ui/components/toast-notification.js.map +1 -1
- package/dist/ui/components/welcome-panel.d.ts +1 -0
- package/dist/ui/components/welcome-panel.js +106 -4
- package/dist/ui/components/welcome-panel.js.map +1 -1
- package/dist/utils/analysis-logger.d.ts +47 -0
- package/dist/utils/analysis-logger.js +70 -0
- package/dist/utils/analysis-logger.js.map +1 -0
- package/dist/utils/automatosx-detector.d.ts +19 -0
- package/dist/utils/automatosx-detector.js +52 -0
- package/dist/utils/automatosx-detector.js.map +1 -0
- package/dist/utils/config-loader.d.ts +4 -0
- package/dist/utils/config-loader.js.map +1 -1
- package/dist/utils/confirmation-service.js +1 -1
- package/dist/utils/confirmation-service.js.map +1 -1
- package/dist/utils/init-previewer.js +26 -4
- package/dist/utils/init-previewer.js.map +1 -1
- package/dist/utils/setup-validator.js +1 -0
- package/dist/utils/setup-validator.js.map +1 -1
- package/dist/utils/text-utils.d.ts +1 -0
- package/dist/utils/text-utils.js +12 -0
- package/dist/utils/text-utils.js.map +1 -1
- package/package.json +19 -4
- package/vitest.config.ts +1 -0
package/dist/commands/mcp.js
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
|
-
import { addMCPServer, removeMCPServer, loadMCPConfig, PREDEFINED_SERVERS } from '../mcp/config.js';
|
|
2
|
+
import { addMCPServer, removeMCPServer, loadMCPConfig, PREDEFINED_SERVERS, getTemplate, generateConfigFromTemplate } from '../mcp/config.js';
|
|
3
|
+
import { getTemplateNames, getTemplatesByCategory } from '../mcp/templates.js';
|
|
3
4
|
import { getMCPManager } from '../llm/tools.js';
|
|
4
5
|
import { MCPServerIdSchema } from '@ax-cli/schemas';
|
|
5
6
|
import chalk from 'chalk';
|
|
6
7
|
import { ConsoleMessenger } from '../utils/console-messenger.js';
|
|
7
8
|
import { extractErrorMessage } from '../utils/error-handler.js';
|
|
9
|
+
import { validateServerConfig, formatValidationResult } from '../mcp/validation.js';
|
|
10
|
+
import { listAllResources, listServerResources, searchResources } from '../mcp/resources.js';
|
|
11
|
+
import { searchRegistry, getRegistryServer, getPopularServers, generateConfigFromRegistry, formatRegistryServer } from '../mcp/registry.js';
|
|
8
12
|
export function createMCPCommand() {
|
|
9
13
|
const mcpCommand = new Command('mcp');
|
|
10
14
|
mcpCommand.description('Manage MCP (Model Context Protocol) servers');
|
|
@@ -12,6 +16,8 @@ export function createMCPCommand() {
|
|
|
12
16
|
mcpCommand
|
|
13
17
|
.command('add <name>')
|
|
14
18
|
.description('Add an MCP server')
|
|
19
|
+
.option('--template', 'Use pre-configured template for this server')
|
|
20
|
+
.option('--interactive', 'Prompt for required environment variables')
|
|
15
21
|
.option('-t, --transport <type>', 'Transport type (stdio, http, sse, streamable_http)', 'stdio')
|
|
16
22
|
.option('-c, --command <command>', 'Command to run the server (for stdio transport)')
|
|
17
23
|
.option('-a, --args [args...]', 'Arguments for the server command (for stdio transport)', [])
|
|
@@ -20,9 +26,83 @@ export function createMCPCommand() {
|
|
|
20
26
|
.option('-e, --env [env...]', 'Environment variables (key=value format)', [])
|
|
21
27
|
.action(async (name, options) => {
|
|
22
28
|
try {
|
|
23
|
-
// Check if
|
|
29
|
+
// Check if using template
|
|
30
|
+
if (options.template) {
|
|
31
|
+
const template = getTemplate(name);
|
|
32
|
+
if (!template) {
|
|
33
|
+
console.error(chalk.red(`ā Template "${name}" not found`));
|
|
34
|
+
console.log();
|
|
35
|
+
console.log(chalk.blue('Available templates:'));
|
|
36
|
+
const templateNames = getTemplateNames();
|
|
37
|
+
templateNames.forEach(t => {
|
|
38
|
+
const tmpl = getTemplate(t);
|
|
39
|
+
console.log(` ${chalk.bold(t)} - ${tmpl?.description}`);
|
|
40
|
+
});
|
|
41
|
+
process.exit(1);
|
|
42
|
+
}
|
|
43
|
+
// Display template information
|
|
44
|
+
console.log(chalk.blue(`\nš¦ Setting up ${chalk.bold(template.name)} MCP server`));
|
|
45
|
+
console.log(chalk.gray(template.description));
|
|
46
|
+
console.log();
|
|
47
|
+
// Check required environment variables
|
|
48
|
+
const envVars = {};
|
|
49
|
+
let missingEnvVars = false;
|
|
50
|
+
for (const envVar of template.requiredEnv) {
|
|
51
|
+
const value = process.env[envVar.name];
|
|
52
|
+
if (!value) {
|
|
53
|
+
console.log(chalk.yellow(`ā ļø Missing environment variable: ${chalk.bold(envVar.name)}`));
|
|
54
|
+
console.log(chalk.gray(` ${envVar.description}`));
|
|
55
|
+
if (envVar.url) {
|
|
56
|
+
console.log(chalk.gray(` More info: ${envVar.url}`));
|
|
57
|
+
}
|
|
58
|
+
console.log();
|
|
59
|
+
missingEnvVars = true;
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
envVars[envVar.name] = value;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
if (missingEnvVars) {
|
|
66
|
+
console.log(chalk.red('ā Setup cannot continue without required environment variables.'));
|
|
67
|
+
console.log();
|
|
68
|
+
console.log(chalk.blue('Setup instructions:'));
|
|
69
|
+
console.log(template.setupInstructions);
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
72
|
+
// Generate config from template
|
|
73
|
+
const config = generateConfigFromTemplate(name, envVars);
|
|
74
|
+
// Add to configuration
|
|
75
|
+
addMCPServer(config);
|
|
76
|
+
console.log(chalk.green(`ā
Configuration saved`));
|
|
77
|
+
// Try to connect immediately
|
|
78
|
+
console.log(chalk.blue('š Connecting to server...'));
|
|
79
|
+
const manager = getMCPManager();
|
|
80
|
+
await manager.addServer(config);
|
|
81
|
+
console.log(chalk.green('ā
Connected successfully'));
|
|
82
|
+
// Show available tools
|
|
83
|
+
const tools = manager.getTools().filter(t => t.serverName === name);
|
|
84
|
+
console.log(chalk.blue(`\nš§ Available tools: ${chalk.bold(tools.length.toString())}`));
|
|
85
|
+
if (tools.length > 0 && tools.length <= 10) {
|
|
86
|
+
tools.forEach(tool => {
|
|
87
|
+
const displayName = tool.name.replace(`mcp__${name}__`, '');
|
|
88
|
+
console.log(` ⢠${chalk.bold(displayName)}: ${tool.description}`);
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
// Show usage examples
|
|
92
|
+
if (template.usageExamples.length > 0) {
|
|
93
|
+
console.log(chalk.blue('\nš” Usage examples:'));
|
|
94
|
+
template.usageExamples.slice(0, 3).forEach(example => {
|
|
95
|
+
console.log(chalk.gray(` ⢠${example}`));
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
console.log(chalk.green(`\n⨠${name} MCP server is ready to use!`));
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
// Check if it's a predefined server (legacy support)
|
|
24
102
|
if (PREDEFINED_SERVERS[name]) {
|
|
25
|
-
const
|
|
103
|
+
const template = PREDEFINED_SERVERS[name];
|
|
104
|
+
console.log(chalk.yellow(`š” Tip: Use ${chalk.bold('--template')} flag for guided setup`));
|
|
105
|
+
const config = template.config;
|
|
26
106
|
addMCPServer(config);
|
|
27
107
|
ConsoleMessenger.plain('mcp_commands.server_predefined', { name });
|
|
28
108
|
// Try to connect immediately
|
|
@@ -248,6 +328,575 @@ export function createMCPCommand() {
|
|
|
248
328
|
process.exit(1);
|
|
249
329
|
}
|
|
250
330
|
});
|
|
331
|
+
// Templates command - List available templates
|
|
332
|
+
mcpCommand
|
|
333
|
+
.command('templates')
|
|
334
|
+
.description('List available MCP server templates')
|
|
335
|
+
.option('--category <category>', 'Filter by category (design, deployment, testing, monitoring, backend, version-control)')
|
|
336
|
+
.action((options) => {
|
|
337
|
+
console.log(chalk.blue.bold('\nš¦ Available MCP Server Templates\n'));
|
|
338
|
+
let templates = Object.values(PREDEFINED_SERVERS);
|
|
339
|
+
if (options.category) {
|
|
340
|
+
templates = getTemplatesByCategory(options.category);
|
|
341
|
+
if (templates.length === 0) {
|
|
342
|
+
console.log(chalk.yellow(`No templates found for category "${options.category}"`));
|
|
343
|
+
console.log();
|
|
344
|
+
console.log(chalk.blue('Available categories:'));
|
|
345
|
+
console.log(' ⢠design, deployment, testing, monitoring, backend, version-control');
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
console.log(chalk.gray(`Showing ${options.category} templates:\n`));
|
|
349
|
+
}
|
|
350
|
+
// Group by category
|
|
351
|
+
const categories = templates.reduce((acc, template) => {
|
|
352
|
+
if (!acc[template.category]) {
|
|
353
|
+
acc[template.category] = [];
|
|
354
|
+
}
|
|
355
|
+
acc[template.category].push(template);
|
|
356
|
+
return acc;
|
|
357
|
+
}, {});
|
|
358
|
+
const categoryIcons = {
|
|
359
|
+
design: 'šØ',
|
|
360
|
+
'version-control': 'š¦',
|
|
361
|
+
deployment: 'š',
|
|
362
|
+
testing: 'š§Ŗ',
|
|
363
|
+
monitoring: 'š',
|
|
364
|
+
backend: 'šļø'
|
|
365
|
+
};
|
|
366
|
+
for (const [category, categoryTemplates] of Object.entries(categories)) {
|
|
367
|
+
const icon = categoryIcons[category] || 'š';
|
|
368
|
+
console.log(chalk.bold(`${icon} ${category.toUpperCase()}`));
|
|
369
|
+
console.log();
|
|
370
|
+
categoryTemplates.forEach(template => {
|
|
371
|
+
const officialBadge = template.officialServer ? chalk.green('official') : chalk.gray('community');
|
|
372
|
+
console.log(` ${chalk.bold(template.name)} [${officialBadge}]`);
|
|
373
|
+
console.log(chalk.gray(` ${template.description}`));
|
|
374
|
+
if (template.requiredEnv.length > 0) {
|
|
375
|
+
const envVarNames = template.requiredEnv.map(e => e.name).join(', ');
|
|
376
|
+
console.log(chalk.gray(` Requires: ${envVarNames}`));
|
|
377
|
+
}
|
|
378
|
+
console.log(chalk.blue(` Usage: ax-cli mcp add ${template.name} --template`));
|
|
379
|
+
console.log();
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
console.log(chalk.gray('š” Tip: Use --category to filter templates by type'));
|
|
383
|
+
console.log(chalk.gray(`Example: ax-cli mcp templates --category design`));
|
|
384
|
+
console.log();
|
|
385
|
+
});
|
|
386
|
+
// Tools command - List tools from a specific server
|
|
387
|
+
mcpCommand
|
|
388
|
+
.command('tools <server-name>')
|
|
389
|
+
.description('List available tools from an MCP server')
|
|
390
|
+
.option('--json', 'Output in JSON format')
|
|
391
|
+
.option('--verbose', 'Show detailed tool schemas')
|
|
392
|
+
.action(async (serverName, options) => {
|
|
393
|
+
try {
|
|
394
|
+
const manager = getMCPManager();
|
|
395
|
+
// Ensure server is connected
|
|
396
|
+
const isConnected = manager.getServers().includes(serverName);
|
|
397
|
+
if (!isConnected) {
|
|
398
|
+
// Try to connect
|
|
399
|
+
const config = loadMCPConfig();
|
|
400
|
+
const serverConfig = config.servers.find(s => s.name === serverName);
|
|
401
|
+
if (!serverConfig) {
|
|
402
|
+
console.error(chalk.red(`ā Server "${serverName}" not found.`));
|
|
403
|
+
console.log(chalk.gray('\nAdd it first with:'));
|
|
404
|
+
console.log(chalk.blue(` ax-cli mcp add ${serverName} --template`));
|
|
405
|
+
process.exit(1);
|
|
406
|
+
}
|
|
407
|
+
console.log(chalk.blue(`Connecting to ${serverName}...`));
|
|
408
|
+
await manager.addServer(serverConfig);
|
|
409
|
+
console.log(chalk.green('ā Connected\n'));
|
|
410
|
+
}
|
|
411
|
+
const tools = manager.getTools().filter(t => t.serverName === serverName);
|
|
412
|
+
if (tools.length === 0) {
|
|
413
|
+
console.log(chalk.yellow('ā ļø No tools found for this server.'));
|
|
414
|
+
console.log(chalk.gray('The server may be disconnected or have no tools available.'));
|
|
415
|
+
return;
|
|
416
|
+
}
|
|
417
|
+
if (options.json) {
|
|
418
|
+
console.log(JSON.stringify(tools, null, 2));
|
|
419
|
+
return;
|
|
420
|
+
}
|
|
421
|
+
// Pretty-print with tree structure
|
|
422
|
+
console.log(chalk.blue.bold(`\nš§ ${serverName} Tools (${tools.length} available)\n`));
|
|
423
|
+
tools.forEach((tool, i) => {
|
|
424
|
+
const isLast = i === tools.length - 1;
|
|
425
|
+
const prefix = isLast ? 'āā' : 'āā';
|
|
426
|
+
const displayName = tool.name.replace(`mcp__${serverName}__`, '');
|
|
427
|
+
console.log(chalk.bold(`${prefix} ${displayName}`));
|
|
428
|
+
console.log(` ${chalk.gray(tool.description || 'No description available')}`);
|
|
429
|
+
if (options.verbose && tool.inputSchema) {
|
|
430
|
+
console.log(chalk.gray(` Schema:`));
|
|
431
|
+
const schemaStr = JSON.stringify(tool.inputSchema, null, 2)
|
|
432
|
+
.split('\n')
|
|
433
|
+
.map(line => ` ${line}`)
|
|
434
|
+
.join('\n');
|
|
435
|
+
console.log(chalk.gray(schemaStr));
|
|
436
|
+
}
|
|
437
|
+
else if (tool.inputSchema?.properties) {
|
|
438
|
+
const params = Object.keys(tool.inputSchema.properties);
|
|
439
|
+
if (params.length > 0) {
|
|
440
|
+
const required = tool.inputSchema.required || [];
|
|
441
|
+
const paramList = params.map(p => required.includes(p) ? `${p}*` : p).join(', ');
|
|
442
|
+
console.log(chalk.gray(` Parameters: ${paramList}`));
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
if (!isLast)
|
|
446
|
+
console.log(' ā');
|
|
447
|
+
});
|
|
448
|
+
console.log();
|
|
449
|
+
console.log(chalk.gray('š” Tip: Use --verbose to see full parameter schemas'));
|
|
450
|
+
console.log(chalk.gray(' Parameters marked with * are required'));
|
|
451
|
+
console.log();
|
|
452
|
+
}
|
|
453
|
+
catch (error) {
|
|
454
|
+
console.error(chalk.red(`ā Error: ${extractErrorMessage(error)}`));
|
|
455
|
+
process.exit(1);
|
|
456
|
+
}
|
|
457
|
+
});
|
|
458
|
+
// Search command - Search tools across all servers
|
|
459
|
+
mcpCommand
|
|
460
|
+
.command('search <query>')
|
|
461
|
+
.description('Search for tools across all MCP servers')
|
|
462
|
+
.option('--json', 'Output in JSON format')
|
|
463
|
+
.action((query, options) => {
|
|
464
|
+
const manager = getMCPManager();
|
|
465
|
+
const allTools = manager.getTools();
|
|
466
|
+
const lowerQuery = query.toLowerCase();
|
|
467
|
+
const matchingTools = allTools.filter(tool => tool.name.toLowerCase().includes(lowerQuery) ||
|
|
468
|
+
tool.description?.toLowerCase().includes(lowerQuery));
|
|
469
|
+
if (matchingTools.length === 0) {
|
|
470
|
+
console.log(chalk.yellow(`\nā ļø No tools found matching "${query}"\n`));
|
|
471
|
+
console.log(chalk.gray('š” Try searching for:'));
|
|
472
|
+
console.log(chalk.gray(' ⢠deploy, git, database, test, file'));
|
|
473
|
+
console.log();
|
|
474
|
+
return;
|
|
475
|
+
}
|
|
476
|
+
if (options.json) {
|
|
477
|
+
console.log(JSON.stringify(matchingTools, null, 2));
|
|
478
|
+
return;
|
|
479
|
+
}
|
|
480
|
+
console.log(chalk.blue.bold(`\nš Found ${matchingTools.length} tools matching "${query}"\n`));
|
|
481
|
+
// Group by server
|
|
482
|
+
const byServer = matchingTools.reduce((acc, tool) => {
|
|
483
|
+
if (!acc[tool.serverName]) {
|
|
484
|
+
acc[tool.serverName] = [];
|
|
485
|
+
}
|
|
486
|
+
acc[tool.serverName].push(tool);
|
|
487
|
+
return acc;
|
|
488
|
+
}, {});
|
|
489
|
+
for (const [serverName, serverTools] of Object.entries(byServer)) {
|
|
490
|
+
console.log(chalk.bold(`${serverName} (${serverTools.length} tools)`));
|
|
491
|
+
serverTools.forEach(tool => {
|
|
492
|
+
const displayName = tool.name.replace(`mcp__${serverName}__`, '');
|
|
493
|
+
console.log(` ⢠${chalk.bold(displayName)}`);
|
|
494
|
+
if (tool.description) {
|
|
495
|
+
console.log(chalk.gray(` ${tool.description}`));
|
|
496
|
+
}
|
|
497
|
+
});
|
|
498
|
+
console.log();
|
|
499
|
+
}
|
|
500
|
+
console.log(chalk.gray('š” Tip: Use "ax-cli mcp tools <server-name>" to see all tools from a server'));
|
|
501
|
+
console.log();
|
|
502
|
+
});
|
|
503
|
+
// Browse command - Interactive template browser (alias for templates)
|
|
504
|
+
mcpCommand
|
|
505
|
+
.command('browse')
|
|
506
|
+
.description('Browse available MCP server templates')
|
|
507
|
+
.action(() => {
|
|
508
|
+
console.log(chalk.blue.bold('\nš MCP Server Template Browser\n'));
|
|
509
|
+
console.log(chalk.gray('Popular templates for front-end development:\n'));
|
|
510
|
+
const popular = ['figma', 'github', 'vercel', 'puppeteer', 'storybook', 'sentry'];
|
|
511
|
+
popular.forEach(name => {
|
|
512
|
+
const template = getTemplate(name);
|
|
513
|
+
if (template) {
|
|
514
|
+
const icon = template.category === 'design' ? 'šØ' :
|
|
515
|
+
template.category === 'version-control' ? 'š¦' :
|
|
516
|
+
template.category === 'deployment' ? 'š' :
|
|
517
|
+
template.category === 'testing' ? 'š§Ŗ' :
|
|
518
|
+
template.category === 'monitoring' ? 'š' : 'šļø';
|
|
519
|
+
console.log(`${icon} ${chalk.bold(template.name)}`);
|
|
520
|
+
console.log(chalk.gray(` ${template.description}`));
|
|
521
|
+
console.log(chalk.blue(` Quick start: ax-cli mcp add ${name} --template`));
|
|
522
|
+
console.log();
|
|
523
|
+
}
|
|
524
|
+
});
|
|
525
|
+
console.log(chalk.gray('š View all templates:'));
|
|
526
|
+
console.log(chalk.blue(' ax-cli mcp templates'));
|
|
527
|
+
console.log();
|
|
528
|
+
console.log(chalk.gray('š Search templates:'));
|
|
529
|
+
console.log(chalk.blue(' ax-cli mcp templates --category design'));
|
|
530
|
+
console.log();
|
|
531
|
+
});
|
|
532
|
+
// Health command - Check MCP server health
|
|
533
|
+
mcpCommand
|
|
534
|
+
.command('health [server-name]')
|
|
535
|
+
.description('Check health status of MCP servers')
|
|
536
|
+
.option('--json', 'Output in JSON format')
|
|
537
|
+
.option('--watch', 'Continuously monitor health (updates every 60s)')
|
|
538
|
+
.action(async (serverName, options) => {
|
|
539
|
+
try {
|
|
540
|
+
const { MCPHealthMonitor } = await import('../mcp/health.js');
|
|
541
|
+
const manager = getMCPManager();
|
|
542
|
+
const healthMonitor = new MCPHealthMonitor(manager);
|
|
543
|
+
if (options.watch) {
|
|
544
|
+
// Continuous monitoring mode
|
|
545
|
+
console.log(chalk.blue.bold('\nš MCP Server Health Monitoring\n'));
|
|
546
|
+
console.log(chalk.gray('Press Ctrl+C to stop\n'));
|
|
547
|
+
// Start monitoring
|
|
548
|
+
healthMonitor.start(60000);
|
|
549
|
+
// Display initial report
|
|
550
|
+
const displayHealth = async () => {
|
|
551
|
+
console.clear();
|
|
552
|
+
console.log(chalk.blue.bold('š MCP Server Health Report\n'));
|
|
553
|
+
console.log(chalk.gray(`Last updated: ${new Date().toLocaleTimeString()}\n`));
|
|
554
|
+
const health = serverName
|
|
555
|
+
? [await healthMonitor.getServerStatus(serverName)].filter(Boolean)
|
|
556
|
+
: await healthMonitor.getHealthReport();
|
|
557
|
+
if (health.length === 0) {
|
|
558
|
+
console.log(chalk.yellow('No servers connected'));
|
|
559
|
+
return;
|
|
560
|
+
}
|
|
561
|
+
for (const server of health) {
|
|
562
|
+
const statusIcon = server.connected ? 'ā' : 'ā';
|
|
563
|
+
const statusColor = server.connected ? chalk.green : chalk.red;
|
|
564
|
+
const statusText = server.connected ? 'Connected' : 'Disconnected';
|
|
565
|
+
console.log(statusColor(`${statusIcon} ${chalk.bold(server.serverName)} (${statusText})`));
|
|
566
|
+
console.log(chalk.gray(` Transport: MCP`));
|
|
567
|
+
if (server.uptime) {
|
|
568
|
+
console.log(chalk.gray(` Uptime: ${MCPHealthMonitor.formatUptime(server.uptime)}`));
|
|
569
|
+
}
|
|
570
|
+
console.log(chalk.gray(` Tools: ${server.toolCount} available`));
|
|
571
|
+
if (server.avgLatency) {
|
|
572
|
+
console.log(chalk.gray(` Latency: avg ${MCPHealthMonitor.formatLatency(server.avgLatency)}, p95 ${MCPHealthMonitor.formatLatency(server.p95Latency || 0)}`));
|
|
573
|
+
}
|
|
574
|
+
const successRateColor = server.successRate >= 95 ? chalk.green :
|
|
575
|
+
server.successRate >= 80 ? chalk.yellow : chalk.red;
|
|
576
|
+
console.log(chalk.gray(` Success Rate: ${successRateColor(`${server.successRate.toFixed(1)}%`)} (${server.successCount}/${server.successCount + server.failureCount} calls)`));
|
|
577
|
+
if (server.lastError) {
|
|
578
|
+
console.log(chalk.red(` Last Error: ${server.lastError}`));
|
|
579
|
+
if (server.lastErrorAt) {
|
|
580
|
+
const timeSinceError = Date.now() - server.lastErrorAt;
|
|
581
|
+
console.log(chalk.gray(` ${MCPHealthMonitor.formatUptime(timeSinceError)} ago`));
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
console.log();
|
|
585
|
+
}
|
|
586
|
+
console.log(chalk.gray('Next update in 60 seconds...'));
|
|
587
|
+
};
|
|
588
|
+
// Display immediately
|
|
589
|
+
await displayHealth();
|
|
590
|
+
// Set up interval
|
|
591
|
+
const watchInterval = setInterval(displayHealth, 60000);
|
|
592
|
+
// Handle Ctrl+C
|
|
593
|
+
process.on('SIGINT', () => {
|
|
594
|
+
clearInterval(watchInterval);
|
|
595
|
+
healthMonitor.stop();
|
|
596
|
+
console.log(chalk.yellow('\n\nš Stopped health monitoring\n'));
|
|
597
|
+
process.exit(0);
|
|
598
|
+
});
|
|
599
|
+
}
|
|
600
|
+
else {
|
|
601
|
+
// One-time health check
|
|
602
|
+
const health = serverName
|
|
603
|
+
? [await healthMonitor.getServerStatus(serverName)].filter(Boolean)
|
|
604
|
+
: await healthMonitor.getHealthReport();
|
|
605
|
+
if (options.json) {
|
|
606
|
+
console.log(JSON.stringify(health, null, 2));
|
|
607
|
+
return;
|
|
608
|
+
}
|
|
609
|
+
if (health.length === 0) {
|
|
610
|
+
if (serverName) {
|
|
611
|
+
console.log(chalk.yellow(`\nā ļø Server "${serverName}" not found\n`));
|
|
612
|
+
}
|
|
613
|
+
else {
|
|
614
|
+
console.log(chalk.yellow('\nā ļø No MCP servers connected\n'));
|
|
615
|
+
console.log(chalk.blue('To add a server:'));
|
|
616
|
+
console.log(chalk.cyan(' ax-cli mcp add figma --template'));
|
|
617
|
+
console.log();
|
|
618
|
+
}
|
|
619
|
+
return;
|
|
620
|
+
}
|
|
621
|
+
console.log(chalk.blue.bold('\nš MCP Server Health Report\n'));
|
|
622
|
+
for (const server of health) {
|
|
623
|
+
const statusIcon = server.connected ? 'ā' : 'ā';
|
|
624
|
+
const statusColor = server.connected ? chalk.green : chalk.red;
|
|
625
|
+
const statusText = server.connected ? 'Connected' : 'Disconnected';
|
|
626
|
+
console.log(statusColor(`${statusIcon} ${chalk.bold(server.serverName)} (${statusText})`));
|
|
627
|
+
console.log(chalk.gray(` Transport: MCP`));
|
|
628
|
+
if (server.uptime) {
|
|
629
|
+
console.log(chalk.gray(` Uptime: ${MCPHealthMonitor.formatUptime(server.uptime)}`));
|
|
630
|
+
}
|
|
631
|
+
console.log(chalk.gray(` Tools: ${server.toolCount} available`));
|
|
632
|
+
if (server.avgLatency) {
|
|
633
|
+
console.log(chalk.gray(` Latency: avg ${MCPHealthMonitor.formatLatency(server.avgLatency)}, p95 ${MCPHealthMonitor.formatLatency(server.p95Latency || 0)}`));
|
|
634
|
+
}
|
|
635
|
+
const successRateColor = server.successRate >= 95 ? chalk.green :
|
|
636
|
+
server.successRate >= 80 ? chalk.yellow : chalk.red;
|
|
637
|
+
console.log(chalk.gray(` Success Rate: ${successRateColor(`${server.successRate.toFixed(1)}%`)} (${server.successCount}/${server.successCount + server.failureCount} calls)`));
|
|
638
|
+
if (server.lastError) {
|
|
639
|
+
console.log(chalk.red(` Last Error: ${server.lastError}`));
|
|
640
|
+
if (server.lastErrorAt) {
|
|
641
|
+
const timeSinceError = Date.now() - server.lastErrorAt;
|
|
642
|
+
console.log(chalk.gray(` ${MCPHealthMonitor.formatUptime(timeSinceError)} ago`));
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
if (server.lastSuccess) {
|
|
646
|
+
const timeSinceSuccess = Date.now() - server.lastSuccess;
|
|
647
|
+
console.log(chalk.gray(` Last Successful Call: ${MCPHealthMonitor.formatUptime(timeSinceSuccess)} ago`));
|
|
648
|
+
}
|
|
649
|
+
console.log();
|
|
650
|
+
}
|
|
651
|
+
console.log(chalk.gray('š” Tip: Use --watch to continuously monitor server health'));
|
|
652
|
+
console.log();
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
catch (error) {
|
|
656
|
+
console.error(chalk.red(`\nā Error: ${extractErrorMessage(error)}\n`));
|
|
657
|
+
process.exit(1);
|
|
658
|
+
}
|
|
659
|
+
});
|
|
660
|
+
// Validate server configuration (Phase 4)
|
|
661
|
+
mcpCommand
|
|
662
|
+
.command('validate <name>')
|
|
663
|
+
.description('Validate MCP server configuration with pre-flight checks')
|
|
664
|
+
.action(async (name) => {
|
|
665
|
+
try {
|
|
666
|
+
// Load configuration
|
|
667
|
+
const config = loadMCPConfig();
|
|
668
|
+
const serverConfig = config.servers.find(s => s.name === name);
|
|
669
|
+
if (!serverConfig) {
|
|
670
|
+
console.error(chalk.red(`\nā Server "${name}" not found in configuration\n`));
|
|
671
|
+
console.log(chalk.gray('Available servers:'));
|
|
672
|
+
const availableServers = config.servers.map(s => s.name);
|
|
673
|
+
if (availableServers.length === 0) {
|
|
674
|
+
console.log(chalk.gray(' (none configured)'));
|
|
675
|
+
}
|
|
676
|
+
else {
|
|
677
|
+
availableServers.forEach(s => console.log(chalk.gray(` ⢠${s}`)));
|
|
678
|
+
}
|
|
679
|
+
console.log();
|
|
680
|
+
process.exit(1);
|
|
681
|
+
}
|
|
682
|
+
console.log(chalk.blue.bold(`\nš Validating "${name}" MCP server configuration...\n`));
|
|
683
|
+
// Run validation
|
|
684
|
+
const result = await validateServerConfig(serverConfig);
|
|
685
|
+
// Display results
|
|
686
|
+
console.log(formatValidationResult(result));
|
|
687
|
+
console.log();
|
|
688
|
+
if (!result.valid) {
|
|
689
|
+
console.log(chalk.yellow('š” Fix the errors above and try again'));
|
|
690
|
+
console.log();
|
|
691
|
+
process.exit(1);
|
|
692
|
+
}
|
|
693
|
+
else if (result.warnings.length > 0) {
|
|
694
|
+
console.log(chalk.blue('š” Configuration is valid but has warnings. Review them before connecting.'));
|
|
695
|
+
console.log();
|
|
696
|
+
}
|
|
697
|
+
else {
|
|
698
|
+
console.log(chalk.green('š Ready to connect! Use: ax-cli mcp add ' + name + ' --template'));
|
|
699
|
+
console.log();
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
catch (error) {
|
|
703
|
+
console.error(chalk.red(`\nā Error: ${extractErrorMessage(error)}\n`));
|
|
704
|
+
process.exit(1);
|
|
705
|
+
}
|
|
706
|
+
});
|
|
707
|
+
// List MCP resources (Phase 4)
|
|
708
|
+
mcpCommand
|
|
709
|
+
.command('resources [server-name]')
|
|
710
|
+
.description('List resources exposed by MCP servers')
|
|
711
|
+
.option('--search <query>', 'Search resources by name or URI')
|
|
712
|
+
.option('--json', 'Output in JSON format')
|
|
713
|
+
.action(async (serverName, options) => {
|
|
714
|
+
try {
|
|
715
|
+
const manager = getMCPManager();
|
|
716
|
+
// Get resources
|
|
717
|
+
const resources = serverName
|
|
718
|
+
? await listServerResources(manager, serverName)
|
|
719
|
+
: await listAllResources(manager);
|
|
720
|
+
// Filter by search query if provided
|
|
721
|
+
const filteredResources = options.search
|
|
722
|
+
? searchResources(resources, options.search)
|
|
723
|
+
: resources;
|
|
724
|
+
if (options.json) {
|
|
725
|
+
console.log(JSON.stringify(filteredResources, null, 2));
|
|
726
|
+
return;
|
|
727
|
+
}
|
|
728
|
+
// Display resources
|
|
729
|
+
if (filteredResources.length === 0) {
|
|
730
|
+
if (serverName) {
|
|
731
|
+
console.log(chalk.yellow(`\nā ļø No resources found for server "${serverName}"\n`));
|
|
732
|
+
}
|
|
733
|
+
else {
|
|
734
|
+
console.log(chalk.yellow('\nā ļø No resources found from any connected server\n'));
|
|
735
|
+
}
|
|
736
|
+
console.log(chalk.gray('Note: Not all MCP servers expose resources.'));
|
|
737
|
+
console.log();
|
|
738
|
+
return;
|
|
739
|
+
}
|
|
740
|
+
console.log(chalk.blue.bold('\nš¦ MCP Resources\n'));
|
|
741
|
+
// Group by server
|
|
742
|
+
const byServer = new Map();
|
|
743
|
+
for (const resource of filteredResources) {
|
|
744
|
+
if (!byServer.has(resource.serverName)) {
|
|
745
|
+
byServer.set(resource.serverName, []);
|
|
746
|
+
}
|
|
747
|
+
byServer.get(resource.serverName).push(resource);
|
|
748
|
+
}
|
|
749
|
+
for (const [server, serverResources] of byServer.entries()) {
|
|
750
|
+
console.log(chalk.bold(`${server} (${serverResources.length} resources)`));
|
|
751
|
+
for (const resource of serverResources) {
|
|
752
|
+
console.log(chalk.green(` ${resource.reference}`));
|
|
753
|
+
if (resource.description) {
|
|
754
|
+
console.log(chalk.gray(` ${resource.description}`));
|
|
755
|
+
}
|
|
756
|
+
if (resource.mimeType) {
|
|
757
|
+
console.log(chalk.gray(` Type: ${resource.mimeType}`));
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
console.log();
|
|
761
|
+
}
|
|
762
|
+
console.log(chalk.gray('š” Use resources in chat with: "Query the @mcp:server/uri"'));
|
|
763
|
+
console.log();
|
|
764
|
+
}
|
|
765
|
+
catch (error) {
|
|
766
|
+
console.error(chalk.red(`\nā Error: ${extractErrorMessage(error)}\n`));
|
|
767
|
+
process.exit(1);
|
|
768
|
+
}
|
|
769
|
+
});
|
|
770
|
+
// Browse MCP Server Registry (Phase 5)
|
|
771
|
+
mcpCommand
|
|
772
|
+
.command('registry')
|
|
773
|
+
.description('Browse MCP server registry')
|
|
774
|
+
.option('--search <query>', 'Search for servers')
|
|
775
|
+
.option('--category <category>', 'Filter by category')
|
|
776
|
+
.option('--transport <type>', 'Filter by transport type (stdio, http, sse)')
|
|
777
|
+
.option('--json', 'Output in JSON format')
|
|
778
|
+
.action(async (options) => {
|
|
779
|
+
try {
|
|
780
|
+
console.log(chalk.blue.bold('\nš¦ MCP Server Registry\n'));
|
|
781
|
+
const searchOptions = {
|
|
782
|
+
query: options.search,
|
|
783
|
+
category: options.category,
|
|
784
|
+
transport: options.transport,
|
|
785
|
+
sortBy: 'stars',
|
|
786
|
+
limit: 20
|
|
787
|
+
};
|
|
788
|
+
const servers = options.search || options.category || options.transport
|
|
789
|
+
? await searchRegistry(searchOptions)
|
|
790
|
+
: await getPopularServers();
|
|
791
|
+
if (options.json) {
|
|
792
|
+
console.log(JSON.stringify(servers, null, 2));
|
|
793
|
+
return;
|
|
794
|
+
}
|
|
795
|
+
if (servers.length === 0) {
|
|
796
|
+
console.log(chalk.yellow('ā ļø No servers found matching your criteria\n'));
|
|
797
|
+
console.log(chalk.gray('Try different search terms or browse all servers'));
|
|
798
|
+
console.log();
|
|
799
|
+
return;
|
|
800
|
+
}
|
|
801
|
+
console.log(chalk.gray(`Found ${servers.length} server(s)\n`));
|
|
802
|
+
for (const server of servers) {
|
|
803
|
+
const badge = server.verified ? chalk.green('ā verified') : chalk.gray('community');
|
|
804
|
+
console.log(`${chalk.bold(server.displayName)} [${badge}] ā ${server.stars}`);
|
|
805
|
+
console.log(chalk.gray(` ${server.description}`));
|
|
806
|
+
console.log(chalk.gray(` Category: ${server.category} | Transport: ${server.transport}`));
|
|
807
|
+
if (server.packageName) {
|
|
808
|
+
console.log(chalk.blue(` Install: ax-cli mcp install ${server.name}`));
|
|
809
|
+
}
|
|
810
|
+
else {
|
|
811
|
+
console.log(chalk.gray(` Repository: ${server.repository}`));
|
|
812
|
+
}
|
|
813
|
+
console.log();
|
|
814
|
+
}
|
|
815
|
+
console.log(chalk.gray('š” Use --search to find specific servers'));
|
|
816
|
+
console.log(chalk.gray('š” Use --category to filter by type (design, database, api, etc.)'));
|
|
817
|
+
console.log();
|
|
818
|
+
}
|
|
819
|
+
catch (error) {
|
|
820
|
+
console.error(chalk.red(`\nā Error: ${extractErrorMessage(error)}\n`));
|
|
821
|
+
process.exit(1);
|
|
822
|
+
}
|
|
823
|
+
});
|
|
824
|
+
// Install MCP server from registry (Phase 5)
|
|
825
|
+
mcpCommand
|
|
826
|
+
.command('install <name>')
|
|
827
|
+
.description('Install MCP server from registry')
|
|
828
|
+
.option('--no-validate', 'Skip validation before installation')
|
|
829
|
+
.option('--no-connect', 'Add configuration but don\'t connect immediately')
|
|
830
|
+
.action(async (name, options) => {
|
|
831
|
+
try {
|
|
832
|
+
console.log(chalk.blue(`\nš¦ Installing "${name}" from registry...\n`));
|
|
833
|
+
// Search registry
|
|
834
|
+
const server = await getRegistryServer(name);
|
|
835
|
+
if (!server) {
|
|
836
|
+
console.error(chalk.red(`ā Server "${name}" not found in registry\n`));
|
|
837
|
+
console.log(chalk.gray('Available options:'));
|
|
838
|
+
console.log(chalk.gray(' ⢠Search registry: ax-cli mcp registry --search <query>'));
|
|
839
|
+
console.log(chalk.gray(' ⢠Browse all: ax-cli mcp registry'));
|
|
840
|
+
console.log();
|
|
841
|
+
process.exit(1);
|
|
842
|
+
}
|
|
843
|
+
// Display server info
|
|
844
|
+
console.log(formatRegistryServer(server, false));
|
|
845
|
+
console.log();
|
|
846
|
+
// Generate configuration
|
|
847
|
+
const config = generateConfigFromRegistry(server);
|
|
848
|
+
// Validate if requested
|
|
849
|
+
if (options.validate !== false) {
|
|
850
|
+
console.log(chalk.blue('š Validating configuration...\n'));
|
|
851
|
+
const validation = await validateServerConfig(config);
|
|
852
|
+
if (!validation.valid) {
|
|
853
|
+
console.log(formatValidationResult(validation));
|
|
854
|
+
console.log();
|
|
855
|
+
console.error(chalk.red('ā Validation failed. Fix errors and try again.\n'));
|
|
856
|
+
process.exit(1);
|
|
857
|
+
}
|
|
858
|
+
if (validation.warnings.length > 0) {
|
|
859
|
+
console.log(chalk.yellow('ā ļø Warnings:\n'));
|
|
860
|
+
validation.warnings.forEach(w => console.log(chalk.yellow(` ⢠${w}`)));
|
|
861
|
+
console.log();
|
|
862
|
+
}
|
|
863
|
+
}
|
|
864
|
+
// Add server to configuration
|
|
865
|
+
await addMCPServer(config);
|
|
866
|
+
console.log(chalk.green(`ā
Server "${server.name}" added to configuration\n`));
|
|
867
|
+
// Connect if requested
|
|
868
|
+
if (options.connect !== false) {
|
|
869
|
+
console.log(chalk.blue('š Connecting to server...\n'));
|
|
870
|
+
try {
|
|
871
|
+
const manager = getMCPManager();
|
|
872
|
+
await manager.addServer(config);
|
|
873
|
+
const tools = manager.getTools().filter(t => t.serverName === server.name);
|
|
874
|
+
console.log(chalk.green(`ā
Connected successfully! ${tools.length} tool(s) available\n`));
|
|
875
|
+
// Show available tools
|
|
876
|
+
if (tools.length > 0) {
|
|
877
|
+
console.log(chalk.gray('Available tools:'));
|
|
878
|
+
tools.slice(0, 5).forEach(tool => {
|
|
879
|
+
console.log(chalk.gray(` ⢠${tool.name.replace(`mcp__${server.name}__`, '')}`));
|
|
880
|
+
});
|
|
881
|
+
if (tools.length > 5) {
|
|
882
|
+
console.log(chalk.gray(` ... and ${tools.length - 5} more`));
|
|
883
|
+
}
|
|
884
|
+
console.log();
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
catch (error) {
|
|
888
|
+
console.error(chalk.yellow(`ā ļø Server added but connection failed: ${extractErrorMessage(error)}\n`));
|
|
889
|
+
console.log(chalk.gray('You can try connecting manually with: ax-cli mcp add ' + server.name + ' --template'));
|
|
890
|
+
console.log();
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
console.log(chalk.green('š Installation complete!\n'));
|
|
894
|
+
}
|
|
895
|
+
catch (error) {
|
|
896
|
+
console.error(chalk.red(`\nā Error: ${extractErrorMessage(error)}\n`));
|
|
897
|
+
process.exit(1);
|
|
898
|
+
}
|
|
899
|
+
});
|
|
251
900
|
return mcpCommand;
|
|
252
901
|
}
|
|
253
902
|
//# sourceMappingURL=mcp.js.map
|