Skip to main content
Glama
sigaihealth

RealVest Real Estate MCP Server

fix-flip.js15.8 kB
export class FixFlipCalculator { constructor() { this.name = 'Fix & Flip Calculator'; this.description = 'Analyze profitability of fix and flip real estate investments'; } getSchema() { return { type: 'object', properties: { purchase_price: { type: 'number', description: 'Property purchase price', minimum: 0 }, rehab_budget: { type: 'number', description: 'Total renovation/rehab budget', minimum: 0 }, after_repair_value: { type: 'number', description: 'Estimated value after repairs (ARV)', minimum: 0 }, purchase_closing_costs: { type: 'number', description: 'Closing costs for purchase', minimum: 0, default: 0 }, holding_period_months: { type: 'number', description: 'Expected project duration in months', minimum: 1, maximum: 24, default: 6 }, financing_type: { type: 'string', description: 'Type of financing', enum: ['cash', 'hard_money', 'conventional', 'private_lender'], default: 'hard_money' }, down_payment_percent: { type: 'number', description: 'Down payment percentage (if financed)', minimum: 0, maximum: 100, default: 20 }, interest_rate: { type: 'number', description: 'Annual interest rate (%)', minimum: 0, maximum: 30, default: 12 }, loan_points: { type: 'number', description: 'Loan origination points', minimum: 0, maximum: 10, default: 2 }, monthly_holding_costs: { type: 'number', description: 'Monthly costs (utilities, insurance, taxes, etc.)', minimum: 0, default: 0 }, selling_costs_percent: { type: 'number', description: 'Selling costs as % of sale price (agent fees, closing)', minimum: 0, maximum: 15, default: 8 }, contingency_percent: { type: 'number', description: 'Contingency for rehab overruns (%)', minimum: 0, maximum: 50, default: 10 } }, required: ['purchase_price', 'rehab_budget', 'after_repair_value'] }; } calculate(params) { const { purchase_price, rehab_budget, after_repair_value, purchase_closing_costs = 0, holding_period_months = 6, financing_type = 'hard_money', down_payment_percent = 20, interest_rate = 12, loan_points = 2, monthly_holding_costs = 0, selling_costs_percent = 8, contingency_percent = 10 } = params; // Calculate financing details const financingDetails = this.calculateFinancing( purchase_price, rehab_budget, financing_type, down_payment_percent, interest_rate, loan_points, holding_period_months ); // Calculate all costs const rehab_contingency = rehab_budget * (contingency_percent / 100); const total_rehab_budget = rehab_budget + rehab_contingency; const total_holding_costs = monthly_holding_costs * holding_period_months; const selling_costs = after_repair_value * (selling_costs_percent / 100); // Total investment calculation const total_cash_needed = financingDetails.cash_to_close + (financing_type === 'cash' ? total_rehab_budget : 0) + (financing_type !== 'cash' && !financingDetails.rehab_financed ? total_rehab_budget : 0); const total_costs = purchase_price + purchase_closing_costs + total_rehab_budget + financingDetails.total_loan_costs + total_holding_costs + selling_costs; // Profit calculations const gross_profit = after_repair_value - total_costs; const net_profit = gross_profit; // Already accounts for all costs const roi = (net_profit / total_cash_needed) * 100; const profit_margin = (net_profit / after_repair_value) * 100; // Annualized return const months_to_years = 12 / holding_period_months; const annualized_roi = roi * months_to_years; // Maximum allowable offer (MAO) using 70% rule const mao_70_rule = (after_repair_value * 0.7) - rehab_budget; const actual_purchase_percent = (purchase_price / after_repair_value) * 100; // Risk analysis const risk_metrics = this.analyzeRisk( purchase_price, after_repair_value, total_rehab_budget, net_profit, actual_purchase_percent ); // Break-even analysis const break_even_sale_price = total_costs; const cushion_amount = after_repair_value - break_even_sale_price; const cushion_percent = (cushion_amount / after_repair_value) * 100; // Timeline analysis const timeline = this.createTimeline( holding_period_months, financingDetails, monthly_holding_costs ); return { deal_summary: { purchase_price: purchase_price, total_rehab_budget: parseFloat(total_rehab_budget.toFixed(2)), after_repair_value: after_repair_value, holding_period_months: holding_period_months }, financing: financingDetails, cost_breakdown: { purchase_price: purchase_price, purchase_closing_costs: purchase_closing_costs, rehab_budget: rehab_budget, rehab_contingency: parseFloat(rehab_contingency.toFixed(2)), total_rehab: parseFloat(total_rehab_budget.toFixed(2)), financing_costs: parseFloat(financingDetails.total_loan_costs.toFixed(2)), holding_costs: parseFloat(total_holding_costs.toFixed(2)), selling_costs: parseFloat(selling_costs.toFixed(2)), total_costs: parseFloat(total_costs.toFixed(2)) }, profit_analysis: { gross_profit: parseFloat(gross_profit.toFixed(2)), net_profit: parseFloat(net_profit.toFixed(2)), roi_percentage: parseFloat(roi.toFixed(2)), annualized_roi: parseFloat(annualized_roi.toFixed(2)), profit_margin: parseFloat(profit_margin.toFixed(2)), profit_per_month: parseFloat((net_profit / holding_period_months).toFixed(2)) }, investment_requirements: { total_cash_needed: parseFloat(total_cash_needed.toFixed(2)), cash_at_closing: parseFloat(financingDetails.cash_to_close.toFixed(2)), cash_for_rehab: parseFloat((total_cash_needed - financingDetails.cash_to_close).toFixed(2)) }, mao_analysis: { mao_70_rule: parseFloat(mao_70_rule.toFixed(2)), actual_purchase_price: purchase_price, actual_percent_of_arv: parseFloat(actual_purchase_percent.toFixed(2)), difference_from_mao: parseFloat((purchase_price - mao_70_rule).toFixed(2)), follows_70_rule: purchase_price <= mao_70_rule }, break_even_analysis: { break_even_price: parseFloat(break_even_sale_price.toFixed(2)), safety_cushion: parseFloat(cushion_amount.toFixed(2)), cushion_percentage: parseFloat(cushion_percent.toFixed(2)), can_afford_price_drop: parseFloat(cushion_percent.toFixed(2)) + '%' }, risk_assessment: risk_metrics, project_timeline: timeline, recommendations: this.generateRecommendations( roi, profit_margin, cushion_percent, risk_metrics, financingDetails ) }; } calculateFinancing(purchasePrice, rehabBudget, financingType, downPaymentPercent, interestRate, loanPoints, holdingMonths) { if (financingType === 'cash') { return { financing_type: 'Cash Purchase', loan_amount: 0, down_payment: purchasePrice, cash_to_close: purchasePrice, monthly_payment: 0, total_interest: 0, loan_origination_fee: 0, total_loan_costs: 0, effective_rate: 0, rehab_financed: false }; } const down_payment = purchasePrice * (downPaymentPercent / 100); const base_loan_amount = purchasePrice - down_payment; // For hard money, often includes rehab in loan const rehab_financed = financingType === 'hard_money'; const loan_amount = rehab_financed ? base_loan_amount + rehabBudget : base_loan_amount; const monthly_rate = interestRate / 100 / 12; const loan_origination_fee = loan_amount * (loanPoints / 100); // Interest-only payment (common for fix & flip) const monthly_payment = loan_amount * monthly_rate; const total_interest = monthly_payment * holdingMonths; const total_loan_costs = total_interest + loan_origination_fee; // Effective annual rate including points const total_cost_percent = (total_loan_costs / loan_amount) * 100; const effective_rate = (total_cost_percent / holdingMonths) * 12; return { financing_type: this.getFinancingTypeName(financingType), loan_amount: parseFloat(loan_amount.toFixed(2)), down_payment: parseFloat(down_payment.toFixed(2)), cash_to_close: parseFloat((down_payment + loan_origination_fee).toFixed(2)), monthly_payment: parseFloat(monthly_payment.toFixed(2)), total_interest: parseFloat(total_interest.toFixed(2)), loan_origination_fee: parseFloat(loan_origination_fee.toFixed(2)), total_loan_costs: parseFloat(total_loan_costs.toFixed(2)), effective_rate: parseFloat(effective_rate.toFixed(2)), rehab_financed: rehab_financed }; } getFinancingTypeName(type) { const names = { cash: 'Cash Purchase', hard_money: 'Hard Money Loan', conventional: 'Conventional Loan', private_lender: 'Private Lender' }; return names[type] || type; } analyzeRisk(purchasePrice, arv, rehabBudget, profit, purchasePercent) { const riskFactors = []; let riskScore = 0; // Purchase price vs ARV if (purchasePercent > 75) { riskFactors.push({ factor: "High Purchase Price", severity: "High", description: "Purchase price exceeds 75% of ARV" }); riskScore += 3; } else if (purchasePercent > 70) { riskFactors.push({ factor: "Moderate Purchase Price", severity: "Medium", description: "Purchase price between 70-75% of ARV" }); riskScore += 2; } // Rehab budget as % of ARV const rehabPercent = (rehabBudget / arv) * 100; if (rehabPercent > 30) { riskFactors.push({ factor: "Heavy Rehab", severity: "High", description: "Rehab costs exceed 30% of ARV" }); riskScore += 3; } else if (rehabPercent > 20) { riskFactors.push({ factor: "Moderate Rehab", severity: "Medium", description: "Rehab costs 20-30% of ARV" }); riskScore += 2; } // Profit margin const profitMargin = (profit / arv) * 100; if (profitMargin < 10) { riskFactors.push({ factor: "Thin Profit Margin", severity: "High", description: "Profit margin under 10%" }); riskScore += 3; } else if (profitMargin < 15) { riskFactors.push({ factor: "Moderate Profit Margin", severity: "Medium", description: "Profit margin 10-15%" }); riskScore += 1; } // Overall risk rating let overallRisk; if (riskScore >= 6) { overallRisk = "High Risk"; } else if (riskScore >= 3) { overallRisk = "Moderate Risk"; } else { overallRisk = "Low Risk"; } return { overall_risk: overallRisk, risk_score: riskScore, risk_factors: riskFactors, mitigation_strategies: this.getRiskMitigationStrategies(riskFactors) }; } getRiskMitigationStrategies(riskFactors) { const strategies = []; riskFactors.forEach(factor => { if (factor.factor.includes("Purchase Price")) { strategies.push("Negotiate a lower purchase price or find motivated sellers"); } if (factor.factor.includes("Rehab")) { strategies.push("Get multiple contractor bids and build in larger contingencies"); } if (factor.factor.includes("Profit Margin")) { strategies.push("Reduce costs, increase ARV through better finishes, or pass on deal"); } }); return [...new Set(strategies)]; // Remove duplicates } createTimeline(holdingMonths, financing, monthlyHoldingCosts) { const timeline = []; // Month 0 - Acquisition timeline.push({ month: 0, phase: "Acquisition", activities: ["Close on property", "Secure permits", "Finalize contractor"], cash_outflow: financing.cash_to_close }); // Rehab months const rehabMonths = Math.ceil(holdingMonths * 0.7); // Assume 70% for rehab for (let i = 1; i <= rehabMonths; i++) { timeline.push({ month: i, phase: "Renovation", activities: this.getRehabActivities(i, rehabMonths), cash_outflow: financing.monthly_payment + monthlyHoldingCosts }); } // Marketing/Sale months for (let i = rehabMonths + 1; i <= holdingMonths; i++) { timeline.push({ month: i, phase: "Marketing & Sale", activities: ["List property", "Show to buyers", "Negotiate offers"], cash_outflow: financing.monthly_payment + monthlyHoldingCosts }); } return timeline; } getRehabActivities(month, totalRehabMonths) { const earlyPhase = month <= totalRehabMonths * 0.3; const midPhase = month <= totalRehabMonths * 0.7; if (earlyPhase) { return ["Demolition", "Structural work", "Major systems"]; } else if (midPhase) { return ["Framing", "Electrical/Plumbing", "Insulation/Drywall"]; } else { return ["Finishes", "Fixtures", "Final touches"]; } } generateRecommendations(roi, profitMargin, cushionPercent, riskMetrics, financing) { const recommendations = []; // ROI-based recommendations if (roi < 15) { recommendations.push({ type: "Caution", category: "Returns", message: "ROI below 15% may not justify the risk and effort", action: "Consider negotiating purchase price or finding higher ARV properties" }); } else if (roi > 30) { recommendations.push({ type: "Positive", category: "Returns", message: "Strong ROI above 30%", action: "Move quickly but verify all assumptions" }); } // Risk-based recommendations if (riskMetrics.overall_risk === "High Risk") { recommendations.push({ type: "Warning", category: "Risk", message: "Multiple high-risk factors identified", action: "Consider passing or restructuring the deal" }); } // Cushion-based recommendations if (cushionPercent < 10) { recommendations.push({ type: "Caution", category: "Safety Margin", message: "Less than 10% price cushion", action: "Build in larger contingencies or reduce purchase price" }); } // Financing recommendations if (financing.effective_rate > 15) { recommendations.push({ type: "Optimization", category: "Financing", message: "High financing costs reducing returns", action: "Shop for better rates or consider partnering for cash purchase" }); } // General best practices recommendations.push({ type: "Best Practice", category: "Execution", message: "Success depends on execution", action: "Have backup contractors and maintain strict project timeline" }); return recommendations; } }

Latest Blog Posts

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/sigaihealth/realvestmcp'

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