·

Tiếng Việt: Puppeteer MCP With Opencode

Puppeteer MCP With Opencode

OpenCode là một AI coding agent CLI (công cụ dòng lệnh chạy agent AI hỗ trợ lập trình) mã nguồn mở, chạy hoàn toàn trong terminal và có triết lý tương tự Claude Code, nhưng điểm khác biệt lớn nhất là OpenCode cho phép bạn cắm vào nhiều LLM (large language model) provider khác nhau — từ Anthropic, OpenAI, đến các model chạy local qua Ollama. Nhờ kiến trúc mở này, OpenCode hỗ trợ MCP (Model Context Protocol) server ngay trong file cấu hình, và Puppeteer MCP là một trong những server hữu ích nhất khi bạn muốn agent tự tay mở trình duyệt, chụp màn hình, và soi lỗi frontend thay vì bạn phải làm thủ công.

Bài viết này sẽ đi từng bước: cài đặt Puppeteer MCP vào OpenCode, dùng agent để tái hiện và debug lỗi rendering (hiển thị giao diện), viết prompt cho các kịch bản UI automation / QA test, và cuối cùng là những giới hạn thực tế bạn cần biết trước khi đưa quy trình này vào công việc hàng ngày.

Installing and Connecting Puppeteer MCP to OpenCode

OpenCode đọc cấu hình MCP server từ file opencode.json hoặc opencode.jsonc (bản có hỗ trợ comment) đặt ở thư mục gốc project, hoặc ở config global (~/.config/opencode/opencode.json) nếu bạn muốn dùng chung cho mọi project.

Bước 1: Kiểm tra Node.js và cài Puppeteer MCP server

Puppeteer MCP server phổ biến nhất chạy qua npx, nên bạn không cần cài global trước — OpenCode sẽ tự động tải khi cần. Tuy vậy nên đảm bảo Node.js >= 18 đã có sẵn:

node -v
npx -v

Bước 2: Thêm cấu hình MCP vào opencode.jsonc

Mở (hoặc tạo mới) file opencode.jsonc ở root project, thêm block mcp như sau:

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "puppeteer": {
      "type": "local",
      "command": ["npx", "-y", "@modelcontextprotocol/server-puppeteer"],
      "environment": {
        "PUPPETEER_LAUNCH_OPTIONS": "{\"headless\": false, \"defaultViewport\": {\"width\": 1440, \"height\": 900}}"
      },
      "enabled": true
    }
  }
}

Vài lưu ý quan trọng khi viết config:

  • command là mảng (array), phần tử đầu là executable, phần sau là args — khác với một số tool khác dùng command + args tách riêng, nên nếu bạn copy config từ Claude Code/Cursor thì cần chuyển đổi format cho đúng schema OpenCode.
  • environment (không phải env) là key OpenCode dùng để truyền biến môi trường (environment variable) vào MCP server process — dễ gõ nhầm nếu bạn quen tay với format khác.
  • enabled: true là bắt buộc trong một số phiên bản OpenCode, mặc định server có thể bị tắt nếu thiếu field này.
  • Nếu muốn chạy headless (không hiện cửa sổ trình duyệt) để tiết kiệm tài nguyên trên máy CI/server, đổi "headless": false thành "headless": true hoặc "new".

Bước 3: Verify server đã load

Chạy OpenCode và gọi lệnh kiểm tra MCP status:

opencode

Trong phiên làm việc, gõ lệnh:

/mcp

hoặc dùng flag khi khởi động để in log chi tiết:

opencode --log-level debug

Nếu server load thành công, bạn sẽ thấy puppeteer xuất hiện trong danh sách MCP server với trạng thái connected, kèm danh sách tools nó expose ra (như puppeteer_navigate, puppeteer_screenshot, puppeteer_click, puppeteer_evaluate...). Nếu thấy trạng thái error hoặc disconnected, thường là do:

  • Sai cú pháp JSON (thiếu dấu phẩy, ngoặc) — dùng jsonc để dễ debug hơn vì cho phép comment.
  • Chrome/Chromium chưa được Puppeteer tải về lần đầu — chạy thử npx puppeteer browsers install chrome trước.
  • Máy chạy trong môi trường không có display (headless server) nhưng config lại để headless: false — sẽ crash ngay khi khởi động browser.

Lưu ý về sự khác biệt giữa các LLM backend

Vì OpenCode cho phép chọn model backend tùy ý (Claude, GPT, Gemini, hay model local qua Ollama), khả năng gọi tool (tool-calling) của MCP server sẽ khác nhau đáng kể tùy model bạn chọn. Các model mạnh về function calling như Claude hoặc GPT-4 class thường gọi đúng tool và parse kết quả JSON ổn định; một số model nhỏ hơn hoặc chạy local có thể gọi sai tham số, hoặc "quên" gọi tool mà tự bịa kết quả. Nên test thử một tác vụ đơn giản (ví dụ chụp screenshot của localhost:3000) trước khi giao việc phức tạp cho agent.

Mẹo: Khi mới cấu hình, hãy yêu cầu OpenCode thực hiện một task cực đơn giản trước — ví dụ "navigate to https://example.com và chụp screenshot" — để xác nhận cả kết nối MCP lẫn khả năng tool-calling của model đang chọn đều hoạt động ổn, trước khi giao các task debug phức tạp hơn.

Letting the OpenCode Agent Reproduce and Debug Frontend Rendering Issues

Một trong những giá trị lớn nhất của Puppeteer MCP không phải là tự động hoá test, mà là biến OpenCode thành một "cặp mắt" thực sự nhìn thấy trang web đang chạy — thay vì chỉ đọc code tĩnh. Khi có bug về rendering (CSS vỡ layout, icon bị thiếu, element bị đè lên nhau), thay vì bạn tự mở DevTools, agent có thể tự mở trình duyệt, chụp ảnh, so sánh, và đọc console log để tìm nguyên nhân.

Quy trình debug điển hình

  1. Agent navigate đến dev URL (thường là localhost với port dev server).
  2. Chụp screenshot toàn trang hoặc theo viewport cụ thể.
  3. So sánh bố cục thực tế với mô tả/kỳ vọng (hoặc ảnh reference nếu có).
  4. Dùng puppeteer_evaluate để chạy JavaScript, đọc getComputedStyle, kiểm tra DOM (Document Object Model — cây cấu trúc của trang HTML) tree.
  5. Đọc console error/warning để tìm exception JS gây layout sai.
  6. Đối chiếu với source code frontend để đề xuất fix.

Ví dụ prompt đầy đủ

Tôi đang gặp lỗi hiển thị trên trang dashboard tại http://localhost:3000/dashboard.
Layout dùng CSS grid nhưng các card thống kê (stat card) đang bị chồng lên nhau
thay vì xếp thành 3 cột như thiết kế.

Hãy thực hiện các bước sau bằng Puppeteer MCP:

1. Navigate tới http://localhost:3000/dashboard, đợi network idle.
2. Set viewport 1440x900, chụp screenshot full page, lưu vào ./debug/dashboard-actual.png.
3. Dùng puppeteer_evaluate để lấy computed style của phần tử có class
   `.stats-grid` và tất cả các `.stat-card` con của nó — in ra
   display, grid-template-columns, gap, width, position.
4. Kiểm tra xem có class CSS nào bị trùng tên hoặc bị override bởi
   một stylesheet khác không (kiểm tra qua document.styleSheets nếu cần).
5. Đọc console log/error trong quá trình load trang — báo cáo nếu có
   warning liên quan đến CSS-in-JS hoặc lỗi tải font/icon.
6. Kiểm tra xem có icon nào bị thiếu (broken image icon hoặc 404)
   bằng cách list toàn bộ request ảnh/svg có status != 200.
7. So sánh kết quả với mô tả thiết kế: 3 cột, mỗi card cao 120px,
   khoảng cách (gap) 16px.
8. Tổng hợp: nguyên nhân gốc rễ là gì (thiếu class, sai breakpoint,
   xung đột CSS, hay thiếu import stylesheet), và đề xuất đoạn code
   sửa cụ thể trong file CSS/component liên quan.

Với prompt chi tiết như trên, agent không chỉ "đoán" mà có dữ liệu thực (computed style, console log, danh sách request lỗi) để đưa ra chẩn đoán chính xác — ví dụ phát hiện grid-template-columns bị một utility class Tailwind override thành 1fr do thứ tự import CSS sai, hoặc icon bị vỡ vì đường dẫn asset build sai trong môi trường dev.

Một số kỹ thuật nâng cao

  • Yêu cầu agent chụp screenshot ở nhiều breakpoint (mobile, tablet, desktop) để phát hiện lỗi responsive.
  • Yêu cầu agent bật --slowMo hoặc chờ animation kết thúc trước khi chụp, tránh chụp nhầm frame giữa transition.
  • Dùng puppeteer_evaluate để inject đoạn script highlight border đỏ quanh các element có overflow, giúp nhìn nhanh phần tử vỡ layout trong screenshot.

Mẹo: Đừng chỉ nhờ agent "chụp screenshot rồi tự nhìn" — hãy yêu cầu nó dùng puppeteer_evaluate để trích xuất computed style dưới dạng text/JSON. Text luôn đáng tin cậy hơn việc suy diễn từ hình ảnh, đặc biệt khi model backend không có khả năng vision tốt.

Running UI Automation and QA Test Scenarios in OpenCode with Puppeteer MCP

Ngoài debug rendering, Puppeteer MCP còn cực kỳ hữu dụng để chạy các kịch bản UI automation nhiều bước — mô phỏng hành vi người dùng thật, điền form, xử lý edge case, và kiểm tra luồng nghiệp vụ end-to-end mà không cần viết một dòng script Playwright/Selenium nào.

Ví dụ prompt: kiểm thử luồng đăng ký tài khoản

Hãy chạy test luồng đăng ký tài khoản trên http://localhost:3000/signup
bằng Puppeteer MCP theo các bước sau:

1. Navigate đến /signup.
2. Điền form với dữ liệu hợp lệ:
   - Email: qa.test+opencode@example.com
   - Password: Test@12345
   - Confirm Password: Test@12345
3. Click nút "Sign up" và chờ điều hướng đến /onboarding.
4. Chụp screenshot trang /onboarding để xác nhận đăng ký thành công.
5. Sau đó, thử lại luồng với các edge case sau, mỗi case chụp
   screenshot phần thông báo lỗi:
   a. Email không hợp lệ (thiếu @)
   b. Password và Confirm Password không khớp
   c. Password ngắn hơn 8 ký tự
   d. Submit form khi để trống tất cả field
6. Với mỗi edge case, kiểm tra thông báo lỗi có hiển thị đúng field
   tương ứng không, và có bị lỗi layout (đè lên input khác) không.
7. Tổng hợp kết quả dưới dạng bảng: Case | Kỳ vọng | Thực tế | Pass/Fail.

Cách viết prompt như trên giúp agent tự chạy một bộ test case nhỏ nhưng đầy đủ happy path lẫn edge case, và tự tổng hợp báo cáo — rất phù hợp cho QA muốn nhanh chóng smoke-test trước khi release mà chưa kịp viết automation script chính thức.

Bảng các Puppeteer MCP action thường dùng

Action / Tool Mục đích Ví dụ dùng trong QA
puppeteer_navigate Điều hướng tới URL Mở trang cần test
puppeteer_screenshot Chụp ảnh toàn trang hoặc element So sánh UI, lưu bằng chứng lỗi
puppeteer_click Click vào element theo selector Bấm nút submit, mở dropdown
puppeteer_fill / puppeteer_type Điền giá trị vào input/textarea Điền form đăng ký, tìm kiếm
puppeteer_select Chọn option trong <select> Test dropdown chọn quốc gia, ngôn ngữ
puppeteer_hover Di chuột qua element Test tooltip, menu hover
puppeteer_evaluate Chạy JS tuỳ ý trong context trang Đọc DOM, computed style, localStorage
puppeteer_pdf (nếu server hỗ trợ) Xuất trang thành PDF Test tính năng export/in ấn

Kỹ thuật viết prompt cho kịch bản nhiều bước

  • Luôn nêu rõ selector hoặc mô tả visual của element (ví dụ "nút có text 'Sign up'") thay vì giả định agent tự đoán đúng CSS selector.
  • Chia nhỏ kịch bản thành từng bước có số thứ tự — agent theo dõi tiến trình tốt hơn nhiều so với một đoạn văn dài không cấu trúc.
  • Yêu cầu agent dừng lại và báo cáo ngay khi gặp lỗi bất ngờ (ví dụ element không tìm thấy), thay vì cố gắng "đoán" bước tiếp theo — tránh test chạy sai mà không ai biết.
  • Với luồng cần đăng nhập trước, cân nhắc cho agent set cookie/localStorage trực tiếp qua puppeteer_evaluate thay vì login lại từ đầu mỗi lần test, tiết kiệm thời gian.

Mẹo: Khi test nhiều edge case liên tiếp, hãy yêu cầu agent reload lại trang (hoặc reset state) trước mỗi case để tránh state cũ (như thông báo lỗi case trước) làm nhiễu kết quả kiểm tra của case sau.

Known Limitations for Puppeteer MCP Frontend Debugging in OpenCode

Puppeteer MCP trong OpenCode là công cụ mạnh nhưng không hoàn hảo. Vì OpenCode hỗ trợ đa dạng LLM backend, một số giới hạn ở đây không đến từ Puppeteer MCP mà từ chính sự khác biệt giữa các model — điều mà người dùng Claude Code hay Cursor (vốn gắn chặt với model của Anthropic/OpenAI) ít gặp phải hơn.

Giới hạn Biểu hiện thực tế Cách khắc phục
Tool-calling không đồng nhất giữa các provider Model nhỏ/local có thể gọi sai tham số tool, hoặc bịa kết quả thay vì gọi thật Ưu tiên dùng model có function calling tốt (Claude, GPT-4 class) cho các task liên quan browser automation; test kỹ trước khi tin tưởng model yếu hơn
Context window (giới hạn bộ nhớ ngữ cảnh) bị tràn khi dump DOM lớn Trang phức tạp (dashboard nhiều component) khiến DOM dump hàng chục nghìn dòng, làm agent bị cắt context hoặc trả lời lan man Yêu cầu agent chỉ lấy computed style/DOM của một selector cụ thể thay vì dump toàn bộ document.body.outerHTML
Khả năng đọc ảnh (vision) khác nhau tuỳ model Một số model backend không có khả năng phân tích hình ảnh, hoặc phân tích sai chi tiết nhỏ trong screenshot Kết hợp screenshot với dữ liệu text (computed style, DOM attributes) thay vì chỉ dựa vào việc "nhìn" ảnh
Screenshot xử lý không ổn định Ảnh trả về có thể bị nén, resize, hoặc không hiển thị đúng trong một số client UI của OpenCode Lưu screenshot ra file và yêu cầu agent đọc lại bằng đường dẫn file thay vì chỉ nhận base64 trong response
Session/state không được giữ giữa các lần gọi Mỗi lần agent gọi lại tool có thể mở tab/browser instance mới, mất login state hoặc cookie đã set trước đó Yêu cầu agent gom nhiều thao tác vào một chuỗi lệnh liên tục thay vì tách rời; hoặc set lại cookie/localStorage đầu mỗi phiên
Vòng lặp lặp-thử chậm hơn IDE tích hợp sẵn So với Cursor/Claude Code có UI xem trực tiếp, OpenCode CLI thuần terminal khiến việc xem lại screenshot, log mất thêm bước mở file Cấu hình sẵn thư mục output cố định cho screenshot, dùng image viewer song song để xem nhanh kết quả

Ngoài bảng trên, một điểm cần lưu ý là độ ổn định của MCP server phụ thuộc nhiều vào phiên bản Puppeteer/Chromium được npx tải về — việc tự động cập nhật đôi khi gây ra thay đổi hành vi bất ngờ (ví dụ selector hoạt động hôm trước bỗng lỗi hôm sau vì Chromium update). Nên cân nhắc pin version cụ thể trong command nếu bạn cần một pipeline QA ổn định lâu dài, ví dụ @modelcontextprotocol/server-puppeteer@1.2.3 thay vì để version mở.

Mẹo: Nếu bạn cần kết quả debug/QA đáng tin cậy cho công việc quan trọng, hãy chốt (pin) rõ model backend và version của Puppeteer MCP server trong config, thay vì để "auto-latest" — tính nhất quán giữa các lần chạy quan trọng hơn việc luôn dùng bản mới nhất.