@vibeplanner/mcp-server
Version:
MCP server for VibePlanner AI - Integrate project management and collaborative memory into Claude Desktop
191 lines • 7.33 kB
JavaScript
/**
* Purpose: CLI wrapper for MCP client with configuration management
* Dependencies: commander, chalk, inquirer
*/
import { Command } from 'commander';
import chalk from 'chalk';
import inquirer from 'inquirer';
import { writeFileSync, readFileSync, existsSync, mkdirSync } from 'fs';
import { join } from 'path';
import { homedir } from 'os';
const program = new Command();
const CONFIG_DIR = join(homedir(), '.claude-collab');
const CONFIG_FILE = join(CONFIG_DIR, 'config');
const DEFAULT_CONFIG = {
apiUrl: process.env.CLAUDE_COLLAB_API_URL || `http://localhost:${process.env.API_PORT || '8100'}`,
timeout: 30000
};
function loadConfig() {
if (!existsSync(CONFIG_FILE)) {
return DEFAULT_CONFIG;
}
try {
const content = readFileSync(CONFIG_FILE, 'utf-8');
const envVars = content.split('\n')
.filter(line => line.trim() !== '' && !line.startsWith('#'))
.reduce((acc, line) => {
const [key, value] = line.split('=');
if (key !== undefined && key !== null && key !== '' && value !== undefined && value !== null && value !== '') {
acc[key.trim()] = value.trim();
}
return acc;
}, {});
return {
apiUrl: envVars.CLAUDE_COLLAB_API_URL ?? DEFAULT_CONFIG.apiUrl,
apiKey: envVars.API_KEY ?? undefined,
timeout: parseInt(envVars.CLAUDE_COLLAB_TIMEOUT ?? String(DEFAULT_CONFIG.timeout))
};
}
catch {
console.error(chalk.yellow('Warning: Could not read config file, using defaults'));
return DEFAULT_CONFIG;
}
}
function saveConfig(config) {
if (!existsSync(CONFIG_DIR)) {
mkdirSync(CONFIG_DIR, { recursive: true });
}
const content = [
'# Claude Collaborative Memory System Configuration',
`CLAUDE_COLLAB_API_URL=${config.apiUrl}`,
config.apiKey !== undefined && config.apiKey !== null && config.apiKey !== '' ? `API_KEY=${config.apiKey}` : '# API_KEY=your-api-key-here',
`CLAUDE_COLLAB_TIMEOUT=${config.timeout}`,
''
].join('\n');
writeFileSync(CONFIG_FILE, content);
}
program
.name('claude-collab-mcp')
.description('Claude Collaborative Memory System MCP Client')
.version('1.0.0');
program
.command('configure')
.description('Configure the MCP client')
.action(async () => {
console.log(chalk.blue('🔧 Configuring Claude Collaborative Memory MCP Client\n'));
const currentConfig = loadConfig();
const answers = await inquirer.prompt([
{
type: 'input',
name: 'apiUrl',
message: 'API Base URL:',
default: currentConfig.apiUrl
},
{
type: 'input',
name: 'apiKey',
message: 'API Key (optional):',
default: currentConfig.apiKey ?? ''
},
{
type: 'number',
name: 'timeout',
message: 'Request timeout (ms):',
default: currentConfig.timeout
}
]);
const newConfig = {
apiUrl: answers.apiUrl,
apiKey: answers.apiKey !== '' ? answers.apiKey : undefined,
timeout: answers.timeout
};
saveConfig(newConfig);
console.log(chalk.green('✅ Configuration saved successfully!'));
console.log(chalk.gray(`Config file: ${CONFIG_FILE}`));
});
program
.command('status')
.description('Check configuration and connection status')
.action(async () => {
console.log(chalk.blue('📊 Claude Collaborative Memory MCP Client Status\n'));
const config = loadConfig();
console.log(chalk.bold('Configuration:'));
console.log(` API URL: ${config.apiUrl}`);
console.log(` API Key: ${config.apiKey !== undefined && config.apiKey !== null && config.apiKey !== '' ? '✅ Set' : '❌ Not set'}`);
console.log(` Timeout: ${config.timeout}ms`);
console.log(` Config file: ${CONFIG_FILE}`);
// Test connection
try {
console.log(chalk.bold('\nTesting connection...'));
const axios = await import('axios');
const response = await axios.default.get(`${config.apiUrl}/health`, {
timeout: config.timeout,
headers: config.apiKey !== undefined && config.apiKey !== null && config.apiKey !== '' ? { 'Authorization': `Bearer ${config.apiKey}` } : {}
});
console.log(chalk.green('✅ Connection successful'));
console.log(` Status: ${response.data.status}`);
console.log(` Version: ${response.data.version}`);
}
catch (error) {
console.log(chalk.red('❌ Connection failed'));
if (error instanceof Error) {
console.log(chalk.gray(` Error: ${error.message}`));
}
}
});
program
.command('start')
.description('Start the MCP server (for Claude integration)')
.action(async () => {
console.log(chalk.blue('🚀 Starting Claude Collaborative Memory MCP Server\n'));
const config = loadConfig();
// Set environment variables
process.env.CLAUDE_COLLAB_API_URL = config.apiUrl;
if (config.apiKey !== undefined && config.apiKey !== null && config.apiKey !== '') {
process.env.API_KEY = config.apiKey;
}
process.env.CLAUDE_COLLAB_TIMEOUT = String(config.timeout);
// Import and start the MCP server
try {
await import('./index.js');
}
catch (error) {
console.error(chalk.red('Failed to start MCP server:'), error);
process.exit(1);
}
});
program
.command('install-guide')
.description('Show installation guide for Claude Desktop')
.action(() => {
console.log(chalk.blue('📖 Claude Desktop Installation Guide\n'));
const config = loadConfig();
const mcpPath = process.argv[1]; // Path to this CLI
console.log(chalk.bold('1. Add to Claude Desktop config:'));
console.log(chalk.gray(' Edit your Claude Desktop config file and add:'));
console.log('');
console.log(chalk.cyan(JSON.stringify({
"mcpServers": {
"claude-collab-memory": {
"command": "node",
"args": [mcpPath, "start"],
"env": {
"CLAUDE_COLLAB_API_URL": config.apiUrl,
...(config.apiKey !== undefined && config.apiKey !== null && config.apiKey !== '' && { "API_KEY": config.apiKey }),
"CLAUDE_COLLAB_TIMEOUT": String(config.timeout)
}
}
}
}, null, 2)));
console.log('');
console.log(chalk.bold('2. Restart Claude Desktop'));
console.log('');
console.log(chalk.bold('3. Verify installation:'));
console.log(chalk.gray(' In Claude, you should see tools like:'));
console.log(' • list_projects');
console.log(' • create_task');
console.log(' • search_documents');
console.log(' • And more...');
console.log('');
console.log(chalk.yellow('💡 Tip: Run `claude-collab-mcp status` to test your connection first'));
});
program.parse();
// Check if running as main module (Node.js compatibility)
if (typeof require !== 'undefined' && require.main === module) {
// If no command provided, show help
if (process.argv.length <= 2) {
program.help();
}
}
//# sourceMappingURL=cli.js.map