@vibe-dev-kit/cli
Version:
Advanced Command-line toolkit that analyzes your codebase and deploys project-aware rules, memories, commands and agents to any AI coding assistant - VDK is the world's first Vibe Development Kit
247 lines (208 loc) • 7.39 kB
JavaScript
/**
* Update MCP Configuration CLI Tool
* -----------------------
* Command-line utility for updating the editor paths and MCP server configurations
* in the 03-mcp-configuration.mdc file based on the current environment.
*/
import { execSync } from 'child_process';
import fs from 'fs';
import path from 'path';
import readline from 'readline';
import { fileURLToPath } from 'url';
import { updateMCPConfigurationFile } from '../shared/editor-path-resolver.js';
import * as ideConfig from '../shared/ide-configuration.js';
// Get directory paths for ES modules
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
// ANSI color codes for pretty output
const colors = {
reset: '\x1b[0m',
bright: '\x1b[1m',
dim: '\x1b[2m',
green: '\x1b[32m',
yellow: '\x1b[33m',
red: '\x1b[31m',
cyan: '\x1b[36m',
magenta: '\x1b[35m',
};
// Parse command line arguments
const args = process.argv.slice(2);
const options = {
path: process.cwd(),
quiet: false,
help: false,
force: false,
};
// Parse arguments
args.forEach((arg) => {
if (arg.startsWith('--path=')) {
options.path = arg.substring('--path='.length);
} else if (arg === '--quiet') {
options.quiet = true;
} else if (arg === '--help') {
options.help = true;
} else if (arg === '--force') {
options.force = true;
}
});
// Show help message and exit if --help is specified
if (options.help) {
console.log(`
${colors.bright}${colors.cyan}Update MCP Configuration Tool${colors.reset}
This tool updates the editor paths and MCP server configurations in the
03-mcp-configuration.mdc file based on detected editors and configuration files.
${colors.bright}Usage:${colors.reset}
node update-mcp-config.js [options]
${colors.bright}Options:${colors.reset}
--path=DIR Path to the project root (default: current directory)
--force Update configuration even if no editors are detected
--quiet Reduce output verbosity
--help Show this help message
${colors.bright}Example:${colors.reset}
node tools/update-mcp-config.js --path=/path/to/project
`);
process.exit(0);
}
// Set verbosity based on --quiet flag
const log = (message) => {
if (!options.quiet) {
console.log(message);
}
};
/**
* Main function to update MCP configuration
*/
async function updateMCPConfig() {
log(`${colors.bright}${colors.cyan}Update MCP Configuration Tool${colors.reset}`);
log(`Updating editor paths and MCP server configurations...`);
// Ensure the path exists and is a directory
if (!fs.existsSync(options.path) || !fs.statSync(options.path).isDirectory()) {
console.error(
`${colors.red}Error: Path does not exist or is not a directory: ${options.path}${colors.reset}`
);
process.exit(1);
}
// Detect IDEs in the project directory
const detectedIDEs = ideConfig.detectIDEs(options.path);
if (detectedIDEs.length === 0 && !options.force) {
console.error(
`${colors.yellow}Warning: No IDE configurations detected in the project.${colors.reset}`
);
console.error(`Use --force to update configuration anyway.`);
process.exit(1);
}
if (detectedIDEs.length > 0) {
log(`${colors.bright}${colors.green}Detected IDE configurations:${colors.reset}`);
detectedIDEs.forEach((ide) => {
log(`${colors.green}• ${ide.name}${colors.reset} (${ide.configFolder})`);
});
log('');
}
// Find rule directories
const ruleDirectories = [];
// First, check detected IDE rule directories
detectedIDEs.forEach((ide) => {
const rulePath = path.join(options.path, ide.rulesFolder);
if (fs.existsSync(rulePath)) {
ruleDirectories.push({
path: rulePath,
source: ide.name,
});
}
});
// Then, check common rule directories if none found from IDEs
if (ruleDirectories.length === 0) {
const commonPaths = ['.ai/rules', '.vscode/ai-rules', '.cursor/rules', '.claude/rules'];
commonPaths.forEach((rulePath) => {
const fullPath = path.join(options.path, rulePath);
if (fs.existsSync(fullPath)) {
ruleDirectories.push({
path: fullPath,
source: 'Common Path',
});
}
});
}
// Prompt for rule directory if none found
if (ruleDirectories.length === 0) {
console.error(`${colors.yellow}Warning: No rule directories found.${colors.reset}`);
// If force option is provided, use the default path
if (options.force) {
const defaultPath = path.join(options.path, '.ai/rules');
console.log(`${colors.yellow}Creating default rule directory: ${defaultPath}${colors.reset}`);
if (!fs.existsSync(defaultPath)) {
fs.mkdirSync(defaultPath, { recursive: true });
}
ruleDirectories.push({
path: defaultPath,
source: 'Default',
});
} else {
console.error(`Use --force to create a default rule directory.`);
process.exit(1);
}
}
// Update the MCP configuration file in each rule directory
let successCount = 0;
for (const ruleDir of ruleDirectories) {
log(
`Updating MCP configuration in ${colors.cyan}${ruleDir.path}${colors.reset} (from ${ruleDir.source})...`
);
// Check for the MCP configuration file
const mcpFilePath = path.join(ruleDir.path, '03-mcp-configuration.mdc');
if (!fs.existsSync(mcpFilePath)) {
log(`${colors.yellow}MCP configuration file not found: ${mcpFilePath}${colors.reset}`);
// Create file from template if it doesn't exist
const templatePath = path.join(__dirname, '../templates/rules/03-mcp-configuration.mdc');
if (fs.existsSync(templatePath)) {
log(`${colors.yellow}Creating from template...${colors.reset}`);
fs.copyFileSync(templatePath, mcpFilePath);
} else {
log(`${colors.yellow}Template not found, creating empty file...${colors.reset}`);
fs.writeFileSync(
mcpFilePath,
`---
description: Defines the available Model Context Protocol (MCP) servers and their capabilities.
globs:
alwaysApply: false
version: "2.1.0"
lastUpdated: "${new Date().toISOString().split('T')[0]}"
compatibleWith: ["Memory-MCP", "Sequential-Thinking-Advanced", "MCP-Integration"]
---
# MCP Server Configuration
This file documents the Model Context Protocol (MCP) servers available in your environment.
`,
'utf8'
);
}
}
// Update the file
const success = updateMCPConfigurationFile(options.path, ruleDir.path);
if (success) {
log(
`${colors.green}✓${colors.reset} Successfully updated MCP configuration in ${colors.cyan}${ruleDir.path}${colors.reset}`
);
successCount++;
} else {
log(
`${colors.red}✗${colors.reset} Failed to update MCP configuration in ${colors.cyan}${ruleDir.path}${colors.reset}`
);
}
}
if (successCount > 0) {
log(
`${colors.green}${colors.bright}MCP configuration updated successfully in ${successCount} directories.${colors.reset}`
);
} else {
console.error(
`${colors.red}${colors.bright}Failed to update MCP configuration in any directory.${colors.reset}`
);
process.exit(1);
}
}
// Run the main function
updateMCPConfig().catch((error) => {
console.error(`${colors.red}Error: ${error.message}${colors.reset}`);
process.exit(1);
});