For AI agents: a documentation index is available at /llms.txt
Skip to main content

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.

Prerequisites

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_agent keeps one browser session alive across tool calls, so cookies and page state survive logins, multi-step forms, and pagination.
  • browserless_smartscraper runs 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:

SegmentPurpose
production-sfo.browserless.ioRegional endpoint. Also production-lon and production-ams for the EU
/stealthStealth route. Hides automation signals and spoofs fingerprints
token=Your Browserless API token
solveCaptchas=trueSolves 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.

Next steps

Was this page helpful?