monacloud-mcp 0.10.4 → 0.10.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/clients.js +1 -1
- package/dist/compute.d.ts +1 -1
- package/dist/compute.js +1 -1
- package/dist/domains.js +4 -4
- package/dist/server.js +5 -5
- package/docs/ai-agent.md +3 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -6,11 +6,11 @@ Human đăng ký MONA Pass một lần, duyệt chi phí, thêm DNS khi cần, q
|
|
|
6
6
|
|
|
7
7
|
## 0.8.1 — luật nạp ví đứng đầu instructions
|
|
8
8
|
|
|
9
|
-
Codex chỉ chắc chắn đọc 512 ký tự đầu của `instructions` MCP, nên luật "ví thiếu → AI tự gọi `cloud_topup`, in QR
|
|
9
|
+
Codex chỉ chắc chắn đọc 512 ký tự đầu của `instructions` MCP, nên luật "ví thiếu → AI tự gọi `cloud_topup`, in QR" được đưa lên đầu; mô tả hệ và APP_FLOW đặt sau. Kiểm thử 17/09: Claude Code (sonnet) và Gemini (Antigravity CLI) tự gọi `cloud_topup` và in QR khi người dùng nói "ví hết tiền, nạp 50k"; Codex chạy headless (`codex exec`) mặc định chặn mọi lời gọi MCP theo approval policy; thêm `--approve-for-me` thì Codex cũng tự gọi `cloud_topup` và in QR (kiểm 17/09). Codex tương tác thì duyệt lời gọi tool như bình thường.
|
|
10
10
|
|
|
11
11
|
## 0.8.0 — Nạp ví ngay trong terminal
|
|
12
12
|
|
|
13
|
-
Ví thiếu tiền thì AI gọi `cloud_topup(amount)`; MCP trả **`qr_ascii`** (QR VietQR chuẩn EMVCo/NAPAS in bằng khối đầy `██`, Claude Code/Codex/Gemini CLI hiện được ngay; terminal nền sáng dùng `qr_ascii_light`, bản gọn `qr_ascii_small`; đã giải mã được bằng ZBar và OpenCV ở cả hai nền), `qr_file` (PNG tại `~/.config/monacloud/`), `qr_url` (ảnh VietQR) cùng ngân hàng, số tài khoản, số tiền, nội dung chuyển khoản. Người dùng mở app ngân hàng quét màn hình, tiền vào tự cộng ví; AI gọi `cloud_topup_status(topup_id)` tới khi `paid` rồi làm tiếp.
|
|
13
|
+
Ví thiếu tiền thì AI gọi `cloud_topup(amount)`; MCP trả **`qr_ascii`** (QR VietQR chuẩn EMVCo/NAPAS in bằng khối đầy `██`, Claude Code/Codex/Gemini CLI hiện được ngay; terminal nền sáng dùng `qr_ascii_light`, bản gọn `qr_ascii_small`; đã giải mã được bằng ZBar và OpenCV ở cả hai nền), `qr_file` (PNG tại `~/.config/monacloud/`), `qr_url` (ảnh VietQR) cùng ngân hàng, số tài khoản, số tiền, nội dung chuyển khoản. Người dùng mở app ngân hàng quét màn hình, tiền vào tự cộng ví; AI gọi `cloud_topup_status(topup_id)` tới khi `paid` rồi làm tiếp. base64 không còn nằm trong text (tiết kiệm 15–25k token mỗi lần). Khi ví chung (`billing`) chưa nhận token hoặc merchant MONA Pay chưa cấu hình, `cloud_topup` tự chuyển sang đường compute `/api/payments/vietqr` (ví local, prefix VIBECLOUD, báo có tự cộng).
|
|
14
14
|
|
|
15
15
|
## 0.5.0 — MONA Base beta
|
|
16
16
|
|
package/dist/clients.js
CHANGED
|
@@ -85,7 +85,7 @@ export class CloudClients {
|
|
|
85
85
|
currency: 'VND',
|
|
86
86
|
wallet: 'local',
|
|
87
87
|
source: '/api/me',
|
|
88
|
-
note: 'Số dư ví local MONA Cloud compute (billing.monacloud.vn không nhận token này). Thiếu tiền thì gọi cloud_topup: QR VietQR in ngay trong terminal, người dùng quét bằng app ngân hàng
|
|
88
|
+
note: 'Số dư ví local MONA Cloud compute (billing.monacloud.vn không nhận token này). Thiếu tiền thì gọi cloud_topup: QR VietQR in ngay trong terminal, người dùng quét bằng app ngân hàng. / Local compute wallet balance; top up with cloud_topup.',
|
|
89
89
|
};
|
|
90
90
|
}
|
|
91
91
|
}
|
package/dist/compute.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
2
|
import type { CloudClients } from './clients.js';
|
|
3
3
|
type Row = Record<string, unknown>;
|
|
4
|
-
export declare const APP_FLOW = "AI l\u00E0m 99%: cloud_app_detect(local_dir) offline \u2192 cloud_app_host_list, cloud_prices/cloud_packages/cloud_plan_list v\u00E0 cloud_balance \u2192 cloud_app_create(local_dir, sandbox=true) n\u1EBFu ch\u01B0a c\u00F3 app host \u0111\u1EC3 \u01B0\u1EDBc t\u00EDnh chi ph\u00ED gi\u1EDD/g\u00F3i \u2192 h\u1ECFi human m\u1ED9t l\u1EA7n duy\u1EC7t chi ph\u00ED n\u1EBFu ch\u01B0a \u0111\u01B0\u1EE3c duy\u1EC7t \u2192 cloud_app_create(local_dir, sandbox=false) \u2192 poll t\u1EDBi done/succeeded \u2192 ki\u1EC3m v\u00E0 tr\u1EA3 URL. C\u1EA7n DB/Supabase? cloud_base_create (beta) \u2014 chung account/v\u00ED MONA Cloud, kh\u1EDBp app deploy. N\u1EBFu human c\u00F3 domain: cloud_app_domain_add v\u00E0 h\u01B0\u1EDBng d\u1EABn CNAME t\u1EEB API. Human \u0111\u0103ng k\u00FD MONA Pass b\u1EB1ng device flow m\u1ED9t l\u1EA7n; h\u1EBFt credit 20k th\u00EC AI g\u1ECDi cloud_topup v\u00E0 in QR (qr_ascii) ngay trong terminal, human ch\u1EC9 qu\u00E9t b\u1EB1ng app ng\u00E2n h\u00E0ng
|
|
4
|
+
export declare const APP_FLOW = "AI l\u00E0m 99%: cloud_app_detect(local_dir) offline \u2192 cloud_app_host_list, cloud_prices/cloud_packages/cloud_plan_list v\u00E0 cloud_balance \u2192 cloud_app_create(local_dir, sandbox=true) n\u1EBFu ch\u01B0a c\u00F3 app host \u0111\u1EC3 \u01B0\u1EDBc t\u00EDnh chi ph\u00ED gi\u1EDD/g\u00F3i \u2192 h\u1ECFi human m\u1ED9t l\u1EA7n duy\u1EC7t chi ph\u00ED n\u1EBFu ch\u01B0a \u0111\u01B0\u1EE3c duy\u1EC7t \u2192 cloud_app_create(local_dir, sandbox=false) \u2192 poll t\u1EDBi done/succeeded \u2192 ki\u1EC3m v\u00E0 tr\u1EA3 URL. C\u1EA7n DB/Supabase? cloud_base_create (beta) \u2014 chung account/v\u00ED MONA Cloud, kh\u1EDBp app deploy. N\u1EBFu human c\u00F3 domain: cloud_app_domain_add v\u00E0 h\u01B0\u1EDBng d\u1EABn CNAME t\u1EEB API. Human \u0111\u0103ng k\u00FD MONA Pass b\u1EB1ng device flow m\u1ED9t l\u1EA7n; h\u1EBFt credit 20k th\u00EC AI g\u1ECDi cloud_topup v\u00E0 in QR (qr_ascii) ngay trong terminal, human ch\u1EC9 qu\u00E9t b\u1EB1ng app ng\u00E2n h\u00E0ng; AI l\u00E0m c\u00E1c b\u01B0\u1EDBc c\u00F2n l\u1EA1i. App git cloud_app_create(repo_url) \u0111\u00E3 live; kh\u00F4ng g\u1ECDi agent_deploy cho deploy d\u1EF1 \u00E1n. / Detect locally, estimate, obtain cost approval once, upload and deploy, create an optional Base, return URL, then attach an optional domain.";
|
|
5
5
|
export declare function rows(value: unknown, key: string): Row[];
|
|
6
6
|
export declare function planEstimate(clients: CloudClients, code: string, cycle?: string): Promise<{
|
|
7
7
|
plan: Row;
|
package/dist/compute.js
CHANGED
|
@@ -4,7 +4,7 @@ import { unwrapData } from './http.js';
|
|
|
4
4
|
import { finishAppJob } from './jobs.js';
|
|
5
5
|
import { detectProject } from './local.js';
|
|
6
6
|
import { localAppTools } from './local-app.js';
|
|
7
|
-
export const APP_FLOW = 'AI làm 99%: cloud_app_detect(local_dir) offline → cloud_app_host_list, cloud_prices/cloud_packages/cloud_plan_list và cloud_balance → cloud_app_create(local_dir, sandbox=true) nếu chưa có app host để ước tính chi phí giờ/gói → hỏi human một lần duyệt chi phí nếu chưa được duyệt → cloud_app_create(local_dir, sandbox=false) → poll tới done/succeeded → kiểm và trả URL. Cần DB/Supabase? cloud_base_create (beta) — chung account/ví MONA Cloud, khớp app deploy. Nếu human có domain: cloud_app_domain_add và hướng dẫn CNAME từ API. Human đăng ký MONA Pass bằng device flow một lần; hết credit 20k thì AI gọi cloud_topup và in QR (qr_ascii) ngay trong terminal, human chỉ quét bằng app ngân hàng
|
|
7
|
+
export const APP_FLOW = 'AI làm 99%: cloud_app_detect(local_dir) offline → cloud_app_host_list, cloud_prices/cloud_packages/cloud_plan_list và cloud_balance → cloud_app_create(local_dir, sandbox=true) nếu chưa có app host để ước tính chi phí giờ/gói → hỏi human một lần duyệt chi phí nếu chưa được duyệt → cloud_app_create(local_dir, sandbox=false) → poll tới done/succeeded → kiểm và trả URL. Cần DB/Supabase? cloud_base_create (beta) — chung account/ví MONA Cloud, khớp app deploy. Nếu human có domain: cloud_app_domain_add và hướng dẫn CNAME từ API. Human đăng ký MONA Pass bằng device flow một lần; hết credit 20k thì AI gọi cloud_topup và in QR (qr_ascii) ngay trong terminal, human chỉ quét bằng app ngân hàng; AI làm các bước còn lại. App git cloud_app_create(repo_url) đã live; không gọi agent_deploy cho deploy dự án. / Detect locally, estimate, obtain cost approval once, upload and deploy, create an optional Base, return URL, then attach an optional domain.';
|
|
8
8
|
const sandbox = z.boolean().optional().describe('Thử 0đ, không tạo hạ tầng thật / Sandbox, no charge');
|
|
9
9
|
const id = z.string().trim().min(1).max(255);
|
|
10
10
|
const planCode = z.string().trim().min(2).max(64);
|
package/dist/domains.js
CHANGED
|
@@ -43,7 +43,7 @@ export function registerDomainTools(server, clients) {
|
|
|
43
43
|
return {
|
|
44
44
|
results,
|
|
45
45
|
guest: true,
|
|
46
|
-
next_step: 'Người dùng chưa đăng nhập MONA Pass. Muốn mua: gọi cloud_domain_reserve (hỏi email + số điện thoại, xác nhận chính tả) → đưa QR trong payment + claim_url
|
|
46
|
+
next_step: 'Người dùng chưa đăng nhập MONA Pass. Muốn mua: gọi cloud_domain_reserve (hỏi email + số điện thoại, xác nhận chính tả) → đưa QR trong payment + claim_url; người dùng chỉ quét QR rồi đăng nhập MONA Pass một bước, không phải đăng ký trước.',
|
|
47
47
|
};
|
|
48
48
|
}
|
|
49
49
|
return results;
|
|
@@ -69,7 +69,7 @@ export function registerDomainTools(server, clients) {
|
|
|
69
69
|
'2. Hỏi người dùng xác nhận chính tả tên miền (vd: "Đăng ký example.vn nhé?") → spelling_confirmed. WHOIS không sửa được sau khi mua.',
|
|
70
70
|
'3. Hỏi duyệt chi phí (giá từ search).',
|
|
71
71
|
'4. cloud_domain_registrant_set để lưu thông tin chủ thể (hỏi người dùng ngay trong phiên); .vn cần CCCD/MST.',
|
|
72
|
-
'Khi gọi mà trả 402 insufficient_balance → gọi cloud_topup, IN NGUYÊN KHỐI qr_ascii (QR VietQR) cho người dùng quét bằng app ngân hàng NGAY trong terminal, chờ cloud_topup_status=paid rồi gọi lại cloud_domain_buy.
|
|
72
|
+
'Khi gọi mà trả 402 insufficient_balance → gọi cloud_topup, IN NGUYÊN KHỐI qr_ascii (QR VietQR) cho người dùng quét bằng app ngân hàng NGAY trong terminal, chờ cloud_topup_status=paid rồi gọi lại cloud_domain_buy.',
|
|
73
73
|
'Kết quả có suggested_next → gợi ý người dùng deploy app lên MONA Cloud (cloud_app_create) và gắn domain (cloud_domain_attach).',
|
|
74
74
|
'.vn sau khi mua ở trạng thái pending_verification → dùng cloud_domain_verify_start (link eKYC/bản khai) rồi cloud_domain_wait.',
|
|
75
75
|
'sandbox=true: giả lập 0đ, không mua thật.',
|
|
@@ -248,7 +248,7 @@ export function registerDomainTools(server, clients) {
|
|
|
248
248
|
}, ({ domain_id }) => runTool(() => clients.vibecloud(`/api/domains/${encodeURIComponent(domain_id)}/records`)));
|
|
249
249
|
server.registerTool('cloud_domain_dns_add', {
|
|
250
250
|
title: 'Thêm bản ghi DNS',
|
|
251
|
-
description: 'Thêm 1 bản ghi DNS. Vd trỏ web: type=A, name=@, data=<IP>. Trỏ www: type=CNAME, name=www, data=<domain>. AI làm trọn
|
|
251
|
+
description: 'Thêm 1 bản ghi DNS. Vd trỏ web: type=A, name=@, data=<IP>. Trỏ www: type=CNAME, name=www, data=<domain>. AI làm trọn.',
|
|
252
252
|
inputSchema: z.object({ domain_id: objectId, ...recordSchema }).strict(),
|
|
253
253
|
}, ({ domain_id, ...record }) => runTool(() => clients.vibecloud(`/api/domains/${encodeURIComponent(domain_id)}/records`, { method: 'POST', body: record })));
|
|
254
254
|
server.registerTool('cloud_domain_dns_update', {
|
|
@@ -289,7 +289,7 @@ export function registerDomainTools(server, clients) {
|
|
|
289
289
|
⚠️ Nếu tôi CHƯA có tài khoản MONA Pass / tool trả login_required: KHÔNG bảo tôi đi đăng ký trước. Dùng cloud_domain_reserve (hỏi email + sđt, hỏi 1 câu "nhận ưu đãi MONA Cloud không?") → đưa tôi QR trong payment để quét trả tiền ngay + claim_url để tôi bấm đăng nhập 1 bước (Google/GitHub/email) → hệ tự tạo ví + mua. Theo dõi bằng cloud_domain_reserve_status; nếu tôi đã login trên máy này thì gọi cloud_domain_claim.
|
|
290
290
|
6. Nếu là .vn: cloud_domain_verify_start đưa tôi link eKYC/bản khai (chụp CCCD + chân dung / ký), rồi cloud_domain_wait tới khi active.
|
|
291
291
|
7. ${app_id ? `Gắn vào app ${app_id} bằng cloud_domain_attach` : 'Gợi ý tôi deploy app lên MONA Cloud (cloud_app_create) rồi gắn domain bằng cloud_domain_attach'} — trỏ DNS + SSL tự động.
|
|
292
|
-
Trả VND đã VAT bằng chuyển khoản QR
|
|
292
|
+
Trả VND đã VAT bằng chuyển khoản QR.`,
|
|
293
293
|
},
|
|
294
294
|
}] }));
|
|
295
295
|
}
|
package/dist/server.js
CHANGED
|
@@ -105,7 +105,7 @@ export function createServer(dependencies = {}) {
|
|
|
105
105
|
const catalog = new TemplateCatalog(config, fetchImpl);
|
|
106
106
|
const server = new McpServer({ name: 'monacloud-mcp', version: PKG_VERSION },
|
|
107
107
|
// Codex chỉ chắc chắn đọc 512 ký tự đầu của instructions → luật quan trọng nhất đặt trước, mô tả hệ đặt sau.
|
|
108
|
-
{ instructions: `Tên miền khi người dùng CHƯA có tài khoản: cloud_domain_search (không cần login) → cloud_domain_reserve (email + sđt) → đưa QR + claim_url
|
|
108
|
+
{ instructions: `Tên miền khi người dùng CHƯA có tài khoản: cloud_domain_search (không cần login) → cloud_domain_reserve (email + sđt) → đưa QR + claim_url (người dùng chỉ quét QR rồi đăng nhập một bước, không phải đăng ký trước); có tài khoản rồi thì cloud_domain_claim/cloud_domain_buy. Ví thiếu tiền: AI tự gọi cloud_topup, in nguyên khối qr_ascii (QR VietQR) cho người dùng quét bằng app ngân hàng ngay trong terminal, rồi cloud_topup_status tới khi paid. Dùng cloud_* cho tài khoản, ví và hạ tầng; monapay_* cho thu tiền; mail_* để gửi email giao dịch (MONA Mail); agent_* cho catalog. Không bao giờ yêu cầu mật khẩu sản phẩm. Đọc → ước tính → hỏi duyệt nếu chưa được duyệt → làm. Dừng chờ người dùng ở: quét QR nạp, duyệt chi phí, thêm DNS, OTP hoặc KYC.\n${ENTITY}\n${APP_FLOW}` });
|
|
109
109
|
server.registerTool('cloud_whoami', {
|
|
110
110
|
title: 'Tài khoản MONA Cloud',
|
|
111
111
|
description: 'Xác minh MONA Pass hiện tại. / Return the current MONA Pass profile.',
|
|
@@ -124,7 +124,7 @@ export function createServer(dependencies = {}) {
|
|
|
124
124
|
}, ({ cursor, limit }) => runTool(() => clients.ledger(cursor, limit)));
|
|
125
125
|
server.registerTool('cloud_topup', {
|
|
126
126
|
title: 'Nạp ví bằng VietQR ngay trong terminal',
|
|
127
|
-
description: 'AI tự tạo yêu cầu nạp ví và nhận QR VietQR: qr_ascii (khối đầy, in thẳng trong Claude Code/Codex/Gemini; nền sáng dùng qr_ascii_light), qr_file (PNG trên máy), qr_url (ảnh). Người dùng chỉ quét bằng app ngân hàng
|
|
127
|
+
description: 'AI tự tạo yêu cầu nạp ví và nhận QR VietQR: qr_ascii (khối đầy, in thẳng trong Claude Code/Codex/Gemini; nền sáng dùng qr_ascii_light), qr_file (PNG trên máy), qr_url (ảnh). Người dùng chỉ quét bằng app ngân hàng. Tiền vào tự cộng ví; xác nhận bằng cloud_topup_status.',
|
|
128
128
|
inputSchema: {
|
|
129
129
|
amount: z.number().int().min(10_000).max(500_000_000).describe('Số tiền nguyên VND, tối thiểu 10.000'),
|
|
130
130
|
idempotency_key: z.string().min(1).max(255).optional(),
|
|
@@ -371,7 +371,7 @@ export function createServer(dependencies = {}) {
|
|
|
371
371
|
}, async (uri) => ({ contents: [{
|
|
372
372
|
uri: uri.href,
|
|
373
373
|
mimeType: 'text/plain',
|
|
374
|
-
text: `${ENTITY}\n\n${APP_FLOW}\n\nHuman đăng ký MONA Pass một lần, duyệt chi phí, thêm DNS khi cần, quét QR nạp ví do AI tạo bằng cloud_topup (in ngay trong terminal
|
|
374
|
+
text: `${ENTITY}\n\n${APP_FLOW}\n\nHuman đăng ký MONA Pass một lần, duyệt chi phí, thêm DNS khi cần, quét QR nạp ví do AI tạo bằng cloud_topup (in ngay trong terminal) và cung cấp OTP/KYC bắt buộc. AI dùng MCP làm phần còn lại.\n\n- cloud_*: tài khoản, ví, ledger, usage, budget, VPS, database, Base beta thay Supabase, job, vòng đời service, plans, subscriptions, invoices/PDF, credit và apps từ git hoặc thư mục local (source=upload); cần DB/Supabase thì dùng cloud_base_create — chung account, khớp app deploy; cloud_app_detect hoàn toàn offline.\n- monapay_*: nối ngân hàng, checkout/QR, giao dịch, webhook và email.\n- mail_*: tài khoản, domain, API key, gửi mail, trạng thái, webhook, suppression (MONA Mail https://monamail.vn, API https://api.monamail.vn)\n- agent_*: catalog và deploy template.\n\nMONA Cloud: https://monacloud.vn\nCompute API: https://api.monacloud.vn\nMONA Pay: https://monapay.vn\n`,
|
|
375
375
|
}] }));
|
|
376
376
|
server.registerResource('monacloud-status', 'monacloud://status', {
|
|
377
377
|
title: 'Trạng thái hệ MONA Cloud',
|
|
@@ -398,7 +398,7 @@ export function createServer(dependencies = {}) {
|
|
|
398
398
|
role: 'user',
|
|
399
399
|
content: {
|
|
400
400
|
type: 'text',
|
|
401
|
-
text: `Dựng app bán hàng ${app_name || 'của tôi'} bằng ${framework || 'stack phù hợp'} trên MONA Cloud. ${APP_FLOW}\nTheo đúng thứ tự:\n1. Gọi cloud_whoami, cloud_balance, cloud_plan_list, cloud_packages và cloud_prices. Báo ước tính và hỏi duyệt chi phí nếu chưa được duyệt. Nếu thiếu tiền, gọi cloud_topup, in nguyên khối qr_ascii kèm số tiền/nội dung để người dùng quét bằng app ngân hàng, rồi cloud_topup_status tới khi paid
|
|
401
|
+
text: `Dựng app bán hàng ${app_name || 'của tôi'} bằng ${framework || 'stack phù hợp'} trên MONA Cloud. ${APP_FLOW}\nTheo đúng thứ tự:\n1. Gọi cloud_whoami, cloud_balance, cloud_plan_list, cloud_packages và cloud_prices. Báo ước tính và hỏi duyệt chi phí nếu chưa được duyệt. Nếu thiếu tiền, gọi cloud_topup, in nguyên khối qr_ascii kèm số tiền/nội dung để người dùng quét bằng app ngân hàng, rồi cloud_topup_status tới khi paid.\n2. Nếu dùng VPS gọi cloud_vps_create và cloud_db_create. Cần DB/Supabase thì ưu tiên cloud_base_create (beta) — chung account, khớp app deploy. Nếu deploy dự án dùng cloud_app_detect(local_dir), cloud_app_host_list rồi cloud_app_create(local_dir), sandbox trước nếu chưa có host. Poll từng job bằng cloud_job_status tới done/succeeded.\n3. Gọi monapay_link nếu MONA Pay còn ở lớp chuyển tiếp. Gọi monapay_whoami; nếu chưa có VA, nối ngân hàng bằng chuỗi monapay_link_bank_start → HỎI OTP → verify → notification_register → HỎI OTP lần 2 → verify. Không tự đoán OTP.\n4. Viết endpoint webhook có HMAC và idempotency theo transaction_code; đăng ký bằng monapay_create_webhook, bắn monapay_test_webhook và đọc monapay_webhook_logs.\n5. Tích hợp monapay_create_checkout hoặc monapay_create_qr vào app, chỉ giao hàng sau CHECKOUT_PAID.\n6. Với dự án local, dùng cloud_app_create(local_dir) sau khi duyệt ước tính; git dùng repo_url; kiểm cloud_app_get/cloud_app_logs và health rồi báo URL. Chỉ dùng VPS thủ công khi người dùng chọn. Nạp tiền qua cloud_topup, người dùng chỉ quét QR và nhập OTP bắt buộc.`,
|
|
402
402
|
},
|
|
403
403
|
}] }));
|
|
404
404
|
server.registerPrompt('gui-mail-otp-monamail', {
|
|
@@ -421,7 +421,7 @@ export function createServer(dependencies = {}) {
|
|
|
421
421
|
5. Gọi mail_api_key_create với name theo app và mode live; khi thử sandbox chọn mode test (mm_test_). Key chỉ trả một lần: ghi trực tiếp vào .env của app dưới tên MONAMAIL_API_KEY, bỏ .env khỏi git, không in key ra chat hoặc log. Chỉ báo prefix nếu cần nhận diện.
|
|
422
422
|
6. Viết code gửi OTP ở server bằng SDK npm monamail: import { MonaMail } from 'monamail'; const monamail = new MonaMail(process.env.MONAMAIL_API_KEY); const { id } = await monamail.emails.send({ from: 'Tên app <noreply@DOMAIN_DA_VERIFY>', to: emailNguoiNhan, subject: 'Mã OTP', text: 'Mã OTP: ' + otp, tags: ['otp'], idempotency_key: requestId }); Thay placeholder bằng domain đã verify, sinh OTP ngẫu nhiên có hạn dùng và giới hạn số lần thử. Giữ cùng idempotency_key khi retry cùng yêu cầu trong 24 giờ. Gọi mail_status để kiểm kết quả.
|
|
423
423
|
7. Viết HTTPS endpoint nhận email.bounced; xác minh HMAC trên timestamp và raw body bằng MonaMail.verifyWebhook, chống replay và xử lý idempotent theo event id. Gọi mail_webhook_create với events: ['email.bounced'], lưu secret riêng trong .env, rồi mail_webhook_test (payload thử là email.delivered). Kiểm suppression bằng mail_suppressions_list khi có bounce.
|
|
424
|
-
Chỉ dừng hỏi người dùng ở bước thêm DNS hoặc nạp tiền (quét QR). Nếu mail_plan_set trả insufficient_funds, gọi cloud_topup, in nguyên khối qr_ascii để người dùng quét bằng app ngân hàng, rồi cloud_topup_status tới khi paid và cloud_balance cập nhật. Dùng mail_plans để đọc giá hiện hành, không hard-code giá.
|
|
424
|
+
Chỉ dừng hỏi người dùng ở bước thêm DNS hoặc nạp tiền (quét QR). Nếu mail_plan_set trả insufficient_funds, gọi cloud_topup, in nguyên khối qr_ascii để người dùng quét bằng app ngân hàng, rồi cloud_topup_status tới khi paid và cloud_balance cập nhật. Dùng mail_plans để đọc giá hiện hành, không hard-code giá. API key lấy qua tool, người dùng chỉ duyệt.`,
|
|
425
425
|
},
|
|
426
426
|
}] }));
|
|
427
427
|
return server;
|
package/docs/ai-agent.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# MONA Cloud MCP — hướng dẫn cho AI agent
|
|
2
2
|
|
|
3
|
-
Tài liệu này dành cho Claude, Codex, Cursor và agent dùng Model Context Protocol. Mục tiêu là hoàn thành tích hợp end-to-end
|
|
3
|
+
Tài liệu này dành cho Claude, Codex, Cursor và agent dùng Model Context Protocol. Mục tiêu là hoàn thành tích hợp end-to-end với các bước người chỉ là duyệt và quét QR; các bước human gồm đăng ký MONA Pass, duyệt chi phí, thêm DNS khi cần, nạp tiền và OTP/KYC bắt buộc.
|
|
4
4
|
|
|
5
5
|
## Luồng chuẩn 0.5.0: AI làm 99%
|
|
6
6
|
|
|
@@ -19,7 +19,7 @@ Human chỉ cần đăng ký MONA Pass/device flow một lần, duyệt chi phí
|
|
|
19
19
|
|
|
20
20
|
1. Bắt đầu bằng `cloud_whoami`. Nếu nhận `login_required`, yêu cầu người dùng chạy `monacloud-mcp login`; không hỏi username hoặc password trong chat.
|
|
21
21
|
2. Trước khi provision thật, đọc `cloud_balance`, `cloud_plan_list` hoặc `cloud_packages`/`cloud_prices`; báo ước tính và hỏi duyệt chi phí nếu chưa được duyệt. Với `sandbox: true`, không cần đọc hoặc nạp ví.
|
|
22
|
-
3. Khi cần nạp, gọi `cloud_topup`; in NGUYÊN khối `qr_ascii` (không bọc lại) kèm ngân hàng, số tài khoản, số tiền, nội dung chuyển khoản; nhắc `qr_file`/`qr_url` nếu terminal hiển thị mờ.
|
|
22
|
+
3. Khi cần nạp, gọi `cloud_topup`; in NGUYÊN khối `qr_ascii` (không bọc lại) kèm ngân hàng, số tài khoản, số tiền, nội dung chuyển khoản; nhắc `qr_file`/`qr_url` nếu terminal hiển thị mờ. Chỉ tiếp tục sau khi `cloud_topup_status` trả `paid` hoặc `cloud_balance` phản ánh tiền vào.
|
|
23
23
|
4. Với OTP ngân hàng, dừng đúng sau `monapay_link_bank_start` và `monapay_notification_register`. Hỏi người dùng mã vừa nhận; không suy đoán, brute-force hoặc ghi OTP vào source/log.
|
|
24
24
|
5. Mọi endpoint webhook phải xác minh HMAC, chống replay theo timestamp và idempotent theo `transaction_code`.
|
|
25
25
|
6. Không giao hàng chỉ dựa vào browser redirect. Chỉ xác nhận đơn sau webhook `CHECKOUT_PAID` hoặc đối soát server-side.
|
|
@@ -175,7 +175,7 @@ const { id } = await monamail.emails.send({
|
|
|
175
175
|
|
|
176
176
|
`emailNguoiNhan`, `otp` và `requestId` lấy từ luồng xác thực của app. Dùng `MonaMail.verifyWebhook({ secret, timestamp, body, signature })` kiểm `X-Mona-Signature` trên `"<X-Mona-Timestamp>.<raw_body>"`. Chống replay theo timestamp, xử lý event một lần theo payload `id`/`X-Mona-Event-Id`.
|
|
177
177
|
|
|
178
|
-
Ranh giới human của luồng Mail sau đăng nhập là **thêm DNS và quét QR nạp tiền**. Khi `mail_plan_set` trả `insufficient_funds`, gọi `cloud_topup`, in `qr_ascii` cho user quét và chờ `cloud_topup_status` paid hoặc `cloud_balance` cập nhật trước khi thử lại.
|
|
178
|
+
Ranh giới human của luồng Mail sau đăng nhập là **thêm DNS và quét QR nạp tiền**. Khi `mail_plan_set` trả `insufficient_funds`, gọi `cloud_topup`, in `qr_ascii` cho user quét và chờ `cloud_topup_status` paid hoặc `cloud_balance` cập nhật trước khi thử lại. API key lấy qua tool. Lỗi Mail giữ `code`, `message`, `next_step`, `request_id` từ API, gồm `domain_not_verified`, `quota_exceeded`, `budget_exceeded` và `idempotency_conflict`.
|
|
179
179
|
|
|
180
180
|
### Sandbox và idempotency Mail
|
|
181
181
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "monacloud-mcp",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.5",
|
|
4
4
|
"description": "MCP server for MONA Cloud — deploy apps (Vercel alternative), Supabase-compatible Postgres/Auth/Storage bases (Supabase alternative), VND wallet, MONA Pay & Mail — for AI agents (Claude, Cursor, Codex) in Vietnam.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://monacloud.vn",
|