palette-mcp 1.0.0 → 1.1.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.
Files changed (84) hide show
  1. package/dist/components/OrderManagementGuide.d.ts +6 -0
  2. package/dist/components/OrderManagementGuide.js +266 -0
  3. package/dist/index-simple.d.ts +2 -0
  4. package/dist/index-simple.js +139 -0
  5. package/dist/index.d.ts +6 -0
  6. package/dist/index.js +16 -226
  7. package/dist/requests/1762927928451-ajgna9b/SomaComponent.html +63 -0
  8. package/dist/requests/1762927928451-ajgna9b/SomaComponent.tsx +913 -0
  9. package/dist/requests/1762927928451-ajgna9b/metadata.json +9 -0
  10. package/dist/requests/1762931214963-cqlwvxn/SomaComponent.html +63 -0
  11. package/dist/requests/1762931214963-cqlwvxn/SomaComponent.tsx +525 -0
  12. package/dist/requests/1762931214963-cqlwvxn/metadata.json +9 -0
  13. package/dist/requests/1762932805663-m5wkk3a/SomaComponent.html +248 -0
  14. package/dist/requests/1762932805663-m5wkk3a/SomaComponent.tsx +1050 -0
  15. package/dist/requests/1762932805663-m5wkk3a/metadata.json +9 -0
  16. package/dist/requests/1762934645710-b67ldow/SomaComponent.html +193 -0
  17. package/dist/requests/1762934645710-b67ldow/SomaComponent.tsx +307 -0
  18. package/dist/requests/1762934645710-b67ldow/metadata.json +9 -0
  19. package/dist/requests/1762934961257-wwnmpvx/SomaComponent.html +193 -0
  20. package/dist/requests/1762934961257-wwnmpvx/SomaComponent.tsx +932 -0
  21. package/dist/requests/1762934961257-wwnmpvx/metadata.json +9 -0
  22. package/dist/requests/1762935126549-yjdcezr/SomaComponent.html +193 -0
  23. package/dist/requests/1762935126549-yjdcezr/SomaComponent.tsx +847 -0
  24. package/dist/requests/1762935126549-yjdcezr/metadata.json +9 -0
  25. package/dist/requests/1762935353759-fuokdeu/SomaComponent.html +193 -0
  26. package/dist/requests/1762935353759-fuokdeu/SomaComponent.tsx +334 -0
  27. package/dist/requests/1762935353759-fuokdeu/metadata.json +9 -0
  28. package/dist/requests/1762935378891-ckwbabn/SomaComponent.html +193 -0
  29. package/dist/requests/1762935378891-ckwbabn/SomaComponent.tsx +256 -0
  30. package/dist/requests/1762935378891-ckwbabn/metadata.json +9 -0
  31. package/dist/requests/1762935418352-181zqu4/SomaComponent.html +193 -0
  32. package/dist/requests/1762935418352-181zqu4/SomaComponent.tsx +45 -0
  33. package/dist/requests/1762935418352-181zqu4/metadata.json +9 -0
  34. package/dist/requests/1762935438157-vzkcbwy/SomaComponent.html +193 -0
  35. package/dist/requests/1762935438157-vzkcbwy/SomaComponent.tsx +238 -0
  36. package/dist/requests/1762935438157-vzkcbwy/metadata.json +9 -0
  37. package/dist/requests/1762935529749-ukzmiu3/SomaComponent.html +193 -0
  38. package/dist/requests/1762935529749-ukzmiu3/SomaComponent.tsx +138 -0
  39. package/dist/requests/1762935529749-ukzmiu3/metadata.json +9 -0
  40. package/dist/requests/1762935556527-jxelwj4/SomaComponent.html +193 -0
  41. package/dist/requests/1762935556527-jxelwj4/SomaComponent.tsx +138 -0
  42. package/dist/requests/1762935556527-jxelwj4/metadata.json +9 -0
  43. package/dist/requests/1762935579673-g39fqly/SomaComponent.html +193 -0
  44. package/dist/requests/1762935579673-g39fqly/SomaComponent.tsx +138 -0
  45. package/dist/requests/1762935579673-g39fqly/metadata.json +9 -0
  46. package/dist/requests/1762935613556-ogvsekd/SomaComponent.html +193 -0
  47. package/dist/requests/1762935613556-ogvsekd/SomaComponent.tsx +150 -0
  48. package/dist/requests/1762935613556-ogvsekd/metadata.json +9 -0
  49. package/dist/requests/1762935943631-hb2drgf/SomaComponent.html +193 -0
  50. package/dist/requests/1762935943631-hb2drgf/SomaComponent.tsx +150 -0
  51. package/dist/requests/1762935943631-hb2drgf/metadata.json +9 -0
  52. package/dist/requests/1762935954110-m7jb9m7/SomaComponent.html +193 -0
  53. package/dist/requests/1762935954110-m7jb9m7/SomaComponent.tsx +150 -0
  54. package/dist/requests/1762935954110-m7jb9m7/metadata.json +9 -0
  55. package/dist/requests/1762936003095-0jnmlga/SomaComponent.html +193 -0
  56. package/dist/requests/1762936003095-0jnmlga/SomaComponent.tsx +150 -0
  57. package/dist/requests/1762936003095-0jnmlga/metadata.json +9 -0
  58. package/dist/requests/1762937044748-7ubrrua/SomaComponent.html +193 -0
  59. package/dist/requests/1762937044748-7ubrrua/SomaComponent.tsx +138 -0
  60. package/dist/requests/1762937044748-7ubrrua/metadata.json +9 -0
  61. package/dist/server.d.ts +18 -0
  62. package/dist/server.js +246 -0
  63. package/dist/smithery.d.ts +50 -0
  64. package/dist/smithery.js +44 -0
  65. package/dist/test-figma-tools.d.ts +2 -0
  66. package/dist/test-figma-tools.js +55 -0
  67. package/dist/test-mcp-servers.d.ts +2 -0
  68. package/dist/test-mcp-servers.js +166 -0
  69. package/dist/test.d.ts +2 -0
  70. package/dist/test.js +76 -0
  71. package/package.json +4 -5
  72. package/smithery.yaml +8 -57
  73. package/src/components/OrderManagementGuide.tsx +459 -0
  74. package/src/index.ts +43 -0
  75. package/src/server.ts +301 -0
  76. package/src/services/code-generator.ts +1330 -0
  77. package/src/services/design-system.ts +2133 -0
  78. package/src/services/figma.ts +422 -0
  79. package/src/smithery.ts +54 -0
  80. package/src/test-figma-tools.ts +72 -0
  81. package/src/test-mcp-servers.ts +180 -0
  82. package/src/test.ts +89 -0
  83. package/src/utils/figma-mcp-client.ts +193 -0
  84. package/src/utils/request-manager.ts +101 -0
package/src/server.ts ADDED
@@ -0,0 +1,301 @@
1
+ /**
2
+ * Palette MCP Server - 공통 로직
3
+ *
4
+ * Local(stdio) 모드와 Remote(Smithery) 모드에서 공유되는 핵심 기능을 정의합니다.
5
+ */
6
+
7
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
8
+ import {
9
+ CallToolRequestSchema,
10
+ ListToolsRequestSchema,
11
+ Tool,
12
+ } from '@modelcontextprotocol/sdk/types.js';
13
+ import { readFile } from 'fs/promises';
14
+ import { FigmaService } from './services/figma.js';
15
+ import { DesignSystemService } from './services/design-system.js';
16
+ import { CodeGenerator, type PreviewType } from './services/code-generator.js';
17
+
18
+ // 서버 설정 타입
19
+ export interface ServerConfig {
20
+ figmaAccessToken?: string;
21
+ githubToken?: string;
22
+ figmaMcpServerUrl?: string;
23
+ }
24
+
25
+ // Tools 정의
26
+ export const tools: Tool[] = [
27
+ {
28
+ name: 'convert_figma_to_react',
29
+ description: 'Figma 디자인을 디자인 시스템을 사용하여 React 컴포넌트로 변환합니다',
30
+ inputSchema: {
31
+ type: 'object',
32
+ properties: {
33
+ figmaUrl: {
34
+ type: 'string',
35
+ description: 'Figma 파일 URL 또는 파일 ID',
36
+ },
37
+ nodeId: {
38
+ type: 'string',
39
+ description: '변환할 특정 노드 ID (선택사항)',
40
+ },
41
+ componentName: {
42
+ type: 'string',
43
+ description: '생성할 컴포넌트 이름',
44
+ },
45
+ previewType: {
46
+ type: 'string',
47
+ enum: ['html', 'image', 'both'],
48
+ description: '미리보기 타입: "html"은 HTML 파일, "image"는 PNG 이미지, "both"는 둘 다 (기본값: "both")',
49
+ default: 'both',
50
+ },
51
+ },
52
+ required: ['figmaUrl', 'componentName'],
53
+ },
54
+ },
55
+ {
56
+ name: 'convert_figma_to_vue',
57
+ description: 'Figma 디자인을 디자인 시스템을 사용하여 Vue 컴포넌트로 변환합니다',
58
+ inputSchema: {
59
+ type: 'object',
60
+ properties: {
61
+ figmaUrl: {
62
+ type: 'string',
63
+ description: 'Figma 파일 URL 또는 파일 ID',
64
+ },
65
+ nodeId: {
66
+ type: 'string',
67
+ description: '변환할 특정 노드 ID (선택사항)',
68
+ },
69
+ componentName: {
70
+ type: 'string',
71
+ description: '생성할 컴포넌트 이름',
72
+ },
73
+ previewType: {
74
+ type: 'string',
75
+ enum: ['html', 'image', 'both'],
76
+ description: '미리보기 타입: "html"은 HTML 파일, "image"는 PNG 이미지, "both"는 둘 다 (기본값: "both")',
77
+ default: 'both',
78
+ },
79
+ },
80
+ required: ['figmaUrl', 'componentName'],
81
+ },
82
+ },
83
+ {
84
+ name: 'list_design_system_components',
85
+ description: '디자인 시스템에서 사용 가능한 컴포넌트 목록을 조회합니다',
86
+ inputSchema: {
87
+ type: 'object',
88
+ properties: {
89
+ framework: {
90
+ type: 'string',
91
+ enum: ['react', 'vue'],
92
+ description: '컴포넌트를 조회할 프레임워크',
93
+ },
94
+ },
95
+ required: ['framework'],
96
+ },
97
+ },
98
+ {
99
+ name: 'analyze_figma_file',
100
+ description: 'Figma 파일 구조와 사용 가능한 컴포넌트를 분석합니다',
101
+ inputSchema: {
102
+ type: 'object',
103
+ properties: {
104
+ figmaUrl: {
105
+ type: 'string',
106
+ description: 'Figma 파일 URL 또는 파일 ID',
107
+ },
108
+ },
109
+ required: ['figmaUrl'],
110
+ },
111
+ },
112
+ ];
113
+
114
+ /**
115
+ * MCP 서버를 생성하고 핸들러를 등록합니다.
116
+ * Local 모드와 Remote 모드에서 공통으로 사용됩니다.
117
+ */
118
+ export function createPaletteServer(config: ServerConfig = {}): Server {
119
+ // 환경변수에서 설정 읽기 (config가 우선)
120
+ if (config.figmaAccessToken) {
121
+ process.env.FIGMA_ACCESS_TOKEN = config.figmaAccessToken;
122
+ }
123
+ if (config.githubToken) {
124
+ process.env.GITHUB_TOKEN = config.githubToken;
125
+ }
126
+ if (config.figmaMcpServerUrl) {
127
+ process.env.FIGMA_MCP_SERVER_URL = config.figmaMcpServerUrl;
128
+ }
129
+
130
+ // MCP 서버 초기화
131
+ const server = new Server({
132
+ name: 'palette',
133
+ version: '1.0.0',
134
+ });
135
+
136
+ // 서비스 초기화
137
+ const figmaService = new FigmaService();
138
+ const designSystemService = new DesignSystemService();
139
+ const codeGenerator = new CodeGenerator(designSystemService);
140
+
141
+ // 도구 목록 핸들러
142
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
143
+ return { tools };
144
+ });
145
+
146
+ // 도구 실행 핸들러
147
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
148
+ const { name, arguments: args } = request.params;
149
+
150
+ try {
151
+ switch (name) {
152
+ case 'convert_figma_to_react': {
153
+ const { figmaUrl, nodeId, componentName, previewType = 'both' } = args as {
154
+ figmaUrl: string;
155
+ nodeId?: string;
156
+ componentName: string;
157
+ previewType?: PreviewType;
158
+ };
159
+
160
+ const figmaData = await figmaService.getFigmaData(figmaUrl, nodeId);
161
+ const files = await codeGenerator.generateAndSaveReactComponent(
162
+ figmaData,
163
+ componentName,
164
+ figmaUrl,
165
+ nodeId,
166
+ previewType
167
+ );
168
+
169
+ // 결과 메시지 구성
170
+ let fileList = `- 컴포넌트: \`${files.componentFile}\`\n`;
171
+ if (files.htmlFile) {
172
+ fileList += `- HTML 미리보기: \`${files.htmlFile}\`\n`;
173
+ }
174
+ if (files.imageFile) {
175
+ fileList += `- 이미지 미리보기: \`${files.imageFile}\`\n`;
176
+ }
177
+ fileList += `- 메타데이터: \`${files.metadataFile}\``;
178
+
179
+ const content: any[] = [
180
+ {
181
+ type: 'text',
182
+ text: `# React Component Generated\n\n**요청 ID:** \`${files.requestId}\`\n**저장 경로:** \`${files.folderPath}\`\n\n## 생성된 파일\n${fileList}\n\n## 컴포넌트 코드\n\n\`\`\`tsx\n${await readFile(files.componentFile, 'utf-8')}\n\`\`\``,
183
+ },
184
+ ];
185
+
186
+ // 이미지가 있으면 이미지도 포함
187
+ if (files.imageFile) {
188
+ try {
189
+ const imageBuffer = await readFile(files.imageFile);
190
+ content.push({
191
+ type: 'image',
192
+ data: imageBuffer.toString('base64'),
193
+ mimeType: 'image/png'
194
+ });
195
+ } catch (error) {
196
+ console.warn('이미지 읽기 실패:', error);
197
+ }
198
+ }
199
+
200
+ return { content };
201
+ }
202
+
203
+ case 'convert_figma_to_vue': {
204
+ const { figmaUrl, nodeId, componentName, previewType = 'both' } = args as {
205
+ figmaUrl: string;
206
+ nodeId?: string;
207
+ componentName: string;
208
+ previewType?: PreviewType;
209
+ };
210
+
211
+ const figmaData = await figmaService.getFigmaData(figmaUrl, nodeId);
212
+ const files = await codeGenerator.generateAndSaveVueComponent(
213
+ figmaData,
214
+ componentName,
215
+ figmaUrl,
216
+ nodeId,
217
+ previewType
218
+ );
219
+
220
+ // 결과 메시지 구성
221
+ let fileList = `- 컴포넌트: \`${files.componentFile}\`\n`;
222
+ if (files.htmlFile) {
223
+ fileList += `- HTML 미리보기: \`${files.htmlFile}\`\n`;
224
+ }
225
+ if (files.imageFile) {
226
+ fileList += `- 이미지 미리보기: \`${files.imageFile}\`\n`;
227
+ }
228
+ fileList += `- 메타데이터: \`${files.metadataFile}\``;
229
+
230
+ const content: any[] = [
231
+ {
232
+ type: 'text',
233
+ text: `# Vue Component Generated\n\n**요청 ID:** \`${files.requestId}\`\n**저장 경로:** \`${files.folderPath}\`\n\n## 생성된 파일\n${fileList}\n\n## 컴포넌트 코드\n\n\`\`\`vue\n${await readFile(files.componentFile, 'utf-8')}\n\`\`\``,
234
+ },
235
+ ];
236
+
237
+ // 이미지가 있으면 이미지도 포함
238
+ if (files.imageFile) {
239
+ try {
240
+ const imageBuffer = await readFile(files.imageFile);
241
+ content.push({
242
+ type: 'image',
243
+ data: imageBuffer.toString('base64'),
244
+ mimeType: 'image/png'
245
+ });
246
+ } catch (error) {
247
+ console.warn('이미지 읽기 실패:', error);
248
+ }
249
+ }
250
+
251
+ return { content };
252
+ }
253
+
254
+ case 'list_design_system_components': {
255
+ const { framework } = args as { framework: 'react' | 'vue' };
256
+ const components = await designSystemService.getAvailableComponents(framework);
257
+
258
+ return {
259
+ content: [
260
+ {
261
+ type: 'text',
262
+ text: `# Available ${framework} Components\n\n${components
263
+ .map((comp) => `- **${comp.name}**: ${comp.description}`)
264
+ .join('\n')}`,
265
+ },
266
+ ],
267
+ };
268
+ }
269
+
270
+ case 'analyze_figma_file': {
271
+ const { figmaUrl } = args as { figmaUrl: string };
272
+ const analysis = await figmaService.analyzeFigmaFile(figmaUrl);
273
+
274
+ return {
275
+ content: [
276
+ {
277
+ type: 'text',
278
+ text: `# Figma File Analysis\n\n${analysis}`,
279
+ },
280
+ ],
281
+ };
282
+ }
283
+
284
+ default:
285
+ throw new Error(`Unknown tool: ${name}`);
286
+ }
287
+ } catch (error) {
288
+ return {
289
+ content: [
290
+ {
291
+ type: 'text',
292
+ text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,
293
+ },
294
+ ],
295
+ isError: true,
296
+ };
297
+ }
298
+ });
299
+
300
+ return server;
301
+ }