### Install Robonine MCP from Source Source: https://context7.com/roboninecom/robonine-mcp/llms.txt Steps to clone the repository, install dependencies, build the project, and then add the compiled entry point to your MCP host. ```bash git clone https://github.com/roboninecom/robonine-mcp.git cd robonine-mcp/mcp npm install npm run build # Point your MCP host at the compiled entry point claude mcp add robonine -- node /path/to/robonine-mcp/mcp/dist/index.js ``` -------------------------------- ### Robot Tool Usage Examples (TypeScript) Source: https://context7.com/roboninecom/robonine-mcp/llms.txt Demonstrates how to call various robot control tools using the `relay.call` method. Includes examples for listing robots, getting positions, setting joints, stopping robots, listing user robots, listing paths, and reading paths. ```typescript // robot_list — list currently connected robot arms await relay.call('robot_list', {}) // → [{ id: 'arm-01', model: 'Robonine X1', status: 'connected' }] // robot_get_position — read joint angles and Cartesian end-effector pose await relay.call('robot_get_position', { robot_id: 'arm-01' }) // → { joints: [0, 45, -30, 0, 90, 0], endEffector: { x: 120.5, y: 0, z: 200.3 } } // robot_set_joints — move arm to target joint positions (degrees) await relay.call('robot_set_joints', { robot_id: 'arm-01', joints: [0, 90, -45, 0, 45, 0] }) // → { success: true, moved_to: [0, 90, -45, 0, 45, 0] } // robot_stop — disable torque on all servos immediately await relay.call('robot_stop', { robot_id: 'arm-01' }) // → { success: true } // user_robot_list — list robots registered to the logged-in user account await relay.call('user_robot_list', {}) // → [{ id: 'arm-01', name: 'Lab Arm 1', model: 'Robonine X1' }] // path_list — list saved motion paths in the user's account await relay.call('path_list', {}) // → [{ id: 'path-7', name: 'Pick and Place', waypoints: 12 }] // path_read — fetch a full motion path with all waypoints await relay.call('path_read', { path_id: 'path-7' }) // → { id: 'path-7', name: 'Pick and Place', waypoints: [[0,0,0,0,0,0], [0,45,-30,0,90,0], ...] } ``` -------------------------------- ### Install Robonine MCP via Claude Code Source: https://context7.com/roboninecom/robonine-mcp/llms.txt Fetches and runs the Robonine MCP server automatically using npx. No manual build step is required. ```bash # Fetch and run automatically — no manual build step needed claude mcp add robonine -- npx -y github:roboninecom/robonine-mcp ``` -------------------------------- ### WebSocket Protocol Message Examples (TypeScript) Source: https://context7.com/roboninecom/robonine-mcp/llms.txt Defines message types for server-to-browser and browser-to-server communication over WebSocket. Includes examples for calls, tool listings, registration, results, errors, and tool definitions. ```typescript import type { BrowserMessage, BrowserToolDef, ServerMessage } from './protocol.js' // ServerMessage: MCP server → browser tab const callMsg: ServerMessage = { type: 'call', id: 'call-42', tool: 'robot_set_joints', args: { robot_id: 'arm-01', joints: [0, 90, -45, 0, 45, 0] } } const listMsg: ServerMessage = { type: 'list_tools', id: 'list-1' } // BrowserMessage: browser tab → MCP server const registerMsg: BrowserMessage = { type: 'register' } const resultMsg: BrowserMessage = { type: 'result', id: 'call-42', value: { success: true, moved_to: [0, 90, -45, 0, 45, 0] } } const errorMsg: BrowserMessage = { type: 'error', id: 'call-42', message: 'Joint limit exceeded on axis 2' } const toolsMsg: BrowserMessage = { type: 'tools', id: 'list-1', tools: [ { name: 'robot_list', description: 'List connected robot arms', readOnly: true }, { name: 'robot_get_position', description: 'Get joint angles and end-effector position', readOnly: true }, { name: 'robot_set_joints', description: 'Move arm to specified joint positions' }, { name: 'robot_stop', description: 'Disable torque on all servos' }, { name: 'user_robot_list', description: 'List your registered robots', readOnly: true }, { name: 'path_list', description: 'List saved motion paths', readOnly: true }, { name: 'path_read', description: 'Read a motion path with all waypoints', readOnly: true }, ] satisfies BrowserToolDef[] } ``` -------------------------------- ### Add Robonine MCP Server via GitHub Source: https://github.com/roboninecom/robonine-mcp/blob/master/README.md Use this command to automatically fetch and run the Robonine MCP server from GitHub. No manual installation steps are required. ```bash claude mcp add robonine -- npx -y github:roboninecom/robonine-mcp ``` -------------------------------- ### Run Robonine MCP with Custom Port Source: https://context7.com/roboninecom/robonine-mcp/llms.txt Example of running the Robonine MCP server using a custom WebSocket port by setting the ROBONINE_MCP_PORT environment variable. ```bash # Use a custom port ROBONINE_MCP_PORT=61000 node dist/index.js ``` -------------------------------- ### Build and Run Robonine MCP Server Locally Source: https://github.com/roboninecom/robonine-mcp/blob/master/README.md Build the Robonine MCP server from the local repository and then point Claude Code to the compiled JavaScript file. This is an alternative to installing from GitHub. ```bash cd mcp && npm install && npm run build claude mcp add robonine -- node /path/to/student-lab/mcp/dist/index.js ``` -------------------------------- ### MCP Server Wiring and Request Handlers Source: https://context7.com/roboninecom/robonine-mcp/llms.txt Illustrates the core wiring of the MCP server in `src/index.ts`, connecting a `BrowserRelay` to an `@modelcontextprotocol/sdk` `Server` over stdio. It implements handlers for `ListTools` and `CallTool` requests, merging local and browser tools and routing calls appropriately. ```typescript // Simplified illustration of the wiring in src/index.ts import { Server } from '@modelcontextprotocol/sdk/server/index.js' import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js' import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js' import { BrowserRelay } from './relay.js' import { callTool, TOOL_DEFS } from './tools.js' const PORT = parseInt(process.env['ROBONINE_MCP_PORT'] ?? '60808', 10) const relay = new BrowserRelay(PORT) const server = new Server( { name: 'robonine', version: '1.0.0' }, { capabilities: { tools: { listChanged: true } } } ) // Push tool-list-changed notification whenever the browser reconnects relay.onBrowserConnect = () => { server.sendToolListChanged().catch(() => {}) } // MCP ListTools: merge static local tools + dynamic browser tools server.setRequestHandler(ListToolsRequestSchema, async () => { const localTools = TOOL_DEFS.map((t) => ({ ...(t.readOnly ? { annotations: { readOnlyHint: true } } : {}), description: t.description, inputSchema: t.inputSchema ?? { properties: {}, type: 'object' as const }, name: t.name, })) let browserTools: typeof localTools = [] if (relay.connected) { try { const defs = await relay.listTools() browserTools = defs.map((t) => ({ ...(t.readOnly ? { annotations: { readOnlyHint: true } } : {}), description: t.description, inputSchema: t.inputSchema ?? { properties: {}, type: 'object' as const }, name: t.name, })) } catch { // browser disconnected mid-listing; omit browser tools gracefully } } return { tools: [...localTools, ...browserTools] } }) // MCP CallTool: route to local handler or browser relay server.setRequestHandler(CallToolRequestSchema, async (req) => { const { arguments: args = {}, name } = req.params try { const result = await callTool(name, args as Record, relay) const text = typeof result === 'string' ? result : JSON.stringify(result, null, 2) return { content: [{ text, type: 'text' as const }] } } catch (err) { const message = err instanceof Error ? err.message : String(err) return { content: [{ text: message, type: 'text' as const }], isError: true } } }) // Connect over stdio (Claude Code communicates over stdin/stdout) const transport = new StdioServerTransport() await server.connect(transport) ``` -------------------------------- ### BrowserRelay Class Usage Source: https://context7.com/roboninecom/robonine-mcp/llms.txt Demonstrates how to instantiate and use the BrowserRelay class to manage WebSocket connections with the Robonine browser tab, including checking connection status, listing tools, and calling tools. ```typescript import { BrowserRelay } from './relay.js' // Start WebSocket server on 127.0.0.1:60808 const relay = new BrowserRelay(60808) // Called whenever the Robonine browser tab connects relay.onBrowserConnect = () => { console.log('Browser connected — robot tools now available') } // Check connection status console.log(relay.connected) // false (no browser yet) // List tools exposed by the browser tab if (relay.connected) { const tools = await relay.listTools() // tools: [{ name: 'robot_list', description: '...', readOnly: true }, ...] console.log(tools.map(t => t.name)) } // Call a tool on the browser tab (relayed to the robot) try { const position = await relay.call('robot_get_position', { robot_id: 'arm-01' }) // position: { joints: [0, 45, -30, 0, 90, 0], endEffector: { x: 120, y: 0, z: 200 } } console.log(position) } catch (err) { // Handles: no browser, timeout after 15 s, or error returned from browser console.error(err.message) // e.g. 'No browser connected. Open the Robonine app, install the MCP Bridge plugin, and connect a robot.' // e.g. 'Tool call "robot_get_position" timed out after 15000ms' } // Graceful shutdown relay.close() ``` -------------------------------- ### Call and Inspect Tools with BrowserRelay Source: https://context7.com/roboninecom/robonine-mcp/llms.txt Demonstrates how to use the `callTool` function to interact with both locally defined tools (like `check_connection`) and tools forwarded to the `BrowserRelay` (like `robot_set_joints` and `robot_stop`). Includes error handling for browser relay operations. ```typescript import { callTool, TOOL_DEFS } from './tools.js' import { BrowserRelay } from './relay.js' const relay = new BrowserRelay(60808) // Inspect locally-handled tools console.log(TOOL_DEFS) // [ // { // name: 'check_connection', // description: 'Check whether the browser relay ... Returns "connected" or "not connected".', // readOnly: true // } // ] // check_connection — resolved locally, never sent to browser const status = await callTool('check_connection', {}, relay) console.log(status) // 'connected' | 'not connected' // robot_set_joints — forwarded to browser relay try { const result = await callTool( 'robot_set_joints', { robot_id: 'arm-01', joints: [0, 90, -45, 0, 45, 0] }, relay ) console.log(result) // e.g. { success: true, moved_to: [0, 90, -45, 0, 45, 0] } } catch (err) { console.error(err.message) // relay error or timeout } // robot_stop — disable torque on all servos const stop = await callTool('robot_stop', { robot_id: 'arm-01' }, relay) console.log(stop) // e.g. { success: true } ``` -------------------------------- ### Robot Tools Source: https://context7.com/roboninecom/robonine-mcp/llms.txt These tools are dynamically registered when the Robonine browser tab connects. They execute inside the browser and communicate with the robot over BT/USB. ```APIDOC ## robot_list ### Description List currently connected robot arms. ### Method `relay.call` ### Parameters `{}` ### Response Example ```json [ { "id": "arm-01", "model": "Robonine X1", "status": "connected" } ] ``` ## robot_get_position ### Description Read joint angles and Cartesian end-effector pose. ### Method `relay.call` ### Parameters #### Path Parameters - **robot_id** (string) - Required - The ID of the robot arm. ### Response Example ```json { "joints": [0, 45, -30, 0, 90, 0], "endEffector": { "x": 120.5, "y": 0, "z": 200.3 } } ``` ## robot_set_joints ### Description Move arm to target joint positions (degrees). ### Method `relay.call` ### Parameters #### Path Parameters - **robot_id** (string) - Required - The ID of the robot arm. - **joints** (array) - Required - An array of joint angles in degrees. ### Response Example ```json { "success": true, "moved_to": [0, 90, -45, 0, 45, 0] } ``` ## robot_stop ### Description Disable torque on all servos immediately. ### Method `relay.call` ### Parameters #### Path Parameters - **robot_id** (string) - Required - The ID of the robot arm. ### Response Example ```json { "success": true } ``` ## user_robot_list ### Description List robots registered to the logged-in user account. ### Method `relay.call` ### Parameters `{}` ### Response Example ```json [ { "id": "arm-01", "name": "Lab Arm 1", "model": "Robonine X1" } ] ``` ## path_list ### Description List saved motion paths in the user's account. ### Method `relay.call` ### Parameters `{}` ### Response Example ```json [ { "id": "path-7", "name": "Pick and Place", "waypoints": 12 } ] ``` ## path_read ### Description Fetch a full motion path with all waypoints. ### Method `relay.call` ### Parameters #### Path Parameters - **path_id** (string) - Required - The ID of the motion path. ### Response Example ```json { "id": "path-7", "name": "Pick and Place", "waypoints": [ [0,0,0,0,0,0], [0,45,-30,0,90,0], ... ] } ``` ``` -------------------------------- ### Configure Robonine MCP Server in MCP Host Config Source: https://github.com/roboninecom/robonine-mcp/blob/master/README.md Add this configuration to your MCP host configuration file to manage the Robonine MCP server. This specifies the command and arguments for running the server. ```json { "mcpServers": { "robonine": { "command": "npx", "args": ["-y", "github:roboninecom/robonine-mcp"] } } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.