Skip to main content
Glama

ptc-web

A standalone browser-content MCP server for JavaScript-rendered pages.

Demo software. It gives compatible MCP clients bounded, inspectable access to web content. Its URL policy and resource limits are deliberate boundaries, but it is not a general-purpose browser automation service.

Read JavaScript-rendered pages as bounded Markdown or structured records. Keep site-specific interpretation in extraction recipes while the server owns browser access, HTML parsing, extraction, and resource limits.

Implemented foundation

  • TypeScript and Node.js 20.19 or newer, with exact dependency versions.

  • Official @modelcontextprotocol/server v2 and MCP 2026-07-28 only over stdio. Legacy initialization is rejected.

  • Playwright Chromium in a server-owned persistent profile, temporary by default and never shared with the user's normal browser profile.

  • Immutable, expiring DOM snapshots; paginated Markdown/text reads; literal passage finding; and declarative CSS-selector record extraction.

  • Mozilla Readability for articles, Turndown with GFM for Markdown, and Cheerio for selectors.

  • Deterministic authored fixtures for article, listing, discussion, documentation, dynamic rendering, and a held-out article layout.

Install and run

Install the Chromium build matching this package once, then start the MCP server through npm:

npx -y playwright@1.63.0 install chromium
npx -y ptc-web

For a source checkout:

pnpm install --frozen-lockfile
pnpm exec playwright install chromium
pnpm run build
node dist/src/cli.js

The process speaks MCP on stdout and writes only bounded diagnostics to stderr. --help and --version do not start Chromium.

Tools

Tool

Contract

page_open

Open a permitted URL and wait for a bounded readiness condition.

page_capture

Freeze the current DOM into an immutable snapshot and return a preview.

page_read

Read paginated Markdown or text using article or document extraction.

page_extract

Apply a declarative container/field CSS recipe to a snapshot.

page_find

Find paginated literal passages in a snapshot representation.

page_close

Close a browser page; its snapshots remain readable until expiry.

Every cursor is process-local, integrity protected, and bound to the immutable snapshot, operation, representation, and recipe/query that issued it. A cursor cannot silently resume against changed parameters. Snapshot coverage reports DOM truncation, blocked subrequests, network request count, and the fact that unloaded site content remains unknown.

Access policy

Public HTTP(S) is allowed by default. URL credentials, other schemes, and IPs that are not globally routable are denied. Hostnames are resolved and every answer must be public. Each intercepted fetch disables automatic redirects; Chromium receives one redirect hop at a time, and every next hop is routed through policy before it is fetched. The same policy applies to every browser subrequest. Service workers are disabled.

Tests and deliberate local installations can allow exact origins (scheme, host, and port) with a comma-separated value:

PTC_WEB_ALLOW_LOCAL_ORIGINS=http://127.0.0.1:8123,http://[::1]:8123 node dist/src/cli.js

This does not allow other ports or other local origins.

Configurable limits

Environment variable

Default

Meaning

PTC_WEB_MAX_CAPTURE_BYTES

2 MiB

Retained UTF-8 DOM bytes per snapshot.

PTC_WEB_MAX_RESOURCE_BYTES

8 MiB

Response-body bytes per browser network request.

PTC_WEB_MAX_REQUESTS_PER_PAGE

256

Requests including explicit redirect hops per page.

PTC_WEB_MAX_RESPONSE_BYTES

48,000

Serialized application result target per tool call.

PTC_WEB_MAX_SNAPSHOTS

32

Live snapshots in one server process.

PTC_WEB_MAX_PAGES

8

Concurrent page handles.

PTC_WEB_MAX_EXTRACT_RECORDS

500

Containers considered by one extraction.

PTC_WEB_MAX_FIND_MATCHES

200

Matches considered by one find.

PTC_WEB_NAVIGATION_TIMEOUT_MS

15,000

Maximum open/readiness time.

PTC_WEB_SNAPSHOT_TTL_MS

300,000

Snapshot lifetime.

All limits must be positive integers; the result limit must be at least 8 KiB. PTC_WEB_PROFILE_DIR opts into a host-owned dedicated profile directory. PTC_WEB_HEADLESS=false displays Chromium. Temporary profiles, pages, and snapshots are cleaned up on normal shutdown; cancellation closes an in-flight page.

Validation

pnpm run verify

The default suite covers the library, browser behavior, MCP stdio transport, security boundaries, fixtures, and extraction behavior. One optional compatibility lane exercises the server through PtcRunner; the server itself does not depend on PtcRunner.

Design

Search, arbitrary click/scroll operations, existing-Chrome integration, hosted extraction services, and a custom extension are intentionally outside this foundation.

Development and releases

CI tests Node.js 20.19, 22, and 24 on Linux and macOS, and smoke-tests the packed npm artifact. See RELEASING.md for the tag-driven npm release process. This project is available under the MIT License.

Dynamic screen-scraper example

The dynamic-parser example combines ptc-web with a separately installed filesystem MCP server. A workflow opens a JavaScript-rendered page, selects parser code from a writable file, executes that parser against the captured page, and saves the result. Changing the parser file changes the screen scraper on the next run without restarting the runtime or modifying ptc-web.

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/andreasronge/ptc-web'

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