Bài 11: Website lên VPS + Ủy quyền Agent MCP

MỤC TIÊU CUỐI BÀI

Từ hôm nay anh em không còn chơi demo trên Vercel nữa. Website chạy trên VPS thật, database thật, và AI agent có cánh tay để làm việc thật — tất cả qua một câu nhắn Telegram.

Đọc trước khi bắt đầu

Nhiệm vụ trước đã có video hướng dẫn dùng VPS và trỏ domain — đó là nền tảng của hôm nay. Nếu anh em đã nắm được 2 thứ đó, phần còn lại rất đơn giản: mở agent coding ngay trong thư mục dự án website, cung cấp thông tin VPS cho nó, là nó tự deploy toàn bộ source website lên VPS giúp anh em.

Sau khi website đã chạy trên VPS, anh em có thể tạo thêm CRM, admin panel, email flow, hay BẤT CỨ tính năng nào cho website. Và đây là lúc MCP bước vào — mỗi tính năng mới anh em vibe ra, chỉ cần build 1 MCP tool tương ứng, là anh em đã có thể điều khiển nó qua Telegram. Business anh em càng lớn, cánh tay AI càng dài.

MỤC TIÊU CUỐI NGÀY

Anh em ngồi cà phê, nảy ra ý tưởng, mở Telegram nhắn một câu kiểu:

"Đổi tiêu đề landing thành 'Flash sale cuối tuần 30%'"

→ goClaw gọi tool MCP → file index.html trên VPS được sửa → khách đang truy cập website refresh là thấy tiêu đề mới. Tất cả trong 3 giây, không mở laptop.

TẠI SAO HÔM NAY ĐẶC BIỆT

Từ Bài 1 đến giờ, website của anh em sống trên Vercel — nhanh, tiện, miễn phí, nhưng nó là "cửa hàng giấy": đẹp để chụp hình, nhưng không ghi được sổ sách thật. Database trên Vercel là file tĩnh, khách không vào thay đổi được gì.

Ở nhiệm vụ trước anh em mua VPS, cài goClaw. Hôm nay anh em kéo cả cửa hàng về VPS — để nó trở thành cửa hàng thật: có kho hàng, có sổ cái, có nhân viên AI đứng trong đó làm việc 24/7.

🔥 MẸO CỦA QUẢNG TRƯỚC KHI BẮT ĐẦU

Đây là bài dài nhất trong chuỗi — có 2 phần lớn. Copy toàn bộ SOP này, mở agent coding trên máy (Antigravity/Cursor/Claude Code) và paste vào prompt mở đầu bên dưới:

MÔ HÌNH HỆ THỐNG

SAU BÀI NÀY SẼ NHÌN THẾ NÀY

1 VPS duy nhất chạy 3 dịch vụ đồng thời

VPS PRODUCTION
🚀 goClaw (AI Gateway) Port 18790
🌐 Website (Landing+Admin) Port 3000
🤖 MCP (Cánh tay AI) Port 3001 (local)
⚡ Kết nối chung dữ liệu: brain.db
NGINX PROXY + AUTOMATIC SSL
ÁNH XẠ TÊN MIỀN (DOMAINS)
app.yourdomain.com → goClaw (Port 18790)
yourdomain.com → Website (Port 3000)
Telegram goClaw MCP brain.db Web UI

💡 Đừng sợ diagram này: Anh em không cần hiểu hết các port và mũi tên. Diagram chỉ để anh em biết "ở cuối ngày, VPS của anh em sẽ chạy 3 thứ cùng lúc, và tất cả đi qua 1 domain". Agent coding lo phần kỹ thuật — anh em chỉ cần biết đích đến trông như vậy.

SOP — HƯỚNG DẪN CHI TIẾT TỪNG BƯỚC

Mở đầu — Khởi động Agent Coding trên máy:

Copy toàn bộ SOP này, mở agent coding trên máy (Antigravity/Cursor/Claude Code) và paste:

LỆNH COPY – MỞ ĐẦU CHƠI TRÊN MÁY

Đây là SOP tôi cần làm hôm nay, có 2 phần lớn: (1) kéo website từ Vercel lên VPS thật, (2) build MCP server cho AI agent có tay chân. Bạn hướng dẫn tôi từng bước một — mỗi lần 1 bước, chờ tôi báo lại rồi mới tiếp. Lỗi gì bạn fix luôn. Bắt đầu bằng việc đọc code website hiện tại của tôi để biết đang dùng ngôn ngữ/framework gì.

Chuẩn bị — Thu thập tất cả các Secret/Env Key (mất 1 phút):

Mở agent coding ở thư mục website và gõ lệnh sau để hiển thị ra toàn bộ bí mật môi trường. Không cần tự đi lục thư mục:

LỆNH COPY – SHOW CÁC SECRET

Tôi sắp deploy website này lên VPS. Trước khi bắt đầu, hãy tìm và hiển thị ra cho tôi TẤT CẢ các giá trị bí mật tôi đang dùng trong dự án này — bao gồm nhưng không giới hạn: API keys, bot tokens, database URLs, email service keys, payment keys, bất kỳ biến môi trường nào. Tìm trong các file thường có: .env, .env.local, .env.production, config.js, config.json, và trong các hardcode giữa code. Hiển thị theo format: TÊN_BIẾN = giá trị thật [ghi rõ đang nằm ở file nào] Nếu chưa có file .env (secrets đang hardcode trong code), báo tôi biết để xử lý.

💡 Tại sao làm bước này trước: Khi deploy lên VPS, agent sẽ cần dán các secret này vào server. Có sẵn danh sách = không bị dừng giữa chừng đi tìm. Anh em chỉ cần copy output của agent và để sẵn bên cạnh — lúc agent hỏi "Resend key là gì?", anh em paste ngay.


Phần Một: Kéo website về nhà mới (VPS)

💡 Nếu anh em có nhiều dự án nằm rải rác:

Qua các bài trước, có thể anh em đã tạo nhiều thư mục source khác nhau cho nhiều dự án khác nhau — ví dụ 1 landing page bán khóa, 1 blog cá nhân, 1 trang portfolio, 1 form waitlist cho sản phẩm mới... Mỗi cái một thư mục riêng.

Tin vui: anh em hoàn toàn có thể copy tất cả các thư mục đó dồn vào 1 thư mục lớn, deploy chung lên 1 VPS. Nếu các dự án có liên quan nhau (cùng khách hàng, cùng database, cùng luồng bán) — anh em còn có thể mix chúng lại thành một hệ thống thống nhất, chia sẻ cùng brain.db, cùng CRM, cùng email flow. (Không bắt buộc — cứ bắt đầu với 1 dự án chính hôm nay, các dự án khác đưa lên sau cũng được).

Bước 1 — Dọn dẹp code sẵn sàng cho Production:

Dùng prompt này để đưa các bí mật vào file `.env` chuẩn chỉnh và đẩy code lên git:

LỆNH COPY – DỌN CODE PRODUCTION

Tôi sắp deploy website này lên VPS Ubuntu chạy production. Hãy kiểm tra và làm giúp tôi: 1. Đọc toàn bộ cấu trúc — tôi đang dùng ngôn ngữ/framework gì? (HTML tĩnh, Node.js, Python...). Nếu là HTML tĩnh thuần, wrap vào 1 Express server đơn giản để có /admin, API endpoints, kết nối brain.db. 2. Check xem thư mục này đã là git repo và đã có remote GitHub chưa. Nếu chưa, tạo repo private tên my-website trên GitHub của tôi và push lên. 3. Tách tất cả bí mật (API key, bot token, Resend key...) ra file .env. Thêm .env và brain.db vào .gitignore. Tạo file .env.example có mẫu các biến cần set. 4. Đảm bảo server listen port từ biến môi trường (process.env.PORT || 3000). 5. Tạo file deploy_notes.md liệt kê: các biến .env cần có trên VPS, lệnh để chạy server, cổng đang lắng nghe. 6. Commit và push lên GitHub. Xong bước này báo tôi trước khi qua bước 2.

💡 Tại sao phải làm bước này: Vercel "tha thứ" mọi thứ — thiếu env cũng chạy, không có server cũng chạy. VPS không. Lên VPS phải chuẩn từ đầu: env riêng, server rõ ràng, không leak secret. Agent làm hết, anh em chỉ duyệt.

Bước 2 — Để Agent Deploy code lên VPS giúp anh em:

Dùng prompt này để Agent thực hiện mọi quy trình SSH, clone, setup biến môi trường và chạy systemd service:

LỆNH COPY – DEPLOY LÊN VPS

Giờ deploy website lên VPS của tôi. THÔNG TIN VPS (điền trước khi gửi): - IP: [điền IP VPS] - SSH user: [thường là root hoặc ubuntu] - SSH port: [thường là 22] - Cách xác thực: [SSH key ở đường dẫn nào, hoặc password] CÁC SECRET/ENV CẦN SET TRÊN VPS: [paste danh sách secret mà anh em đã cho tôi show ra ở bước chuẩn bị đầu ngày] Làm các việc sau, từng bước một, chờ tôi xác nhận từng bước: 1. SSH vào VPS. Cài Node.js (hoặc runtime phù hợp với code của tôi) nếu chưa có. 2. Clone repo my-website từ GitHub về /opt/my-website trên VPS. 3. npm install (hoặc tương đương). Tạo file .env trên VPS với các giá trị thật ở trên. 4. Upload file brain.db hiện tại của tôi từ máy lên /opt/my-website/brain.db (dùng scp). Đây là database có data thật — KHÔNG lấy từ GitHub. 5. Tạo systemd service tên "mywebsite" để website chạy 24/7 trên port 3000, tự restart nếu crash. Enable và start service. 6. Test: curl http://localhost:3000 trên VPS — phải trả HTML về. Nếu lỗi, fix. 7. Báo tôi khi xong, kèm trạng thái service.

💡 Vì sao phải điền thông tin VPS lại: Agent coding không có trí nhớ giữa các phiên — phiên trước khác phiên này. Nhiệm vụ trước anh em đã đưa thông tin rồi, nhưng nếu mở phiên mới, agent sẽ không biết. Luôn paste thông tin vào prompt để chắc. (Nếu sợ paste credentials vào chat: bảo agent đọc từ file ~/.ssh/config).

💡 Giải thích kiểu trẻ con: VPS giống như căn phòng trống trên mây. Agent coding là người chuyển nhà — nó tự bước vào phòng (SSH), lắp đặt đồ điện (Node.js), mang đồ đạc lên (git clone + scp), cắm điện chạy (systemd). Anh em chỉ đứng ngoài đưa chìa khóa và xác nhận.

⚠️ File brain.db không nằm trong GitHub: Đây là data khách thật — anh em đã thêm vào .gitignore ở Bước 1. Phải upload tay bằng scp. Agent sẽ tự chạy lệnh scp, anh em chỉ cần gật đầu.

Bước 3 — Gắn Domain + HTTPS Tự Động:

Chúng ta sẽ cài đặt reverse proxy (Nginx hoặc Caddy) để phân luồng domain chính về port 3000, subdomain app về port 18790 (goClaw):

💡 Quy tắc đơn giản: goClaw luôn ở subdomain, website luôn ở domain chính. Ví dụ anh em có domain quang.com:

  • quang.com → website (khách vào mua hàng)
  • app.quang.com → goClaw (chỉ anh em vào quản lý)

Lý do: website là bộ mặt công khai, phải dễ nhớ; goClaw là phòng kỹ thuật, ẩn đằng sau subdomain.

LỆNH COPY – SETUP DOMAIN + HTTPS

Setup reverse proxy + HTTPS cho VPS của tôi. THÔNG TIN: - VPS đã có goClaw chạy ở port 18790 (từ nhiệm vụ trước) - VPS vừa có website chạy ở port 3000 (vừa deploy) - Domain chính của tôi: [điền domain].com - Tôi mua domain tại: [điền 123host/Namecheap/Cloudflare/GoDaddy...] Tôi muốn kết quả cuối: - [domain chính].com → website (port 3000) - app.[domain chính].com → goClaw (port 18790) Làm giúp tôi: 1. Hướng dẫn tôi cách thêm/đổi A record tại nhà cung cấp domain của tôi, chỉ rõ từng click. Cần 2 A record: - @ (hoặc domain chính) → IP VPS của tôi - app → IP VPS của tôi 2. Trong khi chờ DNS propagate, cài Caddy trên VPS (dễ nhất — tự lo SSL Let's Encrypt miễn phí). Nếu nhiệm vụ trước tôi đã cài Nginx thì giữ Nginx, chỉ thêm server block mới. 3. Tạo Caddyfile (hoặc Nginx config) với 2 block — 1 cho domain chính trỏ về port 3000, 1 cho subdomain app trỏ về port 18790. 4. Reload Caddy/Nginx. Test curl cả 2 URL — phải trả đúng response. 5. Nếu test fail vì DNS chưa propagate, hướng dẫn tôi cách check bằng dig hoặc công cụ online như dnschecker.org. Bắt đầu bước 1. Chờ tôi xác nhận xong mới qua bước 2.

⏱️ DNS propagate: có thể mất 5 phút đến 24 giờ. Đa số trường hợp xong trong 10-30 phút. Nếu lâu hơn — đừng hoảng, cứ làm việc khác (Bước 4 trở đi) trong khi chờ. Test lại sau vài giờ.

💡 Caddy hay Nginx?

Caddy tự lo SSL — không cần chạy certbot, không cần config 100 dòng. Chỉ 2 dòng là xong HTTPS. Đây là cách docs goClaw khuyên dùng.

Nếu nhiệm vụ trước anh em đã cài Nginx: giữ nguyên, chỉ thêm server block mới cho website. Đừng đổi nếu đang ổn.

Bước 4 — Xác nhận Vercel đã tự ngắt:

Chuyện đã xảy ra một cách âm thầm

Khi anh em đổi A record ở Bước 3 để domain trỏ về IP VPS, thì Vercel về bản chất đã bị ngắt kết nối — không phải anh em phải tự "tắt" gì cả. Domain đã rời khỏi Vercel, trỏ về nhà mới. Vercel chỉ còn là project cũ nằm trong dashboard, không còn phục vụ domain của anh em nữa. Giờ chỉ cần xác nhận mọi thứ đã đúng — không phải sửa gì thêm.

Cách test bằng trình duyệt ẩn danh (Incognito/Private)

Phải dùng chế độ ẩn danh vì browser thường nó cache version cũ của Vercel, test trên tab thường có thể lừa anh em.

  • Vào https://yourdomain.com → phải thấy ổ khóa xanh HTTPS, nội dung website hoạt động, form điền được.
  • Vào https://app.yourdomain.com → phải vào được Dashboard goClaw.

Nếu tab ẩn danh vẫn thấy Vercel cũ: Có nghĩa DNS chưa propagate xong. Không phải lỗi — chờ thêm 10-30 phút rồi test lại. Trong lúc chờ, đi tiếp Phần 2 (MCP) được rồi, không ảnh hưởng.

☕ NGHỈ 5 PHÚT TRƯỚC KHI QUA PHẦN 2

Phần 1 vừa xong là một thành tựu lớn — anh em đã có website thật trên VPS thật, không phải ai cũng làm được trong 1 ngày. Đứng dậy, duỗi người, uống nước. Phần 2 sẽ nhẹ hơn về kỹ thuật nhưng hấp dẫn hơn về trải nghiệm. Sẵn sàng thì đi tiếp.


Phần Hai: Trao Cánh Tay Cho Agent MCP

Bước 5 — Hiểu MCP & Xác định Use Case hữu ích:

Hãy tưởng tượng

goClaw + agent anh em tạo ở nhiệm vụ trước = nhân viên giỏi nhưng đang ngồi ở văn phòng kế bên, nhìn qua cửa kính vào cửa hàng của anh em. Nó thấy mọi thứ nhưng không thò tay vào được. MCP = cái ô cửa nhỏ giữa 2 phòng. Qua ô cửa đó, nhân viên thò tay vào cửa hàng làm việc thật.

MCP là gì về mặt kỹ thuật

Một server nhỏ chạy song song website, expose ra vài "nút bấm" cho AI. AI bấm nút nào → server chạy function đó → ghi database, sửa file, gọi API.

Ví dụ thực tế để hiểu rõ hơn

Giả sử anh em muốn chạy flash sale cuối tuần. Anh em muốn đổi tiêu đề landing ngay để khách vào thấy deal mới:

  • Không có MCP: Anh em chat "Đổi tiêu đề landing thành 'Flash sale cuối tuần 30%'". AI: "Dạ, em đã đổi tiêu đề rồi ạ!" nhưng thực tế file index.html trên VPS không đổi chữ nào. Anh em vẫn phải mở laptop chỉnh tay.
  • Có MCP: Anh em chat "Đổi tiêu đề landing thành 'Flash sale cuối tuần 30%'". AI nhìn vào "hộp tools" MCP, thấy function đổi_tiêu_đề(nội_dung_mới) → gọi nó. Function chạy thật trên VPS → mở file index.html → lưu tiêu đề mới. AI: "Đã đổi tiêu đề. Khách đang truy cập website refresh là thấy."

Ví dụ khác: MCP giống như bộ điều khiển từ xa (Remote). Tivi (website) + anh em (AI) ở 2 đầu phòng. Remote (MCP) là thứ duy nhất khiến anh em bật/tắt/đổi kênh từ xa được.

Nghĩ xem anh em cần "tay" làm gì (4 mẫu tham khảo):

🛒 E-commerce (Bán sản phẩm)

Báo cáo đơn hôm nay, gửi email cảm ơn khách vừa mua, đổi giá sản phẩm trên web, thêm khách VIP.
today_ordersthank_customerupdate_pricetag_vip

✍️ Content / Blog

Nhắn ý tưởng → AI viết nháp → lưu database chờ duyệt → 1 câu "đăng bài số 3" là publish.
save_draftlist_draftspublish_postschedule_post

🧠 Second Brain (Ghi chú)

Nhắn idea bất chợt → lưu vào đúng table → hỏi lại lúc nào cũng được → AI tự phân loại.
add_notequery_brainupdate_brand_voice

⚡ Landing dynamic (Waitlist)

Sửa tiêu đề landing qua Telegram, xem ai mới điền form, gửi email thủ công cho 1 người.
update_herolist_waitlistsend_email

Bước 6 — Để AI tự gợi ý danh sách MCP Tool:

Dùng các prompt sau để AI đọc cấu trúc code và đề xuất 3-5 function MCP phù hợp nhất:

LỆNH COPY – GỢI Ý MCP TOOLS

Đọc toàn bộ codebase website này. Dựa vào những gì tôi đã build (database, form, admin panel, email flow, content...), gợi ý cho tôi 3-5 MCP function hữu ích nhất — những thứ mà tôi sẽ thực sự muốn làm qua Telegram hàng ngày. Với mỗi function, ghi: - Tên function (snake_case) - Input params (tên + kiểu dữ liệu) - Output dự kiến - Tình huống dùng hàng ngày (1 câu) - Độ ưu tiên (1-5) Xếp theo độ ưu tiên giảm dần. Tôi sẽ chọn 3 cái để build đầu tiên. Lưu vào file mcp_functions_draft.md.

LỆNH COPY – CHỐT DANH SÁCH

Tôi chọn 3 function sau để build MCP: [điền 3 tên function]. Cập nhật mcp_functions_draft.md chỉ giữ 3 cái này, viết thêm phần "ví dụ câu nhắn Telegram sẽ trigger function này".

Bước 7 — Vibe code MCP Server:

Dùng cách tiếp cận ngắn gọn, AI-First để yêu cầu Agent tự động code MCP server kết nối goClaw, hoặc dùng prompt chi tiết:

LỆNH COPY – AI-FIRST TỰ NHIÊN

Giờ tôi có agent goClaw và đây là docs của nền tảng này: https://docs.goclaw.sh/ Tôi muốn build MCP server để kết nối agent trong goClaw với hệ thống website này. Đọc docs goClaw về MCP integration trước, rồi đọc codebase của tôi, sau đó đề xuất kế hoạch build và làm giúp tôi. Làm từng bước, chờ tôi xác nhận.

LỆNH COPY – BUILD MCP CHI TIẾT

Tạo MCP server trong chính repo my-website này, thư mục /mcp. Dùng transport streamable-http (vì goClaw sẽ gọi qua HTTP localhost). Yêu cầu: 1. Tech stack: cùng ngôn ngữ với website (Node.js dùng @modelcontextprotocol/sdk, Python dùng mcp package). Nếu website Node, dùng Node. 2. Server listen port 3001, chỉ bind 127.0.0.1 (localhost only, KHÔNG public ra internet). 3. Expose đúng 3 function tôi đã chọn trong mcp_functions_draft.md. Mỗi function phải: - Kết nối cùng brain.db với website (cùng file, không tạo DB mới) - Validate input kỹ càng - Trả về kết quả rõ ràng (success/error + message) - Log mọi lần gọi ra console với timestamp 4. Tạo file mcp/README.md hướng dẫn deploy, kèm systemd service file mẫu. 5. Bạn tự chạy MCP server local và tự gọi curl test cả 3 function để đảm bảo chạy được. TÔI KHÔNG chạy test — agent tự làm và báo kết quả. 6. Sau khi test pass, commit+push lên GitHub. Làm từng bước, chờ tôi xác nhận từng bước.

Bước 8 — Deploy MCP lên VPS + Connect vào goClaw:

Tiến hành deploy máy chủ MCP vừa build lên VPS của anh em:

LỆNH COPY – DEPLOY MCP SERVER

Deploy MCP server vừa build lên VPS: 1. SSH vào VPS, vào /opt/my-website (đã có sẵn từ Bước 2). 2. git pull để lấy code MCP mới. 3. npm install các package MCP cần. 4. Tạo systemd service "mcp-server" chạy MCP server ở 127.0.0.1:3001, tự restart. Enable và start. 5. Test trên VPS: curl http://127.0.0.1:3001/mcp (hoặc endpoint health check) — phải phản hồi. 6. Báo tôi trạng thái service. Xong bước này tôi sẽ vào Dashboard goClaw tự thêm MCP server.

3 CÁCH "NÓI" ĐỊA CHỈ MỘT MÁY – VÀ CÁCH CHỌN URL CHO MCP

Cùng 1 máy có thể có 3 "tên gọi":

  • 127.0.0.1 — cách gọi "nhà mình" khi đang đứng ở trong nhà. Chỉ chương trình cùng máy dùng được.
  • 45.76.100.20 (IP public) — địa chỉ nhà nhìn từ ngoài đường. Ai trên internet biết IP đều có thể gọi tới.
  • mcp.yourdomain.com — tên nhà thân thiện, trỏ về IP public.

→ KỊCH BẢN A — goClaw và MCP cùng VPS:

Điền URL: http://127.0.0.1:3001/mcp

Lý do: goClaw gọi MCP mà không cần đi vòng ra internet — gọi "nhà mình" là nhanh và an toàn nhất. Bind MCP ở 127.0.0.1 như đã làm ở Bước 7 là đúng.

→ KỊCH BẢN B — goClaw và MCP khác VPS:

Điền URL: https://mcp.yourdomain.com/mcp (hoặc IP public: http://45.76.100.20:3001/mcp)

Lý do: goClaw đang ở một VPS khác — nó phải "đi ra đường" để gọi MCP. Phải có địa chỉ công khai thì mới gọi tới được. (Cần cấu hình 0.0.0.0 cho MCP, setup subdomain mcp và auth token bảo mật).

**Thêm MCP vào goClaw Dashboard:** Đăng nhập vào dashboard goClaw của anh em → chọn **Capabilities** → **MCP Servers** → Bấm **Add MCP Server** và điền URL theo kịch bản ở trên rồi phân quyền `biz__*` tool cho Telegram Agent của anh em.

Bước 9 — Test qua Telegram — Khoảnh khắc "wow":

Mở Telegram và gửi tin nhắn tự nhiên để bot Agent thực thi tool thông qua MCP Server, ví dụ: "Đổi tiêu đề landing thành 'Flash sale cuối tuần 30%'" hoặc "Báo cáo đơn hôm nay". Refresh lại website trong trình duyệt ẩn danh để chứng kiến điều kỳ diệu!

💡 Nếu agent không gọi tool mà trả lời text thường: Vào Dashboard goClaw → agent detail → tab Files → mở AGENTS.md hoặc SOUL.md → thêm 1 dòng: "Khi user yêu cầu sửa/xoá/báo cáo data, LUÔN gọi tool MCP thay vì chỉ trả lời text." (Hoặc nhắn thẳng: "Dùng tool biz__update_hero để đổi tiêu đề").

Hoàn thành khi:

  • Website chạy trên VPS thật với domain + HTTPS — không còn Vercel.
  • Nhắn 1 câu tự nhiên qua Telegram → AI gọi MCP → website/database thay đổi thật.
Quay lại Bài 10 Tiến tới Bài 12