Nếu bạn đã quen dùng Cursor để code hằng ngày, chắc hẳn bạn từng ước AI agent trong Cursor có thể tự query database, gọi API nội bộ, đọc issue trên Jira, hay search trong Notion — mà không cần bạn copy-paste dữ liệu qua lại. Đó chính xác là vấn đề MCP (Model Context Protocol) giải quyết. MCP là một chuẩn mở cho phép AI agent kết nối tới các "server" cung cấp tool (công cụ), resource (tài nguyên) và data nằm ngoài phạm vi model. Trong bài này, tôi sẽ đi qua toàn bộ quy trình cấu hình MCP server trong Cursor — từ việc tìm đúng chỗ trong UI, viết file mcp.json cho đúng, kích hoạt Agent Mode để dùng tool tự động, đến việc debug khi server "chết" hoặc tool không xuất hiện. Đây là kinh nghiệm thực tế từ việc setup MCP cho nhiều dự án khác nhau, không phải chỉ đọc doc rồi viết lại.
Truy cập bảng cấu hình MCP trong Cursor
Cursor có hai lớp cấu hình MCP: cấu hình toàn cục (global, áp dụng cho mọi project bạn mở) và cấu hình theo project (chỉ áp dụng khi bạn mở đúng project đó). Hiểu rõ hai lớp này ngay từ đầu sẽ tránh được rất nhiều nhầm lẫn về sau, kiểu "tôi đã cấu hình rồi mà sao project khác không thấy tool đâu".
Mở MCP Settings qua UI
Cách nhanh nhất để vào bảng cấu hình MCP:
- Mở Command Palette bằng
Cmd/Ctrl + Shift + P. - Gõ "MCP" — Cursor sẽ gợi ý lệnh View: Open MCP Settings (hoặc tương đương tùy version).
- Ngoài ra bạn có thể vào Cursor Settings (biểu tượng bánh răng, hoặc
Cmd/Ctrl + ,) rồi tìm mục MCP ở sidebar bên trái.
Trong màn hình MCP Settings, bạn sẽ thấy danh sách các server đã cấu hình, trạng thái kết nối (một chấm màu xanh/đỏ/vàng), và số lượng tool mà mỗi server expose ra. Đây là nơi đầu tiên bạn nên nhìn vào mỗi khi nghi ngờ có vấn đề — trước khi mò vào log.
Global config vs Project config
- Global: nằm ở
~/.cursor/mcp.json. Server khai báo ở đây available cho mọi project/workspace bạn mở bằng Cursor trên máy đó. - Project-level: nằm ở
<project-root>/.cursor/mcp.json. Chỉ áp dụng cho project cụ thể đó, và đây là cách được khuyến nghị khi server liên quan trực tiếp đến codebase (ví dụ: MCP server kết nối tới database riêng của service, hoặc tool đọc schema GraphQL của project).
Cursor sẽ merge cả hai file này lại — server ở project-level không "ghi đè" global mà là cộng thêm vào (trừ khi trùng tên, lúc đó project-level thường được ưu tiên). Với team, tôi luôn khuyên đưa mcp.json ở project-level vào Git (trừ phần chứa secret — sẽ nói ở phần sau) để cả team dùng chung một bộ tool nhất quán, tránh tình trạng "trên máy tôi chạy được".
Mẹo: Nếu bạn làm việc trên nhiều project có cùng nhu cầu (ví dụ server filesystem hoặc server Git dùng chung), đặt nó ở global config. Còn server đặc thù cho một service/API riêng, luôn đặt ở project-level để tránh "ô nhiễm" các project khác bằng tool không liên quan.
Thêm MCP server qua JSON config trong Cursor
Cursor đọc cấu hình MCP server theo cùng convention với Claude Desktop và nhiều MCP client khác: một object mcpServers, mỗi key là tên server, value là cách khởi chạy nó.
Cấu hình server chạy qua stdio (phổ biến nhất)
Đây là dạng phổ biến nhất — server chạy như một process con, giao tiếp qua standard input/output (stdio). Ví dụ cấu hình MCP server filesystem chính thức:
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"/Users/you/Projects/my-app"
]
}
}
}
Ví dụ khác, một MCP server kết nối tới Postgres để agent tự query schema/data:
{
"mcpServers": {
"postgres": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-postgres"],
"env": {
"DATABASE_URL": "postgresql://readonly_user:password@localhost:5432/mydb"
}
}
}
}
Lưu ý quan trọng: field env ở đây là environment variable truyền cho process của MCP server, không phải secret của Cursor. Nếu file này được commit vào Git, bạn đang leak credential. Cách xử lý tôi hay dùng trong team:
- Với project-level
mcp.json: chỉ commit phần khung, để value thật rỗng hoặc dùng placeholder, rồi mỗi dev tự điền vào bản local không commit (thêm.cursor/mcp.jsonvào.gitignorenếu cần), hoặc - Trỏ
envtới một script đọc từ secret manager thay vì hard-code giá trị.
Cấu hình server chạy qua SSE / HTTP (remote server)
Nếu MCP server là một service chạy remote (không phải process local), bạn cấu hình theo dạng url thay vì command:
{
"mcpServers": {
"internal-api": {
"url": "https://mcp.internal.company.com/sse",
"headers": {
"Authorization": "Bearer YOUR_TOKEN_HERE"
}
}
}
}
Dạng này dùng cho các MCP server team tự host (ví dụ expose API nội bộ, hệ thống ticket, hay data warehouse) mà không muốn mỗi dev phải tự chạy process local.
Thêm server qua UI
Ngoài việc edit JSON tay, bạn cũng có thể vào MCP Settings, bấm Add new MCP Server, Cursor sẽ hiện form nhập tên, command/URL, args, env — form này thực chất chỉ là giao diện ghi lại vào đúng file mcp.json phía sau. Tôi thường vẫn thích edit JSON trực tiếp vì dễ review qua Git diff và copy giữa các project hơn.
Sau khi lưu file, Cursor sẽ tự động thử khởi động server. Nếu không thấy trạng thái cập nhật, bấm nút refresh/reload cạnh server đó trong MCP Settings.
Mẹo: Đặt tên server ngắn gọn, mô tả đúng chức năng (
postgres-readonly,jira-search) — vì tên này sẽ hiển thị trong danh sách tool mà agent gọi, giúp bạn dễ trace log hơn khi có 5-6 server cùng chạy.
Sử dụng Cursor Agent Mode với custom MCP tool đã bật
Có cấu hình MCP thôi chưa đủ — bạn cần biết cách để Agent Mode thực sự dùng các tool đó trong lúc làm việc.
Bật Agent Mode
Trong composer/chat panel của Cursor, chọn mode Agent (thường là dropdown ở góc, có các mode như Ask, Edit, Agent). Agent Mode cho phép model tự quyết định gọi tool nào, đọc file nào, chạy command nào — thay vì chỉ trả lời một lượt.
Khi bạn mở panel Agent, nếu MCP server đã connect thành công, bạn sẽ thấy icon tool (thường hình cái búa/cờ lê) hiển thị số lượng tool available. Bấm vào đó để xem danh sách tool cụ thể từ mỗi server, và bạn có thể tắt/mở từng tool riêng lẻ nếu không muốn agent dùng một tool nào đó (ví dụ tool delete_file từ server filesystem — cân nhắc tắt nếu bạn lo agent tự ý xóa nhầm).
Viết prompt để agent chủ động gọi MCP tool
Agent sẽ tự quyết định khi nào cần gọi tool dựa trên description của tool đó và câu hỏi của bạn — nhưng prompt rõ ràng giúp agent chọn đúng tool nhanh hơn, giảm số lượt "dò". Vài ví dụ prompt thực tế tôi hay dùng:
Dùng tool postgres, kiểm tra schema của bảng `orders` và `order_items`,
rồi viết cho tôi một Django QuerySet lấy tổng doanh thu theo từng
tháng trong năm 2025, group theo trạng thái order.
Query MCP server jira-search để lấy toàn bộ ticket đang gán cho tôi
có label "bug" và trạng thái "In Progress". Tóm tắt lại theo mức độ
ưu tiên, rồi đề xuất thứ tự nên fix trước.
Trước khi sửa hàm `calculate_discount` trong file này, dùng MCP
filesystem tool để đọc toàn bộ các file trong thư mục `pricing/`
để hiểu context, sau đó đề xuất thay đổi có backward-compatible
với API hiện tại không.
Với các tool có khả năng "ghi" (write) — như update Jira ticket, xóa file, chạy migration — Cursor sẽ hỏi xác nhận trước khi thực thi (permission prompt), trừ khi bạn đã tick "Always allow" cho tool/server đó. Với môi trường production hoặc dữ liệu nhạy cảm, tôi khuyên không bật always-allow cho các tool có side-effect; luôn review từng lệnh gọi.
Mẹo: Nếu agent liên tục không tự gọi đúng tool bạn mong đợi, thử nhắc trực tiếp tên tool trong prompt (ví dụ "dùng tool
search_issues"). Cursor Agent Mode ưu tiên tool được nhắc tên rõ ràng hơn là để model tự suy luận từ description mơ hồ.
Debug các vấn đề kết nối MCP trong Cursor
Đây là phần mà hầu như ai setup MCP cũng phải trải qua ít nhất một lần. Dưới đây là các lỗi thường gặp nhất và cách tôi xử lý theo thứ tự ưu tiên.
Server không start được (status màu đỏ/vàng)
Nguyên nhân phổ biến nhất: command không tìm thấy binary, hoặc thiếu dependency.
- Mở MCP Settings, xem log/error message ngay cạnh server (Cursor thường hiện tooltip hoặc panel log khi click vào status).
- Thử chạy chính xác
command+argsđó trực tiếp trong terminal của bạn:
bash npx -y @modelcontextprotocol/server-postgres
Nếu lệnh này lỗi ngoài terminal, nó cũng sẽ lỗi trong Cursor — vì Cursor chỉ spawn process với đúng command bạn khai báo. - Kiểm tra Cursor có dùng đúng PATH không. Trên macOS, app GUI đôi khi không load
.zshrc/.bash_profilenhư terminal, dẫn đến không tìm thấynode/npx. Cách khắc phục: dùng full path tới binary trongcommand(ví dụ/usr/local/bin/npxhoặc kết quả củawhich npx).
Tool không xuất hiện trong danh sách dù server "connected"
Server hiện trạng thái xanh (đã connect) nhưng bấm vào icon tool lại không thấy tool nào, hoặc thiếu tool bạn mong đợi:
- Kiểm tra xem server có thực sự implement đúng phần
tools/listcủa MCP spec không — một số server custom viết thiếu handler này. - Reload lại Cursor window (
Cmd/Ctrl + Shift + P→ "Reload Window"). MCP client cache danh sách tool tại thời điểm connect; nếu bạn thêm tool mới vào server sau khi đã connect, Cursor không tự refresh. - Xem log chi tiết hơn qua Developer Tools của Cursor (
Help→Toggle Developer Tools), tab Console, filter theo "mcp" để thấy raw JSON-RPC message trao đổi giữa Cursor và server.
Permission prompt hiện liên tục hoặc không hiện
- Nếu prompt hiện liên tục dù bạn đã bấm "Always allow": kiểm tra bạn có đang sửa
mcp.jsonvà server bị restart liên tục không — mỗi lần server "id" thay đổi (do restart), permission cache có thể không match. - Nếu bạn muốn thấy prompt nhưng agent lại tự chạy tool có side-effect mà không hỏi: kiểm tra lại trong MCP Settings xem tool đó có đang bị set "always allow" từ trước (có thể do bấm nhầm) hay không, và revoke lại.
Vấn đề riêng của stdio vs SSE
- stdio: lỗi thường liên quan tới process — command không chạy được, thiếu quyền exec, hoặc server crash ngay sau khi start (thử chạy tay để xem exception). Log của server thường đổ ra
stderr, Cursor có capture lại phần này trong panel log. - SSE/HTTP: lỗi thường liên quan network — sai URL, thiếu header auth, server chặn CORS, hoặc timeout do server ở sau VPN/firewall mà máy bạn chưa connect VPN. Test nhanh bằng
curltới endpoint SSE để loại trừ vấn đề phía Cursor:
bash curl -N -H "Authorization: Bearer YOUR_TOKEN_HERE" https://mcp.internal.company.com/sse
Nếucurlcũng treo hoặc trả lỗi, vấn đề nằm ở server/network, không phải ở cấu hình Cursor.
Mẹo: Luôn giữ một MCP server "tham chiếu" đơn giản (ví dụ server filesystem chính thức) đã biết chắc chạy tốt. Khi nghi ngờ lỗi do Cursor hay do server cụ thể, thử tắt hết server khác, chỉ để server tham chiếu — nếu nó vẫn chạy bình thường, vấn đề chắc chắn nằm ở server bạn vừa thêm, không phải ở Cursor.
Mẹo
Một vài kinh nghiệm tổng hợp sau nhiều lần setup MCP cho các project khác nhau trong Cursor:
Mẹo: Đừng thêm quá nhiều MCP server cùng lúc vào một project. Mỗi tool thêm vào đều làm tăng độ dài của tool description trong context, và model có thể chọn nhầm tool khi có quá nhiều lựa chọn tương tự nhau. Chỉ giữ những server thực sự cần cho workflow hiện tại.
Mẹo: Với server tự viết (custom MCP server), luôn viết description tool càng cụ thể càng tốt — mô tả rõ input/output, ví dụ khi nào nên dùng tool này. Agent Mode chọn tool dựa trên description này, description mơ hồ dẫn đến agent gọi sai tool hoặc bỏ qua tool đúng.
Mẹo: Version của MCP server package cũng quan trọng — dùng
npx -y @package@latestcó thể khiến behavior thay đổi bất ngờ giữa các lần chạy do server auto-update. Pin version cụ thể (@package@1.2.0) cho môi trường team để đảm bảo mọi người dùng chung một hành vi.Mẹo: Khi share
mcp.jsonproject-level qua Git, luôn kèm một filemcp.json.examplehoặc comment hướng dẫn trong README về các biếnenvcần điền, để onboard thành viên mới nhanh hơn mà không lộ secret thật.Mẹo: Nếu bạn làm việc với nhiều MCP server có tool trùng tên chức năng (ví dụ hai server đều có tool
search), đặt tên server rõ ràng và cân nhắc tắt bớt tool không cần thiết trong panel Agent — vừa giảm nhiễu, vừa giúp model chọn đúng tool nhanh hơn, tiết kiệm cả token trong context window (cửa sổ ngữ cảnh) lẫn thời gian phản hồi.