connect_to_ip
Establish a connection to a Nanoleaf device by specifying its IP address and port, enabling control and management of smart lighting features through the Nanoleaf MCP Server.
Instructions
Connect to a Nanoleaf device at a specific IP address
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| ip | Yes | IP address of the Nanoleaf device | |
| port | No | Port number (default: 16021) |
Input Schema (JSON Schema)
{
"properties": {
"ip": {
"description": "IP address of the Nanoleaf device",
"type": "string"
},
"port": {
"default": 16021,
"description": "Port number (default: 16021)",
"type": "number"
}
},
"required": [
"ip"
],
"type": "object"
}
Implementation Reference
- src/index.ts:217-251 (handler)MCP CallToolRequest handler case for 'connect_to_ip': extracts ip and port from arguments, calls NanoleafClient.connectToIP, sets primaryDevice on success, returns appropriate text response.case 'connect_to_ip': try { const ip = request.params.arguments?.ip as string; const port = (request.params.arguments?.port as number) || 16021; const device = await NanoleafClient.connectToIP(ip, port); if (device) { primaryDevice = new NanoleafClient(device); return { content: [ { type: 'text', text: `Successfully connected to Nanoleaf device at ${ip}:${port}`, }, ], }; } else { return { content: [ { type: 'text', text: `No Nanoleaf device found at ${ip}:${port}`, }, ], }; } } catch (error) { return { content: [ { type: 'text', text: `Error connecting to ${request.params.arguments?.ip}: ${error}`, }, ], }; }
- src/index.ts:149-167 (registration)Registration of 'connect_to_ip' tool in ListToolsRequest handler response: includes name, description, and inputSchema (ip: string required; port: number optional default 16021).{ name: 'connect_to_ip', description: 'Connect to a Nanoleaf device at a specific IP address', inputSchema: { type: 'object', properties: { ip: { type: 'string', description: 'IP address of the Nanoleaf device', }, port: { type: 'number', description: 'Port number (default: 16021)', default: 16021, }, }, required: ['ip'], }, },
- src/nanoleaf-client.ts:94-131 (helper)NanoleafClient.connectToIP static helper: probes given IP/port with fallback protocols/ports (http:16021/80, https:443/16021), verifies Nanoleaf by GET /api/v1/ success or 403 Forbidden response, ignores self-signed SSL errors.static async connectToIP(ip: string, port: number = 16021): Promise<NanoleafDevice | null> { // Try different protocols and ports const attempts = [ { ip, port, protocol: 'http' }, { ip, port: 80, protocol: 'http' }, { ip, port: 443, protocol: 'https' }, { ip, port, protocol: 'https' } ]; for (const attempt of attempts) { try { const httpClient = axios.create({ baseURL: `${attempt.protocol}://${attempt.ip}:${attempt.port}/api/v1`, timeout: 5000, // Ignore SSL certificate errors for self-signed certs httpsAgent: attempt.protocol === 'https' ? new https.Agent({ rejectUnauthorized: false }) : undefined }); // Try to make a basic request to see if it's a Nanoleaf device const response = await httpClient.get('/'); // If we get here without error, it's likely a Nanoleaf device return { ip: attempt.ip, port: attempt.port, protocol: attempt.protocol }; } catch (error: any) { console.error(`Attempt ${attempt.protocol}://${attempt.ip}:${attempt.port} failed:`, error.message); // Check if it's a 403 Forbidden (typical for Nanoleaf without auth) if (error.response && error.response.status === 403) { console.error(`Found Nanoleaf device at ${attempt.protocol}://${attempt.ip}:${attempt.port} (403 Forbidden - needs auth)`); return { ip: attempt.ip, port: attempt.port, protocol: attempt.protocol }; } // Continue to next attempt if other error continue; } } return null; }