Browserless MCP in Windsurf (Devin Desktop)
Windsurf, now named Devin Desktop, connects its Devin Local agent to the hosted Browserless MCP server through the Browserless plugin from its marketplace, or through a manual mcp_config.json entry with OAuth or an API token header. Once it's connected, Windsurf can scrape, search, crawl, and drive a cloud browser with the Browserless MCP tools.
- A Browserless API token from your account dashboard, or a Browserless account for OAuth sign-in
- Devin Desktop (formerly Windsurf) installed
Connect to the hosted server
The hosted server runs at https://mcp.browserless.io/mcp, so there's nothing to install.
Install the plugin (recommended). Windsurf is now Devin Desktop. Open Customize → Marketplace → Plugins, search for Browserless, and click Install for me. Devin Desktop then redirects you to sign in with your Browserless account, so there's no token to copy.
Add it manually. Since version 3.9.19, Devin Desktop's agent is Devin Local, which reads the same MCP config as Devin CLI. Add to ~/.config/devin/mcp_config.json (%APPDATA%\devin\mcp_config.json on Windows):
{
"mcpServers": {
"browserless": {
"url": "https://mcp.browserless.io/mcp",
"transport": "http",
"headers": {
"Authorization": "Bearer YOUR_API_TOKEN_HERE"
}
}
}
}
To sign in with OAuth instead, drop the headers block and authenticate from the Devin Local MCP view, or with Devin CLI run devin mcp login browserless.
Older Windsurf versions with Cascade. In Cascade, open the ⋯ menu and choose Open MCP config file, then add the same entry with serverUrl in place of url and transport.
To use a region other than US West, add an x-browserless-api-url header, or a browserlessUrl query parameter on the server URL for clients that only take a URL. See regional endpoints.
Run the server locally
To run the MCP server process on your machine instead, use the @browserless.io/mcp npm package over stdio. You need Node.js 24 or newer. Browser work still runs on Browserless, so this is mainly for pinning a server version (add it to the package name, for example @browserless.io/mcp@1.41.0) or pointing at a self-hosted instance with BROWSERLESS_API_URL. Both setups use the server name browserless, so replace the hosted entry with this one rather than adding both.
Add to the same mcp_config.json:
{
"mcpServers": {
"browserless": {
"command": "npx",
"args": ["-y", "@browserless.io/mcp"],
"env": {
"BROWSERLESS_TOKEN": "YOUR_API_TOKEN_HERE"
}
}
}
}
Check the connection
Open the MCP view in Devin Local and check browserless is listed with its tools. Each server logs to its own MCP: browserless output channel. With Devin CLI installed, devin mcp list shows it too.
FAQ & Troubleshooting
Devin Local asks me to sign in to Browserless again
OAuth tokens are stored locally and refreshed automatically, but a revoked or expired grant needs a new sign-in. Click Authenticate next to the server in the Devin Local MCP view, or run devin mcp logout browserless and then devin mcp login browserless.
I'm still on a Windsurf version with Cascade
Cascade was removed in Devin Desktop 3.9.19. On older versions, add the server through Cascade's Open MCP config file using serverUrl instead of url and transport. Cascade can use at most 100 tools across all MCP servers, so add a disabledTools array if you hit that limit. To check the connection, open the ⋯ menu in the Cascade panel. The MCPs section should list browserless with its enabled tool count.
The server connects but every tool call returns 401 Unauthorized
The token is missing or wrong. Copy it again from your account dashboard and check the header reads Bearer followed by the token, with no quotes or trailing whitespace inside the value. If you used an environment variable, confirm it's set in the environment the client was launched from. GUI apps started from the dock or Start menu don't see variables exported in your shell profile.
The connection fails with an SSE error like Non-200 status code (400)
The hosted server speaks Streamable HTTP only and doesn't support the legacy SSE transport. Check the client entry is using its HTTP transport (see the config above), not an SSE one.