Skip to main content
Glama

Secure Browser MCP

An MCP server that gives an AI client (Claude, etc.) controlled access to a real headless browser on your server — with domain allowlisting, SSRF protection, per-session isolation, an audit log, and cookies/state that survive restarts.

Why "secure" specifically

Browser-automation MCPs are risky by default because the LLM effectively gets a pair of hands on a live browser that can reach anywhere on the internet (and, if misconfigured, your internal network). This server closes the common holes:

Risk

Mitigation

SSRF (browser tricked into hitting internal services / cloud metadata endpoint)

src/security.ts resolves DNS itself and blocks private/loopback/link-local IP ranges, independent of what hostname was requested

DNS rebinding (domain allowlisted, but later resolves to an internal IP)

DNS is re-resolved and IP-checked on every navigation, not cached

javascript: / data: / file: URL abuse

Scheme is rejected before anything touches the browser

Unrestricted destinations

Hard allowlist via ALLOWED_DOMAINS — fails closed if empty

Unauthenticated access to the MCP endpoint

Bearer token required on every request (MCP_AUTH_TOKEN)

Session/cookie leakage across tasks

Each sessionId gets its own isolated BrowserContext (separate cookie jar, storage, cache)

Resource exhaustion

MAX_SESSIONS cap + idle-session reaper (closes contexts unused for 30 min)

Silent/undetectable misuse

Every tool call is written to a SQLite audit_log table with session, params, and result

Oversized responses blowing up context

Text and screenshot payloads are size-capped

Drive-by downloads

acceptDownloads: false by default

This covers the common attack surface, but you're still exposing a browser to an LLM. Keep ALLOWED_DOMAINS as narrow as your task allows, and run this on a host/container with no access to anything sensitive — treat it like you would a CI runner that executes untrusted code.

Related MCP server: mcp-browser-server

Persistent storage — what's actually persisted

Two things, both in SQLite at ./data/browser-mcp.db (path configurable via DATA_DIR):

  1. Browser state — cookies + localStorage per session, captured via Playwright's storageState() and restored on the next browser_navigate call for that sessionId. This is what lets a session stay logged in to a site across server restarts. Call browser_persist_session to save explicitly, or browser_close_session (which persists automatically).

  2. Audit log — every tool invocation, its params, and outcome, so you can review what the browser actually did later (browser_audit_log).

If you'd rather keep this in Supabase instead of local SQLite (e.g. so multiple server instances share state), swap storage.ts for Supabase calls — the function signatures are small and self-contained, so it's a drop-in replacement.

Setup

npm install
npx playwright install --with-deps chromium   # downloads the browser binary
cp .env.example .env
# edit .env: set MCP_AUTH_TOKEN and ALLOWED_DOMAINS
npm run build
npm start

For local iteration without building: npm run dev.

The server listens on POST http://localhost:8787/mcp (Streamable HTTP transport). Point your MCP client at that URL with:

Authorization: Bearer <your MCP_AUTH_TOKEN>

Tools exposed

  • browser_navigate(sessionId, url) — allowlist + SSRF-checked navigation

  • browser_get_text(sessionId, selector?) — read page/element text

  • browser_click(sessionId, selector)

  • browser_type(sessionId, selector, text)

  • browser_screenshot(sessionId) — base64 PNG

  • browser_persist_session(sessionId) — force-save cookies/localStorage

  • browser_close_session(sessionId) — persist + free browser resources

  • browser_list_sessions()

  • browser_audit_log(sessionId, limit?)

sessionId is any string you choose (e.g. "pranav-github-login") — reuse the same one to keep continuity (logged-in state, cookies) across calls.

Deploying on your existing server

  • Render: same pattern you used for the MongoDB MCP — set env vars in the dashboard (don't bake MCP_AUTH_TOKEN into the image), expose port 8787, and set the health check to GET /mcp returning 401 (expected, since it's unauthenticated) rather than a 200.

  • Put this behind HTTPS (Render/most PaaS do this for you) — the bearer token is meaningless over plain HTTP.

  • If the server also hosts other things, run this in its own container so the idle-session reaper and MAX_SESSIONS cap actually bound its resource use independently.

Extending

  • To let the LLM choose domains dynamically instead of a static allowlist, add an approval step (return a tool result asking for confirmation) rather than opening ALLOWED_DOMAINS wide.

  • To persist to Supabase instead of SQLite, replace the functions in src/storage.ts; the audit log schema maps directly to a Postgres table.

  • The MCP TypeScript SDK evolves — if npm install pulls a version with a different StreamableHTTPServerTransport API, check https://github.com/modelcontextprotocol/typescript-sdk for the current signature.

A
license - permissive license
Not graded
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    An open-source MCP server that provides browser automation capabilities to external AI systems, enabling navigation, DOM interaction, and web content extraction.
    20
    Apache 2.0
  • A
    license
    Not graded
    quality
    C
    maintenance
    Security-hardened MCP server that gives AI assistants full control over your real browser session, supporting 36 tools for navigation, data extraction, monitoring, and more.
    MIT
  • A
    license
    A
    quality
    A
    maintenance
    A headless, agent-controllable real browser as an MCP server that enables AI agents to navigate, click, fill, eval JavaScript, and take screenshots on localhost and allowed hosts, with no GUI required.
    27
    4
    MIT

View all related MCP servers

Related MCP Connectors

  • A paid remote MCP for AI agent browser MCP session, built to return verdicts, receipts, usage logs,

  • A paid remote MCP for AI agent browser approval MCP, built to return verdicts, receipts, usage logs,

  • Driflyte MCP server which lets AI assistants query topic-specific knowledge from web and GitHub.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/pranavgawasproject/secure-browser-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server