flowengine-mcp-app 1.0.0 → 1.1.2
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 +188 -112
- package/build/client.d.ts +8 -3
- package/build/client.d.ts.map +1 -1
- package/build/client.js +32 -5
- package/build/client.js.map +1 -1
- package/build/index.d.ts +7 -2
- package/build/index.d.ts.map +1 -1
- package/build/index.js +199 -338
- package/build/index.js.map +1 -1
- package/package.json +3 -2
package/build/index.js
CHANGED
|
@@ -1,201 +1,135 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* FlowEngine MCP
|
|
4
|
-
*
|
|
3
|
+
* FlowEngine MCP Server
|
|
4
|
+
* Manage your white-label automation platform from Claude
|
|
5
|
+
*
|
|
6
|
+
* Core Features:
|
|
7
|
+
* 1. Instance Management - Provision and manage FlowEngine instances
|
|
8
|
+
* 2. Client Portals - Monitor and access client portals
|
|
9
|
+
* 3. AI FlowBuilder - Create forms, chatbots, and UI components
|
|
5
10
|
*/
|
|
6
11
|
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
7
12
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
8
|
-
import { CallToolRequestSchema, ListResourcesRequestSchema, ListToolsRequestSchema, ReadResourceRequestSchema,
|
|
13
|
+
import { CallToolRequestSchema, ListResourcesRequestSchema, ListToolsRequestSchema, ReadResourceRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
|
|
9
14
|
import { FlowEngineClient } from './client.js';
|
|
10
15
|
import { renderPortalsDashboard, renderPortalDetails } from './ui/portals.js';
|
|
11
|
-
import { renderWorkflowsManager, renderWorkflowDetails } from './ui/workflows.js';
|
|
12
16
|
import { renderWidgetBuilder, renderWidgetDetails } from './ui/widgets.js';
|
|
13
17
|
import { renderInstancesManager, renderInstanceDetails } from './ui/instances.js';
|
|
14
|
-
import { renderDemoShowcase } from './ui/demo.js';
|
|
15
18
|
import { renderError } from './ui/base.js';
|
|
16
|
-
//
|
|
19
|
+
// Environment configuration
|
|
17
20
|
const API_KEY = process.env.FLOWENGINE_API_KEY;
|
|
18
21
|
const BASE_URL = process.env.FLOWENGINE_BASE_URL || 'https://flowengine.cloud';
|
|
19
|
-
// Initialize FlowEngine client
|
|
22
|
+
// Initialize FlowEngine client
|
|
20
23
|
const flowengine = API_KEY ? new FlowEngineClient({
|
|
21
24
|
apiKey: API_KEY,
|
|
22
25
|
baseUrl: BASE_URL,
|
|
23
26
|
}) : null;
|
|
24
|
-
// Helper to check if client is available
|
|
25
27
|
function ensureClient() {
|
|
26
28
|
if (!flowengine) {
|
|
27
|
-
throw new Error('FlowEngine API key not configured.
|
|
29
|
+
throw new Error('FlowEngine API key not configured. Set FLOWENGINE_API_KEY in your MCP config.');
|
|
28
30
|
}
|
|
29
31
|
return flowengine;
|
|
30
32
|
}
|
|
31
33
|
const server = new Server({
|
|
32
34
|
name: 'flowengine-mcp',
|
|
33
|
-
version: '
|
|
35
|
+
version: '1.0.0',
|
|
34
36
|
}, {
|
|
35
37
|
capabilities: {
|
|
36
38
|
resources: {},
|
|
37
39
|
tools: {},
|
|
38
|
-
prompts: {},
|
|
39
40
|
},
|
|
40
41
|
});
|
|
41
42
|
/**
|
|
42
|
-
*
|
|
43
|
+
* Interactive UI Resources (MCP Apps)
|
|
44
|
+
*
|
|
45
|
+
* How to use UI resources:
|
|
46
|
+
* 1. Ask Claude: "Show me the FlowEngine client portals dashboard"
|
|
47
|
+
* 2. Ask Claude: "Show me the AI FlowBuilder"
|
|
48
|
+
* 3. Ask Claude: "Show me my FlowEngine instances"
|
|
49
|
+
*
|
|
50
|
+
* These commands will display interactive HTML dashboards.
|
|
51
|
+
* If UI resources don't work, use the regular tools:
|
|
52
|
+
* - flowengine_list_portals
|
|
53
|
+
* - flowengine_list_components
|
|
54
|
+
* - flowengine_list_instances
|
|
43
55
|
*/
|
|
44
56
|
server.setRequestHandler(ListResourcesRequestSchema, async () => {
|
|
45
57
|
return {
|
|
46
58
|
resources: [
|
|
47
59
|
{
|
|
48
|
-
uri: '
|
|
49
|
-
name: '
|
|
50
|
-
description: '
|
|
51
|
-
mimeType: 'text/html',
|
|
60
|
+
uri: 'ui://flowengine/portals',
|
|
61
|
+
name: 'Client Portals Dashboard',
|
|
62
|
+
description: 'Interactive dashboard showing all client portals with their URLs, status, and details. Ask: "Show me the FlowEngine client portals dashboard"',
|
|
63
|
+
mimeType: 'text/html;profile=mcp-app',
|
|
52
64
|
},
|
|
53
65
|
{
|
|
54
|
-
uri: '
|
|
55
|
-
name: '
|
|
56
|
-
description: '
|
|
57
|
-
mimeType: 'text/html',
|
|
66
|
+
uri: 'ui://flowengine/ui-builder',
|
|
67
|
+
name: 'AI FlowBuilder Dashboard',
|
|
68
|
+
description: 'Interactive dashboard for building and managing forms, chatbots, and widgets. Ask: "Show me the AI FlowBuilder"',
|
|
69
|
+
mimeType: 'text/html;profile=mcp-app',
|
|
58
70
|
},
|
|
59
71
|
{
|
|
60
|
-
uri: '
|
|
61
|
-
name: '
|
|
62
|
-
description: '
|
|
63
|
-
mimeType: 'text/html',
|
|
64
|
-
},
|
|
65
|
-
{
|
|
66
|
-
uri: 'app://flowengine/ui-builder',
|
|
67
|
-
name: 'UI Builder',
|
|
68
|
-
description: 'Create and manage forms, chatbots, and interactive components',
|
|
69
|
-
mimeType: 'text/html',
|
|
70
|
-
},
|
|
71
|
-
{
|
|
72
|
-
uri: 'app://flowengine/hosting',
|
|
73
|
-
name: 'Hosting',
|
|
74
|
-
description: 'Manage FlowEngine instances and hosting',
|
|
75
|
-
mimeType: 'text/html',
|
|
72
|
+
uri: 'ui://flowengine/instances',
|
|
73
|
+
name: 'Instance Manager Dashboard',
|
|
74
|
+
description: 'Interactive dashboard for managing FlowEngine n8n instances and hosting. Ask: "Show me my FlowEngine instances"',
|
|
75
|
+
mimeType: 'text/html;profile=mcp-app',
|
|
76
76
|
},
|
|
77
77
|
],
|
|
78
78
|
};
|
|
79
79
|
});
|
|
80
80
|
/**
|
|
81
|
-
*
|
|
81
|
+
* Render Resources
|
|
82
82
|
*/
|
|
83
83
|
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
84
84
|
const uri = request.params.uri;
|
|
85
85
|
try {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
return {
|
|
89
|
-
contents: [
|
|
90
|
-
{
|
|
91
|
-
uri,
|
|
92
|
-
mimeType: 'text/html',
|
|
93
|
-
text: html,
|
|
94
|
-
},
|
|
95
|
-
],
|
|
96
|
-
};
|
|
97
|
-
}
|
|
98
|
-
if (uri === 'app://flowengine/portals') {
|
|
86
|
+
// Client Portals Dashboard
|
|
87
|
+
if (uri === 'ui://flowengine/portals') {
|
|
99
88
|
const instances = await ensureClient().getClientInstances();
|
|
100
89
|
const html = renderPortalsDashboard(instances);
|
|
101
90
|
return {
|
|
102
|
-
contents: [
|
|
103
|
-
{
|
|
104
|
-
uri,
|
|
105
|
-
mimeType: 'text/html',
|
|
106
|
-
text: html,
|
|
107
|
-
},
|
|
108
|
-
],
|
|
109
|
-
};
|
|
110
|
-
}
|
|
111
|
-
if (uri === 'app://flowengine/workflows') {
|
|
112
|
-
const workflows = await ensureClient().getWorkflows();
|
|
113
|
-
const html = renderWorkflowsManager(workflows);
|
|
114
|
-
return {
|
|
115
|
-
contents: [
|
|
116
|
-
{
|
|
117
|
-
uri,
|
|
118
|
-
mimeType: 'text/html',
|
|
119
|
-
text: html,
|
|
120
|
-
},
|
|
121
|
-
],
|
|
91
|
+
contents: [{ uri, mimeType: 'text/html', text: html }],
|
|
122
92
|
};
|
|
123
93
|
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
const html = renderWidgetBuilder(widgets);
|
|
127
|
-
return {
|
|
128
|
-
contents: [
|
|
129
|
-
{
|
|
130
|
-
uri,
|
|
131
|
-
mimeType: 'text/html',
|
|
132
|
-
text: html,
|
|
133
|
-
},
|
|
134
|
-
],
|
|
135
|
-
};
|
|
136
|
-
}
|
|
137
|
-
if (uri === 'app://flowengine/hosting') {
|
|
138
|
-
const instances = await ensureClient().getInstances();
|
|
139
|
-
const html = renderInstancesManager(instances);
|
|
140
|
-
return {
|
|
141
|
-
contents: [
|
|
142
|
-
{
|
|
143
|
-
uri,
|
|
144
|
-
mimeType: 'text/html',
|
|
145
|
-
text: html,
|
|
146
|
-
},
|
|
147
|
-
],
|
|
148
|
-
};
|
|
149
|
-
}
|
|
150
|
-
// Handle detail views with query parameters
|
|
151
|
-
if (uri.startsWith('app://flowengine/portal/')) {
|
|
94
|
+
// Portal Details
|
|
95
|
+
if (uri.startsWith('ui://flowengine/portal/')) {
|
|
152
96
|
const instanceId = uri.split('/').pop() || '';
|
|
153
97
|
const client = ensureClient();
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
]);
|
|
98
|
+
// Fetch data sequentially to avoid API concurrency issues
|
|
99
|
+
const workflows = await client.getClientPanelWorkflows(instanceId);
|
|
100
|
+
const widgets = await client.getClientPanelWidgets(instanceId);
|
|
158
101
|
const html = renderPortalDetails(instanceId, workflows, widgets);
|
|
159
102
|
return {
|
|
160
|
-
contents: [
|
|
161
|
-
{
|
|
162
|
-
uri,
|
|
163
|
-
mimeType: 'text/html',
|
|
164
|
-
text: html,
|
|
165
|
-
},
|
|
166
|
-
],
|
|
103
|
+
contents: [{ uri, mimeType: 'text/html', text: html }],
|
|
167
104
|
};
|
|
168
105
|
}
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
const
|
|
172
|
-
const
|
|
173
|
-
const html = renderWorkflowDetails(workflow, executions);
|
|
106
|
+
// AI FlowBuilder (UI Components)
|
|
107
|
+
if (uri === 'ui://flowengine/ui-builder') {
|
|
108
|
+
const widgets = await ensureClient().getWidgets();
|
|
109
|
+
const html = renderWidgetBuilder(widgets);
|
|
174
110
|
return {
|
|
175
|
-
contents: [
|
|
176
|
-
{
|
|
177
|
-
uri,
|
|
178
|
-
mimeType: 'text/html',
|
|
179
|
-
text: html,
|
|
180
|
-
},
|
|
181
|
-
],
|
|
111
|
+
contents: [{ uri, mimeType: 'text/html', text: html }],
|
|
182
112
|
};
|
|
183
113
|
}
|
|
184
|
-
|
|
114
|
+
// Widget Details
|
|
115
|
+
if (uri.startsWith('ui://flowengine/widget/')) {
|
|
185
116
|
const widgetId = uri.split('/').pop() || '';
|
|
186
117
|
const widget = await ensureClient().getWidget(widgetId);
|
|
187
118
|
const html = renderWidgetDetails(widget);
|
|
188
119
|
return {
|
|
189
|
-
contents: [
|
|
190
|
-
{
|
|
191
|
-
uri,
|
|
192
|
-
mimeType: 'text/html',
|
|
193
|
-
text: html,
|
|
194
|
-
},
|
|
195
|
-
],
|
|
120
|
+
contents: [{ uri, mimeType: 'text/html', text: html }],
|
|
196
121
|
};
|
|
197
122
|
}
|
|
198
|
-
|
|
123
|
+
// Instance Manager
|
|
124
|
+
if (uri === 'ui://flowengine/instances') {
|
|
125
|
+
const instances = await ensureClient().getInstances();
|
|
126
|
+
const html = renderInstancesManager(instances);
|
|
127
|
+
return {
|
|
128
|
+
contents: [{ uri, mimeType: 'text/html', text: html }],
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
// Instance Details
|
|
132
|
+
if (uri.startsWith('ui://flowengine/instance/')) {
|
|
199
133
|
const instanceId = uri.split('/').pop() || '';
|
|
200
134
|
const instances = await ensureClient().getInstances();
|
|
201
135
|
const instance = instances.find((i) => i.id === instanceId);
|
|
@@ -205,122 +139,130 @@ server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
|
205
139
|
const status = await ensureClient().getInstanceStatus(instanceId);
|
|
206
140
|
const html = renderInstanceDetails(instance, status);
|
|
207
141
|
return {
|
|
208
|
-
contents: [
|
|
209
|
-
{
|
|
210
|
-
uri,
|
|
211
|
-
mimeType: 'text/html',
|
|
212
|
-
text: html,
|
|
213
|
-
},
|
|
214
|
-
],
|
|
142
|
+
contents: [{ uri, mimeType: 'text/html', text: html }],
|
|
215
143
|
};
|
|
216
144
|
}
|
|
217
|
-
throw new Error(`Unknown resource
|
|
145
|
+
throw new Error(`Unknown resource: ${uri}`);
|
|
218
146
|
}
|
|
219
147
|
catch (error) {
|
|
220
148
|
const html = renderError(error.message || 'An error occurred');
|
|
221
149
|
return {
|
|
222
|
-
contents: [
|
|
223
|
-
{
|
|
224
|
-
uri,
|
|
225
|
-
mimeType: 'text/html',
|
|
226
|
-
text: html,
|
|
227
|
-
},
|
|
228
|
-
],
|
|
150
|
+
contents: [{ uri, mimeType: 'text/html', text: html }],
|
|
229
151
|
};
|
|
230
152
|
}
|
|
231
153
|
});
|
|
232
154
|
/**
|
|
233
|
-
*
|
|
155
|
+
* Available Tools
|
|
234
156
|
*/
|
|
235
157
|
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
236
158
|
return {
|
|
237
159
|
tools: [
|
|
238
|
-
//
|
|
160
|
+
// Instance Management Tools
|
|
239
161
|
{
|
|
240
|
-
name: '
|
|
241
|
-
description: '
|
|
162
|
+
name: 'flowengine_list_instances',
|
|
163
|
+
description: 'List all FlowEngine n8n instances. Returns JSON array with instance details (id, name, url, status, storage). Use this to see all active instances and their hosting information.',
|
|
242
164
|
inputSchema: {
|
|
243
165
|
type: 'object',
|
|
244
|
-
properties: {
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
enabled: {
|
|
250
|
-
type: 'boolean',
|
|
251
|
-
description: 'Whether to enable (true) or disable (false) the workflow',
|
|
252
|
-
},
|
|
166
|
+
properties: {},
|
|
167
|
+
},
|
|
168
|
+
_meta: {
|
|
169
|
+
ui: {
|
|
170
|
+
resourceUri: 'ui://flowengine/instances',
|
|
253
171
|
},
|
|
254
|
-
required: ['workflowId', 'enabled'],
|
|
255
172
|
},
|
|
256
173
|
},
|
|
257
174
|
{
|
|
258
|
-
name: '
|
|
259
|
-
description: '
|
|
175
|
+
name: 'flowengine_get_instance_status',
|
|
176
|
+
description: 'Get health and status information for a specific instance',
|
|
260
177
|
inputSchema: {
|
|
261
178
|
type: 'object',
|
|
262
179
|
properties: {
|
|
263
180
|
instanceId: {
|
|
264
181
|
type: 'string',
|
|
265
|
-
description: '
|
|
182
|
+
description: 'The instance ID to check',
|
|
266
183
|
},
|
|
267
184
|
},
|
|
185
|
+
required: ['instanceId'],
|
|
268
186
|
},
|
|
269
187
|
},
|
|
270
188
|
{
|
|
271
|
-
name: '
|
|
272
|
-
description: '
|
|
189
|
+
name: 'flowengine_create_instance',
|
|
190
|
+
description: 'Provision a new FlowEngine instance for a client',
|
|
273
191
|
inputSchema: {
|
|
274
192
|
type: 'object',
|
|
275
193
|
properties: {
|
|
276
|
-
|
|
277
|
-
type: '
|
|
278
|
-
description: '
|
|
194
|
+
data: {
|
|
195
|
+
type: 'object',
|
|
196
|
+
description: 'Instance configuration with client info and settings',
|
|
279
197
|
},
|
|
280
198
|
},
|
|
281
|
-
required: ['
|
|
199
|
+
required: ['data'],
|
|
282
200
|
},
|
|
283
201
|
},
|
|
284
|
-
// Instance tools
|
|
285
202
|
{
|
|
286
|
-
name: '
|
|
287
|
-
description: '
|
|
203
|
+
name: 'flowengine_update_instance',
|
|
204
|
+
description: 'Update instance settings and configuration',
|
|
288
205
|
inputSchema: {
|
|
289
206
|
type: 'object',
|
|
290
|
-
properties: {
|
|
207
|
+
properties: {
|
|
208
|
+
data: {
|
|
209
|
+
type: 'object',
|
|
210
|
+
description: 'Updated instance configuration',
|
|
211
|
+
},
|
|
212
|
+
},
|
|
213
|
+
required: ['data'],
|
|
291
214
|
},
|
|
292
215
|
},
|
|
293
216
|
{
|
|
294
|
-
name: '
|
|
295
|
-
description: '
|
|
217
|
+
name: 'flowengine_delete_instance',
|
|
218
|
+
description: 'Permanently delete a FlowEngine instance',
|
|
296
219
|
inputSchema: {
|
|
297
220
|
type: 'object',
|
|
298
221
|
properties: {
|
|
299
222
|
instanceId: {
|
|
300
223
|
type: 'string',
|
|
301
|
-
description: 'The instance ID',
|
|
224
|
+
description: 'The instance ID to delete',
|
|
302
225
|
},
|
|
303
226
|
},
|
|
304
227
|
required: ['instanceId'],
|
|
305
228
|
},
|
|
306
229
|
},
|
|
307
|
-
//
|
|
230
|
+
// Portal Tools
|
|
231
|
+
{
|
|
232
|
+
name: 'flowengine_list_portals',
|
|
233
|
+
description: 'List all client portals with their access URLs. Returns JSON array with portal details (id, instance_name, instance_url, status, storage_limit_gb, created_at). Use this to get portal information for clients.',
|
|
234
|
+
inputSchema: {
|
|
235
|
+
type: 'object',
|
|
236
|
+
properties: {},
|
|
237
|
+
},
|
|
238
|
+
_meta: {
|
|
239
|
+
ui: {
|
|
240
|
+
resourceUri: 'ui://flowengine/portals',
|
|
241
|
+
},
|
|
242
|
+
},
|
|
243
|
+
},
|
|
244
|
+
// UI Component Tools (AI FlowBuilder)
|
|
308
245
|
{
|
|
309
|
-
name: '
|
|
310
|
-
description: 'List all forms, chatbots,
|
|
246
|
+
name: 'flowengine_list_components',
|
|
247
|
+
description: 'List all UI components (forms, chatbots, widgets) built with AI FlowBuilder. Returns JSON array with component details. Optionally filter by instanceId to see components for a specific instance.',
|
|
311
248
|
inputSchema: {
|
|
312
249
|
type: 'object',
|
|
313
250
|
properties: {
|
|
314
251
|
instanceId: {
|
|
315
252
|
type: 'string',
|
|
316
|
-
description: 'Optional instance ID
|
|
253
|
+
description: 'Optional: Filter by instance ID',
|
|
317
254
|
},
|
|
318
255
|
},
|
|
319
256
|
},
|
|
257
|
+
_meta: {
|
|
258
|
+
ui: {
|
|
259
|
+
resourceUri: 'ui://flowengine/ui-builder',
|
|
260
|
+
},
|
|
261
|
+
},
|
|
320
262
|
},
|
|
321
263
|
{
|
|
322
264
|
name: 'flowengine_get_component',
|
|
323
|
-
description: 'Get
|
|
265
|
+
description: 'Get detailed configuration for a specific UI component',
|
|
324
266
|
inputSchema: {
|
|
325
267
|
type: 'object',
|
|
326
268
|
properties: {
|
|
@@ -332,141 +274,144 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
332
274
|
required: ['componentId'],
|
|
333
275
|
},
|
|
334
276
|
},
|
|
335
|
-
// Portal tools
|
|
336
|
-
{
|
|
337
|
-
name: 'flowengine_list_portals',
|
|
338
|
-
description: 'List all client portals',
|
|
339
|
-
inputSchema: {
|
|
340
|
-
type: 'object',
|
|
341
|
-
properties: {},
|
|
342
|
-
},
|
|
343
|
-
},
|
|
344
|
-
// Template tools
|
|
345
277
|
{
|
|
346
|
-
name: '
|
|
347
|
-
description: '
|
|
278
|
+
name: 'flowengine_create_component',
|
|
279
|
+
description: 'Create a new UI component using AI FlowBuilder (form, chatbot, or widget)',
|
|
348
280
|
inputSchema: {
|
|
349
281
|
type: 'object',
|
|
350
|
-
properties: {
|
|
282
|
+
properties: {
|
|
283
|
+
data: {
|
|
284
|
+
type: 'object',
|
|
285
|
+
description: 'Component configuration with type, name, and settings',
|
|
286
|
+
},
|
|
287
|
+
},
|
|
288
|
+
required: ['data'],
|
|
351
289
|
},
|
|
352
290
|
},
|
|
353
291
|
{
|
|
354
|
-
name: '
|
|
355
|
-
description: '
|
|
292
|
+
name: 'flowengine_update_component',
|
|
293
|
+
description: 'Update an existing UI component configuration',
|
|
356
294
|
inputSchema: {
|
|
357
295
|
type: 'object',
|
|
358
296
|
properties: {
|
|
359
|
-
|
|
297
|
+
componentId: {
|
|
360
298
|
type: 'string',
|
|
361
|
-
description: 'The
|
|
299
|
+
description: 'The component ID to update',
|
|
362
300
|
},
|
|
363
|
-
|
|
364
|
-
type: '
|
|
365
|
-
description: '
|
|
301
|
+
data: {
|
|
302
|
+
type: 'object',
|
|
303
|
+
description: 'Updated component configuration',
|
|
366
304
|
},
|
|
367
305
|
},
|
|
368
|
-
required: ['
|
|
306
|
+
required: ['componentId', 'data'],
|
|
369
307
|
},
|
|
370
308
|
},
|
|
371
309
|
{
|
|
372
|
-
name: '
|
|
373
|
-
description: '
|
|
310
|
+
name: 'flowengine_delete_component',
|
|
311
|
+
description: 'Delete a UI component',
|
|
374
312
|
inputSchema: {
|
|
375
313
|
type: 'object',
|
|
376
314
|
properties: {
|
|
377
|
-
|
|
378
|
-
type: 'string',
|
|
379
|
-
description: 'The instance ID to create the workflow in',
|
|
380
|
-
},
|
|
381
|
-
workflowJSON: {
|
|
382
|
-
type: 'object',
|
|
383
|
-
description: 'The workflow JSON definition',
|
|
384
|
-
},
|
|
385
|
-
workflowTitle: {
|
|
315
|
+
componentId: {
|
|
386
316
|
type: 'string',
|
|
387
|
-
description: '
|
|
317
|
+
description: 'The component ID to delete',
|
|
388
318
|
},
|
|
389
319
|
},
|
|
390
|
-
required: ['
|
|
320
|
+
required: ['componentId'],
|
|
391
321
|
},
|
|
392
322
|
},
|
|
393
323
|
],
|
|
394
324
|
};
|
|
395
325
|
});
|
|
396
326
|
/**
|
|
397
|
-
* Handle
|
|
327
|
+
* Handle Tool Calls
|
|
398
328
|
*/
|
|
399
329
|
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
400
330
|
const { name, arguments: args } = request.params;
|
|
401
331
|
try {
|
|
402
332
|
switch (name) {
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
const workflowId = args.workflowId;
|
|
407
|
-
const enabled = args.enabled;
|
|
408
|
-
const result = await ensureClient().toggleWorkflow(workflowId, enabled);
|
|
333
|
+
// Instance Management
|
|
334
|
+
case 'flowengine_list_instances': {
|
|
335
|
+
const instances = await ensureClient().getInstances();
|
|
409
336
|
return {
|
|
410
337
|
content: [
|
|
411
338
|
{
|
|
412
339
|
type: 'text',
|
|
413
|
-
text:
|
|
340
|
+
text: JSON.stringify(instances, null, 2),
|
|
414
341
|
},
|
|
415
342
|
],
|
|
416
343
|
};
|
|
417
344
|
}
|
|
418
|
-
case '
|
|
419
|
-
|
|
420
|
-
|
|
345
|
+
case 'flowengine_get_instance_status': {
|
|
346
|
+
if (!args)
|
|
347
|
+
throw new Error('Missing arguments');
|
|
348
|
+
const instanceId = args.instanceId;
|
|
349
|
+
const status = await ensureClient().getInstanceStatus(instanceId);
|
|
421
350
|
return {
|
|
422
351
|
content: [
|
|
423
352
|
{
|
|
424
353
|
type: 'text',
|
|
425
|
-
text: JSON.stringify(
|
|
354
|
+
text: JSON.stringify(status, null, 2),
|
|
426
355
|
},
|
|
427
356
|
],
|
|
428
357
|
};
|
|
429
358
|
}
|
|
430
|
-
case '
|
|
359
|
+
case 'flowengine_create_instance': {
|
|
431
360
|
if (!args)
|
|
432
361
|
throw new Error('Missing arguments');
|
|
433
|
-
const
|
|
434
|
-
const
|
|
362
|
+
const data = args.data;
|
|
363
|
+
const result = await ensureClient().provisionInstance(data);
|
|
435
364
|
return {
|
|
436
365
|
content: [
|
|
437
366
|
{
|
|
438
367
|
type: 'text',
|
|
439
|
-
text:
|
|
368
|
+
text: `Instance created successfully. ID: ${result.instanceId || result.id || 'N/A'}`,
|
|
440
369
|
},
|
|
441
370
|
],
|
|
442
371
|
};
|
|
443
372
|
}
|
|
444
|
-
case '
|
|
445
|
-
|
|
373
|
+
case 'flowengine_update_instance': {
|
|
374
|
+
if (!args)
|
|
375
|
+
throw new Error('Missing arguments');
|
|
376
|
+
const data = args.data;
|
|
377
|
+
await ensureClient().updateInstance(data);
|
|
446
378
|
return {
|
|
447
379
|
content: [
|
|
448
380
|
{
|
|
449
381
|
type: 'text',
|
|
450
|
-
text:
|
|
382
|
+
text: 'Instance updated successfully',
|
|
451
383
|
},
|
|
452
384
|
],
|
|
453
385
|
};
|
|
454
386
|
}
|
|
455
|
-
case '
|
|
387
|
+
case 'flowengine_delete_instance': {
|
|
456
388
|
if (!args)
|
|
457
389
|
throw new Error('Missing arguments');
|
|
458
390
|
const instanceId = args.instanceId;
|
|
459
|
-
|
|
391
|
+
await ensureClient().deleteInstance(instanceId);
|
|
460
392
|
return {
|
|
461
393
|
content: [
|
|
462
394
|
{
|
|
463
395
|
type: 'text',
|
|
464
|
-
text:
|
|
396
|
+
text: 'Instance deleted successfully',
|
|
465
397
|
},
|
|
466
398
|
],
|
|
467
399
|
};
|
|
468
400
|
}
|
|
469
|
-
|
|
401
|
+
// Portals
|
|
402
|
+
case 'flowengine_list_portals': {
|
|
403
|
+
const portals = await ensureClient().getClientInstances();
|
|
404
|
+
return {
|
|
405
|
+
content: [
|
|
406
|
+
{
|
|
407
|
+
type: 'text',
|
|
408
|
+
text: JSON.stringify(portals, null, 2),
|
|
409
|
+
},
|
|
410
|
+
],
|
|
411
|
+
};
|
|
412
|
+
}
|
|
413
|
+
// UI Components (AI FlowBuilder)
|
|
414
|
+
case 'flowengine_list_components': {
|
|
470
415
|
const instanceId = args ? args.instanceId : undefined;
|
|
471
416
|
const widgets = await ensureClient().getWidgets(instanceId);
|
|
472
417
|
return {
|
|
@@ -492,59 +437,45 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
492
437
|
],
|
|
493
438
|
};
|
|
494
439
|
}
|
|
495
|
-
case '
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
type: 'text',
|
|
501
|
-
text: JSON.stringify(portals, null, 2),
|
|
502
|
-
},
|
|
503
|
-
],
|
|
504
|
-
};
|
|
505
|
-
}
|
|
506
|
-
case 'flowengine_list_templates': {
|
|
507
|
-
const templates = await ensureClient().listTemplates();
|
|
440
|
+
case 'flowengine_create_component': {
|
|
441
|
+
if (!args)
|
|
442
|
+
throw new Error('Missing arguments');
|
|
443
|
+
const data = args.data;
|
|
444
|
+
const result = await ensureClient().createWidget(data);
|
|
508
445
|
return {
|
|
509
446
|
content: [
|
|
510
447
|
{
|
|
511
448
|
type: 'text',
|
|
512
|
-
text:
|
|
449
|
+
text: `Component created successfully. ID: ${result.id || result.widgetId || 'N/A'}`,
|
|
513
450
|
},
|
|
514
451
|
],
|
|
515
452
|
};
|
|
516
453
|
}
|
|
517
|
-
case '
|
|
454
|
+
case 'flowengine_update_component': {
|
|
518
455
|
if (!args)
|
|
519
456
|
throw new Error('Missing arguments');
|
|
520
|
-
const
|
|
521
|
-
const
|
|
522
|
-
|
|
457
|
+
const componentId = args.componentId;
|
|
458
|
+
const data = args.data;
|
|
459
|
+
await ensureClient().updateWidget(componentId, data);
|
|
523
460
|
return {
|
|
524
461
|
content: [
|
|
525
462
|
{
|
|
526
463
|
type: 'text',
|
|
527
|
-
text:
|
|
464
|
+
text: 'Component updated successfully',
|
|
528
465
|
},
|
|
529
466
|
],
|
|
530
467
|
};
|
|
531
468
|
}
|
|
532
|
-
case '
|
|
469
|
+
case 'flowengine_delete_component': {
|
|
533
470
|
if (!args)
|
|
534
471
|
throw new Error('Missing arguments');
|
|
535
|
-
const
|
|
536
|
-
|
|
537
|
-
const workflowTitle = args.workflowTitle;
|
|
538
|
-
const result = await ensureClient().importWorkflowToInstance({
|
|
539
|
-
instanceId,
|
|
540
|
-
workflowJSON,
|
|
541
|
-
workflowTitle,
|
|
542
|
-
});
|
|
472
|
+
const componentId = args.componentId;
|
|
473
|
+
await ensureClient().deleteWidget(componentId);
|
|
543
474
|
return {
|
|
544
475
|
content: [
|
|
545
476
|
{
|
|
546
477
|
type: 'text',
|
|
547
|
-
text:
|
|
478
|
+
text: 'Component deleted successfully',
|
|
548
479
|
},
|
|
549
480
|
],
|
|
550
481
|
};
|
|
@@ -566,82 +497,12 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
566
497
|
}
|
|
567
498
|
});
|
|
568
499
|
/**
|
|
569
|
-
*
|
|
570
|
-
*/
|
|
571
|
-
server.setRequestHandler(ListPromptsRequestSchema, async () => {
|
|
572
|
-
return {
|
|
573
|
-
prompts: [
|
|
574
|
-
{
|
|
575
|
-
name: 'check_workflow_status',
|
|
576
|
-
description: 'Check the status of your workflows',
|
|
577
|
-
},
|
|
578
|
-
{
|
|
579
|
-
name: 'view_recent_executions',
|
|
580
|
-
description: 'View recent workflow executions',
|
|
581
|
-
},
|
|
582
|
-
{
|
|
583
|
-
name: 'manage_portals',
|
|
584
|
-
description: 'Manage your client portals',
|
|
585
|
-
},
|
|
586
|
-
],
|
|
587
|
-
};
|
|
588
|
-
});
|
|
589
|
-
/**
|
|
590
|
-
* Handle prompt requests
|
|
591
|
-
*/
|
|
592
|
-
server.setRequestHandler(GetPromptRequestSchema, async (request) => {
|
|
593
|
-
const { name } = request.params;
|
|
594
|
-
switch (name) {
|
|
595
|
-
case 'check_workflow_status':
|
|
596
|
-
return {
|
|
597
|
-
description: 'Check the status of your workflows',
|
|
598
|
-
messages: [
|
|
599
|
-
{
|
|
600
|
-
role: 'user',
|
|
601
|
-
content: {
|
|
602
|
-
type: 'text',
|
|
603
|
-
text: 'Please show me the status of all my workflows and highlight any that are inactive or having issues.',
|
|
604
|
-
},
|
|
605
|
-
},
|
|
606
|
-
],
|
|
607
|
-
};
|
|
608
|
-
case 'view_recent_executions':
|
|
609
|
-
return {
|
|
610
|
-
description: 'View recent workflow executions',
|
|
611
|
-
messages: [
|
|
612
|
-
{
|
|
613
|
-
role: 'user',
|
|
614
|
-
content: {
|
|
615
|
-
type: 'text',
|
|
616
|
-
text: 'Show me the most recent workflow executions and highlight any failures.',
|
|
617
|
-
},
|
|
618
|
-
},
|
|
619
|
-
],
|
|
620
|
-
};
|
|
621
|
-
case 'manage_portals':
|
|
622
|
-
return {
|
|
623
|
-
description: 'Manage your client portals',
|
|
624
|
-
messages: [
|
|
625
|
-
{
|
|
626
|
-
role: 'user',
|
|
627
|
-
content: {
|
|
628
|
-
type: 'text',
|
|
629
|
-
text: 'Show me all my client portals and their current status.',
|
|
630
|
-
},
|
|
631
|
-
},
|
|
632
|
-
],
|
|
633
|
-
};
|
|
634
|
-
default:
|
|
635
|
-
throw new Error(`Unknown prompt: ${name}`);
|
|
636
|
-
}
|
|
637
|
-
});
|
|
638
|
-
/**
|
|
639
|
-
* Start the server
|
|
500
|
+
* Start Server
|
|
640
501
|
*/
|
|
641
502
|
async function main() {
|
|
642
503
|
const transport = new StdioServerTransport();
|
|
643
504
|
await server.connect(transport);
|
|
644
|
-
console.error('FlowEngine MCP
|
|
505
|
+
console.error('FlowEngine MCP Server running');
|
|
645
506
|
}
|
|
646
507
|
main().catch((error) => {
|
|
647
508
|
console.error('Fatal error:', error);
|