·

GitHub MCP với OpenCode

Cài đặt GitHub MCP trong OpenCode để AI agent có thể quản lý repository, pull request và issue ngay trong trình soạn thảo.

OpenCode là một coding agent chạy trong terminal, mã nguồn mở, được thiết kế để làm việc trực tiếp trong repo của bạn thay vì trong một IDE nặng nề. Điểm mạnh của OpenCode nằm ở việc nó cho phép bạn tự chọn model (Claude, GPT, Gemini, hay cả model chạy local qua Ollama) và tự do gắn thêm MCP server để mở rộng khả năng của agent. Khi bạn gắn GitHub MCP server vào OpenCode, agent không chỉ đọc/sửa code trong working directory mà còn có thể "chạm" trực tiếp vào GitHub — đọc issue, tạo pull request, comment, merge — tất cả từ cùng một phiên làm việc terminal. Bài này sẽ đi từ cài đặt, cấu hình, tới một ví dụ triage issue thực tế, và những hạn chế bạn cần lường trước khi đưa OpenCode + GitHub MCP vào quy trình làm việc hàng ngày.

Cài Đặt và Kết Nối GitHub MCP với OpenCode

Trước khi gắn GitHub MCP, bạn cần có OpenCode chạy được trên máy. Cài nhanh qua npm hoặc script cài đặt chính thức:

npm install -g opencode-ai

curl -fsSL https://opencode.ai/install | bash

opencode --version

OpenCode đọc cấu hình từ file opencode.json ở root của project (ưu tiên cấu hình theo từng repo) hoặc từ ~/.config/opencode/config.json (cấu hình toàn cục, áp dụng cho mọi project khi không có file cấu hình local). Cách tổ chức này rất hợp lý cho GitHub MCP: bạn có thể set một token dùng chung ở global config, rồi override scope/toolset riêng cho từng repo nhạy cảm.

GitHub MCP server chính thức (github/github-mcp-server) hỗ trợ hai kiểu chạy: local qua Docker (stdio transport) hoặc remote qua endpoint HTTP do GitHub host. OpenCode hỗ trợ cả hai kiểu này qua field type trong khối mcp.

Cách 1 — Local qua Docker (khuyến nghị khi bạn cần kiểm soát chặt token và audit log):

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "github": {
      "type": "local",
      "command": [
        "docker", "run", "-i", "--rm",
        "-e", "GITHUB_PERSONAL_ACCESS_TOKEN",
        "-e", "GITHUB_TOOLSETS=repos,issues,pull_requests,code_security",
        "ghcr.io/github/github-mcp-server"
      ],
      "environment": {
        "GITHUB_PERSONAL_ACCESS_TOKEN": "{env:GITHUB_TOKEN}"
      },
      "enabled": true
    }
  }
}

Cách 2 — Remote, dùng endpoint MCP do GitHub host (nhanh hơn, không cần Docker daemon):

{
  "mcp": {
    "github": {
      "type": "remote",
      "url": "https://api.githubcopilot.com/mcp/",
      "headers": {
        "Authorization": "Bearer {env:GITHUB_TOKEN}"
      },
      "enabled": true
    }
  }
}

Cú pháp {env:GITHUB_TOKEN} là cách OpenCode tham chiếu biến môi trường thay vì hard-code secret vào file JSON — đây là điểm bạn phải luôn tuân thủ, tuyệt đối không commit personal access token (PAT — token truy cập cá nhân) thẳng vào file cấu hình rồi push lên repo public.

Về PAT, hãy tạo fine-grained PAT (loại token phạm vi hẹp, gắn theo từng repo cụ thể) thay vì classic token toàn quyền. Chỉ cấp đúng permission cần dùng: Contents: Read and write, Issues: Read and write, Pull requests: Read and write. Nếu chỉ cần agent đọc thông tin (báo cáo, review), set thêm GITHUB_READ_ONLY=1 trong environment để chặn agent gọi bất kỳ tool có khả năng ghi (create/update/merge) — đây là lớp bảo vệ thứ hai, độc lập với scope của token.

Sau khi lưu file, chạy opencode trong repo, rồi gõ lệnh /mcp (hoặc kiểm tra qua panel công cụ) để xác nhận server github đã kết nối và liệt kê được toolset. Nếu không thấy tool nào xuất hiện, 90% nguyên nhân là do Docker image chưa pull được hoặc token thiếu quyền — kiểm tra log bằng opencode --log-level debug.

Mẹo: Đừng gắn toolset đầy đủ (GITHUB_TOOLSETS=all) ngay từ đầu. Bắt đầu với repos,issues,pull_requests — vừa đủ cho 90% workflow hàng ngày, vừa giảm số lượng tool schema mà model phải "nhìn" mỗi lần suy luận, giúp tool-calling chính xác hơn và tiết kiệm context window (cửa sổ ngữ cảnh).

Quản Lý Issues, Pull Requests và Repos từ OpenCode

Khi GitHub MCP đã kết nối, OpenCode có thể gọi trực tiếp các tool như list_issues, get_issue, create_issue, add_issue_comment, update_issue, list_pull_requests, get_pull_request_diff, create_pull_request, merge_pull_request. Bạn không cần biết tên tool để dùng — chỉ cần ra lệnh bằng ngôn ngữ tự nhiên, agent sẽ tự chọn tool phù hợp (đây chính là tool calling — khả năng model tự quyết định gọi hàm nào với tham số nào dựa trên mô tả tool).

Một vài prompt thực tế bạn có thể gõ ngay trong session OpenCode:

Liệt kê 20 issue đang open trong repo này, sắp xếp theo số comment giảm dần,
và cho tôi biết issue nào có khả năng là bug thật (không phải feature request).
Tạo một pull request từ branch hiện tại sang main, title theo convention
Conventional Commits, body liệt kê rõ: Summary, Changes, Testing steps.
Đừng merge, chỉ tạo draft PR.
Xem diff của PR #482, review theo checklist: có test mới không, có breaking
change ở public API không, có leak secret/credential trong code không.
Ghi kết quả review dưới dạng comment trên PR đó.

Vì OpenCode chạy trong terminal ngay tại working directory, agent có lợi thế lớn: nó có thể đối chiếu trực tiếp code local (qua git, file system) với dữ liệu GitHub MCP trả về (qua API), rồi tự đưa ra nhận định — ví dụ so sánh diff trên PR với branch local để phát hiện conflict trước khi bạn merge, việc mà một agent chỉ có quyền truy cập GitHub API thuần (không có local repo) không làm được.

Một pattern nên áp dụng: giới hạn agent theo từng session bằng cách nêu rõ phạm vi ngay trong prompt đầu tiên, ví dụ "chỉ thao tác trên repo org/service-payment, không đụng tới repo khác dù có quyền truy cập". Model đôi khi "hào phóng" gọi tool ngoài phạm vi nếu bạn không rào trước, đặc biệt khi PAT của bạn có quyền trên nhiều repo trong org.

Mẹo: Khi cần agent thao tác ghi (tạo issue, merge PR, xoá branch), luôn yêu cầu nó "dry-run" trước — in ra nội dung sẽ tạo/sửa để bạn duyệt bằng mắt, rồi mới ra lệnh xác nhận thực thi ở turn tiếp theo. Cách này tránh được phần lớn sự cố agent hành động sai ý do hiểu nhầm ngữ cảnh.

Ví Dụ Thực Chiến: Triage Issue Có AI Hỗ Trợ Trong OpenCode

Triage issue (phân loại, gắn nhãn, ưu tiên hoá issue mới) là công việc lặp lại, tốn thời gian, và rất phù hợp để giao cho agent — miễn là bạn kiểm soát được bước cuối. Dưới đây là quy trình từng bước bạn có thể chạy thật trong OpenCode.

Bước 1 — Thu thập issue chưa triage:

Lấy toàn bộ issue đang mở, chưa có label nào (unlabeled), được tạo trong
30 ngày gần nhất, trong repo org/mobile-app.

Agent gọi list_issues với filter tương ứng (state=open, labels rỗng), trả về danh sách kèm title, body, số comment, người tạo.

Bước 2 — Phân loại theo nội dung:

Với từng issue vừa lấy, đọc kỹ title + body và phân loại vào một trong các
nhãn: bug, feature-request, question, needs-more-info. Nếu report thiếu bước
reproduce, thiếu version app, đánh dấu needs-more-info. Trình bày kết quả
dạng bảng: #issue, tiêu đề rút gọn, nhãn đề xuất, lý do (1 câu).

Đây là bước quan trọng nhất: bạn buộc agent phải nêu lý do trước khi hành động. Việc này vừa tăng chất lượng phân loại (model "suy luận" chậm và có cấu trúc hơn khi phải giải thích), vừa cho bạn một bảng để review nhanh trước khi apply thật.

Bước 3 — Review và chỉnh tay (nếu cần):

Đọc bảng agent trả về, sửa lại vài dòng nếu thấy phân loại sai — ví dụ:

Issue #1204 thực ra là bug, không phải question — user chỉ diễn đạt vòng vo.
Cập nhật lại bảng với thông tin này trước khi áp dụng.

Bước 4 — Áp dụng label và comment giải thích:

Áp dụng label theo bảng đã chốt cho từng issue (dùng update_issue hoặc
add_issue_labels). Với các issue needs-more-info, thêm comment lịch sự yêu
cầu bổ sung: bước reproduce, version app, thiết bị/OS. Không đóng issue nào.

Agent lần lượt gọi update_issue (thêm label) và add_issue_comment (viết comment) cho từng issue. Vì bạn đã chốt bảng ở bước 3, phần này gần như không còn rủi ro — agent chỉ "thực thi cơ học" theo quyết định con người đã duyệt.

Bước 5 — Báo cáo tổng kết:

Tóm tắt lại: đã gắn label cho bao nhiêu issue, bao nhiêu issue cần thêm
thông tin, và liệt kê 3 issue có khả năng là bug nghiêm trọng nhất cần
escalate cho team lead.

Kết quả là bạn triage được vài chục issue trong 10-15 phút thay vì nửa ngày, mà vẫn giữ được điểm kiểm soát con người ở đúng chỗ cần thiết (bước 3) — đây chính là mô hình "human-in-the-loop" (con người tham gia vào vòng lặp quyết định) mà bất kỳ workflow agentic đưa vào production đều nên có.

Mẹo: Lưu lại prompt triage thành một file .opencode/prompts/triage-issues.md trong repo và load lại bằng lệnh tham chiếu file mỗi lần cần chạy, thay vì gõ lại từ đầu — vừa nhất quán giữa các lần chạy, vừa dễ tinh chỉnh dần theo thời gian khi bạn phát hiện agent phân loại sai một pattern nào đó.

Những Hạn Chế Cần Biết Của GitHub MCP Trong OpenCode

Trước khi đưa vào workflow chính thức, bạn cần biết rõ những giới hạn thực tế sau, để không đặt kỳ vọng sai:

  • Schema tool lớn ăn context window: GitHub MCP server expose khá nhiều tool (đặc biệt khi bật toolset all), mỗi tool có schema tham số riêng. Với model có context window nhỏ hoặc đang chạy local qua Ollama, lượng schema này chiếm đáng kể token, làm giảm phần ngân sách còn lại cho code và lịch sử hội thoại.
  • Độ tin cậy tool-calling phụ thuộc model: OpenCode cho phép chọn model tự do, nhưng không phải model nào cũng tool-call chính xác như Claude hay GPT-4-class. Với model nhỏ hơn, bạn sẽ gặp tình trạng agent gọi sai tool, truyền tham số thiếu, hoặc "ảo tưởng" ra số issue không tồn tại.
  • Diff lớn vượt giới hạn hiển thị: get_pull_request_diff trả nguyên diff dạng text. Với PR thay đổi hàng nghìn dòng, diff này có thể vượt quá phần context còn lại, khiến agent chỉ review được một phần PR mà không báo rõ là đã bị cắt.
  • Rate limit GitHub API: Cả hai chế độ (local Docker và remote) đều đi qua GitHub REST/GraphQL API, vẫn bị áp rate limit theo token (thường 5000 request/giờ cho PAT thông thường). Khi agent chạy loop liệt kê + xử lý hàng trăm issue liên tục, bạn có thể dính rate limit giữa chừng.
  • Không có OAuth device flow trong OpenCode: Khác với một số IDE tích hợp sẵn luồng đăng nhập GitHub bằng OAuth, OpenCode yêu cầu bạn tự tạo và quản lý PAT thủ công — tiện cho tự động hoá nhưng đòi hỏi bạn tự chịu trách nhiệm xoay token, thu hồi token khi rò rỉ.
  • Không có sandbox thực thi cho action nguy hiểm: Không có cơ chế "confirm trong UI" mặc định như một số IDE khác cho hành động ghi (merge, delete branch) — OpenCode dựa vào chính bạn kiểm soát qua prompt và qua giới hạn permission trên token/toolset.

Mẹo: Với các repo production quan trọng, hãy dùng riêng một PAT chỉ scope cho repo đó và luôn set GITHUB_TOOLSETS tối thiểu cần thiết, thay vì dùng chung một PAT "toàn năng" cho tất cả project — giảm thiệt hại tối đa nếu agent (hoặc bạn) lỡ tay ra lệnh sai phạm vi.

Mẹo

Dưới đây là những kinh nghiệm thực chiến rời rạc, không thuộc riêng một mục nào trên, nhưng rất đáng áp dụng khi dùng GitHub MCP với OpenCode hàng ngày:

  • Tách config theo môi trường: Giữ một opencode.json riêng cho môi trường "an toàn" (repo cá nhân, sandbox) với toolset đầy đủ để thử nghiệm, và một config khác nghiêm ngặt hơn cho repo công ty.
  • Bật logging khi mới làm quen: Chạy với opencode --log-level debug trong vài ngày đầu để quan sát chính xác agent gọi tool nào, với tham số gì — giúp bạn hiệu chỉnh prompt nhanh hơn nhiều so với đoán mò.
  • Đặt tên toolset rõ nghĩa trong prompt: Khi có nhiều MCP server cùng lúc (GitHub, filesystem, database...), luôn nhắc rõ "dùng GitHub MCP" trong prompt nếu tên tool có thể gây nhầm lẫn với tool khác cùng chức năng.
  • Version-pin Docker image: Đừng dùng tag latest cho ghcr.io/github/github-mcp-server trong môi trường CI hoặc workflow tự động — pin version cụ thể để tránh hành vi tool đổi khác sau một lần update image mà bạn không hay biết.

Mẹo: Trước khi tin tưởng giao một workflow agentic quan trọng (release, triage hàng loạt, merge tự động) cho OpenCode + GitHub MCP, hãy chạy thử trên một repo demo/fork trong ít nhất một tuần để hiểu rõ "tính khí" của cặp model + MCP server bạn đang dùng — mỗi model tool-call theo phong cách khác nhau, và chỉ kinh nghiệm thực tế mới cho bạn biết nó đáng tin đến đâu.