Gemini CLI là công cụ dòng lệnh chính thức của Google để tương tác với model Gemini ngay trong terminal, hỗ trợ MCP như một cơ chế mở rộng tool tiêu chuẩn. Với những team đã dùng Google Cloud (Cloud SQL for PostgreSQL, AlloyDB) hoặc muốn tận dụng context window (cửa sổ ngữ cảnh) rất lớn của Gemini cho các task cần đọc nhiều bảng/schema phức tạp cùng lúc, Gemini CLI + Postgres MCP là lựa chọn đáng cân nhắc. Bài này hướng dẫn cài đặt MCP server cho Gemini CLI, cách khai thác nó cho việc khám phá schema và chạy query phân tích, một ví dụ xây báo cáo từ câu hỏi kinh doanh, và so sánh thực tế output giữa Gemini CLI với Claude Code khi cùng làm một task.
Cài đặt và kết nối Postgres MCP vào Gemini CLI
Gemini CLI cấu hình MCP server qua file ~/.gemini/settings.json (global) hoặc .gemini/settings.json trong project (ưu tiên hơn config global khi có cả hai). Cú pháp khai báo dùng key mcpServers, tương thích với chuẩn MCP chung:
{
"mcpServers": {
"postgres": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-postgres",
"postgres://mcp_readonly:StrongPass123@localhost:5432/app_dev"
],
"timeout": 30000
}
}
}
Với bản postgres-mcp có safe mode (nên dùng nếu agent có thể chạm vào dữ liệu gần thật):
{
"mcpServers": {
"postgres-safe": {
"command": "uvx",
"args": [
"postgres-mcp",
"--access-mode=restricted",
"postgres://mcp_readonly:StrongPass123@localhost:5432/app_dev"
]
}
}
}
Sau khi lưu, khởi động Gemini CLI (gemini trong terminal) và gõ:
/mcp
để xem danh sách server và trạng thái kết nối, tương tự các CLI khác. Nếu server báo lỗi, Gemini CLI thường in kèm exit code của tiến trình con (subprocess) khởi chạy MCP server — hữu ích để phân biệt lỗi "không tìm thấy package npx" với lỗi "connection string sai".
Một điểm khác biệt đáng chú ý: Gemini CLI cho phép cấu hình trust ở cấp server, quyết định mức độ agent được tự động gọi tool mà không cần hỏi xác nhận người dùng mỗi lần:
{
"mcpServers": {
"postgres-safe": {
"command": "uvx",
"args": ["postgres-mcp", "--access-mode=restricted",
"postgres://mcp_readonly:StrongPass123@localhost:5432/app_dev"],
"trust": false
}
}
}
Đặt "trust": false (giá trị mặc định an toàn) nghĩa là mỗi lần agent muốn gọi tool MCP, Gemini CLI sẽ hỏi bạn xác nhận trước — nên giữ nguyên giá trị này cho mọi kết nối gần production, chỉ đặt true cho môi trường sandbox hoàn toàn cách ly.
Mẹo: Giữ
trust: falsecho mọi MCP server Postgres trong Gemini CLI trừ khi bạn đang chạy trong container sandbox dùng một lần (throwaway). Việc phải xác nhận từng lệnh gọi tool tốn vài giây nhưng là lớp phòng thủ cuối cùng chống agent chạy nhầm lệnh nguy hiểm do hiểu sai ý bạn.
Khám phá schema và chạy query phân tích từ Gemini CLI
Với context window lớn, Gemini CLI xử lý tốt các task cần load nhiều thông tin schema cùng lúc mà không cần chia nhỏ nhiều lượt gọi tool. Prompt mẫu để khám phá schema toàn diện trong một lượt:
Kết nối MCP postgres-safe. Liệt kê toàn bộ schema, table, column, kiểu dữ liệu,
primary key, foreign key, và index của database. Xuất kết quả dưới dạng một
bảng markdown lớn, nhóm theo từng schema. Đồng thời chỉ ra các bảng không có
primary key (dấu hiệu thiết kế có vấn đề) và các foreign key không có index
đi kèm (dễ gây chậm khi join hoặc khi xóa bản ghi bảng cha).
Việc tìm "foreign key không có index" là một kiểm tra rất thực tế nhưng ít người làm thủ công vì tốn công — PostgreSQL không tự tạo index cho foreign key (khác với primary key luôn có index unique tự động), nên đây là nguồn gốc phổ biến của các query chậm khi DELETE hoặc UPDATE bảng cha phải quét toàn bảng con để kiểm tra ràng buộc.
Query agent thường dùng để phát hiện case này:
SELECT
tc.table_name, kcu.column_name, tc.constraint_name
FROM information_schema.table_constraints tc
JOIN information_schema.key_column_usage kcu
ON tc.constraint_name = kcu.constraint_name
WHERE tc.constraint_type = 'FOREIGN KEY'
AND NOT EXISTS (
SELECT 1 FROM pg_indexes pi
WHERE pi.tablename = tc.table_name
AND pi.indexdef LIKE '%' || kcu.column_name || '%'
);
Sau khi có danh sách, bạn có thể hỏi tiếp để agent đề xuất index cụ thể cho từng foreign key thiếu, kèm ước lượng tác động tới tốc độ ghi trước khi bạn quyết định apply.
Mẹo: Chạy kiểm tra "foreign key thiếu index" định kỳ mỗi khi có migration mới thêm bảng/quan hệ — đây là loại lỗi thiết kế rất dễ lọt qua code review vì không gây lỗi logic, chỉ gây chậm dần theo thời gian khi dữ liệu tăng lên.
Ví dụ thực tế: xây query báo cáo từ một câu hỏi kinh doanh
Một use case rất phổ biến: người không rành SQL (product manager, founder) đưa ra câu hỏi kinh doanh bằng ngôn ngữ tự nhiên, và bạn cần chuyển nó thành báo cáo dữ liệu chính xác. Đây là nơi Gemini CLI với MCP thể hiện tốt vì có thể vừa hiểu ý định nghiệp vụ, vừa tự kiểm chứng bằng dữ liệu thật.
Câu hỏi kinh doanh ví dụ: "Tháng nào trong 6 tháng gần nhất có tỷ lệ khách hàng quay lại mua hàng lần 2 cao nhất, và có liên quan gì đến campaign marketing tháng đó không?"
Prompt cho agent:
Câu hỏi kinh doanh: "Tháng nào trong 6 tháng gần nhất có tỷ lệ khách hàng quay lại
mua hàng lần thứ 2 (trong vòng 30 ngày từ đơn hàng đầu tiên) cao nhất?"
Trước khi viết query, hỏi lại mình nếu định nghĩa "khách hàng mới" hay "đơn hàng
tính là completed" chưa rõ. Sau đó viết và chạy thử query trên postgres-safe,
show kết quả dạng bảng theo từng tháng.
Đây là bước quan trọng cần nhấn mạnh với agent: yêu cầu nó hỏi lại khi định nghĩa nghiệp vụ mơ hồ, thay vì tự giả định rồi cho ra số liệu sai mà nhìn có vẻ hợp lý. Một agent được prompt tốt sẽ hỏi lại kiểu: "Đơn hàng đầu tiên tính theo created_at hay theo thời điểm thanh toán thành công? Và '30 ngày' tính từ ngày tạo tài khoản hay từ đơn hàng đầu tiên?"
Sau khi thống nhất định nghĩa, query có thể trông như:
WITH first_orders AS (
SELECT customer_id, MIN(created_at) AS first_order_at
FROM orders
WHERE status = 'completed'
GROUP BY customer_id
),
repeat_within_30d AS (
SELECT fo.customer_id,
date_trunc('month', fo.first_order_at) AS cohort_month,
EXISTS (
SELECT 1 FROM orders o2
WHERE o2.customer_id = fo.customer_id
AND o2.status = 'completed'
AND o2.created_at > fo.first_order_at
AND o2.created_at <= fo.first_order_at + interval '30 days'
) AS repeated
FROM first_orders fo
WHERE fo.first_order_at >= now() - interval '6 months'
)
SELECT cohort_month,
COUNT(*) AS new_customers,
SUM(CASE WHEN repeated THEN 1 ELSE 0 END) AS repeat_customers,
ROUND(100.0 * SUM(CASE WHEN repeated THEN 1 ELSE 0 END) / COUNT(*), 1) AS repeat_rate_pct
FROM repeat_within_30d
GROUP BY cohort_month
ORDER BY cohort_month;
Sau khi có kết quả theo cohort tháng, bạn có thể nhờ agent đối chiếu tháng có tỷ lệ cao nhất với dữ liệu campaign (nếu có bảng marketing_campaigns hoặc tương tự) để tìm tương quan — nhưng luôn nhắc agent phân biệt rõ "tương quan" và "nguyên nhân", tránh kết luận vội vàng chỉ vì hai số liệu trùng thời điểm.
Mẹo: Với mọi câu hỏi kinh doanh mơ hồ, huấn luyện thói quen prompt "hãy hỏi lại nếu định nghĩa X chưa rõ trước khi viết query" — điều này biến agent từ "máy sinh SQL theo giả định" thành "cộng sự phân tích dữ liệu" thực sự, giảm rủi ro báo cáo sai lặng lẽ đưa cho cấp trên.
So sánh output Postgres MCP giữa Gemini CLI và Claude Code
Sau khi dùng cả hai công cụ trên cùng một database thật cho các task tương tự (map schema, sinh query báo cáo, phân tích EXPLAIN), một vài khác biệt thực tế đáng ghi nhận:
- Độ dài và chi tiết giải thích: Gemini CLI có xu hướng trả lời súc tích hơn theo mặc định khi giải thích execution plan, trong khi Claude Code thường đi sâu hơn vào lý do kỹ thuật (tại sao planner chọn Seq Scan thay vì Index Scan) trừ khi bạn prompt yêu cầu ngắn gọn.
- Cách xử lý khi query lỗi cú pháp: cả hai đều tự sửa và chạy lại, nhưng Claude Code có xu hướng giải thích rõ lỗi gốc là gì trước khi sửa, còn Gemini CLI đôi khi sửa và chạy lại ngay không giải thích trừ khi được hỏi — nên nếu bạn cần audit lại quá trình debug, hãy prompt rõ "giải thích lỗi trước khi sửa".
- Context window: với schema rất lớn (hàng trăm bảng) cần introspect toàn bộ trong một lượt, Gemini CLI ít gặp lỗi tràn context hơn nhờ context window lớn hơn — Claude Code có thể cần bạn chia nhỏ task theo schema/nhóm bảng để tránh vượt giới hạn.
- Cơ chế trust/approval: Gemini CLI có setting
trusttường minh ở cấp server MCP như đã nói ở trên; Claude Code kiểm soát việc này chủ yếu qua permission mode của CLI (interactive approval mỗi lần gọi tool nhạy cảm) — cả hai đều an toàn nếu cấu hình đúng, chỉ khác cơ chế. - Tốc độ phản hồi cho task đơn giản: với các câu query đơn giản (một bảng, không join), cả hai tốc độ tương đương; sự khác biệt rõ nhất nằm ở các task nhiều bước (multi-step) như migration script — Claude Code thường chủ động chia nhỏ thành các bước tường minh hơn theo mặc định.
Không có công cụ nào "tốt hơn tuyệt đối" — lựa chọn nên dựa vào: hệ sinh thái bạn đang dùng (Google Cloud thì Gemini CLI tiện hơn), độ quen thuộc của team, và việc bạn đã có sẵn subscription/API key nào.
Mẹo: Nếu team dùng nhiều model khác nhau, hãy chuẩn hoá cùng một file tóm tắt schema (docs/db-schema-overview.md) và cùng một bộ system prompt an toàn dùng chung cho cả Gemini CLI và Claude Code — tránh tình trạng mỗi công cụ "hiểu" database theo một cách khác nhau vì được prompt khác nhau.
Tips
- Luôn set
trust: falsecho MCP server Postgres trong Gemini CLI khi làm việc với dữ liệu có giá trị thật. - Tận dụng context window lớn của Gemini để load toàn bộ schema một lần, nhưng vẫn nên lưu bản tóm tắt ra file để tái sử dụng giữa các session, tránh tốn token introspect lại.
- Với mọi câu hỏi kinh doanh mơ hồ, yêu cầu agent hỏi lại định nghĩa trước khi viết query — đừng để nó tự giả định.
- Khi so sánh output giữa các công cụ, luôn test trên cùng một database, cùng một prompt, để so sánh công bằng — khác biệt do dữ liệu khác nhau dễ bị nhầm là khác biệt do công cụ.
Mẹo: Ghi lại một "prompt chuẩn" cho các task lặp lại thường xuyên (map schema, phân tích query chậm, sinh migration) và lưu vào file dùng chung cho cả team — dù bạn dùng Gemini CLI, Claude Code, hay công cụ khác, prompt chuẩn giúp kết quả nhất quán hơn giữa các thành viên.