Skip to content
Last updated

Once your agent has started a MoreLogin profile via the Skill, it receives a debugPort. This port can be used to connect directly to the browser instance using CDP (Chrome DevTools Protocol), bypassing the need for WebDriver.

You can instruct your Hermes or OpenClaw agent to write and execute scripts using the following patterns.

1. Connecting with Puppeteer

// Get debugPort from:
// openclaw morelogin browser status --env-id <envId>
const puppeteer = require('puppeteer-core');

async function main() {
  const browser = await puppeteer.connect({
    browserURL: 'http://127.0.0.1:9222', // replace 9222 with actual debugPort
    defaultViewport: null
  });

  const pages = await browser.pages();
  const page = pages[0];
  await page.goto('https://example.com');
  
  // Scrape data or perform actions
  const title = await page.title();
  console.log('Title:', title);
  
  // NOTE: Do not call browser.close() unless you want to destroy the MoreLogin process
  await browser.disconnect();
}
main();

2. Form Fill and Submit

const puppeteer = require('puppeteer-core');

async function main() {
  const browser = await puppeteer.connect({
    browserURL: 'http://127.0.0.1:<debugPort>'
  });
  
  const page = await browser.newPage();
  await page.goto('https://example.com/login');
  
  // Fill form
  await page.type('#username', 'myuser');
  await page.type('#password', 'mypassword');
  
  // Click submit
  await page.click('button[type="submit"]');
  
  // Wait for navigation
  await page.waitForNavigation();
  
  // Verify login
  const isLoggedIn = await page.$('.user-profile');
  console.log('Login successful:', !!isLoggedIn);
  
  await browser.disconnect();
}
main();

3. Data Scraping

const puppeteer = require('puppeteer-core');
const fs = require('fs');

async function main() {
  const browser = await puppeteer.connect({
    browserURL: 'http://127.0.0.1:<debugPort>'
  });
  
  const page = await browser.newPage();
  await page.goto('https://example.com/products');
  
  // Scrape data
  const products = await page.evaluate(() => {
    return Array.from(document.querySelectorAll('.product')).map(el => ({
      name: el.querySelector('.name')?.textContent,
      price: el.querySelector('.price')?.textContent,
      url: el.querySelector('a')?.href
    }));
  });
  
  // Save to file
  fs.writeFileSync('products.json', JSON.stringify(products, null, 2));
  console.log(`Scraped ${products.length} products`);
  
  await browser.disconnect();
}
main();

4. Multi-Tab Operations

const puppeteer = require('puppeteer-core');

async function main() {
  const browser = await puppeteer.connect({
    browserURL: 'http://127.0.0.1:<debugPort>'
  });
  
  // Open multiple tabs
  const page1 = await browser.newPage();
  const page2 = await browser.newPage();
  
  await page1.goto('https://example.com');
  await page2.goto('https://github.com');
  
  // Parallel operations
  await Promise.all([
    page1.screenshot({ path: 'page1.png' }),
    page2.screenshot({ path: 'page2.png' })
  ]);
  
  console.log('Screenshots completed');
  
  await browser.disconnect();
}
main();

Troubleshooting

  • Error: connect ECONNREFUSED: Ensure the profile is running and that the debugPort is correct. You can verify ports using lsof -i :<port>.
  • Browser Crashes on Connection: Use puppeteer-core instead of puppeteer, and ensure you call browser.disconnect() instead of browser.close() when your script finishes.