Skip to main content
Glama
longliaprono1-blip

chatbot-ai-mcp-demo

🎬 AI Chatbot Demo: MCP + PostgreSQL + DeepSeek V4 Pro

"Don't let AI write SQL. Let AI call your secure API."

A professional demo integrating AI securely using MCP (Model Context Protocol) with Next.js 15, PostgreSQL, and DeepSeek V4 Pro - Perfect for vlog content.

🎯 Problem Statement

When integrating AI into products, many devs run into:

  • ❌ Security risks: AI generates wrong or dangerous SQL (DROP TABLE, DELETE)

  • ❌ Hallucination: AI "hallucinates" and creates queries with wrong data

  • ❌ Prompt injection: Users pass in harmful commands

  • ❌ No control: No way to control what AI generates

Related MCP server: dbecho

βœ… Solution: MCP Pattern

User Prompt β†’ AI (DeepSeek V4 Pro) β†’ MCP Tools β†’ PostgreSQL
     ↑                                    ↓
     └─────── JSON Response β†β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Principles:

  • 🧠 AI: Only reasons and decides which tool to call

  • πŸ›‘οΈ MCP Server: Security guards, blocks dangerous commands

  • πŸ’» Dev: 100% control over SQL inside tools

  • πŸ“Š PostgreSQL: Returns safe data


πŸš€ Quick Start

1. Install dependencies

pnpm install

2. Configure 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. Start PostgreSQL

pnpm docker:up

The database will be automatically seeded with:

  • 115 products (5 categories)

  • Inventory data

  • Sales records (30 days)

  • Orders data

4. Run 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. Open browser

Visit: 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

Lists the tables in the database

Input: None
Output: Array of table names

2. get_table_schema

View the detailed structure of a table

Input:

{ "tableName": "products" }

Output: Columns, data types, constraints

3. query_inventory ⭐

Check product stock

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 best-selling products

Input:

{ "limit": 5, "days": 30 }

Output: Ranked list with sales metrics

5. execute_read_query πŸ›‘οΈ

Generic SELECT query with 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:

"Many devs ask me: When integrating AI, how do we keep it from wrecking the database? Today I'm sharing a production-ready solution!"

Scene 2: Architecture Overview (45s)

Visual: Show architecture diagram

User β†’ DeepSeek V4 Pro β†’ MCP Server β†’ PostgreSQL

Narration:

"Instead of letting AI write SQL on its own, we use the MCP Pattern. AI only reasons about which tool to call; devs control the SQL in 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:

"The user asks naturally, AI analyzes, calls the right tool, MCP executes the query safely, and returns easy-to-understand results!"

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:

"When a user tries to wreck the database, the MCP server blocks it instantly! This is the final security gate that AI cannot bypass."

Scene 5: Code Walkthrough (60s)

Key code snippets to show:

  1. 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;
  }
};
  1. 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!' };
}
  1. 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 supports tool calling at only 1/30 the price of GPT-4o. Perfect for startups and 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

  1. Don't let AI write SQL - Dev controls data access

  2. MCP Pattern - Standardized tool calling

  3. Security First - Multiple protection layers

  4. Cost Effective - DeepSeek V4 Pro ~$0.5/1M tokens

  5. 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 and share to support me in creating more quality content! πŸš€

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    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.
    7 npm
    9
    ISC
  • A
    license
    A
    quality
    B
    maintenance
    An MCP server that gives AI agents direct read-only access to PostgreSQL databases, enabling natural language analytics through tools for schema exploration, querying, trend analysis, and data quality checks.
    11
    5
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Read-only PostgreSQL MCP server that enables running SELECT queries, listing tables and schemas, and describing columns, with built-in protection against writes and malicious SQL attacks.
    476 npm
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    MCP server for PostgreSQL that enables safe read-only database queries, table schema inspection, and query execution planning.
    6
    31 npm
    BSD 3-Clause