ken-you-code
Version:
Connect your codebase to Kimi: Ultra-fast AI code analysis with Kimi-K2 model via MCP
129 lines (108 loc) ⢠3.93 kB
text/typescript
import readline from 'readline';
import fs from 'fs';
import path from 'path';
interface SetupConfig {
openRouterApiKey: string;
defaultModel?: string;
maxFileSizeMB?: number;
}
class MCPSetup {
private rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
private async question(prompt: string): Promise<string> {
return new Promise((resolve) => {
this.rl.question(prompt, resolve);
});
}
private getConfigPath(): string {
const homeDir = process.env.HOME || process.env.USERPROFILE || '';
const configDir = path.join(homeDir, '.mcp');
if (!fs.existsSync(configDir)) {
fs.mkdirSync(configDir, { recursive: true });
}
return path.join(configDir, 'single-model-specialist.env');
}
async setup(): Promise<void> {
console.log('š§ Single Model Specialist MCP Setup\n');
// Check if already configured
const configPath = this.getConfigPath();
if (fs.existsSync(configPath)) {
const reconfigure = await this.question('Configuration exists. Reconfigure? (y/N): ');
if (reconfigure.toLowerCase() !== 'y') {
console.log('Setup cancelled.');
this.rl.close();
return;
}
}
console.log('Get your OpenRouter API key from: https://openrouter.ai/keys\n');
const apiKey = await this.question('Enter your OpenRouter API key: ');
if (!apiKey.trim()) {
console.log('ā API key is required');
this.rl.close();
process.exit(1);
}
const model =
(await this.question('Default model (moonshotai/kimi-k2): ')) || 'moonshotai/kimi-k2';
const maxSize = (await this.question('Max file size MB (5): ')) || '5';
const config: SetupConfig = {
openRouterApiKey: apiKey.trim(),
defaultModel: model.trim(),
maxFileSizeMB: parseInt(maxSize),
};
// Write config file
const envContent = `# Single Model Specialist MCP Configuration
# Generated on ${new Date().toISOString()}
OPENROUTER_API_KEY=${config.openRouterApiKey}
DEFAULT_MODEL=${config.defaultModel}
MAX_FILE_SIZE_MB=${config.maxFileSizeMB}
LOG_LEVEL=ERROR
ALLOWED_EXTENSIONS=.py,.js,.ts,.md,.json,.yaml,.yml,.txt,.html,.css,.sql,.sh
`;
fs.writeFileSync(configPath, envContent, { mode: 0o600 }); // Secure permissions
console.log(`\nā
Configuration saved to: ${configPath}`);
console.log('\nš Add to Claude Code with:');
console.log(`claude mcp add single-model-specialist npx single-model-mcp-server`);
console.log('\nš Usage: The MCP will automatically use your saved configuration.');
this.rl.close();
}
async showConfig(): Promise<void> {
const configPath = this.getConfigPath();
if (!fs.existsSync(configPath)) {
console.log('ā No configuration found. Run setup first: npx single-model-mcp-server setup');
return;
}
console.log(`š Configuration file: ${configPath}`);
const content = fs.readFileSync(configPath, 'utf-8');
const masked = content.replace(/OPENROUTER_API_KEY=.+/, 'OPENROUTER_API_KEY=sk-***hidden***');
console.log('\nš Current configuration:');
console.log(masked);
}
}
async function main(): Promise<void> {
const setup = new MCPSetup();
const command = process.argv[2];
switch (command) {
case 'setup':
case 'configure':
await setup.setup();
break;
case 'config':
case 'show-config':
await setup.showConfig();
break;
default:
console.log('š§ Single Model Specialist MCP Server\n');
console.log('Commands:');
console.log(' setup - Configure API keys and settings');
console.log(' show-config - Display current configuration');
console.log('\nFirst time? Run: npx single-model-mcp-server setup');
break;
}
}
if (import.meta.url === `file://${process.argv[1]}`) {
main().catch(console.error);
}
export { MCPSetup };