openclaw-navigator 4.3.7 → 4.3.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/cli.mjs +109 -1
  2. package/mcp.mjs +25 -1
  3. package/package.json +1 -1
package/cli.mjs CHANGED
@@ -58,6 +58,9 @@ const validTokens = new Set();
58
58
  // OC Web UI reverse proxy target (configurable via --ui-port or env)
59
59
  let ocUIPort = parseInt(process.env.OPENCLAW_UI_PORT ?? "4000", 10);
60
60
 
61
+ // Tunnel URL — set once the tunnel is active, exposed via /navigator/status
62
+ let activeTunnelURL = null;
63
+
61
64
  // Pairing code state
62
65
  let pairingCode = null;
63
66
  let pairingData = null;
@@ -217,6 +220,12 @@ function handleRequest(req, res) {
217
220
  pendingCommandCount: pendingCommands.length,
218
221
  recentEventCount: recentEvents.length,
219
222
  },
223
+ tunnel: activeTunnelURL
224
+ ? {
225
+ url: activeTunnelURL,
226
+ uiURL: `${activeTunnelURL}/ui/`,
227
+ }
228
+ : null,
220
229
  });
221
230
  return;
222
231
  }
@@ -670,6 +679,7 @@ ${BOLD}How it works:${RESET}
670
679
 
671
680
  if (result) {
672
681
  tunnelURL = result.url;
682
+ activeTunnelURL = tunnelURL; // Expose via /navigator/status
673
683
  tunnelProcess = result.process;
674
684
  gatewayURL = tunnelURL; // Use tunnel URL as the gateway URL
675
685
 
@@ -844,8 +854,106 @@ ${BOLD}How it works:${RESET}
844
854
 
845
855
  mkdirSync(mcporterDir, { recursive: true });
846
856
  writeFileSync(mcporterConfigPath, JSON.stringify(mcporterConfig, null, 2) + "\n", "utf8");
847
- ok("Registered MCP server with mcporter (15 browser tools available)");
857
+ ok("Registered MCP server with mcporter (16 browser tools available)");
848
858
  info(` Config: ${mcporterConfigPath}`);
859
+
860
+ // Step 3: Install the navigator-bridge skill so the OC agent knows about all tools
861
+ // Try multiple known skill locations
862
+ const skillLocations = [
863
+ "/opt/homebrew/lib/node_modules/openclaw/skills/navigator-bridge",
864
+ join(homedir(), ".openclaw/skills/navigator-bridge"),
865
+ ];
866
+ // Find the first parent that exists, or use the homebrew path
867
+ let skillDir = skillLocations[0]; // default
868
+ for (const loc of skillLocations) {
869
+ const parent = dirname(loc);
870
+ if (existsSync(parent)) {
871
+ skillDir = loc;
872
+ break;
873
+ }
874
+ }
875
+ const skillPath = join(skillDir, "SKILL.md");
876
+ const BT = "```"; // backtick triple for markdown code blocks
877
+ const skillContent = [
878
+ "---",
879
+ "name: navigator-bridge",
880
+ "description: Control the remote Navigator browser and access the OC Web UI via MCP tools. Navigate to URLs, click elements, fill forms, read page content, execute JavaScript, manage tabs, and open the OC dashboard.",
881
+ 'metadata:',
882
+ ' { "openclaw": { "emoji": "🌐", "requires": { "bins": ["mcporter"] } } }',
883
+ "---",
884
+ "",
885
+ "# Navigator Bridge (Remote Browser Control + OC Web UI)",
886
+ "",
887
+ "Control the **remote** Navigator browser through MCP tools via mcporter.",
888
+ "",
889
+ "**Important:** This controls the REMOTE Navigator instance connected via pairing code, NOT local Navigator.",
890
+ "",
891
+ "## Quick start",
892
+ "",
893
+ BT + "bash",
894
+ "# Get the OC Web UI URL and open it in Navigator",
895
+ "mcporter call navigator.navigator_get_ui_url",
896
+ "mcporter call navigator.navigator_navigate url=<uiURL from above>",
897
+ "",
898
+ "# Check connection status",
899
+ "mcporter call navigator.navigator_status",
900
+ BT,
901
+ "",
902
+ "## All 16 tools",
903
+ "",
904
+ "| Tool | What it does |",
905
+ "|------|-------------|",
906
+ "| `navigator_status` | Bridge status, connection, tunnel URL |",
907
+ "| `navigator_get_ui_url` | Get the OC Web UI URL (tunnel + /ui/) |",
908
+ "| `navigator_navigate` | Go to a URL |",
909
+ "| `navigator_open_tab` | Open new tab |",
910
+ "| `navigator_close_tab` | Close a tab |",
911
+ "| `navigator_list_tabs` | List all open tabs |",
912
+ "| `navigator_snapshot` | Full browser state snapshot |",
913
+ "| `navigator_get_text` | Read page text content |",
914
+ "| `navigator_get_html` | Get full page HTML |",
915
+ "| `navigator_click` | Click element by CSS selector |",
916
+ "| `navigator_fill` | Fill input field |",
917
+ "| `navigator_submit` | Submit form |",
918
+ "| `navigator_scroll` | Scroll page |",
919
+ "| `navigator_execute_js` | Run arbitrary JavaScript |",
920
+ "| `navigator_query_element` | Inspect DOM element |",
921
+ "| `navigator_wait_ready` | Wait for page load |",
922
+ "",
923
+ "## Usage",
924
+ "",
925
+ BT + "bash",
926
+ "mcporter call navigator.<tool_name> param=value",
927
+ BT,
928
+ "",
929
+ "## Common workflows",
930
+ "",
931
+ "### Open OC dashboard in Navigator",
932
+ BT + "bash",
933
+ "mcporter call navigator.navigator_get_ui_url",
934
+ "mcporter call navigator.navigator_navigate url=<uiURL>",
935
+ "mcporter call navigator.navigator_wait_ready",
936
+ BT,
937
+ "",
938
+ "### Browse and read a website",
939
+ BT + "bash",
940
+ "mcporter call navigator.navigator_navigate url=https://example.com",
941
+ "mcporter call navigator.navigator_wait_ready",
942
+ "mcporter call navigator.navigator_get_text",
943
+ BT,
944
+ "",
945
+ "### Fill and submit a form",
946
+ BT + "bash",
947
+ 'mcporter call navigator.navigator_fill selector="#email" value="user@example.com"',
948
+ 'mcporter call navigator.navigator_click selector="#submit"',
949
+ "mcporter call navigator.navigator_wait_ready",
950
+ BT,
951
+ "",
952
+ ].join("\n");
953
+ mkdirSync(skillDir, { recursive: true });
954
+ writeFileSync(skillPath, skillContent, "utf8");
955
+ ok("Installed navigator-bridge skill for OC agent");
956
+ info(` Skill: ${skillPath}`);
849
957
  } catch (err) {
850
958
  warn(`mcporter registration failed: ${err.message}`);
851
959
  info(" You can manually configure mcporter for Navigator MCP");
package/mcp.mjs CHANGED
@@ -156,7 +156,13 @@ const TOOLS = [
156
156
  {
157
157
  name: "navigator_status",
158
158
  description:
159
- "Get the Navigator bridge status — connection state, active tabs, current URL, uptime, pending commands.",
159
+ "Get the Navigator bridge status — connection state, active tabs, current URL, uptime, pending commands. Also returns the tunnel URL and OC Web UI URL.",
160
+ inputSchema: { type: "object", properties: {} },
161
+ },
162
+ {
163
+ name: "navigator_get_ui_url",
164
+ description:
165
+ "Get the OC Web UI URL. Returns the Cloudflare tunnel URL with /ui/ path that serves the OpenClaw dashboard. Use this to find the URL before navigating to the UI.",
160
166
  inputSchema: { type: "object", properties: {} },
161
167
  },
162
168
 
@@ -356,6 +362,24 @@ async function handleTool(name, args) {
356
362
  case "navigator_status":
357
363
  return jsonResult(await bridgeGet("/navigator/status"));
358
364
 
365
+ case "navigator_get_ui_url": {
366
+ const status = await bridgeGet("/navigator/status");
367
+ if (status.tunnel?.uiURL) {
368
+ return jsonResult({
369
+ ok: true,
370
+ uiURL: status.tunnel.uiURL,
371
+ tunnelURL: status.tunnel.url,
372
+ hint: "Navigate to uiURL to access the OC Web UI dashboard",
373
+ });
374
+ }
375
+ return jsonResult({
376
+ ok: true,
377
+ uiURL: `${BRIDGE_URL}/ui/`,
378
+ tunnelURL: null,
379
+ hint: "No tunnel active — UI accessible locally only. Start with --mcp to enable tunnel.",
380
+ });
381
+ }
382
+
359
383
  // ── Fire-and-forget ──
360
384
  case "navigator_navigate":
361
385
  return jsonResult(await sendCommand("navigate", { url: args.url }));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openclaw-navigator",
3
- "version": "4.3.7",
3
+ "version": "4.3.9",
4
4
  "description": "One-command bridge + tunnel for the Navigator browser — works on any machine, any OS",
5
5
  "keywords": [
6
6
  "browser",