gearvn-pages-mcp-server 1.1.0 → 1.2.0

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 CHANGED
@@ -2,63 +2,19 @@
2
2
 
3
3
  MCP (Model Context Protocol) Server cho việc deploy và quản lý các trang HTML tĩnh lên GearVN Pages.
4
4
 
5
- ## Tính năng
6
-
7
- ### 1. deploy-page
8
- Deploy hoặc update một trang HTML tĩnh.
9
-
10
- **Parameters:**
11
- - `title` (string): Tiêu đề của trang - **AI Agent tự động generate dựa trên nội dung**
12
- - `content` (string): HTML document đầy đủ với TailwindCSS CDN. JavaScript libraries được phép qua CDN (Alpine.js, Chart.js, GSAP, etc.)
13
- - `slug` (string): URL slug - **AI Agent tự động generate theo format kebab-case từ title hoặc nội dung**
14
-
15
- **Lưu ý quan trọng:**
16
- - User **KHÔNG cần** cung cấp `title` và `slug`
17
- - AI Agent sẽ tự động generate dựa trên yêu cầu của user
18
- - Ví dụ: "tạo website quản lý thu chi" → title: "Quản Lý Thu Chi", slug: "quan-ly-thu-chi"
19
-
20
- **Response:**
21
- ```json
22
- {
23
- "success": true,
24
- "message": "Page deployed successfully",
25
- "url": "https://pages.react.uat.gearvn.xyz/pages/my-page-123"
26
- }
27
- ```
28
-
29
- ### 2. list-pages
30
- Liệt kê tất cả các pages của API key.
31
-
32
- **Response:**
33
- ```json
34
- {
35
- "success": true,
36
- "count": 2,
37
- "pages": [
38
- {
39
- "id": 1,
40
- "slug": "my-page-123",
41
- "title": "My Page",
42
- "created_at": "2025-01-20T10:00:00Z",
43
- "updated_at": "2025-01-20T10:00:00Z"
44
- }
45
- ]
46
- }
47
- ```
48
-
49
5
  ## Cài đặt
50
6
 
51
7
  ### Prerequisites
52
8
  - Node.js 18+
53
9
  - API key từ GearVN Pages (liên hệ admin để lấy)
54
10
 
55
- ## Sử dụng với Claude Desktop
11
+ ### Sử dụng với Claude Desktop
56
12
 
57
- ### Bước 1: Mở file config
13
+ **Bước 1: Mở file config**
58
14
  - macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
59
15
  - Windows: `%APPDATA%\Claude\claude_desktop_config.json`
60
16
 
61
- ### Bước 2: Thêm MCP server config
17
+ **Bước 2: Thêm MCP server config**
62
18
 
63
19
  ```json
64
20
  {
@@ -77,16 +33,16 @@ Liệt kê tất cả các pages của API key.
77
33
  }
78
34
  ```
79
35
 
80
- ### Bước 3: Restart Claude Desktop
36
+ **Bước 3: Restart Claude Desktop**
81
37
 
82
- ## Sử dụng với Cline (VS Code)
38
+ ### Sử dụng với Cline (VS Code)
83
39
 
84
- ### Bước 1: Mở VS Code Settings
40
+ **Bước 1: Mở VS Code Settings**
85
41
 
86
42
  1. Command Palette (Cmd+Shift+P / Ctrl+Shift+P)
87
43
  2. "Preferences: Open User Settings (JSON)"
88
44
 
89
- ### Bước 2: Thêm config
45
+ **Bước 2: Thêm config**
90
46
 
91
47
  ```json
92
48
  {
@@ -105,7 +61,62 @@ Liệt kê tất cả các pages của API key.
105
61
  }
106
62
  ```
107
63
 
108
- ### Bước 3: Reload VS Code
64
+ **Bước 3: Reload VS Code**
65
+
66
+ ## Tính năng
67
+
68
+ ### 1. deploy-page
69
+ Deploy hoặc update một trang HTML tĩnh.
70
+
71
+ **Parameters:**
72
+ - `title` (string): Tiêu đề của trang - **AI Agent tự động generate**
73
+ - `content` (string): HTML document đầy đủ với TailwindCSS CDN. JavaScript libraries được phép qua CDN (Alpine.js, Chart.js, GSAP, etc.)
74
+ - `slug` (string): URL slug - **AI Agent tự động generate hoặc dùng slug có sẵn**
75
+
76
+ **Workflow:**
77
+
78
+ **TẠO TRANG MỚI:**
79
+ 1. User: "Tạo website quản lý thu chi"
80
+ 2. AI generate slug đơn giản: `"quan-ly-thu-chi"`
81
+ 3. AI gọi deploy-page với slug: `"quan-ly-thu-chi"`
82
+ 4. Backend thêm timestamp: `"quan-ly-thu-chi-1730229600"`
83
+ 5. URL: `https://pages.react.uat.gearvn.xyz/pages/quan-ly-thu-chi-1730229600`
84
+
85
+ **UPDATE TRANG CŨ:**
86
+ 1. User: "Sửa trang quản lý thu chi, thêm tính năng X"
87
+ 2. AI gọi `list-pages` → tìm thấy slug: `"quan-ly-thu-chi-1730229600"`
88
+ 3. AI gọi `deploy-page` với slug đầy đủ: `"quan-ly-thu-chi-1730229600"`
89
+ 4. Backend update trang cũ (không tạo mới)
90
+ 5. URL giữ nguyên: `https://pages.react.uat.gearvn.xyz/pages/quan-ly-thu-chi-1730229600`
91
+
92
+ **Response:**
93
+ ```json
94
+ {
95
+ "success": true,
96
+ "message": "Page deployed successfully",
97
+ "url": "https://pages.react.uat.gearvn.xyz/pages/quan-ly-thu-chi-1730229600"
98
+ }
99
+ ```
100
+
101
+ ### 2. list-pages
102
+ Liệt kê tất cả các pages của API key.
103
+
104
+ **Response:**
105
+ ```json
106
+ {
107
+ "success": true,
108
+ "count": 2,
109
+ "pages": [
110
+ {
111
+ "id": 1,
112
+ "slug": "my-page-123",
113
+ "title": "My Page",
114
+ "created_at": "2025-01-20T10:00:00Z",
115
+ "updated_at": "2025-01-20T10:00:00Z"
116
+ }
117
+ ]
118
+ }
119
+ ```
109
120
 
110
121
  ## Ví dụ sử dụng trong Claude
111
122
 
@@ -113,7 +124,7 @@ Liệt kê tất cả các pages của API key.
113
124
 
114
125
  **Prompt của user (đơn giản):**
115
126
  ```
116
- Tạo cho tôi một trang web quản lý thu chi cá nhân với các tính năng:
127
+ Sử dụng gearvn-pages để: Tạo cho tôi một trang web quản lý thu chi cá nhân với các tính năng:
117
128
  - Form thêm giao dịch (loại: thu/chi, số tiền, mô tả, ngày)
118
129
  - Hiển thị danh sách giao dịch dưới dạng bảng
119
130
  - Tổng thu, tổng chi, số dư
@@ -141,7 +152,7 @@ URL: https://pages.react.uat.gearvn.xyz/pages/quan-ly-thu-chi-ca-nhan
141
152
 
142
153
  **Prompt của user:**
143
154
  ```
144
- Tạo landing page bán khóa học lập trình với:
155
+ Sử dụng gearvn-pages để: Tạo landing page bán khóa học lập trình với:
145
156
  - Hero section với CTA button
146
157
  - Sections: Lợi ích, Nội dung khóa học, Giảng viên, Testimonials
147
158
  - Pricing table với 3 gói
@@ -158,7 +169,7 @@ Tạo landing page bán khóa học lập trình với:
158
169
 
159
170
  **Prompt của user:**
160
171
  ```
161
- Tạo portfolio website cho developer với:
172
+ Sử dụng gearvn-pages để: Tạo portfolio website cho developer với:
162
173
  - About me section
163
174
  - Skills với progress bars
164
175
  - Projects showcase với images
@@ -172,13 +183,27 @@ Tạo portfolio website cho developer với:
172
183
  - Thêm Alpine.js CDN cho dark mode
173
184
  - Deploy và trả về URL
174
185
 
175
- ### Liệt kê các pages đã tạo
186
+ ### Ví dụ 4: Liệt kê các pages đã tạo
187
+
188
+ ```
189
+ Sử dụng gearvn-pages để: Liệt kê tất cả các trang web mà tôi đã deploy
190
+ ```
191
+
192
+ Claude sẽ hiển thị danh sách pages với title, slug (có timestamp) và thời gian tạo/cập nhật.
193
+
194
+ ### Ví dụ 5: Update trang đã tồn tại
176
195
 
196
+ **Prompt của user:**
177
197
  ```
178
- Hãy liệt tất cả các trang web tôi đã deploy
198
+ Sử dụng gearvn-pages để: Sửa trang quản thu chi của tôi, thêm tính năng filter theo tháng
179
199
  ```
180
200
 
181
- Claude sẽ hiển thị danh sách pages với title, slug và thời gian tạo/cập nhật.
201
+ **AI Agent sẽ tự động:**
202
+ 1. ✅ Gọi `list-pages` để tìm trang quản lý thu chi
203
+ 2. ✅ Lấy slug đầy đủ có timestamp: `"quan-ly-thu-chi-ca-nhan-1730229600"`
204
+ 3. ✅ Gọi `deploy-page` với slug đầy đủ đó
205
+ 4. ✅ Backend update trang cũ (không tạo trang mới)
206
+ 5. ✅ URL giữ nguyên: `https://pages.react.uat.gearvn.xyz/pages/quan-ly-thu-chi-ca-nhan-1730229600`
182
207
 
183
208
  ## Technical Requirements
184
209
 
package/dist/api.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAQA,wBAAsB,OAAO,CAAC,CAAC,EAC7B,QAAQ,EAAE,MAAM,EAChB,MAAM,GAAE,MAAc,EACtB,IAAI,CAAC,EAAE,OAAO,GACb,OAAO,CAAC,CAAC,CAAC,CAsBZ"}
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAQA,wBAAsB,OAAO,CAAC,CAAC,EAC7B,QAAQ,EAAE,MAAM,EAChB,MAAM,GAAE,MAAc,EACtB,IAAI,CAAC,EAAE,OAAO,GACb,OAAO,CAAC,CAAC,CAAC,CAuCZ"}
package/dist/api.js CHANGED
@@ -17,10 +17,23 @@ export async function callAPI(endpoint, method = "GET", body) {
17
17
  headers,
18
18
  body: body ? JSON.stringify(body) : undefined,
19
19
  });
20
+ // Get response text first
21
+ const responseText = await response.text();
20
22
  if (!response.ok) {
21
- const errorText = await response.text();
22
- throw new Error(`API request failed: ${response.status} ${errorText}`);
23
+ // Check if response is HTML (error page)
24
+ if (responseText.trim().startsWith("<!DOCTYPE") || responseText.trim().startsWith("<html")) {
25
+ throw new Error(`API request failed with status ${response.status}. Server returned HTML instead of JSON. ` +
26
+ `This usually means: 1) Invalid API endpoint, 2) API key authentication failed, or 3) Server error. ` +
27
+ `URL: ${url}`);
28
+ }
29
+ throw new Error(`API request failed: ${response.status} ${responseText}`);
30
+ }
31
+ // Try to parse as JSON
32
+ try {
33
+ return JSON.parse(responseText);
34
+ }
35
+ catch (error) {
36
+ throw new Error(`API returned invalid JSON. Response: ${responseText.substring(0, 200)}...`);
23
37
  }
24
- return response.json();
25
38
  }
26
39
  //# sourceMappingURL=api.js.map
package/dist/api.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA,MAAM,YAAY,GAAG,oCAAoC,CAAC;AAC1D,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC;AAEpC,IAAI,CAAC,OAAO,EAAE,CAAC;IACb,OAAO,CAAC,KAAK,CAAC,iDAAiD,CAAC,CAAC;IACjE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,QAAgB,EAChB,SAAiB,KAAK,EACtB,IAAc;IAEd,MAAM,GAAG,GAAG,GAAG,YAAY,GAAG,QAAQ,EAAE,CAAC;IACzC,MAAM,OAAO,GAA2B;QACtC,WAAW,EAAE,OAAQ;KACtB,CAAC;IAEF,IAAI,IAAI,EAAE,CAAC;QACT,OAAO,CAAC,cAAc,CAAC,GAAG,kBAAkB,CAAC;IAC/C,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;QAChC,MAAM;QACN,OAAO;QACP,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS;KAC9C,CAAC,CAAC;IAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACxC,MAAM,IAAI,KAAK,CAAC,uBAAuB,QAAQ,CAAC,MAAM,IAAI,SAAS,EAAE,CAAC,CAAC;IACzE,CAAC;IAED,OAAO,QAAQ,CAAC,IAAI,EAAgB,CAAC;AACvC,CAAC"}
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA,MAAM,YAAY,GAAG,oCAAoC,CAAC;AAC1D,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC;AAEpC,IAAI,CAAC,OAAO,EAAE,CAAC;IACb,OAAO,CAAC,KAAK,CAAC,iDAAiD,CAAC,CAAC;IACjE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,QAAgB,EAChB,SAAiB,KAAK,EACtB,IAAc;IAEd,MAAM,GAAG,GAAG,GAAG,YAAY,GAAG,QAAQ,EAAE,CAAC;IACzC,MAAM,OAAO,GAA2B;QACtC,WAAW,EAAE,OAAQ;KACtB,CAAC;IAEF,IAAI,IAAI,EAAE,CAAC;QACT,OAAO,CAAC,cAAc,CAAC,GAAG,kBAAkB,CAAC;IAC/C,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;QAChC,MAAM;QACN,OAAO;QACP,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS;KAC9C,CAAC,CAAC;IAEH,0BAA0B;IAC1B,MAAM,YAAY,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IAE3C,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,yCAAyC;QACzC,IAAI,YAAY,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,YAAY,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YAC3F,MAAM,IAAI,KAAK,CACb,kCAAkC,QAAQ,CAAC,MAAM,0CAA0C;gBAC3F,qGAAqG;gBACrG,QAAQ,GAAG,EAAE,CACd,CAAC;QACJ,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,uBAAuB,QAAQ,CAAC,MAAM,IAAI,YAAY,EAAE,CAAC,CAAC;IAC5E,CAAC;IAED,uBAAuB;IACvB,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAM,CAAC;IACvC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CACb,wCAAwC,YAAY,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,KAAK,CAC5E,CAAC;IACJ,CAAC;AACH,CAAC"}
package/dist/index.js CHANGED
File without changes
@@ -1 +1 @@
1
- {"version":3,"file":"deploy-page.d.ts","sourceRoot":"","sources":["../../src/tools/deploy-page.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAI1D,eAAO,MAAM,gBAAgB,EAAE,IAyB9B,CAAC;AAEF,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,OAAO;;;;;GAiCnD"}
1
+ {"version":3,"file":"deploy-page.d.ts","sourceRoot":"","sources":["../../src/tools/deploy-page.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAI1D,eAAO,MAAM,gBAAgB,EAAE,IA4B9B,CAAC;AAEF,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,OAAO;;;;;GAiCnD"}
@@ -1,7 +1,7 @@
1
1
  import { callAPI } from "../api.js";
2
2
  export const DEPLOY_PAGE_TOOL = {
3
3
  name: "deploy-page",
4
- description: "Deploy or update a static HTML page. If the slug already exists, the page will be updated with the new content and title. IMPORTANT: You (AI Agent) must automatically generate appropriate 'title' and 'slug' based on the user's request - user does NOT provide these. The content must be a complete, valid HTML document with TailwindCSS for styling. JavaScript libraries are allowed but MUST be loaded via CDN (e.g., Alpine.js, Chart.js, GSAP, etc.). No build tools or npm packages. No React, Vue, or Angular frameworks allowed.",
4
+ description: "Deploy or update a static HTML page. If the slug already exists, the page will be updated with the new content and title. IMPORTANT: You (AI Agent) must automatically generate appropriate 'title' and 'slug' based on the user's request - user does NOT provide these. The content must be a complete, valid HTML document with TailwindCSS for styling. JavaScript libraries are allowed but MUST be loaded via CDN (e.g., Alpine.js, Chart.js, GSAP, etc.). No build tools or npm packages. No React, Vue, or Angular frameworks allowed. CRITICAL: When passing HTML content as JSON string, ensure all special characters are properly escaped (double quotes \", backslashes \\, newlines \\n, etc.) to prevent JSON syntax errors.",
5
5
  inputSchema: {
6
6
  type: "object",
7
7
  properties: {
@@ -11,11 +11,14 @@ export const DEPLOY_PAGE_TOOL = {
11
11
  },
12
12
  content: {
13
13
  type: "string",
14
- description: "The complete HTML content of the page. Must include <!DOCTYPE html>, <html>, <head> with TailwindCSS CDN link (https://cdn.tailwindcss.com), and <body> tags. Use TailwindCSS utility classes for all styling. JavaScript libraries are allowed but must be imported via CDN links in <script> tags (e.g., Alpine.js from CDN, Chart.js from CDN). Vanilla JavaScript is also acceptable. NO build tools, npm packages, or SPA frameworks (React/Vue/Angular).",
14
+ description: "The complete HTML content of the page. Must include <!DOCTYPE html>, <html>, <head> with TailwindCSS CDN link (https://cdn.tailwindcss.com), and <body> tags. Use TailwindCSS utility classes for all styling. JavaScript libraries are allowed but must be imported via CDN links in <script> tags (e.g., Alpine.js from CDN, Chart.js from CDN). Vanilla JavaScript is also acceptable. NO build tools, npm packages, or SPA frameworks (React/Vue/Angular). IMPORTANT: Properly escape all special characters in HTML for JSON (\" for double quotes, \\\\ for backslashes, \\n for newlines, etc.). Example: <div class=\"container\"> should be passed as <div class=\\\"container\\\">",
15
15
  },
16
16
  slug: {
17
17
  type: "string",
18
- description: "The URL slug for the page. AI Agent should generate this automatically in kebab-case format based on the title or user's request (e.g., 'quan-ly-thu-chi-ca-nhan', 'landing-page-khoa-hoc'). This will be used in the URL as /pages/{slug}",
18
+ description: "The URL slug for the page. IMPORTANT BEHAVIOR: " +
19
+ "FOR NEW PAGES: Generate a simple kebab-case slug (e.g., 'quan-ly-thu-chi', 'landing-page'). The backend will automatically append a timestamp (e.g., 'quan-ly-thu-chi-1730229600') to prevent duplicates. " +
20
+ "FOR UPDATING EXISTING PAGES: Use the EXACT full slug including timestamp (e.g., 'quan-ly-thu-chi-1730229600') from the list-pages response. " +
21
+ "If the exact slug exists for this API key, the page will be updated. Otherwise, a new page with a new timestamp will be created.",
19
22
  },
20
23
  },
21
24
  required: ["title", "content", "slug"],
@@ -1 +1 @@
1
- {"version":3,"file":"deploy-page.js","sourceRoot":"","sources":["../../src/tools/deploy-page.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,MAAM,CAAC,MAAM,gBAAgB,GAAS;IACpC,IAAI,EAAE,aAAa;IACnB,WAAW,EACT,ghBAAghB;IAClhB,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,KAAK,EAAE;gBACL,IAAI,EAAE,QAAQ;gBACd,WAAW,EACT,6FAA6F;aAChG;YACD,OAAO,EAAE;gBACP,IAAI,EAAE,QAAQ;gBACd,WAAW,EACT,gcAAgc;aACnc;YACD,IAAI,EAAE;gBACJ,IAAI,EAAE,QAAQ;gBACd,WAAW,EACT,4OAA4O;aAC/O;SACF;QACD,QAAQ,EAAE,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC;KACvC;CACF,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,IAAa;IAClD,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,IAAsB,CAAC;IAExD,kBAAkB;IAClB,IAAI,CAAC,KAAK,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CACb,oEAAoE,CACrE,CAAC;IACJ,CAAC;IAED,sBAAsB;IACtB,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAqB,YAAY,EAAE,MAAM,EAAE;QACvE,KAAK;QACL,OAAO;QACP,IAAI;KACL,CAAC,CAAC;IAEH,OAAO;QACL,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,MAAe;gBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAClB;oBACE,OAAO,EAAE,IAAI;oBACb,OAAO,EAAE,4BAA4B;oBACrC,GAAG,EAAE,QAAQ,CAAC,GAAG;iBAClB,EACD,IAAI,EACJ,CAAC,CACF;aACF;SACF;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"deploy-page.js","sourceRoot":"","sources":["../../src/tools/deploy-page.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,MAAM,CAAC,MAAM,gBAAgB,GAAS;IACpC,IAAI,EAAE,aAAa;IACnB,WAAW,EACT,6sBAA6sB;IAC/sB,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,KAAK,EAAE;gBACL,IAAI,EAAE,QAAQ;gBACd,WAAW,EACT,6FAA6F;aAChG;YACD,OAAO,EAAE;gBACP,IAAI,EAAE,QAAQ;gBACd,WAAW,EACT,8pBAA8pB;aACjqB;YACD,IAAI,EAAE;gBACJ,IAAI,EAAE,QAAQ;gBACd,WAAW,EACT,iDAAiD;oBACjD,4MAA4M;oBAC5M,8IAA8I;oBAC9I,kIAAkI;aACrI;SACF;QACD,QAAQ,EAAE,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC;KACvC;CACF,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,IAAa;IAClD,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,IAAsB,CAAC;IAExD,kBAAkB;IAClB,IAAI,CAAC,KAAK,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CACb,oEAAoE,CACrE,CAAC;IACJ,CAAC;IAED,sBAAsB;IACtB,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAqB,YAAY,EAAE,MAAM,EAAE;QACvE,KAAK;QACL,OAAO;QACP,IAAI;KACL,CAAC,CAAC;IAEH,OAAO;QACL,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,MAAe;gBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAClB;oBACE,OAAO,EAAE,IAAI;oBACb,OAAO,EAAE,4BAA4B;oBACrC,GAAG,EAAE,QAAQ,CAAC,GAAG;iBAClB,EACD,IAAI,EACJ,CAAC,CACF;aACF;SACF;KACF,CAAC;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,18 +1,12 @@
1
1
  {
2
2
  "name": "gearvn-pages-mcp-server",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "MCP Server for GearVN Pages deployment and management",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "bin": {
8
8
  "gearvn-pages-mcp": "dist/index.js"
9
9
  },
10
- "scripts": {
11
- "build": "tsc",
12
- "watch": "tsc --watch",
13
- "start": "node dist/index.js",
14
- "prepublishOnly": "npm run build"
15
- },
16
10
  "keywords": [
17
11
  "mcp",
18
12
  "model-context-protocol",
@@ -26,5 +20,10 @@
26
20
  "devDependencies": {
27
21
  "@types/node": "^22.10.2",
28
22
  "typescript": "^5.7.2"
23
+ },
24
+ "scripts": {
25
+ "build": "tsc",
26
+ "watch": "tsc --watch",
27
+ "start": "node dist/index.js"
29
28
  }
30
- }
29
+ }
package/src/api.ts CHANGED
@@ -26,10 +26,27 @@ export async function callAPI<T>(
26
26
  body: body ? JSON.stringify(body) : undefined,
27
27
  });
28
28
 
29
+ // Get response text first
30
+ const responseText = await response.text();
31
+
29
32
  if (!response.ok) {
30
- const errorText = await response.text();
31
- throw new Error(`API request failed: ${response.status} ${errorText}`);
33
+ // Check if response is HTML (error page)
34
+ if (responseText.trim().startsWith("<!DOCTYPE") || responseText.trim().startsWith("<html")) {
35
+ throw new Error(
36
+ `API request failed with status ${response.status}. Server returned HTML instead of JSON. ` +
37
+ `This usually means: 1) Invalid API endpoint, 2) API key authentication failed, or 3) Server error. ` +
38
+ `URL: ${url}`
39
+ );
40
+ }
41
+ throw new Error(`API request failed: ${response.status} ${responseText}`);
32
42
  }
33
43
 
34
- return response.json() as Promise<T>;
44
+ // Try to parse as JSON
45
+ try {
46
+ return JSON.parse(responseText) as T;
47
+ } catch (error) {
48
+ throw new Error(
49
+ `API returned invalid JSON. Response: ${responseText.substring(0, 200)}...`
50
+ );
51
+ }
35
52
  }
@@ -5,7 +5,7 @@ import { DeployPageArgs, DeployPageResponse } from "../types.js";
5
5
  export const DEPLOY_PAGE_TOOL: Tool = {
6
6
  name: "deploy-page",
7
7
  description:
8
- "Deploy or update a static HTML page. If the slug already exists, the page will be updated with the new content and title. IMPORTANT: You (AI Agent) must automatically generate appropriate 'title' and 'slug' based on the user's request - user does NOT provide these. The content must be a complete, valid HTML document with TailwindCSS for styling. JavaScript libraries are allowed but MUST be loaded via CDN (e.g., Alpine.js, Chart.js, GSAP, etc.). No build tools or npm packages. No React, Vue, or Angular frameworks allowed.",
8
+ "Deploy or update a static HTML page. If the slug already exists, the page will be updated with the new content and title. IMPORTANT: You (AI Agent) must automatically generate appropriate 'title' and 'slug' based on the user's request - user does NOT provide these. The content must be a complete, valid HTML document with TailwindCSS for styling. JavaScript libraries are allowed but MUST be loaded via CDN (e.g., Alpine.js, Chart.js, GSAP, etc.). No build tools or npm packages. No React, Vue, or Angular frameworks allowed. CRITICAL: When passing HTML content as JSON string, ensure all special characters are properly escaped (double quotes \", backslashes \\, newlines \\n, etc.) to prevent JSON syntax errors.",
9
9
  inputSchema: {
10
10
  type: "object",
11
11
  properties: {
@@ -17,12 +17,15 @@ export const DEPLOY_PAGE_TOOL: Tool = {
17
17
  content: {
18
18
  type: "string",
19
19
  description:
20
- "The complete HTML content of the page. Must include <!DOCTYPE html>, <html>, <head> with TailwindCSS CDN link (https://cdn.tailwindcss.com), and <body> tags. Use TailwindCSS utility classes for all styling. JavaScript libraries are allowed but must be imported via CDN links in <script> tags (e.g., Alpine.js from CDN, Chart.js from CDN). Vanilla JavaScript is also acceptable. NO build tools, npm packages, or SPA frameworks (React/Vue/Angular).",
20
+ "The complete HTML content of the page. Must include <!DOCTYPE html>, <html>, <head> with TailwindCSS CDN link (https://cdn.tailwindcss.com), and <body> tags. Use TailwindCSS utility classes for all styling. JavaScript libraries are allowed but must be imported via CDN links in <script> tags (e.g., Alpine.js from CDN, Chart.js from CDN). Vanilla JavaScript is also acceptable. NO build tools, npm packages, or SPA frameworks (React/Vue/Angular). IMPORTANT: Properly escape all special characters in HTML for JSON (\" for double quotes, \\\\ for backslashes, \\n for newlines, etc.). Example: <div class=\"container\"> should be passed as <div class=\\\"container\\\">",
21
21
  },
22
22
  slug: {
23
23
  type: "string",
24
24
  description:
25
- "The URL slug for the page. AI Agent should generate this automatically in kebab-case format based on the title or user's request (e.g., 'quan-ly-thu-chi-ca-nhan', 'landing-page-khoa-hoc'). This will be used in the URL as /pages/{slug}",
25
+ "The URL slug for the page. IMPORTANT BEHAVIOR: " +
26
+ "FOR NEW PAGES: Generate a simple kebab-case slug (e.g., 'quan-ly-thu-chi', 'landing-page'). The backend will automatically append a timestamp (e.g., 'quan-ly-thu-chi-1730229600') to prevent duplicates. " +
27
+ "FOR UPDATING EXISTING PAGES: Use the EXACT full slug including timestamp (e.g., 'quan-ly-thu-chi-1730229600') from the list-pages response. " +
28
+ "If the exact slug exists for this API key, the page will be updated. Otherwise, a new page with a new timestamp will be created.",
26
29
  },
27
30
  },
28
31
  required: ["title", "content", "slug"],