Kết nối PostgreSQL với Claude Code qua MCP, thiết lập tài khoản chỉ đọc với kiểm soát quyền, để Claude trực tiếp đọc schema, viết query và phân tích dữ liệu.
Sau khi kết nối database, cách Claude Code hoạt động sẽ thay đổi. Bạn không cần copy cấu trúc bảng vào prompt hay giải thích tên field — Claude kết nối trực tiếp, tự đọc schema, tự viết query, và phân tích kết quả cho bạn.
Bài viết này dùng PostgreSQL làm ví dụ, đi qua toàn bộ quá trình từ cấu hình đến sử dụng thực tế.
@modelcontextprotocol/server-postgres chính thức hỗ trợ:
Chỉ đọc. Server này được thiết kế chỉ để truy vấn — không thực thi INSERT, UPDATE hay DELETE.
npm install -g @modelcontextprotocol/server-postgres
Sửa .claude/settings.json (cấp độ dự án):
{
"mcpServers": {
"db": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-postgres",
"postgresql://readonly_user:password@localhost:5432/myapp_production"
]
}
}
}
Định dạng connection string: postgresql://USER:PASSWORD@HOST:PORT/DATABASE
Nếu không muốn lưu password trong file cấu hình, dùng biến môi trường:
{
"mcpServers": {
"db": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-postgres"],
"env": {
"DATABASE_URL": "postgresql://readonly_user:password@localhost:5432/myapp_production"
}
}
}
}
Nếu .claude/settings.json được commit lên git, đảm bảo không có password dạng plain text. Đặt cấu hình nhạy cảm trong .claude/settings.local.json và thêm vào .gitignore.
Đừng cấp tài khoản có quyền ghi cho Claude. Tạo user chỉ đọc trong PostgreSQL:
-- Tạo user chỉ đọc
CREATE USER claude_readonly WITH PASSWORD 'your_password';
-- Cấp quyền kết nối
GRANT CONNECT ON DATABASE myapp_production TO claude_readonly;
-- Cấp quyền sử dụng schema
GRANT USAGE ON SCHEMA public TO claude_readonly;
-- Cấp SELECT trên tất cả bảng hiện có
GRANT SELECT ON ALL TABLES IN SCHEMA public TO claude_readonly;
-- Áp dụng tương tự cho bảng tạo mới trong tương lai
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT SELECT ON TABLES TO claude_readonly;
Nếu có bảng không muốn Claude xem (như sessions, audit_logs), đơn giản là không cấp quyền cho bảng đó, hoặc chuyển sang schema riêng.
Khởi động lại Claude Code rồi hỏi:
Liệt kê tất cả các bảng trong database
Nếu Claude trả về danh sách tên bảng thay vì nói "tôi không có quyền truy cập database", kết nối MCP đã thành công.
Sau khi cấu hình, Claude có thể làm được nhiều hơn. Một số tình huống thực tế:
Tình huống 1: Hiểu cấu trúc dữ liệu
Mối quan hệ giữa bảng users và orders là gì?
Có ràng buộc foreign key không?
Claude trực tiếp query information_schema để đọc cấu trúc bảng và ràng buộc, rồi giải thích rõ ràng — không cần bạn dán schema.
Tình huống 2: Phân tích dữ liệu
Trong số người dùng đăng ký 30 ngày qua,
bao nhiêu phần trăm đã đặt ít nhất một đơn hàng?
Phân theo kênh đăng ký.
Claude viết SQL, thực thi, và phân tích kết quả. Nếu query sai (tên field không khớp chẳng hạn), nó thấy lỗi và tự sửa.
Tình huống 3: Debug
Tìm các đơn hàng có status = 'pending' nhưng created_at đã hơn 7 ngày.
Có bao nhiêu đơn và gần nhất là khi nào?
Loại tra cứu tạm thời này trước đây đòi bạn tự viết SQL hoặc mở công cụ database thủ công. Giờ chỉ cần mô tả nhu cầu.
Tình huống 4: Hỗ trợ phát triển
Tôi muốn thêm cột last_login_at vào bảng users.
Viết SQL migration và kiểm tra xem các index hiện có có đủ không.
Claude đọc cấu trúc bảng hiện tại, viết migration, và phân tích tình trạng index — tất cả trong một bước.
Mặc định, Claude có thể truy cập schema đầy đủ và dữ liệu của tất cả bảng đã được cấp quyền. Hạn chế theo nhu cầu thực tế.
Kiểm soát theo bảng
Chỉ cấp quyền cho một số bảng cụ thể:
-- Chỉ bảng cụ thể, không phải tất cả
GRANT SELECT ON TABLE users, orders, products TO claude_readonly;
-- sessions, payment_tokens, audit_logs không được cấp quyền
Lọc cột nhạy cảm bằng view
Nếu bảng có các field nhạy cảm (hash mật khẩu, API key, số điện thoại), tạo view ẩn chúng đi:
CREATE VIEW users_safe AS
SELECT id, email, created_at, plan, status
FROM users;
-- loại bỏ password_digest, phone, payment_method_id
GRANT SELECT ON users_safe TO claude_readonly;
-- không cấp quyền trên bảng gốc
Claude chỉ có thể query view và không bao giờ thấy field gốc.
Giới hạn số hàng
@modelcontextprotocol/server-postgres mặc định áp dụng giới hạn số hàng trong kết quả query (thường 1.000 hàng), ngăn Claude kéo toàn bộ bảng. Giới hạn này hợp lý — không cần tăng lên.
Database production thường không expose port trực tiếp. Dùng SSH tunnel:
# Chuyển tiếp localhost:5433 đến port 5432 của server từ xa
ssh -L 5433:localhost:5432 [email protected] -N
Dùng port local trong file cấu hình:
"postgresql://readonly_user:password@localhost:5433/myapp_production"
Cũng có thể dùng connection pooler như pgBouncer.
Nếu dự án dùng nhiều database (chính + analytics + cache), cấu hình nhiều MCP Server:
{
"mcpServers": {
"main-db": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-postgres", "postgresql://...chính..."]
},
"analytics-db": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-postgres", "postgresql://...analytics..."]
}
}
}
Claude kết nối cả hai. Chỉ cần nói muốn query database nào.
Thay đổi rõ ràng nhất sau khi kết nối database: các cuộc trò chuyện liên quan đến dữ liệu không còn cần chuẩn bị trước. Không cần giải thích schema, không cần mô tả kiểu field — nói nhu cầu và Claude tự tìm.
Đặc biệt hữu ích khi debug. Quy trình cũ: query database → copy kết quả → dán cho Claude → phân tích. Quy trình mới: mô tả vấn đề → Claude tự query → ra kết luận ngay.