メインコンテンツへスキップ

ヘルプセンター

MCP Server完全セットアップガイド

最終更新: 2024/1/17
mcpsetupclaude-desktopvscodeapiauthentication
MCP Server完全セットアップガイド MCP(Model Context Protocol)サーバーを使用することで、AIアシスタントが築古不動産投資シミュレーターを直接操作できるようになります。このガイドでは、Claude Desktop、VSCode、API経由での接続方法を詳しく解説します。 🎯 MCPサーバーの特徴 統合開発環境:Claude Desktop、VSCodeで直接利用可能 リアルタイム計算:AIが投資シミュレーションをリアルタイムで実行 自動化されたワークフロー:複数の物件比較や分析を自動実行 セキュアな接続:OAuth認証とTLS暗号化で安全 エラーハンドリング:詳細なエラー情報とリトライ機能 🖥️ Claude Desktop セットアップ 1. 設定ファイルの作成 Claude Desktopの設定ディレクトリに設定ファイルを作成します。 macOS ~/Library/Application Support/Claude/claude_desktop_config.json Windows %APPDATA%\Claude\claude_desktop_config.json Linux ~/.config/claude/claude_desktop_config.json 2. 設定ファイルの内容 { "mcpServers": { "kominka-simulator": { "command": "node", "args": [ "server.js" ], "cwd": "/path/to/kominka-mcp-server", "env": { "API_BASE_URL": "https://kominka-apart-sim.vercel.app/api", "SUPABASE_URL": "https://your-project.supabase.co", "SUPABASE_SERVICE_ROLE_KEY": "your-service-role-key", "JWT_SECRET": "your-jwt-secret" } } } } 3. サーバーファイルの準備 NPM パッケージのインストール mkdir kominka-mcp-server cd kominka-mcp-server npm init -y npm install @modelcontextprotocol/sdk axios ws jsonwebtoken npm install --save-dev @types/node typescript server.js の作成 #!/usr/bin/env node const { Server } = require('@modelcontextprotocol/sdk/server/index.js'); const { StdioServerTransport } = require('@modelcontextprotocol/sdk/server/stdio.js'); const axios = require('axios'); const jwt = require('jsonwebtoken'); class KominkaSimulatorServer { constructor() { this.server = new Server( { name: 'kominka-simulator', version: '1.0.0', }, { capabilities: { tools: {}, }, } ); this.apiBaseUrl = process.env.API_BASE_URL || 'https://kominka-apart-sim.vercel.app/api'; this.supabaseUrl = process.env.SUPABASE_URL; this.supabaseServiceKey = process.env.SUPABASE_SERVICE_ROLE_KEY; this.jwtSecret = process.env.JWT_SECRET; this.setupTools(); } setupTools() { // 新規シミュレーション作成ツール this.server.setRequestHandler({ method: 'tools/call', schema: { name: 'create_simulation', description: '新しい不動産投資シミュレーションを作成', inputSchema: { type: 'object', properties: { title: { type: 'string', description: 'シミュレーション名' }, property_type: { type: 'string', enum: ['house', 'apartment'] }, property_price: { type: 'number', description: '物件価格(円)' }, annual_rent: { type: 'number', description: '年間家賃収入(円)' }, vacancy_rate: { type: 'number', description: '空室率(%)' }, expense_rate: { type: 'number', description: '経費率(%)' }, use_loan: { type: 'boolean', description: 'ローン利用有無' }, loan_amount: { type: 'number', description: 'ローン金額(円)' }, loan_interest_rate: { type: 'number', description: 'ローン金利(%)' }, loan_term: { type: 'number', description: 'ローン期間(年)' } }, required: ['title', 'property_type', 'property_price', 'annual_rent'] } } }, async (request) => { try { const response = await axios.post(`${this.apiBaseUrl}/simulations`, request.params, { headers: { 'Authorization': `Bearer ${this.generateJWT()}`, 'Content-Type': 'application/json' } }); return { content: [ { type: 'text', text: `シミュレーション「${request.params.title}」を作成しました。\n\n` + `📊 結果:\n` + `- 表面利回り: ${response.data.results.gross_yield}%\n` + `- 実質利回り: ${response.data.results.net_yield}%\n` + `- 月間キャッシュフロー: ${response.data.results.monthly_cash_flow.toLocaleString()}円\n` + `- ROI: ${response.data.results.roi}%\n` + `- 共有URL: https://kominka-apart-sim.vercel.app/share/${response.data.share_code}` } ] }; } catch (error) { throw new Error(`シミュレーション作成エラー: ${error.response?.data?.error?.message || error.message}`); } }); // シミュレーション一覧取得ツール this.server.setRequestHandler({ method: 'tools/call', schema: { name: 'list_simulations', description: '保存済みシミュレーション一覧を取得', inputSchema: { type: 'object', properties: { limit: { type: 'number', description: '取得件数(最大100)', default: 10 }, sort: { type: 'string', enum: ['created_at', 'updated_at', 'property_price'] }, order: { type: 'string', enum: ['asc', 'desc'] } } } } }, async (request) => { try { const params = new URLSearchParams(); if (request.params.limit) params.append('limit', request.params.limit); if (request.params.sort) params.append('sort', request.params.sort); if (request.params.order) params.append('order', request.params.order); const response = await axios.get(`${this.apiBaseUrl}/simulations?${params}`, { headers: { 'Authorization': `Bearer ${this.generateJWT()}` } }); const simulations = response.data.simulations; const summary = simulations.map(sim => `📋 ${sim.title} (${sim.property_type === 'house' ? '戸建て' : 'アパート'})\n` + ` 価格: ${sim.property_price.toLocaleString()}円\n` + ` 利回り: ${sim.results.gross_yield}%\n` + ` 作成日: ${new Date(sim.created_at).toLocaleDateString('ja-JP')}` ).join('\n\n'); return { content: [ { type: 'text', text: `📊 シミュレーション一覧 (${simulations.length}件)\n\n${summary}` } ] }; } catch (error) { throw new Error(`シミュレーション一覧取得エラー: ${error.response?.data?.error?.message || error.message}`); } }); // リアルタイム計算ツール this.server.setRequestHandler({ method: 'tools/call', schema: { name: 'calculate_metrics', description: '投資指標をリアルタイムで計算(保存なし)', inputSchema: { type: 'object', properties: { property_price: { type: 'number', description: '物件価格(円)' }, annual_rent: { type: 'number', description: '年間家賃収入(円)' }, vacancy_rate: { type: 'number', description: '空室率(%)', default: 5 }, expense_rate: { type: 'number', description: '経費率(%)', default: 20 }, use_loan: { type: 'boolean', description: 'ローン利用有無', default: false }, loan_amount: { type: 'number', description: 'ローン金額(円)' }, loan_interest_rate: { type: 'number', description: 'ローン金利(%)' }, loan_term: { type: 'number', description: 'ローン期間(年)' } }, required: ['property_price', 'annual_rent'] } } }, async (request) => { try { const response = await axios.post(`${this.apiBaseUrl}/simulations/calculate`, request.params, { headers: { 'Authorization': `Bearer ${this.generateJWT()}`, 'Content-Type': 'application/json' } }); const results = response.data.results; return { content: [ { type: 'text', text: `🔢 投資指標計算結果\n\n` + `📊 基本指標:\n` + `- 表面利回り: ${results.gross_yield}%\n` + `- 実質利回り: ${results.net_yield}%\n` + `- 月間キャッシュフロー: ${results.monthly_cash_flow.toLocaleString()}円\n` + `- 年間キャッシュフロー: ${results.annual_cash_flow.toLocaleString()}円\n` + `- ROI: ${results.roi}%\n\n` + `💰 初期費用:\n` + `- 総初期費用: ${results.total_initial_cost.toLocaleString()}円\n` + `${results.monthly_loan_payment ? `- 月間ローン返済額: ${results.monthly_loan_payment.toLocaleString()}円` : ''}` } ] }; } catch (error) { throw new Error(`計算エラー: ${error.response?.data?.error?.message || error.message}`); } }); } generateJWT() { return jwt.sign( { sub: 'mcp-server', aud: 'kominka-simulator' }, this.jwtSecret, { expiresIn: '1h' } ); } async run() { const transport = new StdioServerTransport(); await this.server.connect(transport); } } const server = new KominkaSimulatorServer(); server.run().catch(err => { // Handle server errors }); 🔧 VSCode セットアップ 1. 拡張機能のインストール VSCode Marketplaceから「MCP Client」拡張機能をインストールします。 2. ワークスペース設定 プロジェクトの.vscode/settings.jsonに設定を追加: { "mcp.servers": { "kominka-simulator": { "command": "node", "args": ["path/to/server.js"], "env": { "API_BASE_URL": "https://kominka-apart-sim.vercel.app/api", "SUPABASE_URL": "https://your-project.supabase.co", "SUPABASE_SERVICE_ROLE_KEY": "your-service-role-key", "JWT_SECRET": "your-jwt-secret" } } }, "mcp.autoConnect": true } 3. 使用方法 コマンドパレット:Ctrl+Shift+P → "MCP: Call Tool" チャット機能:VSCodeのチャットでMCPツールを直接呼び出し インテリセンス:型定義によるコード補完 🌐 API経由でのMCP接続 WebSocket接続 WebSocketを使用してMCPサーバーと直接通信できます。 接続例(JavaScript) const WebSocket = require('ws'); const jwt = require('jsonwebtoken'); // JWT トークン生成 const token = jwt.sign( { sub: 'api-client', aud: 'kominka-simulator' }, 'your-jwt-secret', { expiresIn: '1h' } ); // WebSocket接続 const ws = new WebSocket('wss://kominka-apart-sim.vercel.app/mcp', { headers: { 'Authorization': `Bearer ${token}` } }); ws.on('open', () => { // ツール呼び出し ws.send(JSON.stringify({ jsonrpc: '2.0', id: 1, method: 'tools/call', params: { name: 'calculate_metrics', arguments: { property_price: 8000000, annual_rent: 960000, vacancy_rate: 5, expense_rate: 20 } } })); }); ws.on('message', (data) => { const response = JSON.parse(data); }); ws.on('error', (error) => { }); HTTP API ラッパー // MCPツールをHTTP APIとして呼び出し const response = await fetch('https://kominka-apart-sim.vercel.app/api/mcp/tools/call', { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ tool: 'create_simulation', arguments: { title: 'テスト物件', property_type: 'house', property_price: 8000000, annual_rent: 960000 } }) }); const result = await response.json(); 🔐 認証とセキュリティ設定 環境変数の設定 セキュリティのため、認証情報は環境変数で管理します。 .env ファイルの例 # MCP Server Configuration API_BASE_URL=https://kominka-apart-sim.vercel.app/api SUPABASE_URL=https://your-project.supabase.co SUPABASE_SERVICE_ROLE_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... JWT_SECRET=your-super-secret-jwt-key-here # OAuth Configuration (optional) GOOGLE_CLIENT_ID=your-google-client-id GOOGLE_CLIENT_SECRET=your-google-client-secret GITHUB_CLIENT_ID=your-github-client-id GITHUB_CLIENT_SECRET=your-github-client-secret 権限管理 MCP専用JWT:MCPサーバー専用のJWTトークン スコープ制限:読み取り・書き込み権限の細かい制御 IPアドレス制限:特定のIPからのアクセスのみ許可 レート制限:過度なAPI呼び出しの防止 🔍 トラブルシューティング よくある問題と解決方法 1. 接続エラー 症状:MCPサーバーに接続できない 原因:設定ファイルのパスが間違っている 解決方法:設定ファイルの絶対パスを確認 2. 認証エラー 症状:401 Unauthorized エラー 原因:JWT トークンの有効期限切れ 解決方法:JWTトークンを再生成 3. 計算エラー 症状:計算結果が返らない 原因:入力値の範囲エラー 解決方法:物件価格は100万円以上、利回りは妥当な範囲内 デバッグ方法 # ログレベルを設定 export DEBUG=mcp:* node server.js # 詳細なエラー情報を出力 export NODE_ENV=development export LOG_LEVEL=debug 📚 実用例 AIアシスタントとの対話例 基本的な計算 ユーザー: "築30年の戸建て、価格800万円、年間家賃120万円の投資シミュレーションを作成して" AIアシスタント: MCPツールを呼び出して計算します... [create_simulation ツール実行] - 表面利回り: 15.0% - 実質利回り: 12.35% - 月間キャッシュフロー: 65,000円 - ROI: 22.5% この物件は高利回りで収益性が良好です。 複数物件の比較 ユーザー: "3つの物件を比較してベストな投資先を教えて" AIアシスタント: 物件A: 利回り15% ROI 22% 物件B: 利回り12% ROI 18% 物件C: 利回り18% ROI 25% → 物件Cがベストな投資先です。理由:... 🔄 自動更新とメンテナンス 定期メンテナンス JWTトークンの更新:1時間ごとに自動更新 接続の監視:WebSocket接続の自動復旧 ログの管理:ログファイルの自動ローテーション アップデート通知 新機能や重要な更新がある場合、MCPサーバーが自動的に通知します。 🔗 関連リンク API認証・セキュリティガイド エンドポイント詳細リファレンス API完全ガイド MCP仕様書

この記事は役に立ちましたか?