opencli-web-automation
reason-machines/trending-skills
Turn any website into a CLI using browser session reuse and AI-powered command discovery
What is opencli-web-automation?
OpenCLI converts websites into command-line interfaces by reusing Chrome's logged-in browser session. It supports 19 sites with 80+ built-in commands and lets you add custom adapters via TypeScript or YAML for new sites.
- Reuse Chrome browser sessions to access logged-in website data via CLI commands
- Discover APIs and capabilities automatically using AI-powered exploration
- Support 19 pre-built site adapters (Twitter, GitHub, Reddit, YouTube, LinkedIn, Bilibili, etc.) with 80+ commands
- Output results in multiple formats: table, JSON, YAML, Markdown, CSV
- Create new adapters declaratively with YAML or programmatically with TypeScript
- Extract authenticated data using cookie injection, header tokens, and DOM scraping patterns
How to install opencli-web-automation
npx skills add https://github.com/reason-machines/trending-skills --skill opencli-web-automation- Node.js >= 18.0.0
- Chrome browser running and logged into target sites
- Playwright MCP Bridge extension installed in Chrome
- PLAYWRIGHT_MCP_EXTENSION_TOKEN environment variable set after running opencli setup
How to use opencli-web-automation
- 1.Install globally with npm install -g @jackwener/opencli
- 2.Run opencli setup to discover and configure the Playwright MCP token
- 3.Run opencli doctor --live to verify the installation
- 4.Use opencli list to see all available commands for registered sites
- 5.Run commands like opencli twitter trending or opencli github search "query" to fetch data
- 6.Add custom adapters by dropping YAML files into the clis/ folder or writing TypeScript adapters
- 7.Use opencli explore <url> to discover APIs, then opencli synthesize to generate adapters
Use cases
- Extract trending posts from social media sites (Twitter, Reddit, Bilibili) without API keys
- Search GitHub repositories or Product Hunt listings from the command line
- Scrape news feeds (BBC, Hacker News) and format output for piping to other tools
- Automate data collection from sites requiring browser login by reusing Chrome sessions
- Build custom CLI commands for internal or niche websites using YAML or TypeScript adapters
- CLI-first developers and DevOps engineers
- Data engineers needing to extract web data without official APIs
- AI agents and coding assistants (Claude Code, Cursor) automating web tasks
- Security researchers and penetration testers analyzing web applications
- Anyone automating workflows across multiple websites
opencli-web-automation FAQ
No. OpenCLI reuses your Chrome browser session, so you only need to be logged into the target website in Chrome. It works with sites that don't offer public APIs.
19 sites including Twitter, GitHub, Reddit, YouTube, LinkedIn, Bilibili, Zhihu, Xiaohongshu, BBC, Hacker News, and others, with 80+ total commands available.
Yes. Drop a YAML file into the clis/ folder for declarative adapters, or write a TypeScript adapter. Use opencli explore and opencli synthesize to auto-discover APIs and generate adapters.
Table (default), JSON, YAML, Markdown, and CSV. All commands support the --format/-f flag to switch formats.
OpenCLI reuses your Chrome browser's cookies and session. It can also extract auth tokens from localStorage/sessionStorage and inject them into API calls.
Full instructions (SKILL.md)
Source of truth, from reason-machines/trending-skills.
name: opencli-web-automation description: Turn any website into a CLI using browser session reuse and AI-powered command discovery triggers:
- "use opencli to scrape a website"
- "make a CLI command for a website"
- "automate browser with opencli"
- "add a new opencli adapter"
- "extract data from website using CLI"
- "opencli explore and synthesize commands"
- "create yaml adapter for opencli"
- "opencli browser automation"
OpenCLI Web Automation
Skill by ara.so — Daily 2026 Skills collection.
OpenCLI turns any website into a command-line interface by reusing Chrome's logged-in browser session. It supports 19 sites and 80+ commands out of the box, and lets you add new adapters via TypeScript or YAML dropped into the clis/ folder.
Installation
# Install globally via npm
npm install -g @jackwener/opencli
# One-time setup: discovers Playwright MCP token and distributes to all tools
opencli setup
# Verify everything is working
opencli doctor --live
Prerequisites
- Node.js >= 18.0.0
- Chrome browser running and logged into the target site
- Playwright MCP Bridge extension installed in Chrome
Install from Source (Development)
git clone git@github.com:jackwener/opencli.git
cd opencli
npm install
npm run build
npm link
Environment Configuration
# Required: set in ~/.zshrc or ~/.bashrc after running opencli setup
export PLAYWRIGHT_MCP_EXTENSION_TOKEN="<your-token-from-setup>"
MCP client config (Claude/Cursor/Codex ~/.config/*/config.json):
{
"mcpServers": {
"playwright": {
"command": "npx",
"args": ["-y", "@playwright/mcp@latest", "--extension"],
"env": {
"PLAYWRIGHT_MCP_EXTENSION_TOKEN": "$PLAYWRIGHT_MCP_EXTENSION_TOKEN"
}
}
}
}
Key CLI Commands
Discovery & Registry
opencli list # Show all registered commands
opencli list -f yaml # Output registry as YAML
opencli list -f json # Output registry as JSON
Running Built-in Commands
# Public API commands (no browser login needed)
opencli hackernews top --limit 10
opencli github search "playwright automation"
opencli bbc news
# Browser commands (must be logged into site in Chrome)
opencli bilibili hot --limit 5
opencli twitter trending
opencli zhihu hot -f json
opencli reddit frontpage --limit 20
opencli xiaohongshu search "TypeScript"
opencli youtube search "browser automation"
opencli linkedin search "senior engineer"
Output Formats
All commands support --format / -f:
opencli bilibili hot -f table # Rich terminal table (default)
opencli bilibili hot -f json # JSON (pipe to jq)
opencli bilibili hot -f yaml # YAML
opencli bilibili hot -f md # Markdown
opencli bilibili hot -f csv # CSV export
opencli bilibili hot -v # Verbose: show pipeline debug steps
AI Agent Workflow (Creating New Commands)
# 1. Deep explore a site — discovers APIs, auth, capabilities
opencli explore https://example.com --site mysite
# 2. Synthesize YAML adapters from explore artifacts
opencli synthesize mysite
# 3. One-shot: explore → synthesize → register in one command
opencli generate https://example.com --goal "hot posts"
# 4. Strategy cascade — auto-probes PUBLIC → COOKIE → HEADER auth
opencli cascade https://api.example.com/data
Explore artifacts are saved to .opencli/explore/<site>/:
manifest.json— site metadataendpoints.json— discovered API endpointscapabilities.json— inferred command capabilitiesauth.json— authentication strategy
Adding a New Adapter
Option 1: YAML Declarative Adapter
Drop a .yaml file into clis/ — auto-registered on next run:
# clis/producthunt.yaml
site: producthunt
commands:
- name: trending
description: Get trending products on Product Hunt
args:
- name: limit
type: number
default: 10
pipeline:
- type: navigate
url: https://www.producthunt.com
- type: waitFor
selector: "[data-test='post-item']"
- type: extract
selector: "[data-test='post-item']"
fields:
name:
selector: "h3"
type: text
tagline:
selector: "p"
type: text
votes:
selector: "[data-test='vote-button']"
type: text
url:
selector: "a"
attr: href
- type: limit
count: "{{limit}}"
Option 2: TypeScript Adapter
// clis/producthunt.ts
import type { CLIAdapter } from "../src/types";
const adapter: CLIAdapter = {
site: "producthunt",
commands: [
{
name: "trending",
description: "Get trending products on Product Hunt",
options: [
{
flags: "--limit <n>",
description: "Number of results",
defaultValue: "10",
},
],
async run(options, browser) {
const page = await browser.currentPage();
await page.goto("https://www.producthunt.com");
await page.waitForSelector("[data-test='post-item']");
const products = await page.evaluate(() => {
return Array.from(
document.querySelectorAll("[data-test='post-item']")
).map((el) => ({
name: el.querySelector("h3")?.textContent?.trim() ?? "",
tagline: el.querySelector("p")?.textContent?.trim() ?? "",
votes:
el
.querySelector("[data-test='vote-button']")
?.textContent?.trim() ?? "",
url:
(el.querySelector("a") as HTMLAnchorElement)?.href ?? "",
}));
});
return products.slice(0, Number(options.limit));
},
},
],
};
export default adapter;
Common Patterns
Pattern: Authenticated API Extraction (Cookie Injection)
// When a site exposes a JSON API but requires login cookies
async run(options, browser) {
const page = await browser.currentPage();
// Navigate first to ensure cookies are active
await page.goto("https://api.example.com");
const data = await page.evaluate(async () => {
const res = await fetch("/api/v1/feed?limit=20", {
credentials: "include", // reuse browser cookies
});
return res.json();
});
return data.items;
}
Pattern: Header Token Extraction
// Extract auth tokens from browser storage for API calls
async run(options, browser) {
const page = await browser.currentPage();
await page.goto("https://example.com");
const token = await page.evaluate(() => {
return localStorage.getItem("auth_token") ||
sessionStorage.getItem("token");
});
const data = await page.evaluate(async (tok) => {
const res = await fetch("/api/data", {
headers: { Authorization: `Bearer ${tok}` },
});
return res.json();
}, token);
return data;
}
Pattern: DOM Scraping with Wait
async run(options, browser) {
const page = await browser.currentPage();
await page.goto("https://news.ycombinator.com");
// Wait for dynamic content to load
await page.waitForSelector(".athing", { timeout: 10000 });
return page.evaluate((limit) => {
return Array.from(document.querySelectorAll(".athing"))
.slice(0, limit)
.map((row) => ({
title: row.querySelector(".titleline a")?.textContent?.trim(),
url: (row.querySelector(".titleline a") as HTMLAnchorElement)?.href,
score:
row.nextElementSibling
?.querySelector(".score")
?.textContent?.trim() ?? "0",
}));
}, Number(options.limit));
}
Pattern: Pagination
async run(options, browser) {
const page = await browser.currentPage();
const results = [];
let pageNum = 1;
while (results.length < Number(options.limit)) {
await page.goto(`https://example.com/posts?page=${pageNum}`);
await page.waitForSelector(".post-item");
const items = await page.evaluate(() =>
Array.from(document.querySelectorAll(".post-item")).map((el) => ({
title: el.querySelector("h2")?.textContent?.trim(),
url: (el.querySelector("a") as HTMLAnchorElement)?.href,
}))
);
if (items.length === 0) break;
results.push(...items);
pageNum++;
}
return results.slice(0, Number(options.limit));
}
Maintenance Commands
# Diagnose token and config across all tools
opencli doctor
# Test live browser connectivity
opencli doctor --live
# Fix mismatched configs interactively
opencli doctor --fix
# Fix all configs non-interactively
opencli doctor --fix -y
Testing
npm run build
# Run all tests
npx vitest run
# Unit tests only
npx vitest run src/
# E2E tests only
npx vitest run tests/e2e/
# Headless browser mode for CI
OPENCLI_HEADLESS=1 npx vitest run tests/e2e/
Troubleshooting
| Symptom | Fix |
|---|---|
Failed to connect to Playwright MCP Bridge | Ensure extension is enabled in Chrome; restart Chrome after install |
Empty data / Unauthorized | Open Chrome, navigate to the site, log in or refresh the page |
| Node API errors | Upgrade to Node.js >= 18 |
| Token not found | Run opencli setup or opencli doctor --fix |
| Stale login session | Visit the target site in Chrome and interact with it to prove human presence |
Debug Verbose Mode
# See full pipeline execution steps
opencli bilibili hot -v
# Check what explore discovered
cat .opencli/explore/mysite/endpoints.json
cat .opencli/explore/mysite/auth.json
Project Structure (for Adapter Authors)
opencli/
├── clis/ # Drop .ts or .yaml adapters here (auto-registered)
│ ├── bilibili.ts
│ ├── twitter.ts
│ └── hackernews.yaml
├── src/
│ ├── types.ts # CLIAdapter, Command interfaces
│ ├── browser.ts # Playwright MCP bridge wrapper
│ ├── loader.ts # Dynamic adapter loader
│ └── output.ts # table/json/yaml/md/csv formatters
├── tests/
│ └── e2e/ # E2E tests per site
└── CLI-EXPLORER.md # Full AI agent exploration workflow
Related skills
More from reason-machines/trending-skills and the wider catalog.

openmaic-classroom
Next.js platform converting topics into interactive AI-powered lessons with multi-agent discussions, quizzes, and simulations.

openviking-context-database
Open-source context database for AI agents with filesystem-based memory, resources, and skills management

paperclip-ai-orchestration
Open-source platform for orchestrating autonomous AI-agent companies with org charts, budgets, and governance.

picoclaw-ai-assistant
Ultra-lightweight AI assistant in Go for $10 hardware with <10MB RAM and multi-provider LLM support.

posterskill-academic-posters
Generate print-ready academic conference posters from Overleaf papers with an interactive drag-and-drop editor.

shannon-ai-pentester
Autonomous white-box AI pentester that analyzes source code and executes live exploits against web apps and APIs.