webmcp-guard
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., "@webmcp-guardNavigate to webmcp.com and list available webmcp tools"
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.
webmcp-guard
A WebMCP-aware drop-in replacement for @playwright/mcp.
Playwright MCP is the de facto browser-automation MCP server wired into
Claude Code, Cursor, VS Code, and friends. It has no awareness of
WebMCP — the emerging W3C
proposal that lets a page register agent-callable tools directly
(document.modelContext.registerTool, with navigator.modelContext as a
legacy alias). Every agent using plain Playwright MCP on a WebMCP-enabled
site falls back to click/type/scrape automation even when the page is
explicitly offering a better, structured interface.
webmcp-guard sits in front of @playwright/mcp as a proxy: it passes its
entire native tool surface through unchanged (zero behavior regression for
sites that don't use WebMCP), detects WebMCP tools after every navigation,
and — because those tools are JavaScript the page controls rather than
code the server ships — exposes them behind a trust layer: session-scoped
provenance tracking that flags when a previously-seen tool's schema changes,
mandatory confirmation before any page-defined tool call runs, clear
webmcp:* namespacing so they're never confused with native tools, and an
audit log. See docs/trust-boundary-design.md
for the full reasoning behind that design.
Validated against the real ecosystem, not just synthetic tests: all 168
live sites in the webmcp.com public directory, plus a
hand-built adversarial test case. That process found and fixed a real
cross-origin tool-invocation vulnerability in this project's own trust
layer. Full methodology, evidence, and honest limitations in
docs/testing-and-validation.md.
Install / config
Not yet published to npm. For now, build from source (see
Install / build (from source) below) and
point your MCP client config at the built CLI directly. Once published,
install will be exactly npm install -g webmcp-guard / npx webmcp-guard,
mirroring @playwright/mcp's own install path — the config shape below is
already written for that end state, it just uses a local path today instead
of a package name.
webmcp-guard is close-to-drop-in with @playwright/mcp: it only
special-cases --browser and --headless/--headed (needed to build its
own browser launch config), and forwards every other flag — including
--allowed-origins, --blocked-origins, --allow-unrestricted-file-access,
--isolated, --caps, etc. — verbatim to the underlying @playwright/mcp
process it spawns. Any existing playwright-mcp config line keeps working
unmodified.
Before — a typical @playwright/mcp entry in an MCP client config
(mcpServers in Claude Code's or Cursor's config file):
{
"mcpServers": {
"playwright": {
"command": "npx",
"args": [
"@playwright/mcp@latest",
"--browser", "chrome",
"--allowed-origins", "https://example.com",
"--blocked-origins", "https://evil.com"
]
}
}
}After, once published — swap the package name in args, everything
else (all flags, their values, and their order) is unchanged:
{
"mcpServers": {
"playwright": {
"command": "npx",
"args": [
"webmcp-guard@latest",
"--browser", "chrome",
"--allowed-origins", "https://example.com",
"--blocked-origins", "https://evil.com"
]
}
}
}Today, from a local build — same flags, command/args point at the
built CLI instead:
{
"mcpServers": {
"playwright": {
"command": "node",
"args": [
"/absolute/path/to/webmcp-guard/packages/webmcp-guard/dist/cli.js",
"--browser", "chrome",
"--allowed-origins", "https://example.com",
"--blocked-origins", "https://evil.com"
]
}
}
}Once published, the entire migration is a one-line package-name swap — no flags need to be added, removed, or reordered.
Related MCP server: mcp-browser
What webmcp:* tools are, and what you'll see
When webmcp-guard navigates to a page that registers WebMCP tools, it lists
them to your harness as new, separate MCP tools named webmcp:<name> (e.g.
webmcp:add_to_cart) — distinct from and never merged into Playwright's
native tool list, so it's always obvious at a glance whether a tool is
server code or something the page itself defined.
Because a webmcp:* tool's implementation is JavaScript the page controls,
every call into one requires explicit confirmation before it runs — this is
on by default and is not something a misconfigured client can silently skip
past. What that confirmation looks like depends on your client:
Claude Code CLI (and any client that declares MCP
elicitationsupport): you'll see an interactive prompt showing the tool name, the page's origin, and — if the tool's schema has changed since webmcp-guard last saw it from that origin — an explicit warning that its definition changed. You accept or decline; declining, cancelling, or letting the prompt time out (30s) all result in the call being denied, never silently allowed.Clients without elicitation support (e.g. Claude Desktop, or a Cursor session hitting its current elicitation-rendering bug): webmcp-guard falls back to relying on your client's own generic tool-approval settings — Claude Code's
settings.jsonask/allow/denyrules, or Cursor's allowlist/auto-run approvals — keyed on thewebmcp:*tool name. You should configure anask(or equivalent) rule forwebmcp:*tools in these clients yourself; webmcp-guard can't force this from the server side, though every fallback-path call is still recorded to its audit log so the reliance is visible after the fact.
See docs/trust-boundary-design.md for why
this two-track design exists rather than relying on elicitation alone.
Architecture
flowchart TD
Harness["Agent Harness\n(Claude Code / Cursor / etc.)"]
Guard["webmcp-guard\npackages/webmcp-guard"]
Trust["@webmcp-guard/trust-layer\nprovenance · confirmation gate\nnamespacing · audit log"]
Adapter["@webmcp-guard/playwright\nspawns & speaks to @playwright/mcp"]
Upstream["@playwright/mcp\n(spawned subprocess, pinned version)"]
Browser["Real Chrome"]
Page["Web page\n(may register document.modelContext tools)"]
Harness -- "MCP over stdio" --> Guard
Guard -- "native tool calls, pass-through" --> Adapter
Guard -- "webmcp:* calls, gated" --> Trust
Trust -- "evaluated call" --> Adapter
Adapter -- "MCP over stdio\n(internal client)" --> Upstream
Upstream --> Browser
Browser --> Page
style Trust fill:#2d5a2d,stroke:#4ade80,color:#fffwebmcp-guard is a proxy, not a fork: it runs @playwright/mcp as an
internal MCP client via server composition (stdio), rather than vendoring
its source. See Decision 1 in research/decision-log.md for why this
replaced the original fork hypothesis.
packages/playwright(@webmcp-guard/playwright) — the adapter that spawns/speaks to@playwright/mcp, passes tool calls through, and runs the WebMCP detection probe via@playwright/mcp's ownbrowser_evaluatetool. Kept Playwright-specific and adapter-agnostic-by-convention so a future non-Playwright backend could reuse the same shape.packages/trust-layer(@webmcp-guard/trust-layer) — provenance store, schema-diffing, confirmation gating, namespacing, and the audit log. Deliberately has no Playwright-specific imports, since it's meant to generalize to other automation backends later.packages/webmcp-guard(webmcp-guard) — the MCP server itself: connects to the adapter on startup, exposes every upstream Playwright tool unchanged plus any detectedwebmcp:*tools gated by the trust layer, and after everybrowser_navigate/tab-switch, runs the detection probe and logs/caches the result.
The trust gate, per webmcp:* call
flowchart TD
Call["Agent calls webmcp:<tool>"] --> Live{"Tool actually present\non the CURRENTLY active page?"}
Live -- No --> Deny1["Denied — stale tool\nfrom a previous origin\n(closes the cross-origin bug)"]
Live -- Yes --> Verdict{"Provenance verdict"}
Verdict -- "new-tool / unchanged" --> Gate
Verdict -- "schema-changed" --> Warn["Confirmation prompt\nshows explicit warning"] --> Gate
Gate{"Client declared\nMCP elicitation?"}
Gate -- Yes --> Elicit["Structured confirmation\nprompt via elicitation"]
Gate -- No --> Fallback["Relies on client's own\ngeneric ask/allow/deny gate"]
Elicit --> Decision{"Confirmed?"}
Decision -- "No / timeout / error" --> Deny2["Denied — fail closed,\nnever silent-allow"]
Decision -- Yes --> Allow["Tool call forwarded\nto the page"]
Fallback --> Allow
Allow --> Audit["Recorded to audit log"]
Deny1 --> Audit
Deny2 --> AuditInstall / build (from source)
npm install
npm run buildRun
node packages/webmcp-guard/dist/cli.js --browser chromeOr wire it into an MCP client config as shown above.
Testing
npm test # builds all packages, runs the trust-layer's unit tests (18 tests)Unit tests cover the trust layer in isolation (provenance/schema-diffing,
confirmation gating, namespacing, audit log). The larger claim — that this
actually works against the real WebMCP ecosystem — is backed by validation
against all 168 live sites in the public
webmcp.com directory plus a hand-built adversarial
test case, documented in full in
docs/testing-and-validation.md. That
process is what found the cross-origin invocation bug shown in the diagram
above — it was not caught by unit tests or the synthetic adversarial test
alone, only by testing against real, unmodified production sites.
Reproducible via the scripts in research/tools/.
Versions pinned
@playwright/mcp@0.0.79@modelcontextprotocol/sdk@^1.30.0
Further reading
docs/trust-boundary-design.md— the full trust-boundary design document: why WebMCP tools are a different trust boundary, the provenance/schema-diff model, the confirmation-gating design, namespacing, the audit log, and what this project is explicitly not.docs/testing-and-validation.md— the consolidated testing report: methodology, every bug found and fixed with evidence, the full 168-site directory crawl results, and honestly-stated limitations.research/README.md— index of the primary-source research this project was built on (WebMCP spec state, MCP protocol details, prior art, upstream internals) and the raw validation data/tools.research/decision-log.md— architecture decisions and the reasoning behind them (fork vs. proxy, detection property names, confirmation mechanism, provenance persistence, etc.).
License
Apache-2.0 — see LICENSE.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- FlicenseBqualityDmaintenancePlaywright wrapper for MCP that enables LLM-powered clients to control a browser for automation tasks.101
- Flicense-qualityCmaintenanceExposes Playwright browser automation as MCP tools, enabling AI assistants to control a real browser tab-by-tab for form filling, navigation, and more, while preserving the user's active session.
- Alicense-qualityBmaintenanceEnables autonomous web QA by exposing Playwright browser control as MCP tools for navigation, accessibility snapshotting, interaction, and bug detection.6MIT
- Flicense-qualityCmaintenanceExtends @playwright/mcp with 22 additional tools for web automation, direct uploads, element interactions, and advanced scraping workflows in AI agents.
Related MCP Connectors
Browser MCP for logged-in tasks. Uses your Chrome — credentials stay local. Zero-token replay.
A paid remote MCP for AI agent browser DevTools MCP, built to return verdicts, receipts, usage logs,
Screenshot, diff, audit and sitemap-capture any web page — 5 MCP tools for AI agents.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- 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/SARTHAK2511/webmcp-guard'
If you have feedback or need assistance with the MCP directory API, please join our Discord server