Browser Jet Pilot
Browser Jet Pilot is a self-hosted MCP server for browser automation, letting you control a Chromium browser via CDP using 19 deterministic tools. Key capabilities include:
Session Management: Connect to an existing browser or launch a new one (
browser_start), and close sessions (browser_end).Navigation: Navigate to URLs, open new tabs, list and switch between tabs, and retrieve page metadata (URL, title, viewport).
User Interaction: Click elements, fill/clear inputs, type text character-by-character, select dropdown options, hover over elements, and scroll pages or specific elements.
Content Extraction & Observation: Capture full-page or element-specific screenshots (base64 PNG), extract visible text or raw HTML, execute arbitrary JavaScript in the page context, and wait for elements to reach specific states (attached, visible, hidden).
Performance Optimization: Disable WebGL, freeze CSS animations, and throttle
requestAnimationFramefor GPU-heavy pages (browser_disable_shaders/browser_restore_shaders).AI Agent Integration: Optionally use an AI-powered agent (BrowserAgent/BrowserSkill) for autonomous, natural language-driven browser control.
Flexible Transport: Expose browser control via MCP stdio or HTTP transport, with optional API key authentication.
Allows using OpenAI's API as the AI backend for the BrowserAgent to perform autonomous browser tasks.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Browser Jet PilotNavigate to news.ycombinator.com and extract the top story titles."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Browser Jet Pilot
Proudly announcing!
v1.0.1 — Live & Stable 💅
API Key Authentication — secure your HTTP transport with
API_KEYandX-API-KeyheaderConstant-time auth —
crypto.timingSafeEqualkeeps the bad actors guessingFull test suite — 127 Vitest tests, zero flakes, CI-green on every push
Developer tooling — ESLint, Prettier, Husky, lint-staged all tuned and humming
CI/CD pipeline — typecheck → lint → format:check → test across Node 20/22/24
Shader control tools — tame those heavy WebGL pages with
browser_disable_shadersBug fixes — SVG/MathML handling, proper browser cleanup, enhanced type safety
The extras that make it ✨
browser_disable_shaders— block WebGL, freeze CSS animations, throttlerequestAnimationFrameto ~1 FPS. Perfect for those pages that think they're a video game.browser_restore_shaders— bring the sparkle back (WebGL/RAF need a page reload to fully restore, nature of the beast)
Related MCP server: Scout
What even is this?
A self-hosted MCP server for browser automation. Connect to your own Chromium via CDP — no subscription, no cloud, no weird per-session pricing. Just your browser, your infra, your rules.
Drop-in alternative to @browserbasehq/mcp. Same MCP protocol, none of the lock-in.
Features
Connect to your existing browser via Chrome DevTools Protocol, or launch a fresh one managed by Playwright
19 deterministic tools — no LLM required for basic browser control
MCP stdio transport — works with Claude Desktop, Cursor, any MCP client
MCP HTTP transport — expose as a service with optional API key auth
BrowserAgent — AI-powered autonomous agent (OpenAI, Anthropic, or custom endpoint)
BrowserSkill — standardized skill interface for agent frameworks
Multi-tab workflows — because one tab is never enough
Screenshots — base64 PNG, full-page or single element
Comprehensive testing — 127 tests, Vitest, coverage reports
Pre-commit hooks — ESLint + Prettier gatekeep every commit
A little notice 🌸
I want you to understand that this repository contains a highly powerful toolset — exceptionally powerful.
It is shared in good faith, with the expectation that you will use these tools responsibly and for educational purposes, without causing harm to others. There are no guardrails, restrictions, or feature flags that would limit or alter their original capabilities.
As the saying goes, a weapon is only as dangerous as the hands that wield it. Power itself is neutral — its consequences are defined entirely by the intent and discipline of the user.
I won't go into detail about what could go wrong or the many ways these tools might be misused. If you found this repository while looking for that, you likely already know what you're doing — and I won't be the one to outline those paths. Instead, below you'll find guidance on how you should use these tools, along with the valuable, practical functionality they were designed to provide.
Keep in mind: these tools possess an extraordinary level of power, and that power is entirely in your hands.
If any damage occurs — whether through data leaks, automated actions, replay mechanisms, or otherwise — responsibility does not lie with the tools or this project. The sole accountable party is you. ¯\_(ツ)_/¯
Quick Start
1. Have a browser running with CDP
# With Xvfb + Chromium:
chromium --no-sandbox --remote-debugging-port=9222 --disable-gpu
# Or point at your existing Chromium (make sure it has --remote-debugging-port=9222)2. Install & run
npm install
npm run build
# Stdio mode (Claude Desktop, Cursor, etc.)
node dist/index.js
# HTTP mode
node dist/index.js --port 31003. Hook it up to Claude Desktop
Drop this into your claude_desktop_config.json:
Platform | Config path |
macOS |
|
Windows |
|
Linux |
|
{
"mcpServers": {
"browser": {
"command": "node",
"args": ["/absolute/path/to/dist/index.js"],
"env": {
"CDP_URL": "http://localhost:9222"
}
}
}
}Docs (Mintlify)
Project docs live in docs/ — Mintlify format, cute and functional.
npm install # includes Mint CLI as dev dependency
npm run docs:validate # check it builds clean
npm run docs:links # no dead links allowed
npm run docs:dev # browse locallyCI/CD
Every push and PR goes through the wringer. The workflow lives at .github/workflows/ci.yml.
npm ci → typecheck → lint → format:check → testAcross Node 20, 22, and 24 — because we don't mess around. (Node 18 was politely asked to leave the party — vitest v4 needs styleText from node:util, which landed in 20.12.0.)
Development
Scripts at your fingertips
Command | What it does |
| Compile TypeScript → |
| Dev mode with |
| Run the built server |
| BrowserAgent CLI |
| Deterministic tool sequence (no AI) |
| Run the full 127-test suite |
| Tests + coverage report |
| Vitest UI (pretty!) |
| ESLint check |
| ESLint auto-fix |
| Prettier — make it pretty |
| Prettier — is it pretty? |
|
|
| Full reliability test suite |
Pre-commit magic
Husky + lint-staged keep the repo pristine:
.ts,.tsx→ ESLint + Prettier.json,.md,.yml→ Prettier
npm install # hooks set up automatically via the prepare script ✨Docker
Compose (the easy way)
docker compose up -d --build
docker compose ps # should say healthy 💚
curl http://localhost:3100/healthzWhat you get:
MCP endpoint:
http://localhost:3100/mcpHealth check:
http://localhost:3100/healthzBuilt-in container healthcheck against
/healthz
Quick smoke test:
npm run agent -- --server-url http://localhost:3100/mcp --sequence \
browser_start "browser_navigate?url=https://example.com" \
"browser_get_content?selector=body&type=text" browser_endFirst build takes a bit — Playwright Chromium binaries install inside the container. Worth the wait.
Full reliability pass (health + lifecycle + extraction + multi-tab, 5x repeat):
npm run reliability:check
# or against a custom endpoint:
npm run reliability:check -- http://localhost:3100/mcpTeardown
docker compose downPlain Docker (no Compose)
docker build -t browser-jet-pilot:local .
docker run --rm -p 3100:3100 --shm-size=1g \
-e PORT=3100 -e HOST=0.0.0.0 -e LAUNCH=true \
browser-jet-pilot:localExternal Chromium (CDP mode)
docker run --rm -p 3100:3100 --shm-size=1g \
-e PORT=3100 -e HOST=0.0.0.0 -e LAUNCH=false \
-e CDP_URL=http://host.docker.internal:9222 \
browser-jet-pilot:localOn Linux where host.docker.internal doesn't resolve:
--add-host=host.docker.internal:host-gatewayTools
Session
Tool | Description |
| Connect to browser (or launch one). Call this first, always. |
| Close the current session. Bye-bye! |
Navigation
Tool | Parameters | Description |
|
| Go to a URL |
|
| Open a new tab |
| — | List all open tabs |
|
| Switch to tab by index |
| — | Current URL, title, viewport |
Interaction
Tool | Parameters | Description |
|
| Click an element |
|
| Clear and fill an input |
|
| Type character by character |
|
| Select a dropdown option |
|
| Hover over an element |
|
| Scroll page or element |
Observation
Tool | Parameters | Description |
|
| Screenshot (base64 PNG) |
|
| Extract text or HTML |
|
| Run JavaScript in the page |
|
| Wait for an element |
Shader Control
Tool | Parameters | Description |
|
| Block WebGL, freeze CSS animations, throttle RAF to ~1 FPS. Hit this before navigating to heavy shader pages. |
| — | Remove injected style overrides. WebGL/RAF need a page reload to fully come back — that's just how the browser works. |
Configuration
CLI Flags
Flag | Env Var | Default | What it does |
|
| (stdio) | Port for HTTP transport |
|
|
| Bind address |
|
|
| CDP endpoint |
|
|
| Launch a new browser instead of connecting |
|
|
| Viewport width |
|
|
| Viewport height |
Environment
# .env file
CDP_URL=http://localhost:9222
LAUNCH=false
BROWSER_WIDTH=1280
BROWSER_HEIGHT=720
API_KEY=your-secret-api-key # optional — locks down HTTP transportAPI Key Auth 🔐
When running in HTTP mode, you can optionally gate the server behind an API key:
export API_KEY=your-secret-api-keyThen clients include it in the X-API-Key header:
curl -H "X-API-Key: your-secret-api-key" http://localhost:3100/mcpThe server uses crypto.timingSafeEqual for constant-time comparison — no timing attacks on our watch.
Examples
HTTP Transport
node dist/index.js --port 3100 --host 0.0.0.0
# → http://0.0.0.0:3100/mcp
# Connect any MCP client via Streamable HTTP transportLaunch Mode
No browser lying around? Let Playwright handle it:
node dist/index.js --launch --browser-width 1920 --browser-height 1080How it stacks up to Browserbase MCP
Feature | Browserbase MCP | Browser Jet Pilot |
Browser hosting | Browserbase cloud | Your container 💕 |
Cost | Per-session pricing | Free (your infra) |
| Stagehand + LLM | Use deterministic tools or BrowserAgent |
| Stagehand + LLM |
|
| Stagehand + LLM |
|
Screenshot | Via Stagehand | Native |
Tab management | Single page | Multi-tab ✨ |
Shader control | ❌ |
|
Data residency | Browserbase servers | Your server, your data |
Architecture
flowchart LR
subgraph App["Your Application"]
BS["BrowserSkill"]
BA["BrowserAgent (AI)"]
MC["MCP Client<br/>(Claude Desktop, Cursor, etc.)"]
end
BS -->|MCP JSON-RPC| MB["Browser Jet Pilot<br/>(stdio or HTTP)"]
BA -->|MCP JSON-RPC| MB
MC -->|MCP JSON-RPC| MB
MB --> PW["Playwright"]
PW -->|CDP| CH["Your Chromium / Chrome"]BrowserAgent (AI-Powered) 🤖
An autonomous agent that hooks into the MCP server and uses an LLM to figure out what tools to call, in what order, to accomplish your natural language task.
CLI
# AI-powered (needs OPENAI_API_KEY or ANTHROPIC_API_KEY)
npm run agent -- --server-url http://localhost:3100/mcp \
"Go to start.gg and find the latest Tekken 7 tournament"
# Anthropic flavor
npm run agent -- --server-url http://localhost:3100/mcp \
--ai-provider anthropic --ai-model claude-sonnet-4-20250514 \
"Navigate to example.com and extract all links"
# Deterministic mode (no AI, straight tool sequence)
npm run agent -- --server-url http://localhost:3100/mcp --sequence \
browser_start \
"browser_navigate?url=https://example.com" \
browser_screenshot \
browser_endProgrammatic
import { BrowserAgent } from 'browser-jet-pilot/agent'
const agent = new BrowserAgent({
serverUrl: 'http://localhost:3100/mcp',
aiProvider: 'openai',
aiModel: 'gpt-4o',
// aiApiKey: 'sk-...', // or set OPENAI_API_KEY
maxSteps: 20,
})
// AI-powered task
const result = await agent.run(
'Go to start.gg/tournament/12345 and get the bracket'
)
console.log(result.summary)
console.log(
`Steps: ${result.steps.length}, Screenshots: ${result.screenshots.length}`
)
// Deterministic sequence
const result2 = await agent.executeSequence([
{ tool: 'browser_start' },
{ tool: 'browser_navigate', args: { url: 'https://example.com' } },
{ tool: 'browser_screenshot' },
])
await agent.disconnect()Agent Config
Option | Env Var | Default | What it does |
| — | — | MCP server HTTP endpoint |
| — |
| MCP server command (stdio) |
| — |
| MCP server args (stdio) |
| — |
|
|
| — |
| LLM model name |
|
| — | Your API key |
| — | provider default | Custom endpoint |
| — |
| Safety limit per task |
BrowserSkill (Agent Framework Integration) 🧩
A standardized skill wrapper ready to drop into any agent framework. Comes with quick helper methods and automatic screenshot saving.
Programmatic
import { BrowserSkill } from 'browser-jet-pilot/skill'
const skill = new BrowserSkill({
serverUrl: 'http://localhost:3100/mcp',
saveScreenshots: true,
screenshotDir: './screenshots',
})
await skill.init()
// AI-powered browser task
const result = await skill.execute(
'Go to start.gg and extract tournament data',
{ workDir: './workspace' }
)
console.log(result.summary) // "Found 3 tournaments..."
console.log(result.files) // ['./screenshots/step-3-1712...png']
console.log(result.metadata) // steps, duration, tool calls
// Quick helpers (deterministic, no AI needed)
const page = await skill.goto('https://example.com')
const content = await skill.read('https://example.com', '#main-content')
const { base64, file } = await skill.capture('https://example.com', true)
const links = await skill.extract(
'https://example.com',
'Array.from(document.querySelectorAll("a")).map(a => ({text: a.innerText, href: a.href}))'
)
await skill.destroy()Skill Interface
interface SkillResult {
success: boolean
summary: string
files: string[] // saved screenshot paths
data?: any // parsed JSON from last step
metadata: {
steps: number
screenshots: number
totalDuration: number
toolCalls: Array<{ tool: string; args: Record<string, unknown> }>
}
}Requirements
Node.js >= 20.12.0
Chromium with
--remote-debugging-port=9222(or launch mode)For Playwright browser launch:
npx playwright install chromium
License
MIT
designed, written and coded solely by head and from 💜 for you 0xabadbabe (Sudo Qt — jet'aime)
Maintenance
Latest Blog Posts
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/0xABADBABE-ops/browser-jet-pilot'
If you have feedback or need assistance with the MCP directory API, please join our Discord server