npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@krakerxyz/browser-mcp

v1.5.0

Published

MCP server package for remote browser automation.

Readme

@krakerxyz/browser-mcp

MCP server package for remote browser automation.

@krakerxyz/browser-mcp is the MCP-facing bridge your AI tool runs locally.

It is designed to be launched by an MCP host (for example from .mcp.json) and connects that host to a Browser MCP backend over WebSocket.

What it is used for

  • Give MCP-compatible assistants access to a real Chromium browser session
  • Support browser actions such as opening pages, navigation, DOM reads, JS execution, clicks, and screenshots
  • Create and manage isolated browser sessions, each with its own timezone, locale, and geolocation
  • Reach local/dev-only services through optional tunnel ports

Session model

A session is an isolated browser instance (browser context) on the server.

  • The agent creates sessions explicitly with browser_create_session, which returns a sessionId
  • Every page and cookie tool takes that sessionId (just like pages are addressed by pageId), so one connection can drive several sessions at once
  • Each session keeps its own pages, cookies, and state isolated from other sessions
  • A session can fix its timezone, locale, and geolocation at creation time — useful for rendering dates, formatting numbers, and testing location-aware pages
  • Sessions live until closed with browser_close_session or until they sit idle past the server's session timeout; they are not tied to the connection, so they survive reconnects (use browser_list_sessions to rediscover them)

How it works

  1. Your MCP host starts this package over stdio.
  2. This package connects to a Browser MCP server (ws://.../ws/client).
  3. On connect, it discovers tools from the server and registers them dynamically.
  4. MCP tool calls are forwarded to the remote browser backend.
  5. Results are returned to your MCP host over stdio.

This means new server tools can be added without requiring a matching MCP package release.

MCP host configuration (.mcp.json)

Minimal example:

{
  "mcpServers": {
    "browser": {
      "command": "npx",
      "args": [
        "-y",
        "@krakerxyz/browser-mcp",
        "--server",
        "ws://localhost:3100",
        "--api-key",
        "change-me"
      ]
    }
  }
}

Configuration options

  • --server <ws-url> (required): Browser MCP server URL, for example ws://localhost:3100
  • --api-key <key> (optional): Required when the server has API_KEY enabled
  • --name <client-name> (optional): Identifies this client in the server dashboard — sessions it creates are grouped under this name. It does not create or name a session; the agent creates sessions via browser_create_session
  • --tunnel-port <port> (optional, repeatable): Enables localhost tunneling for specific ports

Locale, timezone, and geolocation

browser_create_session accepts optional timezone, locale, and geolocation so the remote browser renders content for a specific place and language:

  • timezone — IANA id like America/New_York; controls how Date and Intl render dates and times
  • locale — BCP 47 tag like de-DE; controls date/number/currency formatting, navigator.language, and the Accept-Language header
  • geolocation{ latitude, longitude, accuracy? } reported to the page's geolocation API (permission is granted automatically)

These are fixed for the life of the session. To use different values (for example to compare how a page renders in two timezones), create another session and drive both side by side.

Tunnel ports

Tunnel ports let the remote browser reach services that are only accessible from the MCP host machine (for example local dev servers).

Example: with --tunnel-port 3000, browsing to http://localhost:3000 in the remote browser is tunneled to port 3000 on the MCP host.

Multiple tunnel ports are supported by repeating --tunnel-port.

Tunnel .mcp.json example:

{
  "mcpServers": {
    "browser": {
      "command": "npx",
      "args": [
        "-y",
        "@krakerxyz/browser-mcp",
        "--server",
        "ws://localhost:3100",
        "--api-key",
        "change-me",
        "--tunnel-port",
        "3000",
        "--tunnel-port",
        "5173"
      ]
    }
  }
}

Tunnel troubleshooting

If navigating to a tunneled URL fails with ERR_SOCKS_CONNECTION_FAILED, the SOCKS bridge reached the server fine, but the client could not open a TCP connection to your local service. The server logs the real reason on a [tunnel] line, e.g. client could not reach localhost:5174: connect ECONNREFUSED. An agent can read the same thing without server-log access by calling the browser_get_connection_diagnostics tool, which returns the recent tunnel results (the failing host:port and error) for clients started with --name.

The most common cause is that the @krakerxyz/browser-mcp process and your dev server are in different network namespaces (for example the MCP host runs in a separate container from the dev server). A working curl localhost:5174 from your shell does not prove the mcp client can reach it. Verify from the same environment the mcp client runs in:

node -e "require('net').connect(5174,'127.0.0.1').on('connect',()=>console.log('reachable')).on('error',e=>console.log('UNREACHABLE',e.code))"

If that prints UNREACHABLE, run the mcp client where it can reach the dev server (same container/network namespace), or bind the dev server to an interface the mcp client can reach. If only localhost fails but 127.0.0.1 works, it's an IPv6 (::1) mismatch — navigate to 127.0.0.1 instead.

Available tools

Tools are discovered dynamically from the server on connect. Start by creating a session with browser_create_session; every page and cookie tool then takes the returned sessionId. The current set of tools provided by the server:

| Tool | Description | |------|-------------| | browser_create_session | Create an isolated browser session and return its sessionId. Optionally set timezone, locale, and geolocation. Call this before opening pages. | | browser_list_sessions | List active sessions with their ids, labels, page counts, and locale settings. | | browser_close_session | Close a session, destroying its browser context and all of its pages. | | browser_get_connection_diagnostics | Get recent tunnel results for this client (which localhost ports the browser reached, and the real error when a tunnel failed). Use after ERR_SOCKS_CONNECTION_FAILED. Retained per --name. | | browser_open_page | Open a new page in a session and navigate to a URL. Optionally accepts a viewport size for responsive layout testing. | | browser_close_page | Close a browser page | | browser_list_pages | List all open pages in a session | | browser_navigate | Navigate an existing page to a new URL | | browser_execute_js | Execute JavaScript in a page context. Expression must return a JSON-serializable value. | | browser_get_dom | Get DOM HTML content. Returns full page HTML or matching elements for a CSS selector. | | browser_capture_screenshot | Capture a screenshot of a page. Returns both an inline image and a downloadable URL. | | browser_click | Click on an element by CSS selector or coordinates | | browser_fill | Clear an input and set its value, dispatching a real input event so SPAs receive the change. Use for <input>, <textarea>, and contenteditable. | | browser_type | Type text one character at a time, dispatching real keydown/input/keyup events. Use when the page reacts to individual keystrokes (autocomplete, masks); prefer browser_fill otherwise. | | browser_press_key | Press a single key or chord (e.g. Enter, Tab, Control+A), optionally focusing a selector first. | | browser_select_option | Select an option in a native <select> by value, label, or index, dispatching real input/change events. | | browser_set_viewport | Set the viewport (screen) size of a page for responsive layout testing. Accepts width/height or a Playwright device preset name. | | browser_set_cookies | Set one or more cookies in a session's browser context. Supports HttpOnly/Secure cookies. | | browser_get_cookies | Get cookies from a session's browser context. | | browser_get_console_logs | Get captured console log entries from a page (buffers last 50). | | browser_get_network_requests | Get captured network request entries from a page (buffers last 20). | | browser_get_performance_report | Collect performance metrics (web vitals-style, CPU sample, long tasks, resources) with optional auto CPU profiling on high usage. | | browser_start_performance_profile | Start a manual CPU sampling profile for a page. | | browser_stop_performance_profile | Stop a manual CPU sampling profile and return top function/file hotspots. |

Because tools are registered dynamically from the server, new tools added to the server become available to the MCP host without requiring a new release of this package.

Server setup (Docker Compose)

services:
  browser-mcp:
    image: joshkrak/browser-mcp:latest
    container_name: browser-mcp
    restart: unless-stopped
    ports:
      - "3100:3100"
    environment:
      API_KEY: "${BROWSER_MCP_API_KEY}"
    volumes:
      - browser-mcp-data:/data

volumes:
  browser-mcp-data:

First start downloads the Chromium browser (~640MB) into the /data volume — it is not baked into the image. Keep /data on a persistent volume (as above) so this happens only once; later starts reuse it. The first container therefore takes longer to report healthy.

If your MCP host is not on the same machine as Docker, replace ws://localhost:3100 with your reachable server URL.