gearvn-pages-mcp-server 1.1.0 → 1.1.1

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,51 @@ 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 dựa trên nội dung**
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 theo format kebab-case từ title hoặc nội dung**
75
+
76
+ **Lưu ý quan trọng:**
77
+ - User **KHÔNG cần** cung cấp `title` và `slug`
78
+ - AI Agent sẽ tự động generate dựa trên yêu cầu của user
79
+ - Ví dụ: "tạo website quản lý thu chi" → title: "Quản Lý Thu Chi", slug: "quan-ly-thu-chi"
80
+
81
+ **Response:**
82
+ ```json
83
+ {
84
+ "success": true,
85
+ "message": "Page deployed successfully",
86
+ "url": "https://pages.react.uat.gearvn.xyz/pages/my-page-123"
87
+ }
88
+ ```
89
+
90
+ ### 2. list-pages
91
+ Liệt kê tất cả các pages của API key.
92
+
93
+ **Response:**
94
+ ```json
95
+ {
96
+ "success": true,
97
+ "count": 2,
98
+ "pages": [
99
+ {
100
+ "id": 1,
101
+ "slug": "my-page-123",
102
+ "title": "My Page",
103
+ "created_at": "2025-01-20T10:00:00Z",
104
+ "updated_at": "2025-01-20T10:00:00Z"
105
+ }
106
+ ]
107
+ }
108
+ ```
109
109
 
110
110
  ## Ví dụ sử dụng trong Claude
111
111
 
@@ -113,7 +113,7 @@ Liệt kê tất cả các pages của API key.
113
113
 
114
114
  **Prompt của user (đơn giản):**
115
115
  ```
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:
116
+ 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
117
  - Form thêm giao dịch (loại: thu/chi, số tiền, mô tả, ngày)
118
118
  - Hiển thị danh sách giao dịch dưới dạng bảng
119
119
  - Tổng thu, tổng chi, số dư
@@ -141,7 +141,7 @@ URL: https://pages.react.uat.gearvn.xyz/pages/quan-ly-thu-chi-ca-nhan
141
141
 
142
142
  **Prompt của user:**
143
143
  ```
144
- Tạo landing page bán khóa học lập trình với:
144
+ Sử dụng gearvn-pages để: Tạo landing page bán khóa học lập trình với:
145
145
  - Hero section với CTA button
146
146
  - Sections: Lợi ích, Nội dung khóa học, Giảng viên, Testimonials
147
147
  - Pricing table với 3 gói
@@ -158,7 +158,7 @@ Tạo landing page bán khóa học lập trình với:
158
158
 
159
159
  **Prompt của user:**
160
160
  ```
161
- Tạo portfolio website cho developer với:
161
+ Sử dụng gearvn-pages để: Tạo portfolio website cho developer với:
162
162
  - About me section
163
163
  - Skills với progress bars
164
164
  - Projects showcase với images
@@ -175,7 +175,7 @@ Tạo portfolio website cho developer với:
175
175
  ### Liệt kê các pages đã tạo
176
176
 
177
177
  ```
178
- Hãy liệt kê tất cả các trang web mà tôi đã deploy
178
+ Sử dụng gearvn-pages để: Liệt kê tất cả các trang web mà tôi đã deploy
179
179
  ```
180
180
 
181
181
  Claude sẽ hiển thị danh sách pages với title, slug và thời gian tạo/cập nhật.
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,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,7 +11,7 @@ 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",
@@ -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,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"}
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.1.1",
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,7 +17,7 @@ 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",