Box MCP Server

by hmk
import { McpError, ErrorCode } from "@modelcontextprotocol/sdk/types.js"; import { GitCommandResult } from '../../types/git.js'; import { exec } from 'child_process'; import { promisify } from 'util'; const execAsync = promisify(exec); export class GitCommandExecutor { private baseDir: string; constructor(baseDir: string) { this.baseDir = baseDir; } /** * Gitコマンドを実行する共通メソッド */ async execGit(command: string, customPath?: string): Promise<GitCommandResult> { const workingDir = customPath || this.baseDir; try { // Gitリポジトリかどうかを確認 try { await execAsync('git rev-parse --git-dir', { cwd: workingDir }); } catch (error) { throw new McpError( ErrorCode.InvalidRequest, `指定されたパス '${workingDir}' はGitリポジトリではありません。` ); } const { stdout, stderr } = await execAsync(`git ${command}`, { cwd: workingDir }); return { success: true, output: stdout.trim(), error: stderr }; } catch (error: any) { if (error instanceof McpError) throw error; return { success: false, output: '', error: error.message }; } } /** * Gitコマンドを実行し、失敗時にMcpErrorをスローする */ async execGitWithError(command: string, customPath?: string, errorMessage?: string): Promise<string> { const result = await this.execGit(command, customPath); if (!result.success) { throw new McpError( ErrorCode.InternalError, errorMessage || `Git command failed: ${result.error}` ); } return result.output; } /** * リモートブランチの存在を確認する */ async doesRemoteBranchExist(branch: string, workingDir: string): Promise<boolean> { try { await this.execGitWithError(`ls-remote --heads origin ${branch}`, workingDir); return true; } catch (error) { return false; } } }