{"id":50791215,"url":"https://github.com/thimo/vscode-integrated-browser-mcp","last_synced_at":"2026-06-12T11:02:05.633Z","repository":{"id":353154703,"uuid":"1206769412","full_name":"thimo/vscode-integrated-browser-mcp","owner":"thimo","description":"VS Code's integrated browser, exposed to Claude Code and other agents via MCP and HTTP.","archived":false,"fork":false,"pushed_at":"2026-05-20T11:01:49.000Z","size":523,"stargazers_count":0,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-20T14:59:46.845Z","etag":null,"topics":["agent","browser-automation","chrome-devtools-protocol","claude-code","mcp","vscode-extension"],"latest_commit_sha":null,"homepage":"https://marketplace.visualstudio.com/items?itemName=thimo.integrated-browser-mcp","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/thimo.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-10T08:32:03.000Z","updated_at":"2026-05-20T10:51:10.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/thimo/vscode-integrated-browser-mcp","commit_stats":null,"previous_names":["thimo/integrated-browser-mcp","thimo/vscode-integrated-browser-mcp"],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/thimo/vscode-integrated-browser-mcp","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thimo%2Fvscode-integrated-browser-mcp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thimo%2Fvscode-integrated-browser-mcp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thimo%2Fvscode-integrated-browser-mcp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thimo%2Fvscode-integrated-browser-mcp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thimo","download_url":"https://codeload.github.com/thimo/vscode-integrated-browser-mcp/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thimo%2Fvscode-integrated-browser-mcp/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34240817,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-12T02:00:06.859Z","response_time":109,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agent","browser-automation","chrome-devtools-protocol","claude-code","mcp","vscode-extension"],"created_at":"2026-06-12T11:02:04.300Z","updated_at":"2026-06-12T11:02:05.623Z","avatar_url":"https://github.com/thimo.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Integrated Browser MCP\n\n[![Release](https://img.shields.io/github/v/release/thimo/vscode-integrated-browser-mcp?label=release)](https://github.com/thimo/vscode-integrated-browser-mcp/releases) [![VS Code Marketplace](https://img.shields.io/badge/marketplace-install-blue)](https://marketplace.visualstudio.com/items?itemName=thimo.integrated-browser-mcp)\n\nExposes VS Code's integrated browser to external agents (Claude Code, scripts, curl) via a local HTTP API and MCP server.\n\nEvery existing browser automation solution targets an external Chrome process. This extension is different: it bridges the browser **already inside VS Code** — with your session cookies, your localhost dev server, your DevTools — to any agent that can speak HTTP or MCP.\n\n## How it works\n\n```\nClaude Code / curl / scripts\n    │\n    │  MCP (stdio) or HTTP\n    ▼\nMCP Server  ──HTTP──▶  VS Code Extension  ──CDP──▶  Integrated Browser\n                       localhost:3788+               (real Chromium, in-editor)\n```\n\nThe extension uses VS Code's built-in `editor-browser` and the Chrome DevTools Protocol (CDP) to provide full browser automation: navigation, JavaScript evaluation, clicking, typing, screenshots, DOM access, console and network monitoring.\n\n## Getting started\n\n1. Install from the [VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=thimo.integrated-browser-mcp), or run:\n   ```bash\n   code --install-extension thimo.integrated-browser-mcp\n   ```\n2. The HTTP server starts automatically on `localhost:3788`\n3. For Claude Code: the MCP server is auto-configured in `~/.claude.json` on first activation\n4. The browser launches lazily on the first request — no browser tab until you need one\n\n### Usage with Claude Code\n\nThe MCP tools are available immediately. Ask Claude Code to use them by name:\n\n```\nuse browser_navigate to open http://localhost:3000\n```\n\nOr reference the MCP server:\n\n```\nuse the integrated-browser-mcp to open my app\n```\n\nThe MCP server ships an `instructions` field that conformant clients surface to the model automatically. If your agent still picks the wrong tool (e.g. shells out to `open` instead of using `browser_navigate`), add a short hint to your project's `CLAUDE.md`:\n\n```\nFor browser automation, use the integrated-browser-mcp MCP tools (browser_navigate, browser_screenshot, etc.) — never shell out to `open`/`xdg-open`/`start`.\n```\n\n### Usage with curl\n\n```bash\ncurl -X POST http://127.0.0.1:3788/navigate \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"url\":\"http://localhost:3000\"}'\n```\n\nSee [HTTP API](#http-api) below for the full endpoint list.\n\n## MCP tools\n\nAll interaction tools accept an optional `tabId` parameter. Omit it to target the active tab.\n\n| Tool | Description |\n|------|-------------|\n| `browser_navigate` | Navigate to a URL |\n| `browser_eval` | Execute JavaScript in the page |\n| `browser_click` | Click an element by CSS selector |\n| `browser_type` | Type text into an element by CSS selector |\n| `browser_scroll` | Scroll the page or a specific element |\n| `browser_screenshot` | Capture page as PNG. `fullPage` for whole-document capture; `waitMs` to delay capture for in-flight CSS transitions. |\n| `browser_screenshot_slice` | Capture one viewport-height slice of a long page. For pages exceeding Chromium's single-PNG axis cap (~16k px). Pair with `browser_emulate` first. |\n| `browser_emulate` | Override viewport dimensions, DPR, mobile flag, and User-Agent. Sticky until `reset:true`. |\n| `browser_snapshot` | Get the accessibility tree |\n| `browser_dom` | Get the full page HTML |\n| `browser_markdown` | Extract page content as markdown (lightweight DOM walker, not Turndown). Pass `outputPath` to write to disk instead of returning the body — workspace-scoped. |\n| `browser_console` | Read buffered console output (aggregates across tabs when `tabId` omitted) |\n| `browser_network` | Read buffered network requests (aggregates across tabs when `tabId` omitted) |\n| `browser_network_clear` | Clear the network log |\n| `browser_download_set` | Configure where downloads land (default `tmp/downloads`, workspace-scoped) and bypass the native save dialog. See [Headless downloads](#headless-downloads). |\n| `browser_downloads` | Read buffered download events (last 50 per tab, aggregates when `tabId` omitted) |\n| `browser_url` | Get the current page URL |\n| `browser_tab_open` | Open a new browser tab (proposed API only) |\n| `browser_tab_close` | Close a tab by id |\n| `browser_tab_list` | List open tabs with their ids, URLs, titles, and active flag |\n| `browser_tab_activate` | Set the default target tab |\n| `browser_status` | Check bridge connection status |\n\n## HTTP API\n\nAll responses follow the format `{ ok: true, data: ... }` or `{ ok: false, error: \"...\" }`.\n\nAll interaction endpoints (navigate, eval, click, type, scroll, screenshot, snapshot, dom, url) accept an optional `tabId` — as a `?tabId=` query param on GET requests or in the JSON body on POST. Omit to target the active tab.\n\n| Method | Endpoint | Body | Description |\n|--------|----------|------|-------------|\n| GET | `/status` | — | Bridge health + diagnostics (transport, active tab, buffer sizes, event counts) |\n| POST | `/navigate` | `{ url, tabId? }` | Navigate to URL |\n| POST | `/eval` | `{ expression, tabId? }` | Run JS in page context |\n| POST | `/click` | `{ selector, tabId? }` | Click element by CSS selector |\n| POST | `/type` | `{ selector, text, tabId? }` | Type into element |\n| POST | `/scroll` | `{ deltaX, deltaY, selector?, tabId? }` | Scroll page or element |\n| GET | `/screenshot` | `?tabId=X\u0026fullPage=true\u0026waitMs=N` | Base64 PNG screenshot. `fullPage=true` captures beyond the viewport. `waitMs` sleeps before capture (handles CSS transitions). |\n| GET | `/screenshot-slice` | `?slice=N\u0026tabId=X` | Viewport-height slice plus metadata. `slice` is 0-indexed; negative from end. Omit `slice` for metadata only. |\n| GET | `/markdown` | `?selector=S\u0026tabId=X` | Page content as markdown. `selector` defaults to `main` (falls back to `body`). |\n| POST | `/emulate` | `{ width, height, deviceScaleFactor?, mobile?, userAgent?, reset?, tabId? }` | Device-metric override. `{reset:true}` clears. |\n| GET | `/snapshot` | `?tabId=X` | Accessibility tree |\n| GET | `/dom` | `?tabId=X` | Full page outerHTML |\n| GET | `/console` | `?limit=N\u0026tabId=X` | Buffered console output (last 200). Aggregates across tabs when `tabId` omitted. |\n| GET | `/network` | `?limit=N\u0026filter=x\u0026tabId=X` | Buffered network requests (last 200). Aggregates across tabs when `tabId` omitted. |\n| POST | `/network/clear` | `?tabId=X` | Clear network log (one tab or all) |\n| POST | `/download/set` | `{ path?, behavior?, tabId? }` | Configure download handling. `behavior` ∈ `allow` (default) / `allowAndName` / `deny` / `default`. `path` is required for `allow`/`allowAndName` and must be absolute when called directly (the MCP layer scopes workspace-relative paths). |\n| GET | `/downloads` | `?limit=N\u0026tabId=X` | Buffered download events (last 50 per tab). Each entry: `{ guid, url, suggestedFilename, state, totalBytes?, receivedBytes?, downloadPath?, startedAt, updatedAt }`. |\n| GET | `/url` | `?tabId=X` | Current page URL |\n| GET | `/tabs` | — | List open tabs `[{ tabId, url, title, active, state, transport }]` |\n| POST | `/tab/open` | `{ url, makeActive? }` | Open a new tab (proposed API only). Returns `{ tabId, url, title }` |\n| POST | `/tab/close/:tabId` | — | Close a tab |\n| POST | `/tab/activate/:tabId` | — | Set the active (default) tab |\n\n## Multi-window support and port discovery\n\nEach VS Code window gets its own browser and HTTP server. Ports are assigned automatically starting from 3788 and incrementing if already taken.\n\n### How the MCP server finds the right window\n\nWhen Claude Code calls a browser tool, the MCP server needs to know which VS Code window to talk to. It resolves this automatically:\n\n1. Each VS Code window registers itself at `~/.integrated-browser-mcp/instances/\u003chash\u003e.json` with its port, workspace path, and PID\n2. The MCP server reads all instance files and filters out dead processes\n3. It matches `process.cwd()` (Claude Code's working directory) against registered workspace paths — deepest match wins\n4. If no workspace matches, it falls back to the most recently started instance\n\nThis means when you run Claude Code inside a VS Code terminal, it automatically connects to the browser in **that** VS Code window.\n\n### Manual override\n\nSet the `BROWSER_BRIDGE_PORT` environment variable to force a specific port:\n\n```bash\nBROWSER_BRIDGE_PORT=3789 claude\n```\n\n### Troubleshooting\n\nIf the MCP server connects to the wrong window, check the registered instances:\n\n```bash\ncat ~/.integrated-browser-mcp/instances/*.json\n```\n\nStale instance files from crashed VS Code windows are cleaned up automatically on the next window startup. You can also delete them manually.\n\n## Enabling worker event capture (proposed API)\n\nBy default the bridge launches the integrated browser via a VS Code debug session and talks to it through `vscode-js-debug`'s CDP proxy. That proxy only forwards events from the main page session — so logs and network requests from web workers and service workers never reach the `/console` and `/network` buffers.\n\nVS Code ships a **proposed API** (`vscode.window.openBrowserTab`) that bypasses `vscode-js-debug` entirely and gives direct multiplexed access to the CDP stream. On this path, worker and iframe events are captured and tagged with a `target` field.\n\nTo enable it, launch VS Code with the proposed API flag:\n\n```bash\ncode --enable-proposed-api=thimo.integrated-browser-mcp\n```\n\nThe extension feature-detects the proposal at startup and uses it if available. Without the flag, the bridge falls back to the debug-session path and works exactly like before — so setting the flag is optional and safe.\n\nCheck which path you're on via the status bar tooltip (`Browser MCP: Connected (proposed)` vs `(debug-session)`), or `GET /status` → `transport: \"browserTab\"` vs `\"websocket\"`.\n\nCaveat: the `browser` proposal is still [tracked upstream](https://github.com/microsoft/vscode/issues/300319) and its shape can change between VS Code releases. The fallback path keeps the extension usable regardless.\n\n## Multi-tab\n\nMulti-tab support requires the proposed API (previous section). When enabled:\n\n- `browser_tab_open(\"https://example.com\")` opens a new tab, returns its `tabId`.\n- `browser_tab_list()` shows all open tabs — the `active` flag marks which one receives commands by default, and the `number` field (1, 2, 3…) matches the `(N) ` prefix in each tab's title. Numbers are stable per tab with reuse: close tab 3 and the next new tab gets 3, but tab 4 stays tab 4 for its lifetime.\n- Every interaction tool (`browser_navigate`, `browser_eval`, `browser_click`, etc.) accepts an optional `tabId`. Omit it to target the active tab; pass it to target a specific tab.\n- `browser_console` and `browser_network` aggregate across all tabs by default — each entry carries the `tabId` of the tab it came from. Pass `tabId` to filter.\n- Closing a tab in the VS Code UI is picked up automatically; the bridge untracks it and the `tabId` becomes invalid.\n\nThe `(N) ` prefix is auto-applied even to pages without a `\u003ctitle\u003e` element (about:blank, raw API responses), and it re-applies after navigation. The bridge strips any prefix a prior version of the extension may have left on a pre-existing tab, so you won't see stacked markers after an upgrade.\n\nOn the debug-session fallback path, the bridge always exposes exactly one tab (synthetic id `tab-main`) and `browser_tab_open` returns an error pointing to the proposed API.\n\n## Headless downloads\n\nBy default the integrated browser shows a native save dialog when a page initiates a download — fine for a human, fatal for an agent. `browser_download_set` switches the active tab's browser session to a configured directory so the file lands somewhere predictable, no UI blocking. `browser_downloads` exposes the buffered `Browser.downloadWillBegin` / `Browser.downloadProgress` events so the agent knows what filename Chromium picked and when the download is finished.\n\nTypical agent flow:\n\n1. `browser_download_set()` — defaults to `\u003cworkspace\u003e/tmp/downloads` with `behavior:\"allow\"`. Parent dirs are created.\n2. Trigger the download (`browser_click`, `browser_navigate` to a file URL, `browser_eval` of a form submit, …).\n3. Poll `browser_downloads` until the matching entry has `state:\"completed\"`.\n4. Read the file from `\u003cdownloadPath\u003e/\u003csuggestedFilename\u003e`.\n5. Optionally `browser_download_set({ behavior: \"default\" })` to restore the save dialog when done.\n\nPath scoping mirrors `browser_markdown`'s `outputPath`: relative paths resolve against the open workspace folder; absolute paths must live inside it. There is no VS Code setting — the AI calls the tool when it needs the behavior.\n\nCaveats:\n- Behavior is **per browser session**, not per tab — Chromium's `Browser.setDownloadBehavior` is browser-level. Calling `browser_download_set` on any tab affects all tabs of that browser.\n- With `behavior:\"allow\"` (default), Chromium silently appends ` (1)`, ` (2)`, … to filenames on collision. CDP doesn't expose the suffix; if the agent cares about exact filenames, clear `tmp/downloads` first or use `behavior:\"allowAndName\"` (saves under the GUID; rename via the events from `browser_downloads`).\n- Add `tmp/` to `.gitignore` — downloads are throwaway.\n\n## Limitations and trust model\n\n- HTTP server binds to `127.0.0.1` only — never network-exposed. No authentication, same trust model as VS Code's built-in terminals.\n- `/eval` runs arbitrary JavaScript in the open page — same trust model as the DevTools console. Don't pass untrusted input.\n- On the debug-session path (default, no proposed-API flag): only one tab, web worker and service worker events not captured, and the debug toolbar / \"(1)\" badge appears while the browser is active.\n- The browser tab lives in the VS Code editor area. Moving it to a side panel is fine; closing it disconnects CDP.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthimo%2Fvscode-integrated-browser-mcp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthimo%2Fvscode-integrated-browser-mcp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthimo%2Fvscode-integrated-browser-mcp/lists"}