Playwright MCP Is Great for Automation. PageBolt MCP Is How You Audit It.
You're building AI agents with Playwright MCP. It handles browser automation beautifully—click, fill forms, navigate, extract data. But when your auditor asks "Show me what the agent actually did," you have API logs. You don't have visual proof.
That's where PageBolt MCP comes in. While Playwright MCP executes actions, PageBolt MCP captures screenshots. Together, they form a compliance-grade audit trail: execution + visual evidence.
The Problem: Execution Without Proof
Playwright MCP is designed for one thing: making browser automation accessible to AI agents. It's powerful. Your agent can:
- Navigate to a URL
- Fill form fields
- Click buttons
- Wait for elements
- Extract text/data
But here's the gap: you can't prove to regulators what happened.
Scenario 1: Compliance audit
Your agent filled out a form and submitted it. API logs show "button_clicked: submit". But did the form actually submit? Did an error message appear that the agent missed? Your auditor can't tell from logs alone.
Scenario 2: Silent failure
The page loaded. The agent extracted data. But what if the page rendered an error message? What if the data was partial? Logs don't show rendering failures.
Scenario 3: Lateral movement risk
Your agent logs show normal API calls. But did it access systems outside its intended scope? Did it trigger compliance violations? Visual proof answers this.
The Solution: Playwright MCP + PageBolt MCP
Combine them:
- Playwright MCP executes the automation (navigate, click, fill)
- PageBolt MCP captures screenshots at decision points (before/after actions, errors, data extraction)
- Your system stores the audit trail (timestamp + screenshot + action)
Real Workflow: Form Submission with Audit Proof
Here's production code using both MCPs together:
const Anthropic = require("@anthropic-ai/sdk");
const client = new Anthropic();
// Define both MCPs as tools
const tools = [
{
name: "playwright_navigate",
description: "Navigate to a URL using Playwright",
input_schema: {
type: "object",
properties: {
url: { type: "string" }
},
required: ["url"]
}
},
{
name: "playwright_fill",
description: "Fill a form field",
input_schema: {
type: "object",
properties: {
selector: { type: "string" },
value: { type: "string" }
},
required: ["selector", "value"]
}
},
{
name: "playwright_click",
description: "Click an element",
input_schema: {
type: "object",
properties: {
selector: { type: "string" }
},
required: ["selector"]
}
},
{
name: "pagebolt_screenshot",
description: "Take a screenshot for audit proof",
input_schema: {
type: "object",
properties: {
url: { type: "string" },
purpose: { type: "string", description: "Why we're capturing this (e.g., 'before submission', 'error check')" }
},
required: ["url", "purpose"]
}
}
];
// Audit trail storage
const auditTrail = [];
// Agent with audit loop
async function auditableAgent(task) {
const messages = [
{
role: "user",
content: `${task}\n\nIMPORTANT: Before and after each action, take a screenshot with PageBolt. This is your audit proof for compliance. Include the purpose (e.g., "before form fill", "after submission", "error check").`
}
];
let response = await client.messages.create({
model: "claude-opus-4-5-20251101",
max_tokens: 4096,
tools: tools,
messages: messages
});
while (response.stop_reason === "tool_use") {
const toolUse = response.content.find(block => block.type === "tool_use");
// Handle Playwright actions
if (toolUse.name.startsWith("playwright_")) {
console.log(`Playwright: ${toolUse.name} → ${JSON.stringify(toolUse.input)}`);
// In real implementation, call Playwright MCP here
// For demo: simulate success
const result = `Success: ${toolUse.name} executed`;
messages.push({ role: "assistant", content: response.content });
messages.push({
role: "user",
content: [
{
type: "tool_result",
tool_use_id: toolUse.id,
content: result
}
]
});
}
// Handle PageBolt screenshots
if (toolUse.name === "pagebolt_screenshot") {
console.log(`PageBolt: Capturing screenshot for audit (${toolUse.input.purpose})`);
// Call PageBolt API
const screenshot = await fetch("https://api.pagebolt.com/screenshot", {
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.PAGEBOLT_API_KEY}`
},
params: { url: toolUse.input.url }
}).then(r => r.json()).catch(e => ({ error: e.message }));
// Store in audit trail
auditTrail.push({
timestamp: new Date().toISOString(),
action: "screenshot",
url: toolUse.input.url,
purpose: toolUse.input.purpose,
screenshot_id: screenshot.id || null
});
messages.push({ role: "assistant", content: response.content });
messages.push({
role: "user",
content: [
{
type: "tool_result",
tool_use_id: toolUse.id,
content: `Screenshot captured: ${screenshot.id}`
}
]
});
}
// Continue agent loop
response = await client.messages.create({
model: "claude-opus-4-5-20251101",
max_tokens: 4096,
tools: tools,
messages: messages
});
}
return {
result: response.content,
auditTrail: auditTrail
};
}
// Run it
const result = await auditableAgent("Fill out the signup form at https://app.example.com/signup with name='John Doe', email='john@example.com'. Submit and verify success.");
console.log("Audit Trail:", JSON.stringify(result.auditTrail, null, 2));
What this does:
- Agent takes a screenshot before filling the form (captures initial state)
- Fills fields using Playwright MCP
- Takes a screenshot after filling (captures form state with data)
- Clicks submit using Playwright MCP
- Takes a screenshot after submit (captures success/error page)
- Returns complete audit trail with timestamps and screenshots
Your auditor can replay the entire session as a visual timeline.
Compliance Use Cases
SOC 2 / HIPAA:
Screenshot healthcare records access → Proves agent accessed only authorized data.
GDPR:
Screenshot consent forms → Proves agent respected user preferences.
PCI DSS:
Screenshot payment pages → Proves agent never captured card details.
FedRAMP:
Screenshot access logs → Proves agent behavior matches security policy.
Without visual proof, you have API logs. With it, you have irrefutable evidence.
When to Use PageBolt + Playwright
| Scenario | Playwright Alone | + PageBolt MCP |
|---|---|---|
| Test automation (internal) | ✅ Sufficient | ❌ Overkill |
| Customer-facing automation | ❌ No audit trail | ✅ Compliance proof |
| Regulated industry access | ❌ Risky | ✅ Required |
| Agent debugging | ⚠️ Logs only | ✅ Visual debugging |
| Legal/audit response | ❌ Insufficient | ✅ Irrefutable |
Rule: If your agent touches regulated data or customer-facing systems, add PageBolt screenshots.
Cost Comparison
Self-hosted visual audit:
- Puppeteer screenshot server: $500+/month
- Storage (videos/images): $100+/month
- Ops time: 20+ hours/month
PageBolt MCP:
- API cost: $29/month (10k screenshots)
- Storage: Included
- Ops time: 0 hours/month
At scale, PageBolt is 10-20x cheaper than self-hosted solutions.
Next Steps
- Add PageBolt MCP to your Claude Agent SDK setup
- Modify Playwright agents to capture screenshots at decision points
- Store audit trail in your compliance system
- Show your auditor the visual replay
Start free — 100 screenshots/month, no credit card. Add compliance proof to your next Playwright automation.
Top comments (0)