Skip to main content
Glama

1MCP Server

searchHandler.ts4.36 kB
import { createRegistryClient } from '@src/domains/registry/mcpRegistryClient.js'; import { SearchMCPServersArgs } from '@src/domains/registry/mcpToolSchemas.js'; import { createSearchEngine } from '@src/domains/registry/searchFiltering.js'; import { OFFICIAL_REGISTRY_KEY, RegistryExtensions, RegistryOptions, RegistryServer, ServerMeta, } from '@src/domains/registry/types.js'; import logger from '@src/logger/logger.js'; import { withErrorHandling } from '@src/utils/core/errorHandling.js'; // Singleton instances let registryClient: ReturnType<typeof createRegistryClient> | null = null; let searchEngine: ReturnType<typeof createSearchEngine> | null = null; let currentRegistryConfig: RegistryOptions | undefined = undefined; /** * Get or create registry client instance */ function getRegistryClient(registryOptions?: RegistryOptions) { // Recreate client if config changed if (!registryClient || JSON.stringify(currentRegistryConfig) !== JSON.stringify(registryOptions)) { if (registryClient) { registryClient.destroy(); } registryClient = createRegistryClient(registryOptions); currentRegistryConfig = registryOptions; } return registryClient; } /** * Get or create search engine instance */ function getSearchEngine() { if (!searchEngine) { searchEngine = createSearchEngine(); } return searchEngine; } /** * Search result with pagination metadata */ export interface SearchMCPServersResult { servers: (RegistryServer & { registryId: string; lastUpdated: string })[]; next_cursor?: string; count: number; } /** * Transform server data for search results */ function transformServerForSearch( server: RegistryServer, ): RegistryServer & { registryId: string; lastUpdated: string } { const meta = server._meta[OFFICIAL_REGISTRY_KEY] as RegistryExtensions; if (!meta) { throw new Error('Missing registry metadata for server'); } return { ...server, registryId: meta.serverId || '', packages: server.packages || [], lastUpdated: meta.updatedAt || '', repository: server.repository, }; } /** * Handle search_mcp_servers tool calls */ export async function handleSearchMCPServers( args: SearchMCPServersArgs, registryOptions?: RegistryOptions, ): Promise<SearchMCPServersResult> { const handler = withErrorHandling(async () => { logger.debug('Processing search_mcp_servers request', args); const client = getRegistryClient(registryOptions); const engine = getSearchEngine(); // Validate and set defaults const limit = Math.min(args.limit || 20, 100); const status = args.status || 'active'; // Build API parameters - pass search to API for server-side filtering const apiParams: Record<string, string | number> = { limit, }; if (args.query) { apiParams.search = args.query; } if (args.cursor) { apiParams.cursor = args.cursor; } // Get servers from registry with API-side search and metadata const response = await client.getServersWithMetadata(apiParams); // Apply client-side filtering for parameters not supported by API const servers = response.servers || []; // Extract RegistryServer objects from ServerResponse objects and preserve metadata const registryServers = servers.map((sr) => ({ ...sr.server, _meta: sr._meta as ServerMeta, // Preserve the metadata from ServerResponse with proper type assertion })); const filteredServers = engine.applyFilters(registryServers, { query: undefined, // Already handled by API - no need for client-side search status: status === 'all' ? undefined : status, registry_type: args.registry_type, transport: args.transport, }); // Transform results for search response const transformedResults = filteredServers.map(transformServerForSearch); logger.debug(`Found ${transformedResults.length} servers matching search criteria`); // Return with pagination metadata return { servers: transformedResults, next_cursor: response.metadata.nextCursor, count: response.metadata.count, }; }, 'Failed to search MCP servers'); return await handler(); } /** * Cleanup resources */ export function cleanupSearchHandler(): void { if (registryClient) { registryClient.destroy(); registryClient = null; } }

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/1mcp-app/agent'

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