opencode
opencode is an open-source terminal coding agent with no built-in browser. This guide adds one through MCP: managed cloud sessions with stealth, automatic CAPTCHA solving, and residential proxies, configured with one entry in opencode.json and one API token.
- A Browserless API token from your account dashboard
- opencode installed
- Node.js, only if you use the Playwright MCP alternative
Why Browserless as opencode's browser
opencode's built-in tools are bash, edit, write, read, grep, glob, lsp, apply_patch, skill, todowrite, webfetch, websearch, and question. None of them drive a browser. webfetch retrieves a URL and hands back its content, which is enough for reading documentation, but it can't log in, click through a multi-step flow, wait on a JavaScript-rendered view, or get past bot detection. The feature request for a built-in browser tool was closed as not planned, so there's no first-party path coming.
That changes what "remote browser" means here. In an agent that ships its own browser tool, a hosted provider is a swap; in opencode it's the whole capability. Adding the Browserless MCP server gives opencode fourteen tools that cover the gap:
browserless_agentkeeps one browser session alive across tool calls, so cookies and page state survive logins, multi-step forms, and pagination.browserless_smartscraperruns cascading strategies on every request: direct fetch, then proxy, then headless browser, then CAPTCHA solving, until the content returns.- The browsers run on Browserless's cloud, not the machine running opencode. One API token covers stealth, residential proxies, and CAPTCHA solving, with no separate provider accounts.
- The remaining tools cover search, crawling, site mapping, exports, Lighthouse audits, and account usage. See the full tool list.
Step 1: Add the server to opencode.json
The Browserless MCP server is remote, so it needs only a URL and your token. Keep the token in your environment rather than the config file:
export BROWSERLESS_API_TOKEN="YOUR_API_TOKEN_HERE"
Then add the server to opencode.json in your project root, or to ~/.config/opencode/opencode.json to make it available everywhere:
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"browserless": {
"type": "remote",
"url": "https://mcp.browserless.io/mcp",
"headers": {
"Authorization": "Bearer {env:BROWSERLESS_API_TOKEN}"
}
}
}
}
Use {env:VAR}, not $VAR or ${VAR}. opencode does its own substitution on config values and doesn't expand shell syntax inside JSON strings, so a ${...} placeholder reaches Browserless verbatim as the Bearer value and gets rejected.
The hosted server speaks Streamable HTTP, which is what opencode uses for "type": "remote". There's no local process, Node, or Docker involved.
Optional: sign in with OAuth instead of a token
opencode enables OAuth on remote MCP servers by default, and the hosted Browserless server supports it. Drop the headers block and authenticate interactively:
opencode mcp auth browserless
opencode runs the OAuth flow with PKCE, registers a client dynamically, and stores the credentials outside your project config. Prefer this if opencode.json is committed to version control, since nothing token-shaped ends up in the repo.
Step 2: Verify the tools loaded
Check that opencode connected to the server. opencode mcp list prints every configured server with its connection status, so browserless should be listed and connected:
opencode mcp list
Then start a session and ask what it can reach:
Which MCP tools do you have available right now?
opencode namespaces MCP tools as <server>_<tool>, so with the server keyed browserless they appear as browserless_browserless_agent, browserless_browserless_smartscraper, and so on. The doubled prefix is expected: opencode prepends the server key to tool names that already start with browserless_. If it bothers you, key the server as something shorter, like bl, and the tools read bl_browserless_agent.
If the list is empty, restart opencode. Config changes aren't picked up mid-session.
Step 3: Try it on a real task
Give opencode something webfetch can't do, so the difference is visible:
Use the Browserless smartscraper to scrape https://www.browserless.io/pricing
and list each plan with its unit allowance, then tell me which strategy
the scraper needed.
Use the Browserless agent to open https://docs.browserless.io, navigate to
the BrowserQL quickstart, and summarize the setup steps.
The second prompt is the one worth watching. browserless_agent holds the session open between tool calls, so opencode navigates, reads the page, and decides where to click next against a browser that still remembers the last page.
Optional: tell opencode what the infrastructure handles
Browserless solves CAPTCHAs in the background, which can take a few seconds. Without context, an agent sees the challenge in the page and either tries to click it or reports that it's blocked. Add this to AGENTS.md in your project root, or ~/.config/opencode/AGENTS.md for every project:
## Browser automation
Browser tools run on Browserless cloud infrastructure with stealth and
automatic CAPTCHA solving enabled.
- Don't click or try to solve CAPTCHA elements. They're solved for you.
- If you see a CAPTCHA or challenge page, wait 15-30 seconds and look again.
Report it only if it's still there after 60 seconds.
- Don't add your own anti-detection workarounds. They conflict with stealth.
Alternative: Playwright MCP over a CDP endpoint
If you want Playwright's browser_* tool semantics instead, register Microsoft's Playwright MCP as a local server and point it at a Browserless CDP endpoint:
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"playwright-browserless": {
"type": "local",
"command": [
"npx",
"-y",
"@playwright/mcp@latest",
"--cdp-endpoint",
"wss://production-sfo.browserless.io/stealth?token={env:BROWSERLESS_API_TOKEN}&solveCaptchas=true"
]
}
}
}
This runs @playwright/mcp on your machine, but the browser it drives is still a Browserless cloud session. The endpoint URL is what turns the features on:
| Segment | Purpose |
|---|---|
production-sfo.browserless.io | Regional endpoint. Also production-lon and production-ams for the EU |
/stealth | Stealth route. Hides automation signals and spoofs fingerprints |
token= | Your Browserless API token |
solveCaptchas=true | Solves CAPTCHAs in real time, at the infrastructure layer |
Add &timeout=300000 for tasks that run longer than the 30-second default, and &proxy=residential for sites with IP reputation checks. The Claude Code + Playwright MCP page covers the full parameter set, the tool list, and the CAPTCHA-handling system prompt. Everything on it applies here; only the registration step differs.
We recommend the hosted MCP server over this route for most work. Playwright MCP gives you primitives (navigate, click, type), while browserless_agent and browserless_smartscraper handle unblocking and retries per request instead of per script.
FAQ & Troubleshooting
opencode doesn't list any Browserless tools
Run opencode mcp list to see whether the server connected. If it's missing entirely, opencode.json failed to parse. Check it with cat opencode.json | jq .. If it's listed but not connected, the usual causes are a URL typo (the endpoint must be exactly https://mcp.browserless.io/mcp) or a bad token. If the server connected before you edited the config, restart opencode; config changes don't apply to a running session.
The server rejects the token, or returns 401
Check the substitution syntax first. opencode expands {env:BROWSERLESS_API_TOKEN} but leaves $BROWSERLESS_API_TOKEN and ${BROWSERLESS_API_TOKEN} untouched, so the shell-style forms arrive at the server as literal text. An unset variable is a quieter version of the same failure: {env:...} resolves to an empty string, and the server sees Authorization: Bearer with nothing after it. Confirm the variable is exported in the shell you launch opencode from with echo $BROWSERLESS_API_TOKEN.
Can I point an opencode CDP browser plugin at Browserless instead?
Not without changes to the plugin. The community CDP plugins take a browser_url per tool call, which looks like it should accept a Browserless endpoint, but they're built around a locally launched Chrome. opencode-chrome-devtools discovers tabs by requesting /json/list, which Browserless doesn't expose because it provisions a browser per connection rather than keeping a list of open tabs. It then rebuilds each WebSocket URL from the host and path alone, dropping the ?token= query string that authenticates the session. Use the MCP route on this page, or Playwright MCP, which passes the full endpoint URL through to the browser.
Isn't opencode web the browser feature?
No. opencode web starts a headless opencode server with a web interface, so you drive opencode from a browser. It doesn't give opencode a browser to drive. The two get conflated in search results for "opencode browser", so it's worth being explicit about which one you're after.
Long-running tasks time out
Browserless sessions default to 30 seconds. Add timeout to the connection URL on the Playwright MCP route (&timeout=300000 for five minutes). On the hosted MCP server, break the work into several browserless_agent calls rather than one long one. The session persists between calls, so you don't lose page state by splitting it up.
What do MCP sessions cost?
Each tool call opens a browser session that consumes units based on session time, plus proxy traffic and CAPTCHA solving if used. See unit consumption for the breakdown.