get_runs
Retrieve a list of all runs on Opentrons Flex or OT-2 robots by specifying the robot's IP address. Manage protocols and monitor run status effectively.
Instructions
List all runs on the robot
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| robot_ip | Yes | Robot IP address |
Implementation Reference
- index.js:1817-1869 (handler)Executes the 'get_runs' tool by querying the Opentrons robot API at /runs, formatting run details (ID, status, created time, protocol, duration), limiting to latest 10, and returning markdown text response.async getRuns(args) { const { robot_ip } = args; try { const data = await this.makeApiRequest( 'GET', `http://${robot_ip}:31950/runs` ); const runs = data.data || []; if (runs.length === 0) { return { content: [ { type: "text", text: `No runs found on robot.` } ] }; } const runList = runs.slice(0, 10).map(r => { const duration = r.completedAt && r.startedAt ? Math.round((new Date(r.completedAt) - new Date(r.startedAt)) / 1000 / 60) : null; return `**Run ${r.id}**\n` + ` Status: ${r.status}\n` + ` Created: ${new Date(r.createdAt).toLocaleString()}\n` + ` Protocol: ${r.protocolId || 'None'}\n` + ` Duration: ${duration ? `${duration} minutes` : 'N/A'}\n`; }).join('\n'); return { content: [ { type: "text", text: `Found ${runs.length} run${runs.length !== 1 ? 's' : ''} on robot${runs.length > 10 ? ' (showing latest 10)' : ''}:\n\n${runList}` } ] }; } catch (error) { return { content: [ { type: "text", text: `❌ Failed to get runs: ${error.message}` } ] }; } }
- index.js:165-174 (schema)Defines the input schema for the get_runs tool, specifying required 'robot_ip' parameter of type string.name: "get_runs", description: "List all runs on the robot", inputSchema: { type: "object", properties: { robot_ip: { type: "string", description: "Robot IP address" } }, required: ["robot_ip"] } },
- index.js:258-259 (registration)Registers the dispatch for 'get_runs' tool calls to the getRuns handler method within the CallToolRequestSchema switch statement.case "get_runs": return this.getRuns(args);
- index.js:31-236 (registration)Includes the get_runs tool in the list returned by ListToolsRequestSchema handler, making it discoverable by MCP clients.this.server.setRequestHandler(ListToolsRequestSchema, async () => { return { tools: [ { name: "search_endpoints", description: "Search Opentrons HTTP API endpoints by functionality, method, path, or any keyword", inputSchema: { type: "object", properties: { query: { type: "string", description: "Search query - searches across endpoint names, descriptions, paths, and tags" }, method: { type: "string", description: "HTTP method filter (GET, POST, PUT, DELETE, PATCH)", enum: ["GET", "POST", "PUT", "DELETE", "PATCH"] }, tag: { type: "string", description: "Filter by API category/tag" }, include_deprecated: { type: "boolean", description: "Include deprecated endpoints in results", default: false } }, required: ["query"] } }, { name: "get_endpoint_details", description: "Get comprehensive details about a specific API endpoint", inputSchema: { type: "object", properties: { method: { type: "string", description: "HTTP method (GET, POST, etc.)" }, path: { type: "string", description: "API endpoint path" } }, required: ["method", "path"] } }, { name: "list_by_category", description: "List all endpoints in a specific functional category", inputSchema: { type: "object", properties: { category: { type: "string", description: "API category/tag to filter by", enum: [ "Health", "Networking", "Control", "Settings", "Modules", "Pipettes", "Calibration", "Run Management", "Protocol Management", "Data files Management", "Simple Commands", "Flex Deck Configuration", "Error Recovery Settings", "Attached Modules", "Attached Instruments", "Labware Offset Management", "System Control", "Client Data", "Maintenance Run Management", "Robot", "Subsystem Management" ] } }, required: ["category"] } }, { name: "get_api_overview", description: "Get high-level overview of the Opentrons HTTP API structure and capabilities", inputSchema: { type: "object", properties: {}, additionalProperties: false } }, { name: "upload_protocol", description: "Upload a protocol file to an Opentrons robot", inputSchema: { type: "object", properties: { robot_ip: { type: "string", description: "Robot IP address (e.g., '192.168.1.100')" }, file_path: { type: "string", description: "Path to protocol file (.py or .json)" }, protocol_kind: { type: "string", enum: ["standard", "quick-transfer"], default: "standard" }, key: { type: "string", description: "Optional client tracking key (~100 chars)" }, run_time_parameters: { type: "object", description: "Optional runtime parameter values" } }, required: ["robot_ip", "file_path"] } }, { name: "get_protocols", description: "List all protocols stored on the robot", inputSchema: { type: "object", properties: { robot_ip: { type: "string", description: "Robot IP address" }, protocol_kind: { type: "string", enum: ["standard", "quick-transfer"], description: "Filter by protocol type (optional)" } }, required: ["robot_ip"] } }, { name: "create_run", description: "Create a new protocol run on the robot", inputSchema: { type: "object", properties: { robot_ip: { type: "string", description: "Robot IP address" }, protocol_id: { type: "string", description: "ID of protocol to run" }, run_time_parameters: { type: "object", description: "Optional runtime parameter values" } }, required: ["robot_ip", "protocol_id"] } }, { name: "control_run", description: "Control run execution (play, pause, stop, resume)", inputSchema: { type: "object", properties: { robot_ip: { type: "string", description: "Robot IP address" }, run_id: { type: "string", description: "Run ID to control" }, action: { type: "string", enum: ["play", "pause", "stop", "resume-from-recovery"], description: "Action to perform" } }, required: ["robot_ip", "run_id", "action"] } }, { name: "get_runs", description: "List all runs on the robot", inputSchema: { type: "object", properties: { robot_ip: { type: "string", description: "Robot IP address" } }, required: ["robot_ip"] } }, { name: "get_run_status", description: "Get detailed status of a specific run", inputSchema: { type: "object", properties: { robot_ip: { type: "string", description: "Robot IP address" }, run_id: { type: "string", description: "Run ID to check" } }, required: ["robot_ip", "run_id"] } }, { name: "robot_health", description: "Check robot health and connectivity", inputSchema: { type: "object", properties: { robot_ip: { type: "string", description: "Robot IP address" } }, required: ["robot_ip"] } }, { name: "control_lights", description: "Turn robot lights on or off", inputSchema: { type: "object", properties: { robot_ip: { type: "string", description: "Robot IP address" }, on: { type: "boolean", description: "True to turn lights on, false to turn off" } }, required: ["robot_ip", "on"] } }, { name: "home_robot", description: "Home robot axes or specific pipette", inputSchema: { type: "object", properties: { robot_ip: { type: "string", description: "Robot IP address" }, target: { type: "string", enum: ["robot", "pipette"], default: "robot", description: "What to home" }, mount: { type: "string", enum: ["left", "right"], description: "Which mount (required if target is 'pipette')" } }, required: ["robot_ip"] } }, { name: "poll_error_endpoint_and_fix", description: "Fetch specific JSON error report and automatically fix protocols", inputSchema: { type: "object", properties: { json_filename: { type: "string", default: "error_report_20250622_124746.json", description: "Name of JSON file to fetch" }, original_protocol_path: { type: "string", default: "/Users/gene/Developer/failed-protocol-5.py", description: "Path to original protocol file" } } } } ] }; });
- index.js:1476-1504 (helper)Helper method used by get_runs (and other tools) to make authenticated HTTP requests to the Opentrons robot API endpoints.async makeApiRequest(method, url, headers = {}, body = null) { try { const options = { method, headers: { 'Opentrons-Version': '*', ...headers } }; if (body) { options.body = body; } const response = await fetch(url, options); const data = await response.json(); if (!response.ok) { throw new Error(`API Error ${response.status}: ${data.message || JSON.stringify(data)}`); } return data; } catch (error) { if (error.code === 'ECONNREFUSED') { throw new Error(`Cannot connect to robot. Please check the IP address and ensure the robot is powered on.`); } throw error; } }