Semantic Dom
БесплатноНе проверенDrives a real Chromium browser to extract a page's DOM into compact Semantic JSON with Playwright-native locators, enabling AI agents to generate consistent, ac
Описание
Drives a real Chromium browser to extract a page's DOM into compact Semantic JSON with Playwright-native locators, enabling AI agents to generate consistent, accurate Playwright tests.
README
Local MCP server (stdio, Node.js + TypeScript) that drives a real Chromium browser via Playwright to extract a live page's DOM into compact, factual Semantic JSON with Playwright-native locators — so AI-generated Playwright tests are consistent across the whole QA team, not just accurate.
Same page → same extraction → same conventions → same test style, regardless of who runs it.
Evidence: benchmark/RESULTS.md — on real pages the Semantic JSON is 92–97% smaller than the raw DOM an agent would otherwise consume, with every locator uniqueness-verified by Playwright's engine and byte-identical output across runs. Docs: How it works (deep dive) · Team guide (setup + connecting your agent) · Benchmark methodology · Roadmap
Quickstart
No clone, no build — the package is on npm. One-time browser setup (installs the Chromium build matching the package's bundled Playwright):
npx -y -p semantic-dom-mcp playwright install chromium
Then add the server to your MCP client:
{
"mcpServers": {
"semantic-dom": {
"command": "npx",
"args": ["-y", "semantic-dom-mcp"],
"env": {
"QA_MCP_ALLOWED_HOSTS": "staging.yourapp.internal,staging.admin.internal",
"QA_MCP_STORAGE_STATE": "./.auth/staging.json"
}
}
}
}
That's the whole setup. Verify by asking your agent to list its MCP tools — you should
see extract_semantic_dom. See docs/GUIDE.md for per-client config
locations (Claude Code, Claude Desktop, Cursor, Windsurf), authenticated staging, and
troubleshooting. To run from a clone instead (contributors), see Development below.
Workflow
- Ask your agent: "extract the checkout page and write a success-path test."
- The agent calls
extract_semantic_dom({ url })— the server navigates a real Chromium page, runs the extractor inside the page, and returns Semantic JSON: every interactive node with a ready-to-paste Playwright locator, uniqueness verified by Playwright's own engine. - The agent uses the
write_playwright_testprompt (scenario + the JSON), which injects the team conventions. - The result is a Playwright test in team style, grounded in real locators — never guessed ones.
MCP surface
| Kind | Name | Purpose |
|---|---|---|
| Tool | extract_semantic_dom |
Extract a URL into Semantic JSON (url, wait_for, wait_selector, include_hidden, max_nodes). Read-only, never touches the page. |
| Tool | extract_semantic_dom_after |
Same, but first runs a short declared action list (fill/click/press/wait, max 20) in the main frame and snapshots the resulting state — for toasts, validation errors, opened dialogs. Refuses to extract if the actions navigated off the allowlist. |
| Tool | check_auth |
Diagnostic: navigates with the configured storageState and reports whether the session bounced to a login-looking page (expired auth shows up as an answer, not a mystery). |
| Tool | list_frames |
Diagnostic frame tree with same-origin/reachability classification. |
| Prompt | write_playwright_test |
Team-standard test-writing prompt (scenario, extract_json, team_name?, framework_note?). |
| Resource | conventions://playwright |
The same team conventions as read-only text. |
Errors (navigation failure, denied host, missing selector) come back as structured JSON in the tool result — the agent can react instead of crashing.
Configuration (environment variables)
| Variable | Meaning |
|---|---|
QA_MCP_ALLOWED_HOSTS |
Required. Comma-separated hostnames the server may navigate to. Navigation is denied by default. Supports host, host:port, and *.domain entries. |
QA_MCP_STORAGE_STATE |
Optional path to a Playwright storageState JSON for pre-authenticated staging sessions. This file holds a live session — it is gitignored; never commit it. |
QA_MCP_TEAM_NAME |
Optional team name used in the write_playwright_test prompt (default QA). |
Security posture
- Tool inputs are untrusted (they arrive via an LLM): strict schemas (
additionalProperties: false), http/https only, host allowlist enforced before any navigation. extract_semantic_domonly reads the DOM — it never clicks, submits, or mutates the page. The one sanctioned exception isextract_semantic_dom_after, which executes only an explicit, bounded, schema-validated action list, never logs fill values, and aborts without extracting if the page leaves the allowlisted hosts.- No network egress beyond navigating to the target URL. No telemetry. Page contents are never logged (stderr carries only high-level events) and are not stored beyond the current call.
Semantics worth knowing
- Snapshot honesty: the JSON is a single moment. A disabled submit button is reported
is_disabled: truewith a note — the conventions instruct the model to write the interactions that change state, not to assume it stays disabled. - Hidden nodes are included and flagged
is_visible: false(tests often assert hidden-ness); passinclude_hidden: falseto drop them (the count dropped is noted, never silent). - Open shadow DOM is traversed and flagged
in_shadow— locators pierce it natively, so no>>>/::shadowCSS is ever emitted. Closed shadow roots appear asshadow_boundarymarker nodes (detected via pre-navigationattachShadowinstrumentation; closed roots created by declarative shadow DOM parse before scripts run and cannot be detected). - Same-origin iframes are extracted per-frame with
frame_pathset (chainframeLocator()in that order). Cross-origin iframes are recorded as opaquecross_origin_framenodes with URL/name only — their DOM is never touched. - Notification & dialog surfaces (
role="alert",role="status", dialogs) are extracted like interactive nodes. When a toast library keeps the live region empty and renders the message in a sibling (a common pattern across UI libraries), the message text is pulled from the enclosing container and flagged. For UI that renders late after an interaction,wait_selector_afteronextract_semantic_dom_afterwaits deterministically instead of guessingsettle_ms. Since those ARIA roles take names from the author (not contents), their role locator isgetByRole('alert')— or with thearia-labelname when one exists. For UI that only appears after an interaction (login-success toast), useextract_semantic_dom_after. - JS-click cards (product tiles with no anchor/role/test-id) are invisible to the factual
rules by design — pass
include_click_targets: trueto include cursor-pointer boundary elements with content, flagged as heuristic and located by their heading text. - Links carry
href(schema 1.1) so agents can discover which page to extract next without scraping. Framework-generated ids (rc_select_*, ReactuseId, Radix, MUI...) are detected and demoted to last-resort with a note — they change between builds and must never be primary. viewport: "mobile"(375×812, touch) snapshots responsive states; visibility flags reflect the active media queries.- Truncation is loud:
max_nodes/ depth caps settruncated: trueplus a note. Non-unique locators carryis_unique: falseanddisambiguationguidance.
Development
git clone https://github.com/helmif/semantic-dom-mcp.git && cd semantic-dom-mcp
npm install
npx playwright install chromium
npm run dev # run the server over stdio via tsx
npm run typecheck # tsc --noEmit (strict)
npm test # Vitest suites against real fixture pages in headless Chromium
npm run build # compile to dist/ (clients can then use "command": "node", "args": ["<path>/dist/index.js"])
Repo layout: src/index.ts (bootstrap) · src/server.ts (MCP surface) · src/browser.ts
(Playwright layer + orchestration) · src/extractor/ (in-page engine + locator resolution) ·
src/types.ts (frozen v1 contract) · src/conventions.ts (single source of team conventions).
Установка Semantic Dom
У этого сервера нет опубликованного пакета — он собирается из исходников. Открой репозиторий и следуй инструкции в README.
▸ github.com/helmif/semantic-dom-mcpFAQ
Semantic Dom MCP бесплатный?
Да, Semantic Dom MCP бесплатный — установка в пару кликов через Unyly без оплаты.
Нужен ли API-ключ для Semantic Dom?
Нет, Semantic Dom работает без API-ключей и переменных окружения.
Semantic Dom — hosted или self-hosted?
Self-hosted: сервер запускается локально на твоей машине командой из раздела установки.
Как установить Semantic Dom в Claude Desktop, Claude Code или Cursor?
Открой Semantic Dom на unyly.org, выбери вкладку своего клиента (Claude Desktop, Claude Code, Cursor) и нажми Install — конфиг сгенерируется автоматически, без правки JSON.
Похожие MCP
Playwright
Browser automation, scraping, screenshots
автор: MicrosoftPuppeteer
Browser automation and web scraping.
автор: modelcontextprotocolopentabs-dev/opentabs
Plugin-based MCP server + Chrome extension that gives AI agents access to web applications through the user's authenticated browser session. 100+ plugins with a
автор: opentabs-devrobhunter/agentdeals
1,500+ developer infrastructure deals, free tiers, and startup programs across 54 categories. Search deals, compare vendors, plan stacks, and track pricing chan
автор: robhunterCompare Semantic Dom with
Не уверен что выбрать?
Найди свой стек за 60 секунд
Автор?
Embed-бейдж для README
Похожее
Все в категории browse
