Playwright Integration
Use Veto with Playwright MCP to validate browser automation actions.
Veto works with Playwright MCP by guarding MCP tools/call requests. Playwright MCP exposes browser automation as schema-only MCP tools, so use veto.wrapMCPTools() around your MCP client forwarder.
TypeScript only, uses the Playwright MCP server.
Installation
npm install veto-sdk
npx playwright installSet up the Playwright MCP server following the Playwright MCP docs.
Quick start
import { Veto } from 'veto-sdk';
const veto = await Veto.init();
// Use your MCP client to list tools and forward calls to Playwright MCP.
const mcpTools = await mcpClient.listTools();
const { tools, callTool } = veto.wrapMCPTools(
mcpTools,
{ callTool: (input) => mcpClient.callTool(input) },
);
// Give `tools` to the model. Use `callTool` instead of direct MCP calls.
const result = await callTool({
name: 'browser_navigate',
arguments: { url: 'https://example.com' },
});How it works
Playwright MCP exposes browser actions as MCP tool definitions (schema-only, no execution logic). veto.wrapMCPTools() returns:
tools: The original MCP tool definitions (pass to your AI model as-is)callTool: A validated function that checks arguments before forwarding to the MCP server
AI model generates tool call
|
v
callTool(name, args)
|
v
Veto validates args
|
+----+----+
| |
allow deny
| |
v v
forward ToolCallDeniedError
to MCP
serverExample output
MCP tools: browser_navigate, browser_click, browser_type, browser_snapshot
Wrapped 4 MCP tools
browser_navigate({url: 'https://example.com'}) # allowed
browser_navigate({url: 'https://malware.site'}) # DENIED by rule
browser_click({element: 'Submit', ref: '42'}) # allowed
browser_type({element: 'Search', ref: '15', text: 'hello'}) # allowed
total_calls: 4
allowed_calls: 3
denied_calls: 1YAML rules for Playwright actions
Block navigation to dangerous URLs:
rules:
- id: block-dangerous-urls
name: Block navigation to dangerous URLs
action: block
tools:
- browser_navigate
conditions:
- field: arguments.url
operator: matches
value: "^https?://(.*\\.)?(malware|phishing|darkweb)\\."
- id: block-file-urls
name: Block file:// protocol
action: block
tools:
- browser_navigate
conditions:
- field: arguments.url
operator: starts_with
value: "file://"Block typing sensitive data:
rules:
- id: block-sensitive-input
name: Block typing passwords or tokens
action: block
tools:
- browser_type
conditions:
- field: arguments.text
operator: matches
value: "(?i)(password|secret|api.?key|token)"Playwright MCP tool names
Common tool names exposed by the Playwright MCP server:
| Tool | Description |
|---|---|
browser_navigate | Navigate to a URL |
browser_click | Click an element |
browser_type | Type text into an element |
browser_snapshot | Take an accessibility snapshot |
browser_screenshot | Take a screenshot |
browser_go_back | Navigate back |
browser_go_forward | Navigate forward |
browser_wait | Wait for a condition |
browser_press_key | Press a keyboard key |
browser_select_option | Select a dropdown option |
Exact tool names depend on the Playwright MCP server version. Use listTools() to discover available tools.

