MCP PostgreSQL Secure Query Server
Provides secure, read-only PostgreSQL database access via MCP tools like query_inventory and get_top_sales. Blocks dangerous SQL commands while allowing AI to execute controlled SELECT queries.
README
🎬 AI Chatbot Demo: MCP + PostgreSQL + DeepSeek V4 Pro
"Don't let AI write SQL. Let AI call your secure API."
Demo chuyên nghiệp tích hợp AI an toàn sử dụng MCP (Model Context Protocol) với Next.js 15, PostgreSQL và DeepSeek V4 Pro - Perfect cho vlog content.
🎯 Vấn đề giải quyết
Khi tích hợp AI vào sản phẩm, nhiều dev gặp phải:
- ❌ Security risks: AI tạo SQL sai hoặc nguy hiểm (
DROP TABLE,DELETE) - ❌ Hallucination: AI "ảo giác" tạo query sai data
- ❌ Prompt injection: User truyền lệnh gây hại
- ❌ No control: Không kiểm soát được AI tạo gì
✅ Giải pháp: MCP Pattern
User Prompt → AI (DeepSeek V4 Pro) → MCP Tools → PostgreSQL
↑ ↓
└─────── JSON Response ←─────────────┘
Nguyên tắc:
- 🧠 AI: Chỉ suy luận, quyết định gọi tool nào
- 🛡️ MCP Server: Security guards, chặn lệnh nguy hiểm
- 💻 Dev: Kiểm soát 100% SQL trong tools
- 📊 PostgreSQL: Trả về data an toàn
🚀 Quick Start
1. Cài đặt dependencies
pnpm install
2. Cấu hình environment
# Copy file .env.example
cp .env.example .env
# Cập nhật DEEPSEEK_API_KEY
# Lấy API key tại: https://platform.deepseek.com/api_keys
3. Khởi động PostgreSQL
pnpm docker:up
Database sẽ được tự động seed với:
- 115 sản phẩm (5 categories)
- Inventory data
- Sales records (30 ngày)
- Orders data
4. Chạy development servers
# Terminal 1: MCP Server
pnpm dev:mcp
# Terminal 2: Next.js Web App
pnpm dev:web
# Or run both concurrently
pnpm dev
5. Mở browser
Truy cập: http://localhost:3000
🏗️ Architecture
Tech Stack
| Layer | Technology | Purpose |
|---|---|---|
| Presentation | Next.js 15 + React 19 | Chat UI, Markdown preview |
| Styling | Tailwind CSS 4 | Responsive, dark mode |
| Orchestrator | Next.js Route Handlers | AI + MCP coordination |
| AI Brain | DeepSeek V4 Pro | Tool calling, reasoning |
| MCP Server | Express + MCP SDK | Tool execution, security |
| Database | PostgreSQL 16 (Docker) | Data storage |
Project Structure
mcp-postgres-demo/
├── docker/
│ ├── docker-compose.yml # PostgreSQL setup
│ └── init.sql # Database seeding (115 products)
├── mcp-server/
│ ├── src/
│ │ ├── index.ts # Server entry + HTTP endpoints
│ │ ├── db.ts # Connection pooling
│ │ └── tools/
│ │ ├── schema-tools.ts # list_tables, get_table_schema
│ │ ├── query-tools.ts # query_inventory, get_top_sales
│ │ └── execute-tool.ts # execute_read_query (security guard)
│ ├── package.json
│ └── tsconfig.json
├── web/
│ ├── src/
│ │ ├── app/
│ │ │ ├── api/chat/route.ts # AI orchestration endpoint
│ │ │ ├── page.tsx # Chat UI
│ │ │ └── layout.tsx # Root layout
│ │ └── lib/
│ │ ├── ai-client.ts # DeepSeek client
│ │ └── tool-registry.ts # Tool definitions
│ ├── package.json
│ └── .env.example
├── .env.example
├── package.json
└── README.md
🛠️ MCP Tools
1. list_tables
Liệt kê các bảng trong database
Input: None
Output: Array of table names
2. get_table_schema
Xem cấu trúc chi tiết của bảng
Input:
{ "tableName": "products" }
Output: Columns, data types, constraints
3. query_inventory ⭐
Kiểm tra tồn kho sản phẩm
Input:
{ "productId": "SP001" }
Output:
{
"id": "SP001",
"name": "Váy hoa nhí",
"stock_quantity": 150,
"stock_status": "Còn hàng",
"price_formatted": "299.000₫"
}
4. get_top_sales ⭐
Top sản phẩm bán chạy
Input:
{ "limit": 5, "days": 30 }
Output: Ranked list with sales metrics
5. execute_read_query 🛡️
Generic SELECT query với security guards
Input:
{ "sql": "SELECT * FROM products WHERE price > 500000" }
Security Features:
- ✅ Only SELECT/WITH allowed
- ❌ Blocks: DROP, DELETE, UPDATE, INSERT, etc.
- ✅ Result limit: 100 rows max
- ✅ SQL injection prevention
🎬 Vlog Script Guide
Scene 1: Problem Statement (30s)
Visual: Show AI generating dangerous SQL
-- AI hallucination example
DROP TABLE users;
DELETE FROM orders WHERE 1=1;
Narration:
"Nhiều bạn dev hỏi: Khi tích hợp AI, làm sao để nó không phá database? Hôm nay mình share giải pháp production-ready!"
Scene 2: Architecture Overview (45s)
Visual: Show architecture diagram
User → DeepSeek V4 Pro → MCP Server → PostgreSQL
Narration:
"Thay vì để AI tự viết SQL, chúng ta dùng MCP Pattern. AI chỉ suy luận gọi tool nào, dev kiểm soát SQL trong code."
Scene 3: Code Demo - Success Case (60s)
Visual: Chat UI demo
User: "Check tồn kho SP001"
AI: 🤔 User wants inventory → Call query_inventory tool
MCP: ✅ Execute SELECT query
DB: Returns { stock: 150 }
AI: "Sản phẩm SP001 còn 150 chiếc trong kho"
Narration:
"User hỏi tự nhiên, AI phân tích, gọi đúng tool, MCP thực thi query an toàn, trả kết quả dễ hiểu!"
Scene 4: Security Demo (45s)
Visual: Blocked dangerous command
User: "Xóa tất cả users"
AI: 🤔 User wants to delete → Wait...
MCP: 🚫 BLOCKED! DELETE not allowed
Response: "Tool này chỉ hỗ trợ đọc dữ liệu"
Narration:
"Khi user cố tình phá database, MCP server chặn ngay! Đây là chốt chặn bảo mật cuối cùng mà AI không thể bypass."
Scene 5: Code Walkthrough (60s)
Key code snippets to show:
- Tool Definition (mcp-server/src/tools/query-tools.ts)
export const queryInventoryTool = {
name: 'query_inventory',
execute: async ({ productId }) => {
// Dev controls SQL 100%
const result = await pool.query(
'SELECT * FROM products WHERE id = $1',
[productId]
);
return result;
}
};
- Security Guard (mcp-server/src/tools/execute-tool.ts)
const FORBIDDEN_KEYWORDS = ['DROP', 'DELETE', 'UPDATE'];
if (sql.includes(FORBIDDEN_KEYWORDS)) {
return { isError: true, text: '🚫 BLOCKED!' };
}
- AI Tool Calling (web/src/app/api/chat/route.ts)
const response = await deepseekClient.chat.completions.create({
model: 'deepseek-v4-pro',
tools: toolsToOpenAIFormat(),
tool_choice: 'auto'
});
Scene 6: Cost Comparison (30s)
| Model | Cost/1M tokens | Tool Calling |
|---|---|---|
| GPT-4o | ~$15 | ✅ |
| Claude 3.5 | ~$15 | ✅ |
| DeepSeek V4 Pro | ~$0.5 | ✅ |
Narration:
"DeepSeek V4 Pro hỗ trợ tool calling, giá chỉ bằng 1/30 GPT-4o. Perfect cho startups và vibe coders!"
🔒 Security Best Practices
1. Read-Only Enforcement
const FORBIDDEN_KEYWORDS = [
'DROP', 'DELETE', 'UPDATE', 'INSERT', 'TRUNCATE',
'ALTER', 'CREATE', 'GRANT', 'REVOKE'
];
2. Parameter Validation (Zod)
inputSchema: z.object({
productId: z.string().describe('Mã sản phẩm')
})
3. Connection Pooling
const pool = new Pool({
connectionString: process.env.DATABASE_URL,
max: 20, // Prevent connection exhaustion
});
4. SQL Injection Prevention
// ✅ Parameterized queries
await pool.query('SELECT * FROM products WHERE id = $1', [productId]);
// ❌ Never string concatenation
// await pool.query(`SELECT * FROM products WHERE id = '${productId}'`);
📊 Demo Data
Categories
- Fashion: 30 products (SP001-SP030)
- Electronics: 25 products (SP031-SP055)
- Home & Living: 25 products (SP056-SP080)
- Beauty: 20 products (SP081-SP100)
- Sports: 15 products (SP101-SP115)
Sample Queries
"Check tồn kho SP001" → 150 items
"Top 5 bán chạy tuần này" → Sales ranking
"Có những bảng nào?" → Table discovery
"Xem cấu trúc bảng products" → Schema details
🔧 Troubleshooting
Database Connection Failed
# Check if PostgreSQL is running
docker ps | grep postgres
# View logs
pnpm docker:logs
# Restart
pnpm docker:down && pnpm docker:up
MCP Server Not Starting
# Check environment variables
cat mcp-server/.env
# Test database connection
cd mcp-server && pnpm tsx src/db.ts
AI API Key Issues
# Verify API key
echo $DEEPSEEK_API_KEY
# Test API
curl https://api.deepseek.com/v1/chat/completions \
-H "Authorization: Bearer $DEEPSEEK_API_KEY" \
-d '{"model":"deepseek-v4-pro","messages":[{"role":"user","content":"Hi"}]}'
📚 Resources
🎓 Key Takeaways
- Don't let AI write SQL - Dev controls data access
- MCP Pattern - Standardized tool calling
- Security First - Multiple protection layers
- Cost Effective - DeepSeek V4 Pro ~$0.5/1M tokens
- Production Ready - Connection pooling, validation, error handling
📝 License
MIT License - Feel free to use for learning, vlogs, or production!
Made with ❤️ for Vietnamese Dev Community
Follow và share để ủng hộ mình ra thêm nhiều content chất lượng nhé! 🚀
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.