Files
goodgo-platform/libs/mcp-servers/src/nestjs/mcp-registry.service.ts
Ho Ngoc Hai 53c33a1c50 feat(mcp): add industrial parks and reports MCP tool servers
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>
2026-04-16 05:16:11 +07:00

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;
}
}