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

@thinkbrowse/mcp

v0.3.3

Published

Let your AI coding agent test its own frontend work. Connects Claude Code, Cursor, and any MCP client to your real Chrome browser — real sessions, real cookies, no headless conflicts.

Readme

@thinkbrowse/mcp

MCP (Model Context Protocol) server for ThinkBrowse. Gives AI agents the ability to control your actual Chrome browser — with all your cookies and active sessions — or a cloud browser for headless automation.

Why ThinkBrowse vs Playwright MCP

| Capability | ThinkBrowse MCP | Playwright MCP | |---|---|---| | Uses your real Chrome cookies | ✅ Local mode — browse as you | ❌ Fresh context, no auth | | Access sites you're logged into | ✅ LinkedIn, Salesforce, internal tools | ❌ Requires scripted login every time | | Cloud headless sessions | ✅ Isolated Playwright browser on demand | ❌ Local browser only (no ThinkBrowse cloud) | | Runtime local ↔ cloud switching | ✅ set_mode tool, no restart | ❌ Single mode per server | | Structured content extraction | ✅ Reader layer (articles, structured data) | ❌ Raw DOM access only | | Session recording + sharing | ✅ Full video, screenshots, AI analysis | ❌ | | Persistent sessions | ✅ Resume across agent invocations | ❌ Single-run only | | Direct browser actions | ✅ Browser tools + local_action_* | ✅ Browser tools | | AI task planning | ✅ task_create / task_execute | ❌ |

TL;DR: Use ThinkBrowse when you need to browse as yourself (authenticated sites, internal tools). Use Playwright MCP for stateless public-web automation.

Installation

Claude Code

claude mcp add thinkbrowse --transport stdio \
  -e THINKBROWSE_API_KEY=your-key \
  -- npx @thinkbrowse/mcp

Claude Desktop / Cursor / VS Code

Add to your MCP config file:

| Tool | Config file | |------|------------| | Claude Desktop | ~/Library/Application Support/Claude/claude_desktop_config.json | | Cursor | .cursor/mcp.json in project root | | VS Code (Copilot) | .vscode/mcp.json in project root |

Auto mode (recommended) — tries local Chrome first, falls back to cloud:

{
  "mcpServers": {
    "thinkbrowse": {
      "command": "npx",
      "args": ["@thinkbrowse/mcp"],
      "env": {
        "THINKBROWSE_API_KEY": "your-key"
      }
    }
  }
}

Local only (Chrome extension, no API key needed):

{
  "mcpServers": {
    "thinkbrowse": {
      "command": "npx",
      "args": ["@thinkbrowse/mcp", "--mode", "local"]
    }
  }
}

Cloud only:

{
  "mcpServers": {
    "thinkbrowse": {
      "command": "npx",
      "args": ["@thinkbrowse/mcp", "--mode", "cloud"],
      "env": {
        "THINKBROWSE_API_KEY": "your-key"
      }
    }
  }
}

Security note: MCP config files (.cursor/mcp.json, .vscode/mcp.json) are often committed to git. Use environment variable references where supported, or add these files to .gitignore to avoid leaking your API key.

Global install (alternative)

npm install -g @thinkbrowse/mcp
thinkbrowse-mcp --mode auto

Modes

| Mode | Backend | Requires | |------|---------|----------| | auto | Tries local first, falls back to cloud | Either of the below | | local | Chrome extension + native host | Chrome with ThinkBrowse extension | | cloud | ThinkBrowse REST API (Fly.io) | API key from thinkbrowse.io |

Page cache tools (page_cache_html, page_cache_text, page_cache_screenshot): stateless POST /api/cache/* on the service. In local mode, set THINKBROWSE_BASE_URL and THINKBROWSE_API_KEY (or pass --base-url / --api-key so the native host client can reach the API — the native host itself has no /api/cache routes).

Runtime switching: Use the set_mode tool to switch between local and cloud without restarting.

Local mode setup

MCP Server  ──HTTP──>  Native Host  ──stdio──>  Chrome Extension  ──>  Chrome tabs
  1. Install the ThinkBrowse Chrome extension
  2. Set up the native host binary (extension guides you through this)
  3. Verify: curl http://localhost:$(cat ~/.thinkbrowse/port)/health
  4. Add MCP config above

Available Tools (48 + 1 optional)

48 tools are always registered. set_mode is registered when the server is started with mode-switch support (the default CLI binary enables it).

Session Lifecycle

| Tool | Description | Modes | |------|-------------|-------| | session_create | Create a new browser session | all | | session_status | Get session URL, title, action count | all | | session_delete | Terminate session, preserve artifacts | all | | session_list | List all active sessions | all | | session_wait_ready | Poll until session is ready (use after create in cloud mode) | all | | session_use | Set default session ID for subsequent tool calls | all | | session_release | Release the current local session ownership without closing the tab | local | | session_artifacts | List screenshots and recordings for a session | cloud |

Mode Switching

| Tool | Description | Modes | |------|-------------|-------| | set_mode | Switch between local/cloud/auto at runtime without restart | all |

Navigation

| Tool | Description | Modes | |------|-------------|-------| | navigate | Go to a URL, wait for page load | all | | go_back | Navigate back in browser history | all | | go_forward | Navigate forward in browser history | all | | wait_for_element | Wait for a CSS selector to appear | all |

Interaction

| Tool | Description | Modes | |------|-------------|-------| | click | Click an element by CSS selector | all | | type_text | Type text into an element (appends) | all | | fill | Fill a form field (replaces content) | all | | press_key | Press a keyboard key (Enter, Tab, Escape, etc.) | all | | scroll | Scroll the page or a specific element | all | | hover | Hover over an element (triggers tooltips/menus) | all | | select_option | Select from a <select> dropdown | all |

Observation

| Tool | Description | Modes | |------|-------------|-------| | snapshot | Get accessibility tree (lightweight page overview) | all | | screenshot | Capture page screenshot (png/jpeg/webp, full-page option) | all | | extract | Extract text, HTML, or structured data from elements | all | | evaluate | Run JavaScript in the page context | all | | get_url | Return the current page URL | all | | get_title | Return the current page title | all | | get_html | Return current page HTML with explicit truncation metadata when large | all | | sleep | Pause for a bounded duration in milliseconds | all |

Tab Management

| Tool | Description | Modes | |------|-------------|-------| | tab_list | List all open browser tabs | local | | tab_new | Open a new tab (optionally with URL) | local | | tab_close | Close a tab by ID | local | | tab_attach | Attach to an existing local tab and bind it as the default session | local | | tab_switch | Switch the active local browser tab without rebinding the default session | local | | window_new | Open a new local browser window and bind it as the default session | local |

Dialog Handling

| Tool | Description | Modes | |------|-------------|-------| | get_dialog | Check for open alert/confirm/prompt dialogs | all | | handle_dialog | Accept or dismiss a dialog with optional text | all |

Wait

| Tool | Description | Modes | |------|-------------|-------| | wait_for_text | Wait for specific text to appear on the page | all |

Monitoring

| Tool | Description | Modes | |------|-------------|-------| | console_messages | Get browser console messages (log, warn, error) | all | | network_requests | Get network requests made by the page | all | | clear_logs | Clear console and network logs for a clean capture | all |

Local Actions

| Tool | Description | Modes | |------|-------------|-------| | local_action_run | Run a direct native-host action against the currently attached local tab | local | | local_action_status | Check the status of a previously started local action | local | | local_action_cancel | Cancel a running local action | local |

Task Planning

| Tool | Description | Modes | |------|-------------|-------| | task_create | Create an AI task plan from natural language | cloud | | task_execute | Execute a task plan | cloud | | task_status | Check task execution status | cloud |

Local Session Semantics

The new local lifecycle tools intentionally distinguish between ownership-changing operations and focus-only operations:

  • tab_attach rebinding: attaches to an existing local Chrome tab and sets it as the default session for subsequent session-scoped tool calls.
  • window_new rebinding: opens a fresh local window and sets the resulting tab as the default session.
  • tab_switch focus-only: changes the active local browser tab, but does not steal or rewrite the current default session just because browser focus changed.
  • session_release clearing: releases the current local session ownership and clears the default session when that bound local context is released.

Lock safety follows the same high-level contract as the CLI:

  • contested live local locks fail explicitly
  • same-owner rebinds can succeed idempotently
  • stale locks may be replaced only when the existing owner is no longer live

This package now exposes the CLI's local native-host execution flow as:

  • local_action_run
  • local_action_status
  • local_action_cancel

The naming is intentional:

  • action means a direct operation against a browser context
  • task means a higher-level cloud multi-step planning/execution workflow

CLI Options

thinkbrowse-mcp [options]

Options:
  --mode <mode>        cloud, local, or auto (default: auto)
  --api-key <key>      API key for cloud mode (or set THINKBROWSE_API_KEY)
  --base-url <url>     Cloud API URL (default: https://api.thinkbrowse.io)
  --port <port>        Override native host port
  --session-id <id>    Default session ID (enables session_use)
  -h, --help           Show help
  -v, --version        Show version

Environment Variables

| Variable | Description | |----------|-------------| | THINKBROWSE_API_KEY | API key for cloud mode | | THINKBROWSE_BASE_URL | Cloud API base URL | | THINKBROWSE_BRIDGE_PORT | Override native host port | | THINKBROWSE_LOCAL | Set to true to force local mode |

Port Discovery

The native host writes its port to ~/.thinkbrowse/port on startup. The MCP server reads this automatically.

Priority: --port flag > THINKBROWSE_BRIDGE_PORT env > ~/.thinkbrowse/port > 3012

Testing

# Unit tests
bun test

# Smoke test — full session lifecycle against cloud
THINKBROWSE_API_KEY=your-key bun run scripts/smoke-mcp-parity.ts

# Smoke test — clear_logs only
bun run test:smoke

Programmatic Usage

Basic:

import { createServer, CloudClient } from '@thinkbrowse/mcp';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';

const client = new CloudClient({
  baseUrl: 'https://api.thinkbrowse.io',
  apiKey: process.env.THINKBROWSE_API_KEY!,
});

const server = createServer(client);
await server.connect(new StdioServerTransport());

With runtime mode switching:

import { createServer, CloudClient } from '@thinkbrowse/mcp';
import type { ClientRef } from '@thinkbrowse/mcp';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';

const client = new CloudClient({
  baseUrl: 'https://api.thinkbrowse.io',
  apiKey: process.env.THINKBROWSE_API_KEY!,
});

const clientRef: ClientRef = { current: client };
const server = createServer(client, {
  clientRef,
  onSetMode: async (mode) => {
    // Return a new client for the requested mode
    return new CloudClient({ baseUrl: '...', apiKey: '...' });
  },
});

await server.connect(new StdioServerTransport());

License

MIT