discover_client
Locate and optionally launch an MCP client to facilitate communication between AI applications using the Model Context Protocol.
Instructions
Find and optionally start an MCP client
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| clientType | Yes | ||
| autoStart | No | ||
| timeout | No |
Implementation Reference
- src/server.ts:176-254 (handler)Main handler function implementing the discover_client tool: checks connected clients, discovers new ones, connects, or auto-starts clients based on input parameters.
private async handleClientDiscovery(params: any): Promise<ClientDiscoveryResult> { const { clientType, autoStart = false, timeout = this.config.clientStartupTimeoutMs || 30000 } = params; this.logger.info(`Discovering client of type: ${clientType}, autoStart: ${autoStart}`); // Check if client is already connected const connectedClients = this.connectionManager.getConnectedClientsByType(clientType); if (connectedClients.length > 0) { this.logger.info(`Found connected client: ${connectedClients[0].id}`); return { found: true, client: connectedClients[0] }; } // Try to find a discovered but not connected client const discoveredClients = this.discoveryManager.getClientsByType(clientType); if (discoveredClients.length > 0) { this.logger.info(`Found discovered client: ${discoveredClients[0].id}`); // Attempt to connect to the client this.connectionManager.handleRegistration(JSON.stringify( this.registrationProtocol.createRegisterMessage( clientType, { supportedMethods: ['tools/call'], supportedTransports: ['unix-socket'], targetType: clientType }, 'unix-socket', discoveredClients[0].id, discoveredClients[0].socketPath ) )); return { found: true, client: discoveredClients[0] }; } // If autoStart is true, attempt to start the client if (autoStart) { try { const startupOptions = this.getClientStartupOptions(clientType); if (!startupOptions) { this.logger.warn(`No startup configuration available for client type: ${clientType}`); return { found: false, error: `No startup configuration available for client type: ${clientType}` }; } const client = await this.startClient(clientType, startupOptions, timeout); this.logger.info(`Started client: ${client.id}`); return { found: true, client, startupAttempted: true, startupSuccessful: true }; } catch (error: unknown) { const errorMessage = error instanceof Error ? error.message : 'Unknown error'; this.logger.error(`Failed to start client: ${errorMessage}`); return { found: false, error: `Failed to start client: ${errorMessage}`, startupAttempted: true, startupSuccessful: false }; } } this.logger.warn(`No ${clientType} clients available`); return { found: false, error: `No ${clientType} clients available` }; } - src/server.ts:71-82 (registration)Registration of the discover_client tool in MCP server capabilities, including description and input schema.
'discover_client': { description: 'Find and optionally start an MCP client', inputSchema: { type: 'object', properties: { clientType: { type: 'string', enum: ['claude', 'cline'] }, autoStart: { type: 'boolean' }, timeout: { type: 'number' } }, required: ['clientType'] } }, - src/server.ts:125-133 (handler)Request handler dispatcher for tool calls, routing 'discover_client' to its implementation.
this.server.setRequestHandler(CallToolRequestSchema, async (request) => { if (request.params.name === 'discover_client') { return this.handleClientDiscovery(request.params.arguments); } if (request.params.name === 'tools/call') { return this.handleToolCall(request.params.arguments); } throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${request.params.name}`); }); - src/server.ts:139-150 (schema)Tool schema returned in ListToolsRequestSchema response.
name: 'discover_client', description: 'Find and optionally start an MCP client', inputSchema: { type: 'object', properties: { clientType: { type: 'string', enum: ['claude', 'cline'] }, autoStart: { type: 'boolean' }, timeout: { type: 'number' } }, required: ['clientType'] } }, - src/server.ts:262-313 (helper)Helper function to start a client process, used when autoStart is true in discover_client.
private async startClient( clientType: string, options: ClientStartupOptions, timeout: number ): Promise<ClientInfo> { return new Promise((resolve, reject) => { const timeoutId = setTimeout(() => { reject(new Error(`Client startup timed out after ${timeout}ms`)); }, timeout); try { const childProcess = spawn(options.command!, options.args || [], { env: { ...process.env, ...options.env }, cwd: options.cwd }); const client: ClientInfo = { id: randomUUID(), type: clientType as 'claude' | 'cline', transport: 'stdio', connected: true, lastSeen: new Date(), state: ConnectionState.CONNECTING, processId: childProcess.pid }; this.stateManager.registerClient(client); // Wait for initial connection childProcess.once('spawn', () => { clearTimeout(timeoutId); client.state = ConnectionState.CONNECTED; this.stateManager.updateClientState(client.id, ConnectionState.CONNECTED); resolve(client); }); childProcess.on('error', (error: Error) => { clearTimeout(timeoutId); reject(error); }); childProcess.on('exit', (code: number) => { if (code !== 0) { reject(new Error(`Client process exited with code ${code}`)); } }); } catch (error) { clearTimeout(timeoutId); reject(error); } }); }