Sáu tháng trước, tôi đối mặt với một vấn đề nghe chừng đơn giản nhưng đau đầu: pipeline kiểm thử E2E cho sàn thương mại điện tử có 12.000 SKU, mỗi SKU cần một agent AI truy xuất DOM, đánh giá bố cục rồi tự động đề xuất sửa CSS. Selenium truyền thống quá cứng nhắc, Playwright tốt nhưng vẫn bắt tôi viết selector thủ công cho từng mẫu giao diện. Khi tôi kết nối chrome-devtools-mcp với Claude Code thông qua gateway Đăng ký tại đây — HolySheep AI — mọi thứ thay đổi: agent có thể "nhìn" DOM, "đọc" console log, "bắt" network request và tự quyết định selector trong runtime.
Bài viết này chia sẻ kiến trúc tôi đã tinh chỉnh qua 4 tháng vận hành production, kèm số liệu benchmark thật và cách tối ưu chi phí vượt 85% so với gọi API trực tiếp từ hãng.
1. Kiến trúc tổng quan
Hệ thống gồm 4 lớp tách biệt, mỗi lớp tối ưu độc lập:
- Lớp MCP Server:
chrome-devtools-mcpchạy local, expose các toolnavigate,click,evaluate,screenshotqua giao thức JSON-RPC 2.0 - Lớp Transport:
stdiocho worker nội bộ, HTTP+SSE cho tác vụ chạy trên máy từ xa - Lớp LLM Gateway: endpoint
https://api.holysheep.ai/v1tương thích OpenAI/Anthropic, định tuyến tới nhiều hãng mô hình - Lớp Orchestration: Claude Code CLI đóng vai trò agent loop, gọi MCP server, gọi LLM, parse tool_use và phản hồi lại cho MCP
Điểm mấu chốt tôi rút ra: chrome-devtools-mcp không thay thế Playwright mà bổ sung cho Playwright. Nó cho phép agent suy luận về DOM thay vì bị gò bó bởi selector cố định, biến mỗi tác vụ browser thành một bài toán suy luận có ngữ cảnh.
2. Cài đặt production
2.1 Khởi tạo MCP server
{
"mcpServers": {
"chrome-devtools": {
"command": "npx",
"args": ["-y", "chrome-devtools-mcp@latest", "--headless", "--isolated"],
"env": {
"CHROME_PATH": "/usr/bin/google-chrome-stable",
"MCP_LOG_LEVEL": "info",
"MCP_TRANSPORT": "stdio"
}
}
}
}
File trên đặt tại ~/.claude/mcp_servers.json. Cờ --isolated rất quan trọng: nó ép mỗi session dùng profile Chrome riêng, tránh leak cookie giữa các tenant và chặn tình trạng session A làm hỏng state của session B khi chạy song song.
2.2 Cấu hình Claude Code dùng HolySheep gateway
export ANTHROPIC_BASE_URL="https://api.holysheep.ai/v1"
export ANTHROPIC_API_KEY="YOUR_HOLYSHEEP_API_KEY"
export ANTHROPIC_MODEL="claude-sonnet-4.5"
Tối ưu concurrency cho 16 worker song song
export CLAUDE_CODE_MAX_CONCURRENCY=16
export CLAUDE_CODE_REQUEST_TIMEOUT=90000
export CLAUDE_CODE_TELEMETRY_DISABLED=1
claude code --mcp-config ~/.claude/mcp_servers.json \
--max-turns 40 \
--verbose \
--output-format stream-json
HolySheep là gateway duy nhất tôi từng dùng hỗ trợ đồng thời cả chuẩn OpenAI và Anthropic trong cùng một endpoint, nên khi chuyển từ Claude sang GPT-4.1 hay DeepSeek tôi chỉ đổi biến môi trường ANTHROPIC_MODEL mà không phải sửa code agent.
3. Script orchestration với concurrency control
import asyncio
import os
from anthropic import AsyncAnthropic
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
16 là con số benchmark kỹ: vượt 24 sẽ vượt rate-limit Chrome DevTools Protocol
SEMAPHORE = asyncio.Semaphore(16)
async def run_audit_task(url: str, prompt: str) -> dict:
async with SEMAPHORE:
async with stdio_client(StdioServerParameters(
command="npx",
args=["-y", "chrome-devtools-mcp@latest", "--headless", "--isolated"]
)) as (read, write):
async with ClientSession(read, write) as session:
await session.initialize()
await session.call_tool("navigate", {"url": url, "waitUntil": "networkidle"})
dom_meta = await session.call_tool("evaluate", {
"expression": "JSON.stringify({len: document.documentElement.outerHTML.length, errors: window.__errors || []})"
})
client = AsyncAnthropic(
base_url="https://api.holysheep.ai/v1",
api_key=os.environ["ANTHROPIC