Skip to main content
Glama

Hello-MCP

by hongsw
import { execSync, spawn } from 'child_process'; import os from 'os'; import fs from 'fs'; import path from 'path'; /** * Windows에서 프로그램 설치 여부 및 위치 확인 * @param {string} programName - 찾을 프로그램 이름 * @returns {object} - 설치 여부와 위치 정보 */ export function checkWindowsProgram(programName) { if (os.platform() !== 'win32') { throw new Error('이 메서드는 Windows에서만 동작합니다'); } const result = { installed: false, location: null, version: null }; // Claude의 일반적인 설치 경로 확인 if (programName === 'Claude') { const possiblePaths = [ path.join(os.homedir(), 'AppData', 'Local', 'AnthropicClaude', 'claude.exe') ]; for (const claudePath of possiblePaths) { if (fs.existsSync(claudePath)) { result.installed = true; result.location = claudePath; try { // Windows에서 파일 버전 정보 추출 const versionCommand = `powershell -command "(Get-Item '${claudePath}').VersionInfo.FileVersion"`; result.version = execSync(versionCommand, { encoding: 'utf-8' }).trim(); } catch (error) { // 버전 정보 추출 실패는 무시 } return result; } } } try { // 레지스트리를 통해 프로그램 확인 (32비트 및 64비트) const registryPaths = [ 'HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall', 'HKLM\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall' ]; for (const regPath of registryPaths) { try { const command = `reg query "${regPath}" /s /f "${programName}"`; const output = execSync(command, { encoding: 'utf-8' }); if (output.includes(programName)) { result.installed = true; // 설치 경로 추출 시도 const locationMatch = output.match(/InstallLocation\s+REG_SZ\s+(.+)/); if (locationMatch) { result.location = locationMatch[1].trim(); } // 버전 정보 추출 시도 const versionMatch = output.match(/DisplayVersion\s+REG_SZ\s+(.+)/); if (versionMatch) { result.version = versionMatch[1].trim(); } break; } } catch (error) { // 레지스트리 검색 실패는 무시하고 계속 진행 continue; } } return result; } catch (error) { // 모든 검색 방법이 실패한 경우 return result; } } /** * macOS에서 프로그램 설치 여부 및 위치 확인 * @param {string} programName - 찾을 프로그램 이름 * @returns {object} - 설치 여부와 위치 정보 */ export function checkMacProgram(programName) { if (os.platform() !== 'darwin') { throw new Error('이 메서드는 macOS에서만 동작합니다'); } const result = { installed: false, location: null, version: null }; // Claude의 일반적인 설치 경로 확인 if (programName === 'Claude') { const possiblePaths = [ '/Applications/Claude.app', path.join(os.homedir(), 'Applications', 'Claude.app') ]; for (const claudePath of possiblePaths) { if (fs.existsSync(claudePath)) { result.installed = true; result.location = claudePath; // 버전 정보 추출 시도 try { const infoPlistPath = path.join(claudePath, 'Contents/Info.plist'); if (fs.existsSync(infoPlistPath)) { const versionCommand = `/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "${infoPlistPath}"`; result.version = execSync(versionCommand, { encoding: 'utf-8' }).trim(); } } catch (error) { // 버전 정보 추출 실패는 무시 } return result; } } } try { // Spotlight를 사용하여 앱 검색 const mdfindCommand = `mdfind "kMDItemKind == 'Application'" -name "${programName}"`; const mdfindOutput = execSync(mdfindCommand, { encoding: 'utf-8' }); if (mdfindOutput.trim()) { const locations = mdfindOutput.split('\n').filter(Boolean); if (locations.length > 0) { result.installed = true; result.location = locations[0]; // 첫 번째 발견된 위치 사용 // 버전 정보 추출 시도 try { const infoPlistPath = path.join(result.location, 'Contents/Info.plist'); if (fs.existsSync(infoPlistPath)) { const versionCommand = `/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "${infoPlistPath}"`; result.version = execSync(versionCommand, { encoding: 'utf-8' }).trim(); } } catch (error) { // 버전 정보 추출 실패는 무시 } return result; } } return result; } catch (error) { return result; } } /** * 운영체제에 맞는 프로그램 설치 확인 함수 호출 * @param {string} programName - 찾을 프로그램 이름 * @returns {object} - 설치 여부와 위치 정보 */ export function checkProgramInstallation(programName) { const platform = os.platform(); try { if (platform === 'win32') { return checkWindowsProgram(programName); } else if (platform === 'darwin') { return checkMacProgram(programName); } else { throw new Error('지원되지 않는 운영체제입니다'); } } catch (error) { return { installed: false, location: null, version: null, error: error.message }; } } /** * 현재 실행 환경의 쉘 정보를 감지 * @returns {object} - 쉘 환경 정보 */ export function detectShellEnvironment() { const result = { platform: os.platform(), shell: process.env.SHELL || 'unknown', type: 'unknown', debug: { env: { SHELL: process.env.SHELL, TERM: process.env.TERM, MSYSTEM: process.env.MSYSTEM, ComSpec: process.env.ComSpec, PSModulePath: process.env.PSModulePath }, path: process.env.PATH, cwd: process.cwd(), home: os.homedir() } }; try { if (result.platform === 'win32') { // Windows 환경 감지 if (process.env.MSYSTEM) { // MINGW (Git Bash) 환경 result.type = 'mingw'; result.debug.msystem = process.env.MSYSTEM; console.log('MINGW(Git Bash) 환경이 감지되었습니다.'); } else { // PowerShell 또는 CMD 감지 try { execSync('powershell $PSVersionTable', { stdio: 'pipe' }); result.type = 'powershell'; console.log('PowerShell 환경이 감지되었습니다.'); } catch (error) { if (process.env.ComSpec && process.env.ComSpec.toLowerCase().includes('cmd.exe')) { result.type = 'cmd'; console.log('CMD 환경이 감지되었습니다.'); } else { console.log('알 수 없는 Windows 환경입니다.'); } } } } else if (result.platform === 'darwin') { // macOS 쉘 환경 감지 const shell = process.env.SHELL || ''; if (shell.includes('bash')) { result.type = 'bash'; console.log('Bash 환경이 감지되었습니다.'); } else if (shell.includes('zsh')) { result.type = 'zsh'; console.log('Zsh 환경이 감지되었습니다.'); } else { result.type = 'unix'; console.log('기타 Unix 쉘 환경이 감지되었습니다.'); } } // 추가 환경 정보 수집 try { if (result.platform === 'win32') { if (result.type === 'powershell') { result.debug.shellVersion = execSync('powershell $PSVersionTable.PSVersion', { stdio: 'pipe' }).toString(); } else if (result.type === 'cmd') { result.debug.shellVersion = execSync('cmd /c ver', { stdio: 'pipe' }).toString(); } } else { result.debug.shellVersion = execSync('echo $SHELL_VERSION', { stdio: 'pipe' }).toString(); } } catch (error) { result.debug.shellVersionError = error.message; } } catch (error) { result.error = error.message; console.error('쉘 환경 감지 중 오류 발생:', error); } // console.log('감지된 쉘 환경:', result); return result; } /** * 쉘 환경에 따른 명령어 매핑 */ const SHELL_COMMANDS = { windows: { mingw: { kill: (processName) => `winpty powershell.exe -Command \"Stop-Process -Name Claude -Force -ErrorAction SilentlyContinue\"`, start: (exePath) => `start /B C:/Users/${os.userInfo().username}/AppData/Local/AnthropicClaude/claude.exe`, list: 'tasklist | grep -i "claude"' }, powershell: { kill: (processName) => `Stop-Process -Name Claude -Force -ErrorAction SilentlyContinue`, start: (exePath) => `Start-Process -WindowStyle Hidden "C:/Users/${os.userInfo().username}/AppData/Local/AnthropicClaude/claude.exe"`, list: 'Get-Process | Where-Object { $_.Name -like "*claude*" } | Select-Object Name, Id' }, cmd: { kill: (processName) => `taskkill /F /IM Claude.exe`, start: (exePath) => `start /B C:/Users/${os.userInfo().username}/AppData/Local/AnthropicClaude/claude.exe`, list: 'tasklist | findstr /i "claude"' } }, darwin: { all: { kill: (bundleId) => `pkill -f "${bundleId}"`, start: (appPath) => `open "${appPath}"`, list: 'ps aux | grep -i "Claude.app"' } } }; /** * 초기화 및 환경 설정 * @returns {object} - 초기화 결과 */ export async function initialize() { const result = { success: false, shellEnvironment: null, claudeInfo: null }; try { // 1. 쉘 환경 감지 console.log('쉘 환경 감지 중...'); result.shellEnvironment = detectShellEnvironment(); // 2. Claude 설치 확인 console.log('Claude Desktop 설치 확인 중...'); result.claudeInfo = checkProgramInstallation('Claude'); if (!result.claudeInfo.installed) { result.message = 'Claude Desktop이 설치되어 있지 않습니다.'; return result; } // 3. 명령어 세트 설정 const platform = os.platform(); if (platform === 'win32') { result.commands = SHELL_COMMANDS.windows[result.shellEnvironment.type] || SHELL_COMMANDS.windows.cmd; } else if (platform === 'darwin') { result.commands = SHELL_COMMANDS.darwin.all; } else { throw new Error('지원되지 않는 운영체제입니다.'); } result.success = true; result.message = '초기화가 완료되었습니다.'; } catch (error) { result.success = false; result.message = `초기화 중 오류가 발생했습니다: ${error.message}`; result.error = { message: error.message, stack: error.stack }; } // console.log('초기화 결과:', result); return result; } /** * Claude Desktop 프로그램 재시작 * @returns {object} - 재시작 성공 여부와 메시지 */ export async function restartClaudeDesktop() { const result = { success: false, platform: os.platform() }; try { // 초기화 및 환경 설정 const initResult = await initialize(); if (!initResult.success) { return { ...result, message: initResult.message, error: initResult.error }; } result.shellEnvironment = initResult.shellEnvironment; result.claudeInfo = initResult.claudeInfo; result.commands = initResult.commands; // console.log('재시작 시작 - 환경:', result.shellEnvironment); if (result.platform === 'win32') { // Windows에서 프로세스 종료 try { const killCmd = result.commands.kill('claude.exe'); execSync(killCmd, { stdio: 'pipe' }); } catch (error) { // 프로세스 종료 중 오류는 무시 } // 잠시 대기 await new Promise(resolve => setTimeout(resolve, 1000)); // 프로세스 시작 try { const claudePath = `C:/Users/${os.userInfo().username}/AppData/Local/AnthropicClaude/claude.exe`; spawn(claudePath, [], { detached: true, stdio: 'ignore', shell: true }).unref(); result.success = true; result.message = 'Claude Desktop이 성공적으로 재시작되었습니다.'; } catch (error) { throw new Error(`프로세스 시작 실패: ${error.message}`); } } else if (result.platform === 'darwin') { // macOS 처리 try { // 프로세스 종료 execSync('pkill -f "Claude"', { stdio: 'pipe' }); // 잠시 대기 await new Promise(resolve => setTimeout(resolve, 1500)); // 프로세스 시작 spawn('open', ['-a', 'Claude'], { detached: true, stdio: 'ignore' }).unref(); result.success = true; result.message = 'Claude Desktop이 성공적으로 재시작되었습니다.'; } catch (error) { throw new Error(`프로세스 시작 실패: ${error.message}`); } } } catch (error) { result.success = false; result.message = `재시작 중 오류가 발생했습니다: ${error.message}`; result.error = { message: error.message, stack: error.stack }; } // console.log('최종 재시작 결과:', result); return result; }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/hongsw/hello-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server