Skip to main content
Glama

neu-browser-mcp

An MCP server that gives an agent a remote browser: create one, get a CDP URL to drive it, hand the user a live view, pick up the files it downloaded, and shut it down.

Why

  • Lifecycle only. It does not click, type or navigate. The agent drives the browser over CDP with agent-browser, Playwright, or any CDP client.

  • Same tools on any backend. Prompts and skills stay the same when the browser moves between nap, kernel, browser-use and hyperbrowser. Each backend is a small adapter behind one interface.

  • Credentials stay on the server. The backend token never enters the agent's context.

  • Human handoff and downloads. Backends with a live view give you a URL to watch or take over the browser. Files the browser downloads can be listed, linked, or read.

Related MCP server: mcp-browser-kit

Tools

Tool

What it does

create_browser

Starts a browser and returns browser_id, connect_url (CDP WebSocket), connect_command (a ready-to-run agent-browser connect …), cdp_url (CDP over HTTP, for Playwright's connectOverCDP) and live_view_url. Takes an optional timeout_seconds.

list_browsers

Lists active browsers with the same connection info, so an agent can reconnect to one it lost track of.

delete_browser

Stops a browser.

list_browser_files

Lists files in the browser's sandbox, the backend's download directory by default.

get_browser_file_url

Returns a download URL for one file, or ready: false if it is not there yet.

read_browser_file

Returns the contents of one file: text as text, anything else as a base64 resource. The server reads with the backend's credentials. Reads are capped at 256 KB.

Backends

A capability a backend lacks shows up as null or as a missing tool. See Adding a backend.

Backend

Timeout (default / max)

Live view

CDP over HTTP

Metadata

List files

Download link

Read file

nap

1 hour / 24 hours

✅

✅

✅

✅

✅

❌

kernel

1 hour idle / 72 hours idle

✅

❌

✅

✅

❌

✅

browser-use

1 hour / 4 hours

✅

✅

✅

❌

❌

❌

hyperbrowser

1 hour / 12 hours

✅

❌

❌

❌

❌

❌

More backends are planned.

Run it as a server

Requires Node.js 22 or newer. The server speaks MCP over stdio.

{
  "mcpServers": {
    "browser": {
      "command": "npx",
      "args": ["-y", "neu-browser-mcp"],
      "env": {
        "NEU_BROWSER_BACKEND": "nap",
        "NAP_BROWSER_URL": "https://browser.example.com",
        "NAP_BROWSER_TOKEN": "<token>"
      }
    }
  }
}

NEU_BROWSER_BACKEND picks the backend and defaults to nap. Each backend then reads its own variables.

nap

Variable

Meaning

NAP_BROWSER_URL

Base URL of the browser service API. Required.

NAP_BROWSER_TOKEN

Bearer token for the browser service. Required.

NAP_BROWSER_PUBLIC_URL

Base URL used in file download links. Set it when NAP_BROWSER_URL is an internal address users cannot reach. Defaults to NAP_BROWSER_URL.

kernel

Variable

Meaning

KERNEL_API_KEY

Kernel API key. Required.

browser-use

Variable

Meaning

BROWSER_USE_API_KEY

Browser Use Cloud API key. Required.

hyperbrowser

Variable

Meaning

HYPERBROWSER_API_KEY

Hyperbrowser API key. Required.

Use it as a library

To add the tools to an MCP server you already run, register them on it:

import { McpServer } from '@modelcontextprotocol/server'
import { createNapProvider, registerBrowserTools } from 'neu-browser-mcp'

const server = new McpServer({ name: 'my-server', version: '1.0.0' })

registerBrowserTools(server, {
  provider: createNapProvider({
    baseUrl: 'http://browser.internal:3005',
    publicBaseUrl: 'https://browser.example.com',
    token: async () => lookUpTokenFor(tenant),
  }),
  scope: { tenant_id: tenant.id },
})

The server can come from either generation of the MCP TypeScript SDK: @modelcontextprotocol/server (v2) or @modelcontextprotocol/sdk (v1).

scope is a set of tags that confines the tools to one tenant. Every browser they create carries the tags, list_browsers returns only browsers that carry them, and a tool given a browser ID refuses it unless that browser carries them. This is what keeps tenants apart when they share the backend's credentials. token can be a string or an async function; a function is called once, on first use.

To pick the backend from the environment, the way the standalone server does, use providerFromEnv(process.env).

Adding a backend

A backend implements BrowserProvider from src/types.ts:

interface BrowserProvider {
  readonly name: string
  readonly capabilities: ProviderCapabilities
  createSession(opts?: CreateSessionOptions): Promise<BrowserSession>
  listSessions(opts?: ListSessionsOptions): Promise<BrowserSession[]>
  releaseSession(id: string): Promise<void>
  readonly files?: BrowserFiles // list, and optionally downloadUrl and read
}

interface ProviderCapabilities {
  timeout: { kind: 'absolute' | 'idle'; defaultSeconds: number; maxSeconds: number }
  liveView: boolean
  httpCdp: boolean
  metadata: boolean
}

The required part is the session lifecycle plus a CDP WebSocket URL. Everything else is declared, and the tools adapt:

Declaration

Effect when absent

timeout

Always present. Sets the default and maximum the agent is told about, and whether the timeout counts from creation (absolute) or inactivity (idle).

liveView

live_view_url is null and the tool descriptions do not mention it.

httpCdp

cdp_url is null, and the agent is told to use connect_url with Playwright too.

metadata

registerBrowserTools throws if a scope is given, since the backend could not keep tenants apart.

files member

No file tools are registered.

files.downloadUrl

get_browser_file_url is not registered.

files.read

read_browser_file is not registered.

src/providers/nap.ts is the reference implementation.

Development

npm install
npx tsc --noEmit
npx biome check .
npm test

See CONTRIBUTING.md.

License

Apache License 2.0

Available Tools

5 tools
create_browserCreate BrowserA

Create a headless Chrome browser instance. Returns browser_id plus connection info:

  • connect_command: a ready-to-run agent-browser command — just run it as-is to start driving the browser.

  • connect_url: a wss:// URL for "agent-browser connect". Do NOT pass cdp_url here.

  • cdp_url: an https:// URL for Playwright only, via browser.connectOverCDP(cdp_url).

  • live_view_url: share with the user so they can watch. The browser auto-expires after the timeout (default 1 hour, max 24 hours).

NameRequiredDescriptionDefault
timeout_secondsNoBrowser timeout in seconds (default: 3600, max: 86400)

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations at all, the description still discloses the important behavioral facts: the browser is headless, it auto-expires, and it has a default and maximum lifetime. It also carries a useful negative constraint ('Do NOT pass cdp_url here'). It stops short of stating concurrency limits, whether creation is metered, or what a failure looks like, so not a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Action statement is front-loaded, then a tight bullet list where each line maps to a distinct return field and its correct use. No filler sentences, and the expiry caveat sits last where it belongs.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, so the description correctly takes on the job of documenting browser_id, connect_command, connect_url, cdp_url, and live_view_url — including the crucial warning not to interchange the URLs. That makes it callable and consumable. It lacks only edge-case behavior such as limits or error conditions.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% for the single timeout_seconds parameter, and the description merely restates the default 1 hour / max 24 hours already written in the schema. Baseline 3 is appropriate — the schema does the work and the description adds no new parameter semantics.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb+resource: 'Create a headless Chrome browser instance.' That is unambiguously distinct from the siblings list_browsers, delete_browser, and file-retrieval tools, so an agent can route correctly without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied by naming — create a browser when you need one — and the description gives good downstream guidance on which returned handle to use for which client (agent-browser vs Playwright vs user sharing). However, it never states when to reach for this tool versus an existing browser session, and gives no exclusions or preconditions for creation.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

delete_browserDelete BrowserB

Stop and destroy a browser instance.

NameRequiredDescriptionDefault
browser_idYesID of the browser to delete

TDQS

B3.1/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full behavioral burden. 'Destroy' signals a destructive, likely irreversible mutation, which is useful, but nothing is said about whether associated files/artifacts are removed, whether active sessions are terminated, required permissions, or behavior when the ID is invalid.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One short sentence, front-loaded with the action and resource, with zero filler. Nothing is redundant or buried.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple one-parameter tool with full schema coverage, the description is minimally adequate. However, as a destructive operation with no annotations and no output schema, it should disclose irreversibility and side effects on the browser's files or sessions.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The single browser_id parameter is fully documented in the schema (100% coverage), so the description adds little. Baseline 3 applies when the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb pair ('stop and destroy') and a specific resource ('browser instance'), so an agent knows exactly what the tool does. It doesn't explicitly differentiate from siblings like create_browser or list_browsers, though the delete semantics are self-evidently distinct.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to call this versus alternatives, no prerequisite checks (e.g., confirm the browser exists), and no mention of what to do if the instance is still in use. The agent must infer all usage context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_browser_file_urlGet Browser File Download URLA

Get a download URL for a file inside the browser sandbox. Returns the URL alongside the current file state — use ready: true to confirm the file exists. The URL embeds an auth token and can be handed to the user (e.g. as a clickable link in chat) or fetched directly. Files are only available while the browser is alive.

NameRequiredDescriptionDefault
pathYesFull file path (e.g. /tmp/downloads/foo.pdf)
browser_idYesID of the browser

TDQS

A4.3/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does so well: it discloses that the URL embeds an auth token (a security-relevant trait), that a file-state object is returned alongside the URL, and the hard lifetime constraint that files only exist while the browser is alive. These are behaviors an agent cannot infer from the schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four short sentences, action stated first, then return shape, then usage, then the lifetime caveat. Every sentence contributes a distinct fact with no repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, and the description compensates by explaining the return (URL plus current file state, with `ready` as the existence signal) and the token/lifetime caveats. An agent has everything needed to call it and interpret the result correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and both parameters are documented in the schema, so the baseline is 3. The description adds no syntax or format detail for `path` or `browser_id` beyond what the schema already says.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The first sentence gives a specific verb+resource: 'Get a download URL for a file inside the browser sandbox.' That clearly separates it from list_browser_files, but it never names a sibling or explicitly contrasts scope, so it stops short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It states concrete usage contexts — hand the link to the user (e.g. clickable in chat) or fetch directly — and tells the agent to check `ready: true` before assuming the file exists. It does not state when to prefer list_browser_files instead, so no explicit alternative routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_browser_filesList Browser FilesA

List files inside the browser sandbox. Defaults to /tmp/downloads — point downloads there first, via CDP Browser.setDownloadBehavior with downloadPath: "/tmp/downloads". Use after a download completes to discover what was saved. The browser sandbox is ephemeral, so files only exist while the browser is alive. There can be a brief delay between CDP downloadProgress reporting "completed" and the file being readable; if a file looks truncated, retry after a moment.

NameRequiredDescriptionDefault
pathNoDirectory path (default: /tmp/downloads)
patternNoOptional glob pattern to filter results
browser_idYesID of the browser

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations exist, so the description carries the full burden, and it discloses several non-obvious traits: the sandbox is ephemeral (files vanish when the browser dies), a CDP download-path prerequisite exists, and there is a race between downloadProgress "completed" and file readability with retry advice. It omits what happens on a nonexistent path or permission errors.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four short sentences, front-loaded with the operation and default, then prerequisites and the timing caveat. Nearly every sentence earns its place; the redundant restatement of the default path slightly overlaps with the schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, so the description should hint at the return shape; it says files are discovered but never indicates whether entries are names, paths, or sizes. Everything else an agent needs to call it correctly — location, prerequisite, retry behavior — is present.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, including the default (/tmp/downloads) for path, so the schema already does the heavy lifting. The description reinforces the default path but says nothing about the glob `pattern` parameter or how results are ordered, adding no meaning beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ("List files inside the browser sandbox") with the default location, so the operation is immediately identifiable. It does not explicitly contrast with the closest sibling, get_browser_file_url, though the scope difference (listing vs. retrieving a URL) is implied.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives clear situational guidance: "Use after a download completes to discover what was saved," plus the prerequisite of pointing downloads at /tmp/downloads via CDP Browser.setDownloadBehavior. It does not name an alternative tool or a when-not condition, but the context for invoking it is unambiguous.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_browsersList BrowsersA

List all active browser instances. Each item includes the same connection info as create_browser (cdp_url, live_view_url, plus connect_url/connect_command for running browsers), so this doubles as a reconnect path — pick a running browser and run its connect_command.

NameRequiredDescriptionDefault

No parameters

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations exist, so the description carries the full burden, and it does disclose the return shape: each item carries cdp_url, live_view_url, and connect_url/connect_command for running browsers. It also discloses the filter (only active instances) and the pro tip that connect_command can be executed directly. Missing only minor traits like ordering or whether stopped browsers ever appear.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with what it lists, then immediately the payoff (identity with create_browser's connection info) and the actionable conclusion. No sentence is filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema and no annotations, so the description must explain returns — it does, describing the per-item fields and the distinction between running browsers and the rest. A note on what identifies each entry (name/id) or ordering would close the remaining gap, but an agent can call this correctly as written.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so there is no parameter semantics to explain and the baseline of 4 applies. The description correctly keeps its focus on return values instead of inventing parameter guidance.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ("List all active browser instances") with a scoping qualifier ("active"). It also names create_browser as the source of the identical connection fields, which lets an agent relate it to a sibling, though it doesn't explicitly contrast with list_browser_files or the delete tool.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives a concrete second use case — as a reconnect path via connect_command — which is real guidance an agent can act on. It stops short of stating when not to call it or naming alternatives to pick instead, so it is clear context without explicit exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 5 tool updatesv0.2.4
    • First observedcreate_browser
    • First observeddelete_browser
    • First observedget_browser_file_url
    • First observedlist_browser_files
    • First observedlist_browsers

TDQS

A3.9/5.0

Scored across 5 tools

Disambiguation4/5

Each tool has a distinct role: lifecycle (create/list/delete), file listing, and file URL retrieval. The only mild overlap is that list_browsers re-exposes connection info also returned by create_browser, but that is a documented reconnect convenience rather than a genuine ambiguity.

Naming Consistency5/5

All five tools follow a consistent snake_case verb_noun pattern (create_browser, list_browsers, delete_browser, list_browser_files, get_browser_file_url). The singular/plural browser vs. browsers variation is trivial and matches the resource semantics.

Tool Count5/5

Five tools is well-scoped for a browser-sandbox lifecycle server: create, list, delete, and two file-access tools. Nothing feels padded or missing to the point of being thin.

Completeness4/5

Full lifecycle (create/list/delete) plus sandbox file discovery and download URL generation are covered, which is appropriate given that actual browsing is delegated to the external agent-browser/CDP connection. Minor gaps exist, such as no way to extend a browser's timeout or delete sandbox files.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers