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 +83 -58
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +16 -3
- package/dist/api.js.map +1 -1
- package/dist/index.js +0 -0
- package/dist/tools/deploy-page.d.ts.map +1 -1
- package/dist/tools/deploy-page.js +6 -3
- package/dist/tools/deploy-page.js.map +1 -1
- package/package.json +7 -8
- package/src/api.ts +20 -3
- package/src/tools/deploy-page.ts +6 -3
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
|
-
|
|
11
|
+
### Sử dụng với Claude Desktop
|
|
56
12
|
|
|
57
|
-
|
|
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
|
-
|
|
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
|
-
|
|
36
|
+
**Bước 3: Restart Claude Desktop**
|
|
81
37
|
|
|
82
|
-
|
|
38
|
+
### Sử dụng với Cline (VS Code)
|
|
83
39
|
|
|
84
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
198
|
+
Sử dụng gearvn-pages để: Sửa trang quản lý thu chi của tôi, thêm tính năng filter theo tháng
|
|
179
199
|
```
|
|
180
200
|
|
|
181
|
-
|
|
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,
|
|
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
|
-
|
|
22
|
-
|
|
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,
|
|
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,
|
|
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.
|
|
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,
|
|
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.
|
|
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
|
-
|
|
31
|
-
|
|
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
|
-
|
|
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
|
}
|
package/src/tools/deploy-page.ts
CHANGED
|
@@ -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.
|
|
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"],
|