
Kết nối Claude với database qua MCP server: demo Postgres tutorial cho Claude Desktop truy vấn SQL bằng ngôn ngữ tự nhiên
Cài đặt MCP server cho Postgres và kết nối với Claude Desktop để truy vấn database bằng ngôn ngữ tự nhiên. Hiểu cách Claude đọc schema, sinh SQL, và á
Mỗi lần muốn Claude phân tích dữ liệu, bạn lại copy-paste schema kèm vài câu SQL vào chat? Cách đó vừa chậm vừa dễ lệch khi schema đổi. MCP server cho Postgres giải quyết đúng pain point này: Claude đọc schema, sinh SQL, và chạy query trực tiếp trên DB của bạn. Bài này đi qua setup Postgres 17 với `uv`, test bằng MCP Inspector, gắn vào Claude Desktop, 3 lỗi bảo mật phải né, và khi nào nên tự viết server thay vì dùng package có sẵn.
MCP server cho Postgres giải quyết vấn đề gì
Khi muốn Claude phân tích dữ liệu từ database, bạn thường phải copy-paste schema và các truy vấn SQL vào chat. Cách làm này tốn thời gian và dễ lỗi nếu schema thay đổi.
Model Context Protocol (MCP) là một tiêu chuẩn mã nguồn mở do Anthropic định nghĩa. Nó giúp các tác nhân AI và LLM tương tác với công cụ và dữ liệu bên ngoài một cách có cấu trúc [F1]. Với một MCP server cho PostgreSQL, Claude có thể tự động đọc schema và sinh ra SQL phù hợp.
Điểm khác biệt chính là Claude sẽ luôn lấy phiên bản schema mới nhất tại thời điểm truy vấn thông qua tài nguyên `db://schema` [F3]. Điều này loại bỏ việc phải dán schema thủ công mỗi khi có thay đổi.
Một MCP server cho PostgreSQL có thể triển khai các công cụ như `execute_query` để chạy truy vấn SQL và `test_connection` để xác minh kết nối cơ sở dữ liệu [F2]. Nó cũng hỗ trợ các tài nguyên như `db://tables` để liệt kê các bảng và `db://tables/{table_name}` cho schema của một bảng cụ thể [F3]. Các mẫu tạo truy vấn và công cụ xây dựng truy vấn phân tích cũng có thể được sử dụng [F4].
Các trường hợp sử dụng hữu ích bao gồm: khám phá các database lạ, viết báo cáo ad-hoc, hoặc debug các truy vấn chậm bằng cách dùng `EXPLAIN ANALYZE`.

Chuẩn bị môi trường: Postgres 17, uv và Claude Desktop
Trước khi đụng tới MCP, bạn cần 4 thứ sẵn sàng trên máy: Python 3.8 trở lên, `uv` (package manager Python hiện đại), `npx` đi kèm Node.js, và một PostgreSQL database đang chạy [F5]. Mình dùng Postgres 17 cho demo này, nhưng các version 14-16 cũng chạy tốt với cùng config. Claude Desktop bạn cài sẵn bản Mac hoặc Windows tùy hệ điều hành.
Cài `uv` nhanh nhất qua curl script chính thức của Astral. Sau khi xong, verify bằng `uv --version` để chắc binary đã vào PATH:
curl -LsSf https://astral.sh/uv/install.sh | sh
uv --version
# uv 0.x.xTiếp theo, mình tạo một database demo tên `vibeclaude_demo` với 3 bảng `users`, `products`, `orders`. Đây là schema e-commerce kinh điển, đủ để test các câu hỏi như "top 5 user order nhiều nhất" hay "sản phẩm nào sắp hết stock". Quan trọng hơn: mình tạo luôn một role Postgres read-only riêng cho MCP, KHÔNG dùng superuser. Đây là layer bảo vệ cơ bản, kể cả khi Claude sinh nhầm `DELETE FROM users`, query sẽ fail ở permission level.
CREATE DATABASE vibeclaude_demo;
\c vibeclaude_demo
CREATE TABLE users (
id SERIAL PRIMARY KEY,
email TEXT UNIQUE NOT NULL,
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE TABLE products (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
price NUMERIC(10,2),
stock INT DEFAULT 0
);
CREATE TABLE orders (
id SERIAL PRIMARY KEY,
user_id INT REFERENCES users(id),
product_id INT REFERENCES products(id),
quantity INT,
ordered_at TIMESTAMPTZ DEFAULT NOW()
);
-- Read-only role cho MCP, không cho phép write
CREATE ROLE mcp_reader WITH LOGIN PASSWORD 'change_me_strong_pw';
GRANT CONNECT ON DATABASE vibeclaude_demo TO mcp_reader;
GRANT USAGE ON SCHEMA public TO mcp_reader;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO mcp_reader;Connection string Postgres dùng format chuẩn `postgresql://mcp_reader:your_pw@localhost:5432/vibeclaude_demo`. Lát nữa mình paste chuỗi này vào config Claude Desktop ở section sau. Một mẹo nhỏ: đừng commit connection string vào git — để vào file `.env` hoặc password manager, đặc biệt khi bạn share repo demo lên GitHub.
Sau khi seed thêm vài dòng dummy data (5-10 user, 10-20 product, 30 order), môi trường đã sẵn sàng. Phần kế tiếp mình sẽ cài MCP server cho Postgres và verify nó nhìn thấy 3 bảng vừa tạo.
Cài đặt và chạy thử với MCP Inspector
Trước khi gắn server vào Claude Desktop, mình recommend test bằng MCP Inspector để chắc chắn phần kết nối DB không lỗi. Yêu cầu tiên quyết khá nhẹ: Python 3.8+, uv (package manager Python hiện đại), npx đi kèm Node.js, và một Postgres đang chạy [F5]. Mình clone repo `simple-psql-mcp` về local rồi cài deps qua uv. Nếu lười, bạn có thể chạy thẳng bằng `uvx` mà không cần clone.
# Clone và setup môi trường
git clone https://github.com/NetanelBollag/simple-psql-mcp.git
cd simple-psql-mcp
uv venv && source .venv/bin/activate
uv pip install -e .
# Set env cho DB connection
export DATABASE_URL="postgresql://user:pass@localhost:5432/mydb"
export DB_SCHEMA="public"
# Chạy MCP Inspector để test server trước khi gắn Claude
npx @modelcontextprotocol/inspector uv run simple-psql-mcpFile `mcp_config.json` (hoặc set env trực tiếp như trên) cần 2 biến chính: `DATABASE_URL` theo format Postgres URI đầy đủ, và `DB_SCHEMA` mặc định nếu DB của bạn chia nhiều schema. Mình thường để `public` cho dev local. Production thì point thẳng tới schema riêng để tránh vô tình đụng bảng system.
Sau khi lệnh trên chạy, Inspector mở UI ở localhost. Tab Tools hiển thị 2 function chính: `execute_query` để chạy SQL bất kỳ và `test_connection` để verify DB còn sống [F2]. Tab Resources liệt kê 3 endpoint: `db://tables` (danh sách bảng), `db://tables/{table_name}` (schema của 1 bảng), và `db://schema` (toàn bộ schema DB) [F3]. Tab Prompts có sẵn vài template để LLM xây query phân tích [F4] — phần này mình sẽ động tới ở section sau.
Quick smoke test: trong tab Tools, chọn `execute_query`, paste `SELECT version()` rồi bấm Run. Nếu trả về một row chứa version string Postgres của bạn — server kết nối đúng [F2]. Tiếp đó thử `test_connection` để xác nhận, rồi click qua Resources và mở `db://tables` xem danh sách bảng có khớp DB không [F3]. Nếu Inspector báo connection refused, kiểm tra `DATABASE_URL` trước — đặc biệt password có ký tự đặc biệt phải URL-encode. Lỗi import module thường do quên `source .venv/bin/activate`.
Kết nối server vào Claude Desktop và demo truy vấn
Sau khi đã cài đặt MCP server cho PostgreSQL, bước tiếp theo là kết nối nó với Claude Desktop. Bạn cần chỉnh sửa file cấu hình của Claude Desktop để thêm thông tin về server mới này.
Đường dẫn file cấu hình `claude_desktop_config.json` sẽ khác nhau tùy theo hệ điều hành bạn đang sử dụng. Trên macOS, file này thường nằm trong thư mục `~/Library/Application Support/Claude/` hoặc tương tự. Với Windows, bạn có thể tìm trong `C:\Users\<YourUsername>\AppData\Roaming\Claude\`.
Bạn thêm một block JSON vào phần `mcpServers` với `command` là lệnh chạy server và `args` là các tham số cần thiết. Đảm bảo thay thế các giá trị placeholder như `YOUR_DB_USER`, `YOUR_DB_PASSWORD`, `YOUR_DB_HOST`, `YOUR_DB_PORT`, và `YOUR_DB_NAME` bằng thông tin database của bạn.
{
"mcpServers": {
"postgres": {
"command": "npx",
"args": [
"@modelcontextprotocol/simple-psql-mcp",
"--user", "YOUR_DB_USER",
"--password", "YOUR_DB_PASSWORD",
"--host", "YOUR_DB_HOST",
"--port", "YOUR_DB_PORT",
"--database", "YOUR_DB_NAME"
]
}
}
}Sau khi lưu file cấu hình, bạn cần khởi động lại Claude Desktop. Nếu mọi thứ thành công, bạn sẽ thấy một biểu tượng công cụ mới xuất hiện ở góc dưới của cửa sổ chat, cho biết MCP server PostgreSQL đã sẵn sàng hoạt động.
Demo 1: Liệt kê các bảng trong database
Bạn có thể bắt đầu bằng một câu hỏi đơn giản như "list các bảng trong database". Claude sẽ tự động gọi tài nguyên `db://tables` của MCP server để lấy danh sách các bảng [F3]. Đây là cách Claude hiểu và tương tác với cấu trúc database của bạn.
Demo 2: Truy vấn dữ liệu phức tạp
Tiếp theo, hãy thử một truy vấn phức tạp hơn: "top 5 user có nhiều order nhất tháng này". Claude sẽ đọc schema database thông qua MCP server và tự động sinh ra một câu lệnh SQL JOIN để thực hiện yêu cầu này. Điều này minh họa khả năng của Claude trong việc chuyển đổi ngôn ngữ tự nhiên thành SQL.
SELECT u.username, COUNT(o.order_id) AS total_orders
FROM users u
JOIN orders o ON u.user_id = o.user_id
WHERE o.order_date >= date_trunc('month', current_date)
AND o.order_date < date_trunc('month', current_date) + interval '1 month'
GROUP BY u.username
ORDER BY total_orders DESC
LIMIT 5;Demo 3: Sử dụng prompt template cho truy vấn phân tích
MCP server cũng cho phép bạn định nghĩa các prompt template. Ví dụ, bạn có thể yêu cầu Claude "tạo báo cáo phân tích doanh số theo khu vực". Claude sẽ sử dụng các prompt do server expose để xây dựng các truy vấn phân tích theo mẫu đã định sẵn [F4], giúp bạn nhanh chóng có được insight từ dữ liệu mà không cần viết SQL thủ công.

Bảo mật: 3 lỗi nguy hiểm cần tránh
Kết nối Claude với database qua MCP server mang lại nhiều tiện ích, nhưng cũng tiềm ẩn các rủi ro bảo mật đáng kể. Mình cần nắm rõ những lỗ hổng này để bảo vệ dữ liệu của mình.
Rủi ro 1: Lỗ hổng thực thi lệnh hệ điều hành (RCE)
Một trong những rủi ro nghiêm trọng nhất là khả năng thực thi lệnh hệ điều hành (RCE) thông qua giao thức STDIO (Standard Input/Output) nếu không được xử lý đúng cách. Đã có báo cáo về việc hơn 200.000 máy chủ bị lộ do lỗ hổng này. Cụ thể, phiên bản Flowise 1.83.7 từng có lỗ hổng CVSS 9.9 cho phép RCE qua MCP STDIO, cho thấy mức độ nguy hiểm của việc không sanitize input.
Rủi ro 2: Lỗi phần mềm trong MCP server
Ngay cả các MCP server được quản lý cũng có thể chứa lỗi. Ví dụ, một số phiên bản MCP của Snowflake đã gặp phải sự cố với các công cụ/cuộc gọi, ngay cả với một truy vấn đơn giản như `SELECT 42`. Những lỗi này có thể dẫn đến việc truy cập hoặc thao tác dữ liệu không mong muốn.
Rủi ro 3: Claude tạo truy vấn SQL nguy hiểm
Claude có thể tự động tạo ra các truy vấn SQL nguy hiểm như `DROP TABLE` hoặc `UPDATE` mà không có mệnh đề `WHERE`, dẫn đến mất mát hoặc hỏng dữ liệu nghiêm trọng. Để giảm thiểu rủi ro này, bạn nên cấu hình tài khoản database với vai trò chỉ có quyền `SELECT` (read-only role) cho kết nối mà Claude sử dụng. Bạn cũng có thể giới hạn IP truy cập database trong file `pg_hba.conf` của PostgreSQL.
Một mẹo hữu ích khác là thêm `statement_timeout` vào chuỗi kết nối database. Điều này giúp tránh việc Claude chạy các truy vấn quá nặng, có thể làm treo toàn bộ hệ thống production của bạn.
Cuối cùng, đừng bao giờ commit chuỗi kết nối database (như `DATABASE_URL`) trực tiếp vào Git. Thay vào đó, hãy sử dụng các biến môi trường và cấu hình chúng an toàn trong Claude Desktop hoặc môi trường triển khai của bạn.
Khi nào nên tự viết server thay vì dùng package
Nếu use case của bạn dừng ở mức explore data, viết report nhanh, hoặc debug query thì package có sẵn đã đủ — không cần đụng tay vào codebase MCP server. Các tool như `execute_query`, `test_connection` cộng với resources `db://tables`, `db://tables/{table_name}` và `db://schema` cover phần lớn workflow daily khi bạn muốn Claude truy vấn DB ad-hoc [F2,F3]. Thêm prompts cho query template thì gần như đủ bộ cho dev khám phá dữ liệu hằng ngày [F4].
Tự viết server chỉ thực sự đáng công khi yêu cầu vượt khỏi mức generic. Vài case điển hình mình từng gặp khi setup cho team:
Filter row-level security theo user đang login, không tin tham số mà Claude tự generate
Audit log mọi query Claude gọi vào một table riêng để compliance review sau này
Masking PII như email, phone, CMND trước khi trả response cho LLM
Expose stored procedure phức tạp thành một tool riêng, thay vì để Claude tự sinh SQL raw rồi cầu may đúng schema
Cách tiết kiệm thời gian nhất là fork một codebase nhỏ rồi sửa, đừng viết từ đầu. `simple-psql-mcp` chạy trên Python 3.8+ với `uv` quản lý dep và `npx` để spawn server qua Claude Desktop — codebase ngắn, dễ đọc, dễ thay đổi tools/resources tùy nhu cầu [F5]. Bạn chỉ cần thêm logic auth, masking, hoặc audit vào layer `execute_query`, giữ nguyên phần resource handlers, là đã có server custom hợp với môi trường nội bộ.
Trade-off rõ: bạn phải maintain thêm một service. MCP là chuẩn mở còn đang hoàn thiện [F1] nên thỉnh thoảng phải update theo breaking change của spec hoặc SDK. Nếu team không có người sẵn sàng own service này lâu dài thì stick với package public vẫn an toàn hơn — đỡ tốn dev hours mà vẫn đủ dùng cho phần lớn case.
Tổng kết: MCP server cho Postgres biến Claude Desktop thành SQL client hiểu ngôn ngữ tự nhiên, miễn là bạn cấu hình read-only role và giới hạn schema cẩn thận. Nếu bạn đang build internal tool quanh database công ty, phần next về cách viết MCP server custom sẽ là bước tiếp theo đáng đọc.