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 @@
export { McpIntegrationModule } from './mcp.module';

View File

@@ -0,0 +1,35 @@
import { Module, type OnModuleInit } from '@nestjs/common';
import { McpModule as McpCoreModule, McpRegistryService } from '@goodgo/mcp-servers';
import { SearchModule } from '@modules/search';
import { TypesenseClientService } from '@modules/search/infrastructure/services/typesense-client.service';
import { LoggerService } from '@modules/shared/infrastructure/logger.service';
@Module({
imports: [
SearchModule,
McpCoreModule.forRoot({
aiServiceBaseUrl: process.env['AI_SERVICE_URL'] || 'http://localhost:8000',
typesenseCollectionName: 'listings',
}),
],
})
export class McpIntegrationModule implements OnModuleInit {
constructor(
private readonly typesenseClient: TypesenseClientService,
private readonly mcpRegistry: McpRegistryService,
private readonly logger: LoggerService,
) {}
async onModuleInit(): Promise<void> {
this.mcpRegistry.setTypesenseClient(this.typesenseClient.getClient());
// Re-initialize servers now that Typesense client is available
await this.mcpRegistry.onModuleInit();
const servers = this.mcpRegistry.getServerNames();
this.logger.log(
`MCP servers initialized: ${servers.join(', ')}`,
'McpIntegrationModule',
);
}
}

View File

@@ -40,7 +40,7 @@ const QueryHandlers = [SearchPropertiesHandler, GeoSearchHandler];
...CommandHandlers,
...QueryHandlers,
],
exports: [ListingIndexerService, SEARCH_REPOSITORY],
exports: [ListingIndexerService, SEARCH_REPOSITORY, TypesenseClientService],
})
export class SearchModule implements OnModuleInit {
constructor(