flowengine-mcp-app 1.1.2 → 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 +4 -5
- package/build/index.js +55 -53
- package/build/index.js.map +1 -1
- package/build/ui/base.d.ts +1 -0
- package/build/ui/base.d.ts.map +1 -1
- package/build/ui/base.js +201 -77
- package/build/ui/base.js.map +1 -1
- package/build/ui/chat.d.ts +6 -0
- package/build/ui/chat.d.ts.map +1 -0
- package/build/ui/chat.js +1530 -0
- package/build/ui/chat.js.map +1 -0
- package/build/ui/component-viewer.d.ts +14 -0
- package/build/ui/component-viewer.d.ts.map +1 -0
- package/build/ui/component-viewer.js +678 -0
- package/build/ui/component-viewer.js.map +1 -0
- package/build/ui/dashboard.d.ts +21 -0
- package/build/ui/dashboard.d.ts.map +1 -0
- package/build/ui/dashboard.js +252 -0
- package/build/ui/dashboard.js.map +1 -0
- package/build/ui/instances.js +4 -0
- package/build/ui/instances.js.map +1 -1
- package/build/ui/n8n-viewer.d.ts +12 -0
- package/build/ui/n8n-viewer.d.ts.map +1 -0
- package/build/ui/n8n-viewer.js +371 -0
- package/build/ui/n8n-viewer.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* n8n Workflow Viewer - Direct workflow display via MCP
|
|
3
|
+
* No chat interface - just displays workflows returned by MCP
|
|
4
|
+
*/
|
|
5
|
+
export function renderN8nViewer(workflow) {
|
|
6
|
+
const workflowJson = workflow ? JSON.stringify(workflow) : JSON.stringify({
|
|
7
|
+
"name": "Empty Workflow",
|
|
8
|
+
"nodes": [
|
|
9
|
+
{
|
|
10
|
+
"parameters": {},
|
|
11
|
+
"id": "1",
|
|
12
|
+
"name": "Start",
|
|
13
|
+
"type": "n8n-nodes-base.start",
|
|
14
|
+
"typeVersion": 1,
|
|
15
|
+
"position": [250, 300]
|
|
16
|
+
}
|
|
17
|
+
],
|
|
18
|
+
"connections": {}
|
|
19
|
+
});
|
|
20
|
+
// Escape JSON for safe embedding in HTML/JavaScript
|
|
21
|
+
const escapedWorkflowJson = workflowJson
|
|
22
|
+
.replace(/\\/g, '\\\\')
|
|
23
|
+
.replace(/`/g, '\\`')
|
|
24
|
+
.replace(/\$/g, '\\$');
|
|
25
|
+
return `<!DOCTYPE html>
|
|
26
|
+
<html lang="en">
|
|
27
|
+
<head>
|
|
28
|
+
<meta charset="UTF-8">
|
|
29
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
30
|
+
<title>FlowEngine - n8n Workflow Viewer</title>
|
|
31
|
+
<style>
|
|
32
|
+
* {
|
|
33
|
+
margin: 0;
|
|
34
|
+
padding: 0;
|
|
35
|
+
box-sizing: border-box;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
body {
|
|
39
|
+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
|
40
|
+
background: #000000;
|
|
41
|
+
color: #ffffff;
|
|
42
|
+
height: 100vh;
|
|
43
|
+
overflow: hidden;
|
|
44
|
+
display: flex;
|
|
45
|
+
flex-direction: column;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/* Header */
|
|
49
|
+
.viewer-header {
|
|
50
|
+
padding: 12px 16px;
|
|
51
|
+
border-bottom: 1px solid rgba(31, 41, 55, 1);
|
|
52
|
+
display: flex;
|
|
53
|
+
justify-content: space-between;
|
|
54
|
+
align-items: center;
|
|
55
|
+
gap: 12px;
|
|
56
|
+
background: #000000;
|
|
57
|
+
flex-shrink: 0;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.logo {
|
|
61
|
+
display: flex;
|
|
62
|
+
align-items: center;
|
|
63
|
+
gap: 8px;
|
|
64
|
+
font-size: 16px;
|
|
65
|
+
font-weight: 700;
|
|
66
|
+
background: linear-gradient(135deg, #3b82f6, #8b5cf6, #10b981);
|
|
67
|
+
-webkit-background-clip: text;
|
|
68
|
+
-webkit-text-fill-color: transparent;
|
|
69
|
+
background-clip: text;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.workflow-title {
|
|
73
|
+
flex: 1;
|
|
74
|
+
font-size: 14px;
|
|
75
|
+
font-weight: 500;
|
|
76
|
+
color: rgba(209, 213, 219, 1);
|
|
77
|
+
padding: 0 16px;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.header-actions {
|
|
81
|
+
display: flex;
|
|
82
|
+
gap: 8px;
|
|
83
|
+
align-items: center;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.action-btn {
|
|
87
|
+
display: flex;
|
|
88
|
+
align-items: center;
|
|
89
|
+
justify-content: center;
|
|
90
|
+
gap: 6px;
|
|
91
|
+
padding: 6px 12px;
|
|
92
|
+
background: rgba(31, 41, 55, 0.5);
|
|
93
|
+
border: 1px solid rgba(75, 85, 99, 1);
|
|
94
|
+
border-radius: 6px;
|
|
95
|
+
color: rgba(209, 213, 219, 1);
|
|
96
|
+
font-size: 12px;
|
|
97
|
+
font-weight: 500;
|
|
98
|
+
cursor: pointer;
|
|
99
|
+
transition: all 0.2s;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.action-btn:hover {
|
|
103
|
+
background: rgba(31, 41, 55, 0.8);
|
|
104
|
+
border-color: rgba(107, 114, 128, 1);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.action-btn.primary {
|
|
108
|
+
background: #ffffff;
|
|
109
|
+
color: #000000;
|
|
110
|
+
border-color: #ffffff;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
.action-btn.primary:hover {
|
|
114
|
+
background: rgba(229, 231, 235, 1);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/* n8n Viewer Container */
|
|
118
|
+
.viewer-container {
|
|
119
|
+
flex: 1;
|
|
120
|
+
position: relative;
|
|
121
|
+
overflow: hidden;
|
|
122
|
+
background: #000000;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
#n8nDemoElement {
|
|
126
|
+
width: 100%;
|
|
127
|
+
height: 100%;
|
|
128
|
+
border: none;
|
|
129
|
+
background: #000000;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/* Loading State */
|
|
133
|
+
.loading-overlay {
|
|
134
|
+
position: absolute;
|
|
135
|
+
inset: 0;
|
|
136
|
+
background: #000000;
|
|
137
|
+
display: flex;
|
|
138
|
+
flex-direction: column;
|
|
139
|
+
align-items: center;
|
|
140
|
+
justify-content: center;
|
|
141
|
+
gap: 16px;
|
|
142
|
+
z-index: 10;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
.loading-overlay.hide {
|
|
146
|
+
display: none;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
.spinner {
|
|
150
|
+
width: 40px;
|
|
151
|
+
height: 40px;
|
|
152
|
+
border: 3px solid rgba(75, 85, 99, 0.3);
|
|
153
|
+
border-top-color: #3b82f6;
|
|
154
|
+
border-radius: 50%;
|
|
155
|
+
animation: spin 0.8s linear infinite;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
@keyframes spin {
|
|
159
|
+
to { transform: rotate(360deg); }
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
.loading-text {
|
|
163
|
+
font-size: 14px;
|
|
164
|
+
color: rgba(156, 163, 175, 1);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/* Empty State */
|
|
168
|
+
.empty-state {
|
|
169
|
+
display: flex;
|
|
170
|
+
flex-direction: column;
|
|
171
|
+
align-items: center;
|
|
172
|
+
justify-content: center;
|
|
173
|
+
height: 100%;
|
|
174
|
+
padding: 32px;
|
|
175
|
+
text-align: center;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
.empty-state svg {
|
|
179
|
+
margin-bottom: 16px;
|
|
180
|
+
opacity: 0.3;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
.empty-state h3 {
|
|
184
|
+
font-size: 18px;
|
|
185
|
+
font-weight: 600;
|
|
186
|
+
color: #ffffff;
|
|
187
|
+
margin-bottom: 8px;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
.empty-state p {
|
|
191
|
+
font-size: 14px;
|
|
192
|
+
color: rgba(156, 163, 175, 1);
|
|
193
|
+
max-width: 400px;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
::-webkit-scrollbar {
|
|
197
|
+
width: 8px;
|
|
198
|
+
height: 8px;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
::-webkit-scrollbar-track {
|
|
202
|
+
background: transparent;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
::-webkit-scrollbar-thumb {
|
|
206
|
+
background: rgba(75, 85, 99, 0.5);
|
|
207
|
+
border-radius: 4px;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
::-webkit-scrollbar-thumb:hover {
|
|
211
|
+
background: rgba(75, 85, 99, 0.7);
|
|
212
|
+
}
|
|
213
|
+
</style>
|
|
214
|
+
</head>
|
|
215
|
+
<body>
|
|
216
|
+
<!-- Header -->
|
|
217
|
+
<div class="viewer-header">
|
|
218
|
+
<div class="logo">
|
|
219
|
+
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
220
|
+
<path d="M12 2L2 7L12 12L22 7L12 2Z" fill="url(#gradient)" stroke="currentColor" stroke-width="2"/>
|
|
221
|
+
<path d="M2 17L12 22L22 17" stroke="currentColor" stroke-width="2"/>
|
|
222
|
+
<path d="M2 12L12 17L22 12" stroke="currentColor" stroke-width="2"/>
|
|
223
|
+
<defs>
|
|
224
|
+
<linearGradient id="gradient" x1="2" y1="2" x2="22" y2="22">
|
|
225
|
+
<stop offset="0%" stop-color="#3b82f6"/>
|
|
226
|
+
<stop offset="50%" stop-color="#8b5cf6"/>
|
|
227
|
+
<stop offset="100%" stop-color="#10b981"/>
|
|
228
|
+
</linearGradient>
|
|
229
|
+
</defs>
|
|
230
|
+
</svg>
|
|
231
|
+
FlowEngine
|
|
232
|
+
</div>
|
|
233
|
+
<div class="workflow-title" id="workflowTitle">Workflow Viewer</div>
|
|
234
|
+
<div class="header-actions">
|
|
235
|
+
<button class="action-btn" id="shareBtn" title="Share workflow">
|
|
236
|
+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
237
|
+
<circle cx="18" cy="5" r="3"></circle>
|
|
238
|
+
<circle cx="6" cy="12" r="3"></circle>
|
|
239
|
+
<circle cx="18" cy="19" r="3"></circle>
|
|
240
|
+
<line x1="8.59" y1="13.51" x2="15.42" y2="17.49"></line>
|
|
241
|
+
<line x1="15.41" y1="6.51" x2="8.59" y2="10.49"></line>
|
|
242
|
+
</svg>
|
|
243
|
+
<span>Share</span>
|
|
244
|
+
</button>
|
|
245
|
+
<button class="action-btn" id="exportBtn" title="Export workflow">
|
|
246
|
+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
247
|
+
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path>
|
|
248
|
+
<polyline points="7 10 12 15 17 10"></polyline>
|
|
249
|
+
<line x1="12" y1="15" x2="12" y2="3"></line>
|
|
250
|
+
</svg>
|
|
251
|
+
<span>Export</span>
|
|
252
|
+
</button>
|
|
253
|
+
<button class="action-btn primary" id="openN8nBtn" title="Open in n8n">
|
|
254
|
+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
255
|
+
<path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path>
|
|
256
|
+
<polyline points="15 3 21 3 21 9"></polyline>
|
|
257
|
+
<line x1="10" y1="14" x2="21" y2="3"></line>
|
|
258
|
+
</svg>
|
|
259
|
+
<span>Open in n8n</span>
|
|
260
|
+
</button>
|
|
261
|
+
</div>
|
|
262
|
+
</div>
|
|
263
|
+
|
|
264
|
+
<!-- n8n Viewer Container -->
|
|
265
|
+
<div class="viewer-container">
|
|
266
|
+
<!-- Loading Overlay -->
|
|
267
|
+
<div class="loading-overlay" id="loadingOverlay">
|
|
268
|
+
<div class="spinner"></div>
|
|
269
|
+
<div class="loading-text">Loading workflow viewer...</div>
|
|
270
|
+
</div>
|
|
271
|
+
|
|
272
|
+
<!-- n8n Demo Element -->
|
|
273
|
+
<n8n-demo id="n8nDemoElement"></n8n-demo>
|
|
274
|
+
</div>
|
|
275
|
+
|
|
276
|
+
<!-- Load n8n Web Components -->
|
|
277
|
+
<script src="https://n8n-io.github.io/n8n-demo-webcomponent/webcomponents-loader.js"></script>
|
|
278
|
+
<script type="module" src="https://n8n-io.github.io/n8n-demo-webcomponent/n8n-demo.bundled.js"></script>
|
|
279
|
+
|
|
280
|
+
<script>
|
|
281
|
+
// Workflow data from MCP
|
|
282
|
+
const workflowData = JSON.parse(\`${escapedWorkflowJson}\`);
|
|
283
|
+
const demoElement = document.getElementById('n8nDemoElement');
|
|
284
|
+
const loadingOverlay = document.getElementById('loadingOverlay');
|
|
285
|
+
const workflowTitle = document.getElementById('workflowTitle');
|
|
286
|
+
const shareBtn = document.getElementById('shareBtn');
|
|
287
|
+
const exportBtn = document.getElementById('exportBtn');
|
|
288
|
+
const openN8nBtn = document.getElementById('openN8nBtn');
|
|
289
|
+
|
|
290
|
+
// Initialize n8n demo
|
|
291
|
+
function initDemo() {
|
|
292
|
+
if (customElements.get('n8n-demo')) {
|
|
293
|
+
try {
|
|
294
|
+
demoElement.setAttribute('workflow', JSON.stringify(workflowData));
|
|
295
|
+
demoElement.setAttribute('theme', 'dark');
|
|
296
|
+
demoElement.setAttribute('collapseformobile', 'false');
|
|
297
|
+
|
|
298
|
+
// Update title
|
|
299
|
+
workflowTitle.textContent = workflowData.name || 'Workflow Viewer';
|
|
300
|
+
|
|
301
|
+
// Hide loading overlay
|
|
302
|
+
setTimeout(() => {
|
|
303
|
+
loadingOverlay.classList.add('hide');
|
|
304
|
+
}, 500);
|
|
305
|
+
} catch (error) {
|
|
306
|
+
console.error('Failed to initialize n8n demo:', error);
|
|
307
|
+
loadingOverlay.innerHTML = \`
|
|
308
|
+
<div class="empty-state">
|
|
309
|
+
<svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
|
|
310
|
+
<circle cx="12" cy="12" r="10"></circle>
|
|
311
|
+
<line x1="12" y1="8" x2="12" y2="12"></line>
|
|
312
|
+
<line x1="12" y1="16" x2="12.01" y2="16"></line>
|
|
313
|
+
</svg>
|
|
314
|
+
<h3>Failed to Load Workflow</h3>
|
|
315
|
+
<p>Unable to initialize the workflow viewer. Please try again.</p>
|
|
316
|
+
</div>
|
|
317
|
+
\`;
|
|
318
|
+
}
|
|
319
|
+
} else {
|
|
320
|
+
setTimeout(initDemo, 100);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
// Start initialization
|
|
325
|
+
setTimeout(initDemo, 500);
|
|
326
|
+
|
|
327
|
+
// Share button - Copy workflow JSON to clipboard
|
|
328
|
+
shareBtn.addEventListener('click', () => {
|
|
329
|
+
const workflow = JSON.stringify(workflowData, null, 2);
|
|
330
|
+
navigator.clipboard.writeText(workflow).then(() => {
|
|
331
|
+
const originalText = shareBtn.innerHTML;
|
|
332
|
+
shareBtn.innerHTML = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="20 6 9 17 4 12"></polyline></svg><span>Copied!</span>';
|
|
333
|
+
setTimeout(() => {
|
|
334
|
+
shareBtn.innerHTML = originalText;
|
|
335
|
+
}, 2000);
|
|
336
|
+
}).catch(err => {
|
|
337
|
+
console.error('Failed to copy:', err);
|
|
338
|
+
alert('Failed to copy workflow to clipboard');
|
|
339
|
+
});
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
// Export button - Download workflow as JSON file
|
|
343
|
+
exportBtn.addEventListener('click', () => {
|
|
344
|
+
const workflow = JSON.stringify(workflowData, null, 2);
|
|
345
|
+
const blob = new Blob([workflow], { type: 'application/json' });
|
|
346
|
+
const url = URL.createObjectURL(blob);
|
|
347
|
+
const a = document.createElement('a');
|
|
348
|
+
a.href = url;
|
|
349
|
+
a.download = (workflowData.name || 'workflow').replace(/[^a-z0-9]/gi, '-').toLowerCase() + '.json';
|
|
350
|
+
a.click();
|
|
351
|
+
URL.revokeObjectURL(url);
|
|
352
|
+
|
|
353
|
+
const originalText = exportBtn.innerHTML;
|
|
354
|
+
exportBtn.innerHTML = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="20 6 9 17 4 12"></polyline></svg><span>Exported!</span>';
|
|
355
|
+
setTimeout(() => {
|
|
356
|
+
exportBtn.innerHTML = originalText;
|
|
357
|
+
}, 2000);
|
|
358
|
+
});
|
|
359
|
+
|
|
360
|
+
// Open in n8n button
|
|
361
|
+
openN8nBtn.addEventListener('click', () => {
|
|
362
|
+
// This would open the workflow in the actual n8n instance
|
|
363
|
+
// You can customize this based on your n8n instance URL
|
|
364
|
+
const n8nUrl = 'https://n8n.flowengine.cloud';
|
|
365
|
+
window.open(n8nUrl, '_blank');
|
|
366
|
+
});
|
|
367
|
+
</script>
|
|
368
|
+
</body>
|
|
369
|
+
</html>`;
|
|
370
|
+
}
|
|
371
|
+
//# sourceMappingURL=n8n-viewer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"n8n-viewer.js","sourceRoot":"","sources":["../../src/ui/n8n-viewer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AASH,MAAM,UAAU,eAAe,CAAC,QAAuB;IACrD,MAAM,YAAY,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC;QACxE,MAAM,EAAE,gBAAgB;QACxB,OAAO,EAAE;YACP;gBACE,YAAY,EAAE,EAAE;gBAChB,IAAI,EAAE,GAAG;gBACT,MAAM,EAAE,OAAO;gBACf,MAAM,EAAE,sBAAsB;gBAC9B,aAAa,EAAE,CAAC;gBAChB,UAAU,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC;aACvB;SACF;QACD,aAAa,EAAE,EAAE;KAClB,CAAC,CAAC;IAEH,oDAAoD;IACpD,MAAM,mBAAmB,GAAG,YAAY;SACrC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC;SACpB,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAEzB,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wCAiQ+B,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAuFnD,CAAC;AACT,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "flowengine-mcp-app",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "FlowEngine Model Context Protocol server for Claude. Manage n8n workflows, build UI components, configure client portals, and provision instances directly from Claude Desktop, VSCode, or CLI.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|