Kết nối Claude Code với database: truy vấn dữ liệu thực với MCP

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ế.

Dùng MCP Server nào

@modelcontextprotocol/server-postgres chính thức hỗ trợ:

  • Đọc schema của tất cả các bảng (tên field, kiểu dữ liệu, ràng buộc)
  • Thực thi query SQL và trả về kết quả
  • Hỗ trợ nhiều schema

Chỉ đọc. Server này được thiết kế chỉ để truy vấn — không thực thi INSERT, UPDATE hay DELETE.

Cài đặt

npm install -g @modelcontextprotocol/server-postgres

Cấu hình

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.

Tạo tài khoản chỉ đọc trước

Đừ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.

Xác nhận kết nối

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.

Ví dụ sử dụng thực tế

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.

Kiểm soát những gì Claude có thể thấy

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.

Kết nối database từ xa

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.

Nhiều database

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 trong thực tế

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.