Skip to main content
Glama

MCP Bridge Server

router.ts4.05 kB
import { Message, RouterConfig, ClientInfo } from './types.js'; import { StateManager } from './stateManager.js'; import { EventEmitter } from 'events'; export class Router extends EventEmitter { private config: RouterConfig; private stateManager: StateManager; constructor(config: RouterConfig, stateManager: StateManager) { super(); this.config = config; this.stateManager = stateManager; } /** * Determine the target client type based on routing rules */ private determineTargetType(message: Message): 'claude' | 'cline' | undefined { console.error('Determining target type for message:', message.method); // Check specific routing rules first const rule = this.config.routingRules?.[message.method]; if (rule) { console.error('Found routing rule:', rule); return rule.targetType; } // Fall back to default target type console.error('Using default target type:', this.config.defaultTargetType); return this.config.defaultTargetType; } /** * Route a message to its target client */ public async routeMessage(message: Message): Promise<boolean> { try { // If target is specified, use it directly if (message.targetClientId) { console.error('Using specified target client:', message.targetClientId); this.emit('message', message.targetClientId, message); return true; } // Otherwise, determine target based on routing rules const targetType = this.determineTargetType(message); if (!targetType) { throw new Error(`Unable to determine target type for method: ${message.method}`); } // Get available clients of the target type const availableClients = this.stateManager.getConnectedClientsByType(targetType); console.error(`Found ${availableClients.length} available clients of type ${targetType}:`, availableClients.map(c => `${c.id} (${c.connected ? 'connected' : 'disconnected'})`)); if (availableClients.length === 0) { throw new Error(`No available clients of type: ${targetType}`); } // For now, just use the first available client // TODO: Implement more sophisticated client selection (load balancing, etc.) const targetClient = availableClients[0]; console.error('Selected target client:', targetClient.id); // Update message with target client const routedMessage: Message = { ...message, targetClientId: targetClient.id }; this.emit('message', targetClient.id, routedMessage); return true; } catch (error) { this.emit('error', error); return false; } } /** * Register a message handler for a specific client */ public onMessage( handler: (clientId: string, message: Message) => void ): void { this.on('message', handler); } /** * Register an error handler */ public onError( handler: (error: Error) => void ): void { this.on('error', handler); } /** * Check if a client is available to handle a message */ public isClientAvailable(clientId: string): boolean { const clients = this.stateManager.getConnectedClientsByType('claude') .concat(this.stateManager.getConnectedClientsByType('cline')); return clients.some(client => client.id === clientId); } /** * Get all available clients */ public getAvailableClients(): ClientInfo[] { return [ ...this.stateManager.getConnectedClientsByType('claude'), ...this.stateManager.getConnectedClientsByType('cline'), ...this.stateManager.getConnectedClientsByType('other') ]; } /** * Update routing rules */ public updateRoutingRules(rules: RouterConfig['routingRules']): void { this.config = { ...this.config, routingRules: rules }; } /** * Set default target type */ public setDefaultTargetType(type: 'claude' | 'cline'): void { this.config = { ...this.config, defaultTargetType: type }; } }

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/glassBead-tc/SubspaceDomain'

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