3 giờ sáng thứ Sáu, tôi ngồi trước màn hình với một tách cà phê đã nguội. Hệ thống RAG nội bộ mà team mình phải bàn giao cho phòng pháp chế của một tập đoàn tài chính đang "sống dở chết dở": 47 tài liệu PDF hợp đồng, hơn 12.000 dòng log audit, và một database PostgreSQL chứa metadata khách hàng cần truy vấn bằng ngôn ngữ tự nhiên thay vì SQL thuần. Cursor IDE thì mạnh, nhưng mặc định nó không "biết" cách nói chuyện với Postgres của tôi. Bài viết này là ghi chú từ chính cuộc giải cứu đó — cấu hình MCP Server để biến Cursor thành một trợ lý AI có thể đọc schema, chạy query, và đề xuất tối ưu hóa index trực tiếp trong editor.
MCP Server là gì và vì sao dự án RAG cần nó?
Model Context Protocol (MCP) là chuẩn mở do Anthropic khởi xướng, cho phép một LLM giao tiếp hai chiều với công cụ ngoài — database, file system, API — thông qua một server trung gian. Với dự án RAG, lợi ích rõ ràng:
- AI có thể
SELECTtrực tiếp bảngdocuments,embeddingsmà không cần copy-paste schema. - Giảm sai sót khi LLM "tưởng tượng" cột không tồn tại (hallucination).
- Dev workflow liền mạch: viết prompt ở ô chat, nhận query chạy được ở terminal ngay bên cạnh.
Để mọi thứ vận hành mượt mà, mình dùng HolySheep AI làm backend suy luận. Với tỷ giá ¥1 = $1 (tiết kiệm hơn 85% so với OpenAI), hỗ trợ thanh toán WeChat/Alipay, độ trễ dưới 50ms, đây là lựa chọn hợp lý cho team phải chạy agent liên tục. Giá tham khảo 2026/MTok: GPT-4.1 $8, Claude Sonnet 4.5 $15, Gemini 2.5 Flash $2.50, DeepSeek V3.2 $0.42 — mình chọn DeepSeek V3.2 để cân bằng giữa chất lượng embedding context và chi phí.
Điều kiện tiên quyết
- Cursor IDE phiên bản 0.42+ (hỗ trợ MCP ổn định).
- Node.js 18 trở lên, đã cài
npmhoặcpnpm. - PostgreSQL 14+ đang chạy, có thông tin host/port/user/password.
- Một API key từ HolySheep AI — đăng ký là nhận tín dụng miễn phí, đủ để test 500+ request đầu tiên.
Bước 1 — Tạo MCP Server kết nối PostgreSQL
Mình dùng package @modelcontextprotocol/server-postgres (do cộng đồng MCP phát triển). Khởi tạo thư mục và cài đặt:
mkdir cursor-pg-mcp && cd cursor-pg-mcp
npm init -y
npm install @modelcontextprotocol/server-postgres pg dotenv
Tạo file .env để giữ thông tin nhạy cảm (đừng commit lên Git):
# .env — thay bằng giá trị thật của bạn
PG_HOST=127.0.0.1
PG_PORT=5432
PG_DATABASE=rag_legal
PG_USER=rag_reader
PG_PASSWORD=MatKhauRatManh_2026
HOLYSHEEP_API_KEY=YOUR_HOLYSHEEP_API_KEY
HOLYSHEEP_BASE_URL=https://api.holysheep.ai/v1
Tiếp theo, viết server.js — đây là "trái tim" của MCP server, vừa expose schema vừa chấp nhận query an toàn (chỉ SELECT, chặn mọi thứ có DROP/DELETE/INSERT):
import { Server } from "@modelcontextprotocol/server-postgres";
import pg from "pg";
import "dotenv/config";
const pool = new pg.Pool({
host: process.env.PG_HOST,
port: Number(process.env.PG_PORT),
database: process.env.PG_DATABASE,
user: process.env.PG_USER,
password: process.env.PG_PASSWORD,
max: 10,
idleTimeoutMillis: 30_000,
});
const FORBIDDEN = /\b(insert|update|delete|drop|alter|truncate|create|grant|revoke)\b/i;
async function safeQuery(sql) {
if (FORBIDDEN.test(sql)) {
throw new Error("Chỉ chấp nhận câu lệnh đọc (SELECT/WITH/EXPLAIN).");
}
const client = await pool.connect();
try {
const result = await client.query(sql);
return { rows: result.rows, rowCount: result.rowCount };
} finally {
client.release();
}
}
const server = new Server(
{ name: "postgres-rag", version: "1.0.0" },
{ capabilities: { tools: { "pg.query": safeQuery } } }
);
server.listen().then(() => {
console.log("MCP server đang lắng nghe trên stdio...");
});
Bước 2 — Đăng ký MCP server với Cursor IDE
Mở Cursor → Settings → MCP, nhấn "Add new global MCP server". Cursor sẽ mở file ~/.cursor/mcp.json. Dán cấu hình sau (đường dẫn tuyệt đối, trỏ tới file server.js vừa tạo):
{
"mcpServers": {
"postgres-rag": {
"command": "node",
"args": ["/Users/tenban/cursor-pg-mcp/server.js"],
"env": {
"PG_HOST": "127.0.0.1",
"PG_PORT": "5432",
"PG_DATABASE": "rag_legal",
"PG_USER": "rag_reader",
"PG_PASSWORD": "MatKhauRatManh_2026",
"HOLYSHEEP_API_KEY": "YOUR_HOLYSHEEP_API_KEY",
"HOLYSHEEP_BASE_URL": "https://api.holysheep.ai/v1"
}
}
}
}
Sau khi lưu, quay lại panel MCP — bạn sẽ thấy chấm xanh bên cạnh postgres-rag nghĩa là server đã sống. Mở Composer (Cmd+I) và thử prompt:
"Liệt kê 5 bảng có nhiều hơn 10.000 dòng trong schema public, kèm số row ước tính."
Cursor sẽ tự gọi tool pg.query, chạy SQL SELECT relname, n_live_tup FROM pg_stat_user_tables WHERE n_live_tup > 10000 ORDER BY n_live_tup DESC LIMIT 5; và trả kết quả ngay trong khung chat.
Bước 3 — Tích hợp HolySheep AI để sinh query thông minh hơn
Để AI "biết" phải sinh SQL kiểu gì cho tối ưu, mình viết một script phụ trợ nl2sql.js gọi HolySheep, base_url phải là https://api.holysheep.ai/v1 (tuyệt đối không dùng api.openai.com hay api.anthropic.com):
import OpenAI from "openai";
import "dotenv/config";
const client = new OpenAI({
apiKey: process.env.HOLYSHEEP_API_KEY,
baseURL: process.env.HOLYSHEEP_BASE_URL, // https://api.holysheep.ai/v1
});
const SCHEMA_HINT = `
Bảng documents(id uuid, title text, content text, embedding vector(1536), created_at timestamptz);
Bảng chunks(id uuid, document_id uuid, content text, embedding vector(1536));
Bảng audit_logs(id bigserial, user_id int, action text, payload jsonb, at timestamptz);
`;
export async function nl2sql(question) {
const res = await client.chat.completions.create({
model: "deepseek-v3.2",
messages: [
{
role: "system",
content: Bạn là chuyên gia PostgreSQL. Chỉ sinh câu SELECT/WITH hợp lệ. Schema: ${SCHEMA_HINT},
},
{ role: "user", content: question },
],
temperature: 0.1,
max_tokens: 600,
});
return res.choices[0].message.content.trim();
}
// Ví dụ: nl2sql("Top 10 user audit nhiều nhất tuần qua?")
Với DeepSeek V3.2 ở mức $0.42 / triệu token, trung bình mỗi prompt nl2sql tốn chưa đến $0.0001 — rẻ hơn 19 lần so với GPT-4.1 ($8/MTok) trong khi chất lượng SQL vẫn ổn cho các truy vấn trung bình.
Lỗi thường gặp và cách khắc phục
Lỗi 1 — "MCP server exited with code 1" ngay khi khởi động
Nguyên nhân: Cursor chạy server với biến môi trường rỗng, hoặc pool không kết nối được Postgres.
Cách khắc phục: Kiểm tra panel MCP logs trong Cursor. Đảm bảo đường dẫn trong args là tuyệt đối (ví dụ /Users/.../server.js), và user Postgres có quyền CONNECT. Test thủ công:
node /Users/tenban/cursor-pg-mcp/server.js
Nếu thấy "MCP server đang lắng nghe trên stdio..." là OK
Lỗi 2 — "401 Unauthorized" khi gọi HolySheep AI
Nguyên nhân: Sai apiKey, hoặc vô tình dán nhầm key của OpenAI/Anthropic. Một số dev cũ hay quên tiền tố baseURL.
Cách khắc phục: Đăng nhập HolySheep AI → Dashboard → Copy lại key. Trong code, đảm bảo:
const client = new OpenAI({
apiKey: process.env.HOLYSHEEP_API_KEY,
baseURL: "https://api.holysheep.ai/v1", // BẮT BUỘC, không để trống
});
Lỗi 3 — Query chạy mãi không trả kết quả (timeout)
Nguyên nhân: Cursor mặc định timeout 25 giây cho tool call. Các truy vấn RAG quét bảng documents hàng triệu dòng dễ vượt ngưỡng.
Cách khắc phục: Thêm statement_timeout trong pool config và ép query luôn có LIMIT:
const pool = new pg.Pool({
// ... các option cũ
statement_timeout: 20_000, // 20 giây, nhỏ hơn timeout của Cursor
});
// Trong prompt, dặn AI: "Luôn thêm LIMIT <= 1000 cho mọi SELECT."
Lỗi 4 — AI tự ý sinh câu DROP TABLE
Nguyên nhân: Model hallucination hoặc prompt injection từ dữ liệu.
Cách khắc phục: Đã có sẵn FORBIDDEN regex trong safeQuery. Ngoài ra, trong Postgres, cấp quyền SELECT thuần cho user rag_reader:
-- Chạy với quyền superuser
REVOKE ALL ON SCHEMA public FROM rag_reader;
GRANT USAGE ON SCHEMA public TO rag_reader;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO rag_reader;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO rag_reader;
Kiểm tra cuối cùng và mẹo vận hành
- Restart Cursor sau mỗi lần sửa
mcp.jsonđể server nạp lại. - Log mọi query ra file để audit — dự án pháp chế rất cần điều này.
- Đặt rate-limit ở MCP server (ví dụ 30 query/phút) để tránh lạm dụng.
- Theo dõi credit HolySheep trong dashboard; với WeChat/Alipay, nạp rất nhanh cho team châu Á.
Cuối cùng, sau 3 giờ sáng hôm đó, mình bàn giao hệ thống RAG với 47 tài liệu PDF được index, một Cursor IDE có thể trả lời "Hợp đồng nào có điều khoản chấm dứt sớm hơn 30 ngày?" chỉ bằng một câu hỏi tiếng Việt. Chi phí suy luận cả tháng chưa đến $2 nhờ giá ¥1 = $1 và chọn model phù hợp. Bạn có thể bắt đầu hành trình tương tự ngay hôm nay.