OpenCode (opencode.ai) là một AI coding agent chạy trên terminal (TUI - Text User Interface, giao diện dòng lệnh dạng tương tác), mã nguồn mở, cho phép bạn cắm thêm nhiều MCP (Model Context Protocol) server để mở rộng khả năng của agent. Khác với một số công cụ khác, OpenCode được cấu hình hoàn toàn qua file opencode.json, không có giao diện đồ họa để bấm "connect" — mọi thứ đều tường minh trong config. Điều này vừa là điểm mạnh (dễ version control, dễ chia sẻ giữa team) vừa là điểm cần lưu ý (bạn phải tự tay khai báo đúng cú pháp).
Trong bài này, chúng ta sẽ đi từ việc cài đặt Sentry MCP server vào OpenCode, cách đặt câu hỏi để truy vấn issue (lỗi được Sentry ghi nhận) và stack trace (dấu vết ngăn xếp lỗi, cho biết lỗi xảy ra ở đâu trong code), cho đến một ví dụ thực tế điều tra lỗi production, và cuối cùng là những giới hạn bạn cần biết trước khi đưa workflow này vào quy trình làm việc chính thức của team.
Installing and Connecting Sentry MCP to OpenCode
Vị trí file cấu hình
OpenCode đọc cấu hình MCP từ hai cấp:
- Project-level: file
opencode.jsonđặt tại thư mục gốc của project (cùng cấp với.git). Cấu hình ở đây chỉ áp dụng khi bạn chạyopencodetrong project đó — phù hợp khi Sentry project gắn với đúng codebase này. - Global-level: file
~/.config/opencode/opencode.json(trên Linux/macOS). Cấu hình ở đây áp dụng cho mọi project bạn mở bằng OpenCode — phù hợp nếu bạn muốn có sẵn Sentry MCP mọi lúc, không phải khai báo lại từng repo.
Nếu cả hai file đều khai báo cùng một MCP server, cấu hình project-level thường override (ghi đè) global-level. Khuyến nghị: để token/credential chung ở global config, còn URL hoặc project slug đặc thù thì khai báo ở project-level.
Cấu hình remote MCP (khuyến nghị cho Sentry Cloud)
Sentry cung cấp một remote MCP server (server chạy từ xa, không cần cài đặt local) tại https://mcp.sentry.dev/mcp. Đây là cách đơn giản nhất nếu bạn dùng Sentry SaaS (sentry.io):
{
"mcp": {
"sentry": {
"type": "remote",
"url": "https://mcp.sentry.dev/mcp",
"enabled": true
}
}
}
Khi chạy opencode, lần đầu tiên gọi tới server này, OpenCode sẽ cố gắng khởi động luồng xác thực OAuth (giao thức cấp quyền truy cập không cần chia sẻ mật khẩu trực tiếp) qua trình duyệt để bạn đăng nhập vào Sentry. Nếu môi trường của bạn không có trình duyệt (ví dụ đang SSH vào server, hoặc chạy trong CI), bạn nên dùng phương án token thủ công bên dưới thay vì phụ thuộc vào OAuth.
Cấu hình bằng auth token thủ công (self-hosted hoặc không có OAuth flow)
Nếu bạn dùng Sentry self-hosted (tự triển khai on-premise), hoặc môi trường không hỗ trợ OAuth qua trình duyệt, hãy tạo một auth token (mã xác thực dùng để chứng minh quyền truy cập API) từ Sentry: vào Settings → Auth Tokens, tạo token mới với scope tối thiểu gồm project:read, event:read, org:read (thêm event:write nếu bạn muốn agent cập nhật trạng thái issue).
Khai báo token qua biến môi trường thay vì hard-code trực tiếp vào file JSON:
{
"mcp": {
"sentry": {
"type": "remote",
"url": "https://mcp.sentry.dev/mcp",
"enabled": true,
"headers": {
"Authorization": "Bearer $SENTRY_AUTH_TOKEN"
}
}
}
}
Với Sentry self-hosted, đổi url thành endpoint MCP nội bộ của bạn, ví dụ https://sentry.internal.company.com/mcp.
Nếu bạn muốn chạy Sentry MCP dưới dạng local server (ví dụ dùng gói @sentry/mcp-server chạy qua npx) thay vì remote, cấu hình sẽ có dạng "type": "local":
{
"mcp": {
"sentry": {
"type": "local",
"command": ["npx", "-y", "@sentry/mcp-server"],
"environment": {
"SENTRY_AUTH_TOKEN": "{env:SENTRY_AUTH_TOKEN}",
"SENTRY_ORG": "your-org-slug"
},
"enabled": true
}
}
}
Luôn đặt SENTRY_AUTH_TOKEN như một biến môi trường của shell (ví dụ export trong .bashrc/.zshrc hoặc file .env được load riêng), tuyệt đối không commit token thẳng vào opencode.json nếu file này nằm trong repo được đẩy lên Git.
Kiểm tra kết nối thành công
Sau khi lưu config, khởi động lại phiên làm việc bằng lệnh opencode trong terminal. Có hai cách xác nhận MCP đã kết nối:
- Log khởi động: khi OpenCode start, nó in ra danh sách MCP server đã load. Tìm dòng dạng
mcp server "sentry" connectedhoặc tương tự — nếu thấy lỗifailed to connectthì kiểm tra lại URL/token. - Lệnh
/mcptrong TUI: gõ/mcpngay trong phiên chat của OpenCode để liệt kê các MCP server đang active kèm trạng thái (connected/disconnected) và danh sách tool mà server đó expose (công bố cho agent sử dụng), ví dụfind_issues,get_issue_details,search_events.
Mẹo: Nếu
/mcpbáo server "connected" nhưng danh sách tool trống, gần như chắc chắn token của bạn thiếu scope cần thiết. Vào lại Sentry, kiểm tra token có đủ quyềnproject:readvàevent:readhay chưa, rồi thử lại — không cần khởi động lại toàn bộ OpenCode, chỉ cần restart phiên chat.
Querying Sentry Issues and Stack Traces from OpenCode
Khi Sentry MCP đã connected, bạn không cần nhớ cú pháp Sentry API — chỉ cần diễn đạt bằng ngôn ngữ tự nhiên trong phiên chat của OpenCode, LLM (Large Language Model, mô hình ngôn ngữ lớn) sẽ tự quyết định gọi tool nào của MCP server để lấy dữ liệu.
Liệt kê các issue chưa xử lý
Prompt ví dụ:
Liệt kê giúp tôi 10 issue (lỗi được ghi nhận) chưa resolved
trong project "checkout-service", sắp xếp theo số lượng
event (sự kiện lỗi xảy ra) nhiều nhất trước.
OpenCode sẽ gọi một tool tương tự find_issues hoặc search_issues với tham số project slug, status filter (is:unresolved), và sort order. Output mẫu trong TUI:
Đã tìm thấy 10 issues (unresolved) trong checkout-service:
1. [CHECKOUT-142] TypeError: Cannot read properties of undefined
(reading 'total') — 1,204 events — last seen 2h ago
2. [CHECKOUT-98] PaymentGatewayTimeoutError — 312 events
— last seen 5h ago
3. [CHECKOUT-201] NullPointerException at OrderValidator.java:87
— 289 events — last seen 1d ago
...
Lấy chi tiết một issue cụ thể kèm stack trace
Prompt ví dụ:
Lấy chi tiết issue CHECKOUT-142, hiển thị đầy đủ stack trace
và breadcrumb (dấu vết các hành động/sự kiện trước khi lỗi xảy ra)
gần nhất.
Agent gọi tool dạng get_issue_details (hoặc get_issue tuỳ phiên bản MCP server) với issue ID, trả về gồm: tiêu đề lỗi, số lần xảy ra, môi trường (production/staging), stack trace đầy đủ theo từng frame (khung gọi hàm), và breadcrumb — chuỗi log/click/request trước thời điểm exception được ném ra.
Tương quan issue với trace ID
Với hệ thống có distributed tracing (theo dõi luồng request xuyên suốt nhiều service), bạn có thể yêu cầu OpenCode nối issue với trace (một chuỗi các span/request được Sentry hoặc APM ghi lại xuyên suốt một request):
Issue CHECKOUT-142 có trace ID nào đi kèm không? Nếu có,
lấy toàn bộ trace đó để xem request này đi qua những service nào
trước khi lỗi xảy ra ở checkout-service.
Agent sẽ trích trace ID từ event detail, sau đó gọi tiếp một tool tra cứu trace (ví dụ get_trace hoặc search_events lọc theo trace_id:...) để trả về toàn bộ hành trình request — hữu ích khi lỗi ở checkout-service thực ra bắt nguồn từ một service upstream (ví dụ inventory-service trả về payload sai định dạng).
| Nhu cầu | Prompt mẫu | Tool MCP thường được gọi |
|---|---|---|
| Danh sách issue chưa xử lý | "Liệt kê issue unresolved trong project X" | find_issues / search_issues |
| Chi tiết 1 issue | "Lấy chi tiết issue CHECKOUT-142" | get_issue_details |
| Stack trace + breadcrumb | "Cho tôi xem stack trace và breadcrumb của issue này" | get_issue_details, get_event |
| Tương quan theo trace | "Trace ID này đi qua service nào?" | get_trace / search_events |
| Lọc theo release | "Issue nào mới xuất hiện từ release v2.3.0?" | search_issues với filter release: |
Mẹo: Khi diễn đạt prompt, luôn nêu rõ project slug và khoảng thời gian (ví dụ "trong 24 giờ qua", "kể từ release v2.3.0"). MCP tool của Sentry cần tham số filter cụ thể; nếu bạn hỏi chung chung như "có lỗi gì không", agent dễ chọn nhầm project mặc định hoặc trả về dữ liệu quá rộng, làm loãng context window (giới hạn dung lượng văn bản mà LLM có thể xử lý trong một lượt).
Practical Example: Investigating a Production Error in OpenCode
Giả sử team bạn nhận được cảnh báo (alert) qua Slack: Sentry vừa ghi nhận issue mới CHECKOUT-142 — TypeError: Cannot read properties of undefined (reading 'total') tại checkout-service, tăng đột biến 1,200+ event chỉ trong 2 giờ, ảnh hưởng đến luồng thanh toán production. Dưới đây là luồng điều tra thực tế bằng OpenCode, rút gọn qua các lượt hội thoại.
Bước 1 — Lấy issue và stack trace
Bạn:
Lấy chi tiết issue CHECKOUT-142 trong project checkout-service,
kèm full stack trace và 10 breadcrumb gần nhất trước khi lỗi xảy ra.
OpenCode (sau khi gọi tool get_issue_details):
Issue: CHECKOUT-142
Title: TypeError: Cannot read properties of undefined (reading 'total')
Environment: production
First seen: 2026-07-09 08:14 UTC
Events: 1,204 (last 2h)
Affected users: 890
Stack trace (top frames):
at calculateOrderTotal (src/services/orderService.js:47)
at processCheckout (src/controllers/checkoutController.js:112)
at Router.handle (node_modules/express/lib/router/index.js:284)
Breadcrumbs (gần nhất → xa nhất):
[08:13:58] http.request POST /api/checkout status=200
[08:13:58] db.query SELECT * FROM carts WHERE id=? rows=1
[08:13:59] custom applyDiscountCode("SUMMER25")
[08:13:59] custom cart.summary = undefined
[08:13:59] exception TypeError at orderService.js:47
Bước 2 — Yêu cầu root cause analysis (phân tích nguyên nhân gốc rễ)
Bạn:
Dựa trên stack trace và breadcrumb này, phân tích root cause
(nguyên nhân gốc rễ) của lỗi giúp tôi. Nếu cần xem thêm code,
đọc file src/services/orderService.js.
OpenCode (đọc thêm file orderService.js trong repo local qua tool đọc file, kết hợp dữ liệu từ Sentry):
Phân tích:
Breadcrumb cho thấy ngay trước khi lỗi xảy ra, có bước
applyDiscountCode("SUMMER25") set cart.summary = undefined.
Trong orderService.js dòng 47:
function calculateOrderTotal(cart) {
return cart.summary.total * (1 - cart.discountRate);
}
Khi mã giảm giá SUMMER25 được áp dụng, một nhánh code khác
(applyDiscountCode) đang gán đè cart.summary = undefined thay vì
cart.summary = { total: ..., items: [...] }. Đây gần như chắc chắn
là bug trong applyDiscountCode, mới được merge vào release v2.3.0
(theo dữ liệu Sentry, issue chỉ xuất hiện từ release này).
Root cause: applyDiscountCode ghi đè toàn bộ cart.summary thay vì
chỉ cập nhật trường discountRate, khiến calculateOrderTotal gọi
.total trên undefined.
Bước 3 — Yêu cầu agent đề xuất patch
Bạn:
Đề xuất một patch để fix lỗi này, ưu tiên sửa tận gốc
ở applyDiscountCode chứ không patch phòng thủ ở calculateOrderTotal.
Cho tôi xem diff.
OpenCode:
Đọc thêm src/services/discountService.js... Tìm thấy nguyên nhân:
--- a/src/services/discountService.js
+++ b/src/services/discountService.js
@@ -22,7 +22,10 @@ function applyDiscountCode(cart, code) {
const discount = lookupDiscount(code);
- cart.summary = discount.rate;
+ cart.summary = {
+ ...cart.summary,
+ discountRate: discount.rate,
+ };
return cart;
}
Giải thích: dòng cũ gán thẳng discount.rate (một số) vào
cart.summary, ghi đè toàn bộ object. Patch giữ nguyên cart.summary
hiện có (spread ...cart.summary) và chỉ thêm/ghi đè trường
discountRate, để calculateOrderTotal vẫn truy cập được
cart.summary.total bình thường.
Đề xuất thêm: bổ sung unit test cho applyDiscountCode để đảm bảo
cart.summary.total không bị mất sau khi áp mã giảm giá — tránh
regression tương tự trong tương lai.
Bước 4 — Đóng vòng lặp
Sau khi review diff, bạn có thể yêu cầu OpenCode tạo commit, viết test, hoặc (nếu MCP server hỗ trợ) thử đánh dấu issue là "in progress"/gắn assignee ngay trong Sentry để team biết đang có người xử lý — phần này liên quan trực tiếp đến giới hạn được nói ở mục kế tiếp.
Mẹo: Luôn yêu cầu agent trích dẫn rõ dòng code và breadcrumb làm căn cứ cho root cause analysis, thay vì chấp nhận kết luận suông. Việc này giúp bạn (và reviewer) verify (xác minh) lại logic suy luận của agent trước khi merge patch, tránh trường hợp agent "đoán" sai nguyên nhân dù patch trông có vẻ hợp lý.
Known Limitations for Sentry MCP in OpenCode
So với Claude Code (một AI coding CLI khác cũng hỗ trợ MCP rất sâu), tích hợp Sentry MCP trên OpenCode hiện có một số giới hạn thực tế cần lưu ý trước khi đưa vào quy trình chính thức:
- OAuth và dynamic client registration (đăng ký client động, cơ chế cho phép app tự động đăng ký với authorization server mà không cần cấu hình thủ công trước) chưa thực sự trưởng thành. Trong nhiều môi trường (SSH, remote dev container, CI), luồng OAuth qua trình duyệt của OpenCode không kích hoạt được trơn tru như trên Claude Code. Giải pháp thực tế là bỏ qua OAuth, dùng auth token thủ công như đã hướng dẫn ở phần cài đặt.
- Ít UI xác nhận quyền (permission/approval) cho từng tool call. Claude Code thường có prompt hỏi "cho phép agent gọi tool X không?" trước mỗi lần thực thi hành động có tác động (ví dụ update issue). OpenCode hiện chưa có affordance (cơ chế tương tác) tương đương rõ ràng cho MCP tool calls — nghĩa là bạn cần review kỹ prompt/system config, và cân nhắc giới hạn scope của auth token (chỉ cấp quyền
read, không cấpwrite) nếu chưa tin tưởng hoàn toàn vào việc agent tự ý gọi tool ghi dữ liệu. - Tool
update_issue(hoặc tương đương) có thể không khả dụng hoặc bị giới hạn scope. Tuỳ phiên bản Sentry MCP server và scope của token, hành động như "resolve issue", "assign issue cho ai đó", "thêm comment vào issue" có thể không thực hiện được trực tiếp từ OpenCode. Khi đó, bạn cần thao tác thủ công qua Sentry UI hoặc gọi thẳng Sentry API. - Cộng đồng và tài liệu còn nhỏ. OpenCode là dự án mã nguồn mở tương đối trẻ so với Claude Code; khi gặp lỗi cấu hình MCP lạ, khả năng tìm thấy câu trả lời có sẵn trên GitHub issue hay diễn đàn thấp hơn — bạn thường phải tự debug bằng cách đọc log hoặc source code của OpenCode.
Fallback: resolve issue thủ công qua Sentry API
Khi update_issue không khả dụng qua MCP, bạn vẫn có thể resolve issue trực tiếp bằng curl (dùng cùng auth token đã tạo ở trên):
curl -X PUT \
"https://sentry.io/api/0/organizations/your-org-slug/issues/CHECKOUT-142/" \
-H "Authorization: Bearer $SENTRY_AUTH_TOKEN" \
-H "Content-Type: application/json" \
-d '{"status": "resolved"}'
Nếu muốn resolve kèm thông tin release đã fix (giúp Sentry tự động cảnh báo nếu lỗi tái xuất hiện ở release sau):
curl -X PUT \
"https://sentry.io/api/0/organizations/your-org-slug/issues/CHECKOUT-142/" \
-H "Authorization: Bearer $SENTRY_AUTH_TOKEN" \
-H "Content-Type: application/json" \
-d '{"status": "resolved", "statusDetails": {"inNextRelease": true}}'
Mẹo: Nếu team bạn phải dùng fallback
curlthường xuyên vì thiếu toolupdate_issue, hãy cân nhắc viết một script bash nhỏ (hoặc alias) wrap sẵn lệnh curl này với biến project/issue ID truyền vào — vừa nhanh hơn gõ tay, vừa tránh gõ sai token/scope mỗi lần. Đây cũng là bước đệm hợp lý trước khi Sentry MCP server bổ sung đầy đủ tool ghi dữ liệu (write) cho OpenCode trong các phiên bản sau.