Warning: This server is designed for use in trusted, private networks only. It is not hardened for exposure to the public internet — do not bind it to a public interface or place it behind a public-facing proxy without additional access controls.
A stateless Model Context Protocol (MCP) server that exposes browser-automation tools via Puppeteer and HTML parsing via Cheerio. Served over HTTP using the StreamableHTTP transport from the MCP SDK. Designed to run containerised — Chromium is included in the container image.
visit_pagetool — fetches any HTTP/HTTPS URL using a real Chromium browser and returns either the raw HTML or clean extracted text.- Response caching — in-memory cache (15-minute TTL, 100-entry cap) prevents redundant browser navigations.
- Stateless transport — each POST
/mcprequest gets its own MCP server instance; no session state is kept between calls. - Health check —
GET /healthreturns{"status":"ok"}for container orchestration probes. - Security — only
httpandhttpsURL schemes are accepted, preventing SSRF and local-file access.
# 1. Clone the repository
git clone https://github.com/arisjulio/browser-mcp.git
cd browser-mcp
# 2. Configure environment
cp .env.example .env
# Edit .env and set PORT
# 3. Start
docker compose up -d
# or
podman compose up -dVerify:
curl http://localhost:${PORT}/health
# {"status":"ok"}| Variable | Required | Description |
|---|---|---|
PORT |
Yes | TCP port the HTTP server listens on |
Fetches a web page using a real Chromium browser and returns its content.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
url |
string |
Yes | — | HTTP or HTTPS URL to visit |
extractText |
boolean |
No | false |
When true, returns clean readable text instead of raw HTML |
Returns: { content: [{ type: "text", text: string }] }
Example (raw HTML):
{
"tool": "visit_page",
"arguments": { "url": "https://example.com" }
}Example (clean text):
{
"tool": "visit_page",
"arguments": { "url": "https://example.com", "extractText": true }
}When extractText is true, the server strips script, style, nav, footer, header, aside, iframe, svg, and img elements, then returns the page title followed by the visible body text (capped at 50,000 characters).
| Method | Path | Description |
|---|---|---|
POST |
/mcp |
MCP StreamableHTTP endpoint |
GET |
/health |
Health check — returns {"status":"ok"} |