Browserless plugin for OpenCode using puppeteer-core
npm install oc-browserless

Browserless plugin for OpenCode using puppeteer-core.
- Web Browsing: Navigate and browse web pages with content extraction and security certificate information
- DuckDuckGo Search: Search the web with raw HTML content
- Screenshots: Capture screenshots in PNG, JPEG, and WebP formats
- PDF Generation: Convert HTML or URLs to PDF documents
- Browser Lifecycle Management: Automatic browser connection management
Install Bun if you haven't already:
``bash`
curl -fsSL https://bun.sh/install | bash
After installation, restart your terminal or source your shell profile:
`bashFor bash
source ~/.bashrc
Verify Bun installation:
`bash
bun --version
`$3
`bash
npm install -g oc-browserless
`$3
`bash
npm install oc-browserless
`$3
Add to your
opencode.json:`json
{
"$schema": "https://opencode.ai/config.json",
"plugin": ["oc-browserless"]
}
`Browserless Setup
$3
Using Docker:
`bash
docker run -p 3000:3000 -e "CONCURRENT=10" browserless/chrome:latest
`Or install globally:
`bash
npm install -g browserless
browserless --port=3000
`Then set environment variable:
`bash
export BROWSERLESS_URL=ws://localhost:3000
`$3
Sign up for browserless.io and get your API key:
`bash
export BROWSERLESS_URL=wss://your-browserless-instance.com
export BROWSERLESS_API_KEY=your-api-key
`$3
Copy the example environment file:
`bash
cp .env.example .env
`Edit
.env with your browserless configuration:`bash
BROWSERLESS_URL=ws://localhost:3000
BROWSERLESS_API_KEY=your-api-key-if-using-remote
`Development Setup
$3
`bash
git clone https://github.com/rh-id/oc-browserless.git
cd oc-browserless
`$3
`bash
bun install
`This will install:
- Runtime dependencies (
puppeteer-core, @opencode-ai/plugin)
- Development dependencies (ESLint, Prettier, TypeScript)$3
`bash
bun run build
`This will:
1. Compile TypeScript files to JavaScript in
dist/ directory
2. Generate type declarations
3. Copy compiled files to .opencode/ for local OpenCode testingNote: The
.opencode/ directory is used for local development with OpenCode. When the package is published to npm, only the dist/ directory is included.$3
Run opencode in the project directory:
`bash
opencode
`The plugin is automatically loaded from
.opencode/plugin/ directory.Project Structure
`
oc-browserless/
├── .github/workflows/ # CI/CD workflows
│ ├── build.yml # Build and test
│ ├── lint.yml # Linting and formatting
│ └── release.yml # Automated releases
├── .husky/ # Git hooks
│ └── pre-commit # Pre-commit lint-staged
├── .opencode/ # OpenCode plugin files (compiled for local dev)
│ ├── plugin/ # Compiled plugin
│ │ └── browserless.js # Plugin entry point (all code)
│ └── package.json # Dependencies for local dev
├── dist/ # Compiled output (published to npm)
│ └── plugin/
│ ├── browserless.js # Compiled plugin
│ ├── browserless.d.ts # Type declarations
│ ├── browserless.js.map # Source map
│ └── browserless.d.ts.map # Type source map
├── scripts/ # Build scripts
│ └── build-copy.js # Build copy script
├── src/ # Source code (TypeScript)
│ └── plugin/
│ └── browserless.ts # Complete plugin (all code, ~613 lines)
├── Configuration Files
│ ├── .gitignore
│ ├── .gitattributes
│ ├── eslint.config.cjs
│ ├── .prettierrc
│ ├── .env.example
│ ├── .release-please-manifest.json
│ ├── opencode.json
│ ├── package.json
│ └── tsconfig.json
└── Documentation
├── README.md
├── CONTRIBUTING.md
└── LICENSE
`Plugin Development
For contributors working on the plugin locally:
$3
1. Make your changes to
src/plugin/browserless.ts2. Build the project:
`bash
bun run build
` This compiles TypeScript and copies the output to
.opencode/plugin/ directory3. The
.opencode/ directory is used for local development with OpenCode:
- It contains the compiled plugin code
- When the package is published to npm, only the dist/ directory is included
- Running opencode in the project root automatically loads the plugin from .opencode/plugin/4. Test your changes:
`bash
opencode
` The plugin is automatically loaded from
.opencode/plugin/ directory5. Iterate:
- Make changes to
src/plugin/browserless.ts
- Run bun run build to update .opencode/plugin/
- Test with opencode$3
`
src/plugin/
└── browserless.ts # Source code (edit this)dist/plugin/ # Compiled output (published to npm)
├── browserless.js
├── browserless.d.ts
└── browserless.js.map
.opencode/plugin/ # Local dev copy (for testing with opencode)
└── browserless.js # Same compiled code as dist/plugin/browserless.js
`$3
The
bun run build command:1. Compiles TypeScript files to JavaScript in
dist/ directory
2. Generates type declarations (.d.ts)
3. Copies compiled files to .opencode/ for local OpenCode testingNote: Always run
bun run build after making changes to test them locally.Usage
The plugin provides the following tools for OpenCode:
$3
`typescript
// Navigate to a URL and get content
{
"tool": "browse",
"args": {
"url": "https://example.com"
}
}
`$3
`typescript
// Search the web
{
"tool": "search",
"args": {
"query": "TypeScript best practices"
}
}
`Returns:
`json
{
"success": true,
"query": "TypeScript best practices",
"html": "..."
}
`$3
`typescript
// Capture screenshot
{
"tool": "screenshot",
"args": {
"url": "https://example.com",
"path": "./screenshot.png",
"format": "png",
"fullPage": true
}
}
`$3
`typescript
// Generate PDF from URL
{
"tool": "pdf",
"args": {
"url": "https://example.com",
"path": "./output.pdf",
"format": "A4",
"printBackground": true
}
}// Generate PDF from HTML
{
"tool": "pdf",
"args": {
"html": "
Hello World
",
"path": "./output.pdf"
}
}
`Browser Lifecycle
All browser operations automatically manage their own connections:
- No manual start/stop required - tools handle this internally
- Each tool execution creates an isolated browser instance
- Browser sessions are NOT persistent across tool calls
- Browserless supports multiple concurrent connections automatically
- Each tool operates in isolation with no shared state
- No connection reuse - each operation creates fresh browser instance
API Reference
$3
Navigate to and browse web pages.
| Argument | Type | Required | Default | Description |
| -------- | ------ | -------- | ------- | ------------------ |
| url | string | Yes | - | URL to navigate to |
Returns:
`json
{
"success": true,
"url": "https://example.com",
"title": "Example Domain",
"content": "...",
"certificate": {
"issuer": "CN=DigiCert Inc",
"protocol": "TLS 1.3",
"subjectName": "CN=example.com",
"subjectAlternativeNames": ["example.com", "www.example.com"],
"validFrom": 1234567890,
"validTo": 1234567890
}
}
`The
certificate field is null for HTTP connections or when security details are unavailable.$3
Search using DuckDuckGo.
| Argument | Type | Required | Default | Description |
| -------- | ------ | -------- | ------- | ------------ |
| query | string | Yes | - | Search query |
$3
Capture page screenshots.
| Argument | Type | Required | Default | Description |
| -------------- | ------- | -------- | ------- | ----------------------------- |
| url | string | No | - | URL to screenshot |
| path | string | No | - | Output file path |
| format | enum | No | png | Format: png, jpeg, webp |
| fullPage | boolean | No | false | Full page screenshot |
| quality | number | No | - | Quality for jpeg/webp (0-100) |
| viewportWidth | number | No | - | Viewport width |
| viewportHeight | number | No | - | Viewport height |
$3
Generate PDF from HTML or URL.
| Argument | Type | Required | Default | Description |
| --------------- | ------- | -------- | ------- | ----------------- |
| html | string | No\* | - | HTML content |
| url | string | No\* | - | URL to convert |
| path | string | No | - | Output file path |
| format | enum | No | A4 | Paper format |
| printBackground | boolean | No | true | Print backgrounds |
| landscape | boolean | No | false | Landscape mode |
| marginTop | string | No | 0cm | Top margin |
| marginBottom | string | No | 0cm | Bottom margin |
| marginLeft | string | No | 0cm | Left margin |
| marginRight | string | No | 0cm | Right margin |
\*Either
html or url is required.Development
`bash
Install dependencies
bun installBuild
bun run buildTest
bun testLint
bun run lintFormat
bun run format
`$3
Linting:
`bash
bun run lint
`Auto-fix linting issues:
`bash
bun run lint:fix
`Check formatting:
`bash
bun run format:check
`Auto-fix formatting:
`bash
bun run format
`Type checking:
`bash
bunx tsc --noEmit
`Testing:
`bash
bun test
`CI/CD
$3
- Runs on push and PR
- Installs dependencies
- Builds project
- Uploads artifacts
$3
- Runs on push and PR
- Lints code with ESLint
- Checks formatting
$3
- Runs on main branch
- Uses release-please for automated versioning
- Publishes to npm on release
Versioning
Uses automated versioning with release-please:
-
feat: → Minor version bump (1.x.0)
- fix: → Patch version bump (x.x.1)
- BREAKING CHANGE: → Major version bump (2.0.0)Troubleshooting
$3
Error: "Failed to connect to browserless"
- Check
BROWSERLESS_URL environment variable
- Ensure browserless instance is running
- Verify WebSocket URL is correct (use ws:// or wss://)
- Verify firewall/network settingsVerify browserless is running:
`bash
curl http://localhost:3000/health
`Check WebSocket URL format:
- Local:
ws://localhost:3000
- Remote: wss://your-browserless.com$3
Error: "Operation timed out"
- Increase timeout in browser options
- Check network connectivity
- Verify URL is accessible
$3
Error: "Browser not connected" or connection failures
- Check
BROWSERLESS_URL environment variable
- Ensure browserless instance is running
- Each tool creates its own connection - no manual management needed
- Try running the tool again if connection fails$3
If you see TypeScript errors about missing types:
Before dependencies are installed (expected):
1.
Cannot find module 'puppeteer-core' → Run bun install
2. Cannot find module '@opencode-ai/plugin' → Run bun install
3. Cannot find name 'setTimeout' / URL / process / fetch → Will resolve after bun installThese are not actual errors - they're just TypeScript not being able to resolve types until dependencies are installed.
After dependencies are installed:
1. Restart your TypeScript server in your IDE
2. Clear Bun cache:
`bash
rm -rf node_modules
bun install
`$3
If build fails:
1. Check TypeScript version:
`bash
bun --version
`2. Update dependencies:
`bash
bun update
`$3
The project includes several clean scripts for easy cleanup:
`bash
Clean build output only
bun run cleanClean build output and dependencies
bun run clean:depsClean build output and all dependencies
bun run clean:allFull reset: clean everything, reinstall dependencies, and rebuild
bun run reset
`Use these when:
-
clean - After making changes to TypeScript files
- clean:deps - When dependencies need reinstalling
- clean:all - When you want a fresh start
- reset - When troubleshooting build or cache issues$3
If you encounter build errors:
`bash
Option 1: Full reset
bun run resetOption 2: Manual clean and rebuild
rm -rf dist
bun run build
``If you find this project useful and would like to support its continued development, consider making a donation or becoming a sponsor:
Your support helps maintain and improve the project. Thank you! ❤️
MIT © Ruby Hartono
Contributions are welcome! Please feel free to submit a Pull Request.
For issues and questions, please use the GitHub Issues page.