feat(mcp): add MCP Server Integration — Property Search, Analytics, Valuation

Implement 3 MCP servers in libs/mcp-servers/ using @modelcontextprotocol/sdk:

- Property Search: NL search via Typesense, property comparison, detail lookup
- Market Analytics: market reports, price trends, district comparison
- Valuation: AVM integration with Python AI service, feature extraction, batch valuation

Includes NestJS integration module with SSE transport for in-process hosting.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
Ho Ngoc Hai
2026-04-08 03:22:27 +07:00
parent efa49e225e
commit cb00b12d7b
17 changed files with 1077 additions and 41 deletions

View File

@@ -0,0 +1,89 @@
import type { Client as TypesenseClient } from 'typesense';
export interface PropertySearchDeps {
typesenseClient: TypesenseClient;
collectionName?: string;
}
export interface MarketAnalyticsDeps {
typesenseClient: TypesenseClient;
collectionName?: string;
}
export interface ValuationDeps {
aiServiceBaseUrl: string;
}
export interface McpServerConfig {
name: string;
version: string;
}
export interface PropertyComparisonResult {
properties: PropertySummary[];
comparison: {
priceRange: { min: number; max: number; avg: number };
areaRange: { min: number; max: number; avg: number };
pricePerM2Range: { min: number; max: number; avg: number };
};
}
export interface PropertySummary {
listingId: string;
title: string;
propertyType: string;
transactionType: string;
priceVND: number;
pricePerM2: number | null;
areaM2: number;
bedrooms: number | null;
bathrooms: number | null;
address: string;
district: string;
city: string;
}
export interface MarketReport {
district: string;
city: string;
propertyType: string | null;
totalListings: number;
averagePriceVND: number;
medianPriceVND: number;
averagePricePerM2: number;
averageArea: number;
priceDistribution: { range: string; count: number }[];
}
export interface PriceTrend {
district: string;
city: string;
period: string;
dataPoints: { label: string; avgPrice: number; count: number }[];
}
export interface ValuationEstimate {
estimatedPriceVND: number;
confidence: number;
pricePerM2: number;
priceRangeLow: number;
priceRangeHigh: number;
}
export interface FeatureExtractionResult {
features: {
area: number | null;
district: string | null;
city: string | null;
propertyType: string | null;
bedrooms: number | null;
bathrooms: number | null;
floors: number | null;
frontage: number | null;
roadWidth: number | null;
priceMentioned: number | null;
hasLegalPaper: boolean | null;
};
tokens: string[];
entities: { text: string; label: string }[];
}