Add IndustrialParkServer for KCN/KCX search and analytics, and ReportsServer for market report generation. Include unit tests for industrial parks server. Co-Authored-By: Paperclip <noreply@paperclip.ing>
85 lines
2.7 KiB
TypeScript
85 lines
2.7 KiB
TypeScript
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
import { Injectable, Inject, type OnModuleInit } from '@nestjs/common';
|
|
import type { Client as TypesenseClient } from 'typesense';
|
|
import { MCP_MODULE_OPTIONS } from './mcp.constants';
|
|
import type { McpModuleOptions } from './mcp.module';
|
|
|
|
@Injectable()
|
|
export class McpRegistryService implements OnModuleInit {
|
|
private readonly servers = new Map<string, McpServer>();
|
|
private typesenseClient: TypesenseClient | null = null;
|
|
|
|
constructor(
|
|
@Inject(MCP_MODULE_OPTIONS) private readonly options: McpModuleOptions,
|
|
) {}
|
|
|
|
async onModuleInit(): Promise<void> {
|
|
// Lazy import to avoid hard dependency at module load time
|
|
const { createPropertySearchServer } = await import('../property-search/property-search.server');
|
|
const { createMarketAnalyticsServer } = await import('../market-analytics/market-analytics.server');
|
|
const { createValuationServer } = await import('../valuation/valuation.server');
|
|
const { createIndustrialParksServer } = await import('../industrial-parks/industrial-parks.server');
|
|
const { createReportsServer } = await import('../reports/reports.server');
|
|
|
|
// Typesense client is injected from the host app via setTypesenseClient
|
|
// If not set by the time servers are needed, tools that require it will fail gracefully
|
|
if (this.typesenseClient) {
|
|
this.servers.set(
|
|
'property-search',
|
|
createPropertySearchServer({
|
|
typesenseClient: this.typesenseClient,
|
|
collectionName: this.options.typesenseCollectionName,
|
|
}),
|
|
);
|
|
|
|
this.servers.set(
|
|
'market-analytics',
|
|
createMarketAnalyticsServer({
|
|
typesenseClient: this.typesenseClient,
|
|
collectionName: this.options.typesenseCollectionName,
|
|
}),
|
|
);
|
|
}
|
|
|
|
this.servers.set(
|
|
'valuation',
|
|
createValuationServer({
|
|
aiServiceBaseUrl: this.options.aiServiceBaseUrl,
|
|
}),
|
|
);
|
|
|
|
if (this.typesenseClient) {
|
|
this.servers.set(
|
|
'industrial-parks',
|
|
createIndustrialParksServer({
|
|
typesenseClient: this.typesenseClient,
|
|
aiServiceBaseUrl: this.options.aiServiceBaseUrl,
|
|
}),
|
|
);
|
|
}
|
|
|
|
this.servers.set(
|
|
'reports',
|
|
createReportsServer({
|
|
aiServiceBaseUrl: this.options.aiServiceBaseUrl,
|
|
}),
|
|
);
|
|
}
|
|
|
|
setTypesenseClient(client: TypesenseClient): void {
|
|
this.typesenseClient = client;
|
|
}
|
|
|
|
getServer(name: string): McpServer | undefined {
|
|
return this.servers.get(name);
|
|
}
|
|
|
|
getServerNames(): string[] {
|
|
return Array.from(this.servers.keys());
|
|
}
|
|
|
|
getAllServers(): Map<string, McpServer> {
|
|
return this.servers;
|
|
}
|
|
}
|