gem-design-mcp-server 1.0.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.
Files changed (3) hide show
  1. package/README.md +79 -0
  2. package/build/index.js +142 -0
  3. package/package.json +34 -0
package/README.md ADDED
@@ -0,0 +1,79 @@
1
+ # GemDesign MCP Server
2
+
3
+ GemDesign 的官方 Model Context Protocol (MCP) 服务端。允许 AI 助手(如 Trae, Claude Desktop)直接访问 GemDesign API,执行页面查询、内容获取和项目还原等操作。
4
+
5
+ ## 功能特性
6
+
7
+ - **页面列表查询**: 获取应用下的所有页面结构。
8
+ - **页面内容获取**: 获取特定页面的 HTML 源码。
9
+
10
+ ## 安装与使用
11
+
12
+ ### 方式一:使用 npx (推荐)
13
+
14
+ 无需安装,直接在 MCP Host (如 Trae) 的配置中使用:
15
+
16
+ ```json
17
+ {
18
+ "mcpServers": {
19
+ "GemDesign": {
20
+ "command": "npx",
21
+ "args": ["-y", "gem-design-mcp-server"],
22
+ "env": {
23
+ "GEMDESIGN_API_KEY": "your_api_key_here"
24
+ }
25
+ }
26
+ }
27
+ }
28
+ ```
29
+
30
+ ### 方式二:全局安装
31
+
32
+ ```bash
33
+ npm install -g gem-design-mcp-server
34
+ ```
35
+
36
+ 配置:
37
+
38
+ ```json
39
+ {
40
+ "mcpServers": {
41
+ "gem-design": {
42
+ "command": "gem-design-mcp-server",
43
+ "env": {
44
+ "GEMDESIGN_API_KEY": "your_api_key_here"
45
+ }
46
+ }
47
+ }
48
+ }
49
+ ```
50
+
51
+ ### 方式三:源码运行
52
+
53
+ 1. Clone 仓库
54
+ 2. `npm install`
55
+ 3. `npm run build`
56
+ 4. 配置 command 为 `node`,args 为 `["/path/to/build/index.js"]`
57
+
58
+ ## 环境变量
59
+
60
+ | 变量名 | 说明 | 默认值 | 必填 |
61
+ | :------------------- | :-------------------------- | :--------------------------------- | :--- |
62
+ | `GEMDESIGN_API_KEY` | 您的 GemDesign API 访问令牌 | - | 是 |
63
+ | `GEMDESIGN_BASE_URL` | API 基础地址 | `http://localhost:8000` (开发环境) | 否 |
64
+
65
+ ## 开发调试
66
+
67
+ ```bash
68
+ # 安装依赖
69
+ npm install
70
+
71
+ # 编译
72
+ npm run build
73
+
74
+ # 启动模拟服务器
75
+ node mock-api.js
76
+
77
+ # 运行测试客户端
78
+ node test-client.js
79
+ ```
package/build/index.js ADDED
@@ -0,0 +1,142 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __importDefault = (this && this.__importDefault) || function (mod) {
4
+ return (mod && mod.__esModule) ? mod : { "default": mod };
5
+ };
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ const mcp_js_1 = require("@modelcontextprotocol/sdk/server/mcp.js");
8
+ const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
9
+ const zod_1 = require("zod");
10
+ const axios_1 = __importDefault(require("axios"));
11
+ const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
12
+ // --- 1. Environment Variables & Configuration ---
13
+ const API_KEY = process.env.GEMDESIGN_API_KEY;
14
+ // Default to localhost:8000 as requested if not provided
15
+ const BASE_URL = process.env.GEMDESIGN_BASE_URL || "http://localhost:8000";
16
+ if (!API_KEY) {
17
+ console.error("Error: GEMDESIGN_API_KEY environment variable is required.");
18
+ process.exit(1);
19
+ }
20
+ class GemDesignClient {
21
+ client;
22
+ constructor(baseURL, token) {
23
+ this.client = axios_1.default.create({
24
+ baseURL,
25
+ headers: {
26
+ "X-GemDesign-AccessToken": token,
27
+ "Content-Type": "application/json",
28
+ },
29
+ timeout: 10000, // 10s timeout
30
+ });
31
+ }
32
+ /**
33
+ * Generic POST request handler
34
+ */
35
+ async post(endpoint, payload) {
36
+ try {
37
+ const response = await this.client.post(endpoint, payload);
38
+ // Basic validation of response status
39
+ if (response.status < 200 || response.status >= 300) {
40
+ throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `[GemDesign API Error] HTTP ${response.status}: ${response.statusText}`);
41
+ }
42
+ const body = response.data;
43
+ // Handle "data wrapper" logic
44
+ // Assuming if body has 'data' property, we return that.
45
+ // If 'code' exists and indicates error, we throw.
46
+ // This is a heuristic based on common patterns.
47
+ if (body && typeof body === 'object' && 'data' in body) {
48
+ // Check for business logic error codes if present
49
+ // Example: if (body.code && body.code !== 200) ...
50
+ // For now, we return data.
51
+ return body.data;
52
+ }
53
+ // Fallback: return the whole body if structure is unexpected but valid JSON
54
+ return body;
55
+ }
56
+ catch (error) {
57
+ this.handleError(error);
58
+ throw error; // Make TS happy, handleError always throws
59
+ }
60
+ }
61
+ handleError(error) {
62
+ if (axios_1.default.isAxiosError(error)) {
63
+ const axiosError = error;
64
+ // 401/403 -> InvalidRequest (Auth Error)
65
+ if (axiosError.response?.status === 401 || axiosError.response?.status === 403) {
66
+ throw new types_js_1.McpError(types_js_1.ErrorCode.InvalidRequest, "[GemDesign Auth Error] Invalid AccessToken. Please check your environment configuration.");
67
+ }
68
+ // 404/500 or others -> InternalError
69
+ const msg = axiosError.response?.data?.message || axiosError.message;
70
+ throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `[GemDesign API Error] ${msg}`);
71
+ }
72
+ // Unknown error
73
+ throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `[GemDesign Unknown Error] ${error instanceof Error ? error.message : String(error)}`);
74
+ }
75
+ }
76
+ const apiClient = new GemDesignClient(BASE_URL, API_KEY);
77
+ // --- 3. MCP Server Setup ---
78
+ const server = new mcp_js_1.McpServer({
79
+ name: "gem-design-mcp",
80
+ version: "1.0.0",
81
+ });
82
+ // --- 4. Tool Definitions ---
83
+ /**
84
+ * Tool: gemdesign_list_pages
85
+ * Description: Get list of pages for a given App UUID
86
+ */
87
+ server.tool("gemdesign_list_pages", {
88
+ appuuid: zod_1.z.string().describe("The unique identifier of the GemDesign App"),
89
+ }, async ({ appuuid }) => {
90
+ try {
91
+ const pages = await apiClient.post("/api/v1/listPages", { appuuid });
92
+ return {
93
+ content: [
94
+ {
95
+ type: "text",
96
+ text: JSON.stringify(pages, null, 2),
97
+ },
98
+ ],
99
+ };
100
+ }
101
+ catch (error) {
102
+ // McpErrors are already thrown by apiClient, but we ensure they propagate correctly
103
+ // The SDK handles threw errors by returning an error response
104
+ throw error;
105
+ }
106
+ });
107
+ /**
108
+ * Tool: gemdesign_get_page_content
109
+ * Description: Get raw HTML content for a specific page
110
+ */
111
+ server.tool("gemdesign_get_page_content", {
112
+ appuuid: zod_1.z.string().describe("The unique identifier of the GemDesign App"),
113
+ pageuuid: zod_1.z.string().describe("The unique identifier of the Page"),
114
+ }, async ({ appuuid, pageuuid }) => {
115
+ try {
116
+ // The user mentioned this returns HTML string.
117
+ // It might be wrapped in JSON { data: "<html>..." } or direct string.
118
+ // Our apiClient handles { data: ... } unwrapping.
119
+ const htmlContent = await apiClient.post("/api/v1/getPageHtml", { appuuid, pageuuid });
120
+ return {
121
+ content: [
122
+ {
123
+ type: "text",
124
+ text: typeof htmlContent === 'string' ? htmlContent : JSON.stringify(htmlContent),
125
+ },
126
+ ],
127
+ };
128
+ }
129
+ catch (error) {
130
+ throw error;
131
+ }
132
+ });
133
+ // --- 5. Start Server ---
134
+ async function main() {
135
+ const transport = new stdio_js_1.StdioServerTransport();
136
+ await server.connect(transport);
137
+ console.error("GemDesign MCP Server running on stdio");
138
+ }
139
+ main().catch((error) => {
140
+ console.error("Fatal error in main loop:", error);
141
+ process.exit(1);
142
+ });
package/package.json ADDED
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "gem-design-mcp-server",
3
+ "version": "1.0.1",
4
+ "description": "MCP Server for GemDesign API",
5
+ "main": "build/index.js",
6
+ "bin": {
7
+ "gem-design-mcp-server": "./build/index.js"
8
+ },
9
+ "files": [
10
+ "build"
11
+ ],
12
+ "scripts": {
13
+ "build": "tsc && node -e \"require('fs').chmodSync('build/index.js', '755')\"",
14
+ "start": "node build/index.js",
15
+ "dev": "ts-node src/index.ts"
16
+ },
17
+ "keywords": [
18
+ "mcp",
19
+ "gemdesign",
20
+ "ai"
21
+ ],
22
+ "author": "",
23
+ "license": "ISC",
24
+ "dependencies": {
25
+ "@modelcontextprotocol/sdk": "^1.0.1",
26
+ "axios": "^1.6.0",
27
+ "zod": "^3.22.0"
28
+ },
29
+ "devDependencies": {
30
+ "@types/node": "^20.0.0",
31
+ "ts-node": "^10.9.0",
32
+ "typescript": "^5.0.0"
33
+ }
34
+ }