UNPKG

mcp-integration-server-solin

Version:

MCP Server for Cody, YouTrack, and Forgejo integration

163 lines (133 loc) β€’ 4.74 kB
#!/usr/bin/env node import fs from 'fs'; import path from 'path'; import { fileURLToPath } from 'url'; import readline from 'readline'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const projectRoot = path.join(__dirname, '..'); const rl = readline.createInterface({ input: process.stdin, output: process.stdout }); function question(prompt) { return new Promise((resolve) => { rl.question(prompt, resolve); }); } async function setupEnvironment() { console.log('πŸš€ MCP 톡합 μ„œλ²„ 섀정을 μ‹œμž‘ν•©λ‹ˆλ‹€...\n'); const config = {}; // YouTrack μ„€μ • console.log('πŸ“‹ YouTrack μ„€μ •'); config.YOUTRACK_BASE_URL = await question('YouTrack μ„œλ²„ URL (예: https://company.youtrack.cloud): '); config.YOUTRACK_TOKEN = await question('YouTrack API 토큰: '); // Forgejo μ„€μ • console.log('\nπŸ”§ Forgejo μ„€μ •'); config.FORGEJO_BASE_URL = await question('Forgejo μ„œλ²„ URL (예: https://git.company.com): '); config.FORGEJO_TOKEN = await question('Forgejo μ•‘μ„ΈμŠ€ 토큰: '); config.FORGEJO_USERNAME = await question('Forgejo μ‚¬μš©μžλͺ…: '); // MCP μ„œλ²„ μ„€μ • console.log('\nβš™οΈ MCP μ„œλ²„ μ„€μ •'); config.MCP_SERVER_NAME = await question('μ„œλ²„ 이름 (κΈ°λ³Έκ°’: integration-server): ') || 'integration-server'; config.MCP_SERVER_VERSION = await question('μ„œλ²„ 버전 (κΈ°λ³Έκ°’: 1.0.0): ') || '1.0.0'; // .env 파일 생성 const envContent = Object.entries(config) .map(([key, value]) => `${key}=${value}`) .join('\n'); const envPath = path.join(projectRoot, '.env'); fs.writeFileSync(envPath, envContent); console.log('\nβœ… ν™˜κ²½ 섀정이 μ™„λ£Œλ˜μ—ˆμŠ΅λ‹ˆλ‹€!'); console.log(`πŸ“ μ„€μ • 파일: ${envPath}`); rl.close(); } async function checkDependencies() { console.log('\nπŸ” μ˜μ‘΄μ„± 확인 쀑...'); const packageJsonPath = path.join(projectRoot, 'package.json'); if (!fs.existsSync(packageJsonPath)) { console.log('❌ package.json을 찾을 수 μ—†μŠ΅λ‹ˆλ‹€.'); return false; } console.log('βœ… package.json 확인됨'); return true; } async function createDirectories() { console.log('\nπŸ“ 디렉토리 ꡬ쑰 생성 쀑...'); const dirs = [ 'dist', 'logs', 'config' ]; dirs.forEach(dir => { const dirPath = path.join(projectRoot, dir); if (!fs.existsSync(dirPath)) { fs.mkdirSync(dirPath, { recursive: true }); console.log(`βœ… ${dir} 디렉토리 생성됨`); } else { console.log(`πŸ“ ${dir} 디렉토리 이미 μ‘΄μž¬ν•¨`); } }); } async function generateConfigTemplate() { console.log('\nπŸ“ μ„€μ • ν…œν”Œλ¦Ώ 생성 쀑...'); const configTemplate = { server: { name: '${MCP_SERVER_NAME}', version: '${MCP_SERVER_VERSION}', logLevel: 'info' }, youtrack: { baseUrl: '${YOUTRACK_BASE_URL}', token: '${YOUTRACK_TOKEN}', timeout: 30000 }, forgejo: { baseUrl: '${FORGEJO_BASE_URL}', token: '${FORGEJO_TOKEN}', username: '${FORGEJO_USERNAME}', timeout: 30000 }, cody: { localAnalysis: true, analysisRules: { maxFunctionLength: 50, minCommentRatio: 0.1, checkSecurity: true, checkPerformance: true } } }; const configPath = path.join(projectRoot, 'config', 'config.template.json'); fs.writeFileSync(configPath, JSON.stringify(configTemplate, null, 2)); console.log(`βœ… μ„€μ • ν…œν”Œλ¦Ώ 생성됨: ${configPath}`); } async function main() { try { console.log('🎯 MCP 톡합 μ„œλ²„ μ„€μ • 도ꡬ\n'); // μ˜μ‘΄μ„± 확인 const depsOk = await checkDependencies(); if (!depsOk) { console.log('❌ 섀정을 μ€‘λ‹¨ν•©λ‹ˆλ‹€.'); process.exit(1); } // 디렉토리 생성 await createDirectories(); // μ„€μ • ν…œν”Œλ¦Ώ 생성 await generateConfigTemplate(); // ν™˜κ²½ λ³€μˆ˜ μ„€μ • await setupEnvironment(); console.log('\nπŸŽ‰ 섀정이 μ™„λ£Œλ˜μ—ˆμŠ΅λ‹ˆλ‹€!'); console.log('\nλ‹€μŒ 단계:'); console.log('1. npm install (μ˜μ‘΄μ„± μ„€μΉ˜)'); console.log('2. npm run build (ν”„λ‘œμ νŠΈ λΉŒλ“œ)'); console.log('3. npm start (μ„œλ²„ μ‹œμž‘)'); console.log('\n개발 λͺ¨λ“œλ‘œ μ‹€ν–‰ν•˜λ €λ©΄: npm run dev'); } catch (error) { console.error('❌ μ„€μ • 쀑 였λ₯˜κ°€ λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€:', error.message); process.exit(1); } } // μŠ€ν¬λ¦½νŠΈκ°€ 직접 싀행될 λ•Œλ§Œ main ν•¨μˆ˜ 호좜 if (import.meta.url === `file://${process.argv[1]}`) { main(); }