@stellisoft/stellify-mcp 0.1.1 → 0.1.5

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/dist/index.js CHANGED
@@ -17,84 +17,254 @@ const stellify = new StellifyClient({
17
17
  apiUrl: API_URL,
18
18
  apiToken: API_TOKEN,
19
19
  });
20
+ // =============================================================================
21
+ // STELLIFY AI WORKFLOW GUIDE
22
+ // =============================================================================
23
+ // Stellify stores code as structured JSON, not text files.
24
+ // This enables surgical AI edits at the statement level.
25
+ //
26
+ // -----------------------------------------------------------------------------
27
+ // REAL-TIME UI BROADCASTING (use this for demonstrations!)
28
+ // -----------------------------------------------------------------------------
29
+ // When users ask you to SHOW, DISPLAY, BUILD, or DEMONSTRATE anything visually,
30
+ // use broadcast_element_command FIRST. This sends real-time updates via WebSocket
31
+ // directly to the user's browser - no database storage, instant feedback.
32
+ //
33
+ // Use broadcast_element_command for:
34
+ // - Showing the user something visually
35
+ // - Building UI elements as you discuss them
36
+ // - Sending messages/content to the browser
37
+ // - Any "live" or "real-time" interaction
38
+ //
39
+ // Use html_to_elements/update_element for:
40
+ // - Permanent changes that should persist
41
+ // - Building components that will be saved
42
+ //
43
+ // SUPPORTED FILE TYPES:
44
+ // - PHP: Controllers, Models, Middleware, Classes
45
+ // - JavaScript/TypeScript: JS files, Vue SFCs
46
+ // - UI: Elements (HTML structure stored as JSON)
47
+ //
48
+ // -----------------------------------------------------------------------------
49
+ // GENERAL WORKFLOW (applies to all file types)
50
+ // -----------------------------------------------------------------------------
51
+ // 1. Create file skeleton (create_file) - empty structure, no methods yet
52
+ // 2. Add methods (create_method) - creates signature only
53
+ // 3. Add method bodies (add_method_body) - implementation code
54
+ // 4. Add statements (create_statement + add_statement_code) - for non-method code
55
+ // 5. Save file (save_file) - finalize with all references
56
+ //
57
+ // -----------------------------------------------------------------------------
58
+ // PHP EXAMPLE: Creating a Controller
59
+ // -----------------------------------------------------------------------------
60
+ // 1. create_file: type='controller', name='UserController'
61
+ // 2. create_method: name='store', parameters=[{name:'request', type:'Request'}]
62
+ // 3. add_method_body: code='return response()->json($request->all());'
63
+ //
64
+ // -----------------------------------------------------------------------------
65
+ // VUE COMPONENT WORKFLOW (step-by-step)
66
+ // -----------------------------------------------------------------------------
67
+ // Vue components combine UI elements with reactive data. Follow this order:
68
+ //
69
+ // 1. get_project - Find the 'js' directory UUID
70
+ // 2. create_file - type='js', extension='vue' in js directory
71
+ // 3. Create statements for IMPORTS and DATA (each needs create_statement + add_statement_code):
72
+ // - "import { ref } from 'vue';" ← REQUIRED for using ref()
73
+ // - "const count = ref(0);"
74
+ // NOTE: Vue imports are NOT auto-generated. You must add them manually.
75
+ // 4. create_method - Creates method signature (returns UUID)
76
+ // add_method_body - Add implementation: "count.value++;"
77
+ // 5. html_to_elements - Convert template HTML to elements (no 'page' needed)
78
+ // NOTE: Vue bindings like {{ count }} auto-create statements linked to elements
79
+ // 6. update_element - Wire event handlers (e.g., click → method UUID)
80
+ // 7. save_file - Finalize with:
81
+ // - extension: 'vue'
82
+ // - template: [rootElementUuid] (from html_to_elements)
83
+ // - data: [methodUuid] (METHOD UUIDs only!)
84
+ // - statements: [importStmtUuid, countStmtUuid] (STATEMENT UUIDs - imports, refs)
85
+ //
86
+ // Vue SFC file structure:
87
+ // - extension: 'vue'
88
+ // - template: Array of root element UUIDs (<template> section)
89
+ // - data: Array of METHOD UUIDs only (<script setup> functions)
90
+ // - statements: Array of STATEMENT UUIDs (<script setup> imports, variables, refs)
91
+ // - includes: Array of file UUIDs to import
92
+ //
93
+ // -----------------------------------------------------------------------------
94
+ // ELEMENT EVENT HANDLERS (for frontend files)
95
+ // -----------------------------------------------------------------------------
96
+ // Elements can have these event properties (value is method UUID):
97
+ // - click: Fires on click (@click)
98
+ // - submit: Fires on form submit (@submit)
99
+ // - change: Fires on input change (@change)
100
+ // - input: Fires on input in real-time (@input)
101
+ // - focus: Fires when element receives focus (@focus)
102
+ // - blur: Fires when element loses focus (@blur)
103
+ // - keydown: Fires on key press (@keydown)
104
+ // - keyup: Fires on key release (@keyup)
105
+ // - mouseenter: Fires on mouse enter (@mouseenter)
106
+ // - mouseleave: Fires on mouse leave (@mouseleave)
107
+ //
108
+ // =============================================================================
20
109
  // Define MCP tools
21
110
  const tools = [
111
+ {
112
+ name: 'get_project',
113
+ description: `Get the active Stellify project for the authenticated user.
114
+
115
+ IMPORTANT: Call this first before any other operations.
116
+
117
+ Returns:
118
+ - uuid: Project UUID (needed for most operations)
119
+ - name: Project name
120
+ - branch/branches: Git branch info
121
+ - directories: Array of {uuid, name} for existing directories (js, controllers, models, etc.)
122
+
123
+ Use the directories array to find existing directories before creating new ones.
124
+ For example, look for a "js" directory before creating Vue components.`,
125
+ inputSchema: {
126
+ type: 'object',
127
+ properties: {},
128
+ },
129
+ },
22
130
  {
23
131
  name: 'create_file',
24
- description: 'Create a new file (class, model, controller, middleware) in a Stellify project. This creates the file structure but no methods yet.',
132
+ description: `Create a new file in a Stellify project.
133
+
134
+ This creates an EMPTY file shell - no methods, statements, or template yet. The file exists but has no content.
135
+
136
+ COMPLETE WORKFLOW:
137
+ 1. create_file → creates empty shell, returns file UUID
138
+ 2. create_statement + add_statement_code → add variables/imports (returns statement UUIDs)
139
+ 3. create_method + add_method_body → add functions (returns method UUIDs)
140
+ 4. html_to_elements → create template elements (returns element UUIDs)
141
+ 5. save_file → FINALIZE by wiring template/data arrays with all collected UUIDs
142
+
143
+ For PHP: Use type='class', 'model', 'controller', or 'middleware'.
144
+ For Vue: Use type='js' and extension='vue'. Place in the 'js' directory.
145
+
146
+ DEPENDENCY RESOLUTION (automatic):
147
+ Pass 'includes' as an array of namespace strings (e.g., ["App\\Models\\User", "Illuminate\\Support\\Facades\\Hash"]).
148
+ The system resolves these to UUIDs automatically, creating missing dependencies on-demand:
149
+ - App\\* classes → creates stub file in your project (tenant DB)
150
+ - Illuminate\\*/Laravel\\* → fetches from Laravel API, creates in Application DB
151
+ - Vendor packages → fetches from vendor, creates in Application DB`,
25
152
  inputSchema: {
26
153
  type: 'object',
27
154
  properties: {
28
- project_id: {
155
+ directory: {
29
156
  type: 'string',
30
- description: 'The UUID of the Stellify project',
157
+ description: 'The UUID of the directory to create the file in (get from get_project directories array)',
31
158
  },
32
159
  name: {
33
160
  type: 'string',
34
- description: 'File name (e.g., "Calculator", "UserController")',
161
+ description: 'File name without extension (e.g., "Counter", "UserController")',
35
162
  },
36
163
  type: {
37
164
  type: 'string',
38
- enum: ['class', 'model', 'controller', 'middleware'],
39
- description: 'Type of file to create',
165
+ enum: ['class', 'model', 'controller', 'middleware', 'js'],
166
+ description: 'Type of file: "js" for JavaScript/Vue, others for PHP',
167
+ },
168
+ extension: {
169
+ type: 'string',
170
+ description: 'File extension. Use "vue" for Vue components, omit for PHP files.',
40
171
  },
41
172
  namespace: {
42
173
  type: 'string',
43
- description: 'PHP namespace (e.g., "App\\Services\\", "App\\Http\\Controllers\\")',
174
+ description: 'PHP namespace (e.g., "App\\Services\\"). Only for PHP files.',
175
+ },
176
+ includes: {
177
+ type: 'array',
178
+ items: { type: 'string' },
179
+ description: 'Array of namespace strings to include as dependencies (e.g., ["App\\Models\\User", "Illuminate\\Support\\Facades\\Hash"]). These are resolved to UUIDs automatically.',
44
180
  },
45
181
  },
46
- required: ['project_id', 'name', 'type'],
182
+ required: ['directory', 'name', 'type'],
47
183
  },
48
184
  },
49
185
  {
50
186
  name: 'create_method',
51
- description: 'Create a method signature in a file. This only creates the method declaration, not the body. Use add_method_body to add implementation.',
187
+ description: `Create a method signature in a file. This only creates the method declaration, not the body. Use add_method_body to add implementation.
188
+
189
+ Parameters are automatically created as clauses. The response includes the clause UUIDs for each parameter.
190
+
191
+ Example request:
192
+ {
193
+ "file": "file-uuid",
194
+ "name": "verify",
195
+ "visibility": "public",
196
+ "returnType": "object",
197
+ "nullable": true,
198
+ "parameters": [
199
+ { "name": "credentials", "datatype": "array" }
200
+ ]
201
+ }
202
+
203
+ Example response includes:
204
+ {
205
+ "uuid": "method-uuid",
206
+ "name": "verify",
207
+ "returnType": "object",
208
+ "nullable": true,
209
+ "parameters": ["clause-uuid-for-credentials"],
210
+ ...
211
+ }`,
52
212
  inputSchema: {
53
213
  type: 'object',
54
214
  properties: {
55
- file_uuid: {
215
+ file: {
56
216
  type: 'string',
57
217
  description: 'UUID of the file to add the method to',
58
218
  },
59
219
  name: {
60
220
  type: 'string',
61
- description: 'Method name (e.g., "add", "store", "index")',
221
+ description: 'Method name (e.g., "increment", "store", "handleClick")',
62
222
  },
63
223
  visibility: {
64
224
  type: 'string',
65
225
  enum: ['public', 'protected', 'private'],
66
- description: 'Method visibility',
67
- default: 'public',
226
+ description: 'Method visibility (PHP only)',
68
227
  },
69
228
  is_static: {
70
229
  type: 'boolean',
71
- description: 'Whether the method is static',
72
- default: false,
230
+ description: 'Whether the method is static (PHP only)',
73
231
  },
74
- return_type: {
232
+ returnType: {
75
233
  type: 'string',
76
- description: 'Return type (e.g., "int", "string", "JsonResponse", "void")',
234
+ description: 'Return type (e.g., "int", "string", "void", "object")',
235
+ },
236
+ nullable: {
237
+ type: 'boolean',
238
+ description: 'Whether the return type is nullable (e.g., ?object)',
77
239
  },
78
240
  parameters: {
79
241
  type: 'array',
80
- description: 'Array of method parameters',
242
+ description: 'Array of method parameters. Each parameter is created as a clause.',
81
243
  items: {
82
244
  type: 'object',
83
245
  properties: {
84
246
  name: {
85
247
  type: 'string',
86
- description: 'Parameter name (without $)',
248
+ description: 'Parameter name (e.g., "credentials", "id")',
249
+ },
250
+ datatype: {
251
+ type: 'string',
252
+ description: 'Parameter data type (e.g., "array", "int", "string", "Request")',
87
253
  },
88
254
  type: {
89
255
  type: 'string',
90
- description: 'Parameter type (e.g., "int", "string", "Request")',
256
+ description: 'Clause type, defaults to "variable"',
257
+ },
258
+ value: {
259
+ type: 'string',
260
+ description: 'Parameter value, defaults to the name',
91
261
  },
92
262
  },
93
- required: ['name', 'type'],
263
+ required: ['name'],
94
264
  },
95
265
  },
96
266
  },
97
- required: ['file_uuid', 'name'],
267
+ required: ['file', 'name'],
98
268
  },
99
269
  },
100
270
  {
@@ -103,11 +273,11 @@ const tools = [
103
273
  inputSchema: {
104
274
  type: 'object',
105
275
  properties: {
106
- file_uuid: {
276
+ file: {
107
277
  type: 'string',
108
278
  description: 'UUID of the file containing the method',
109
279
  },
110
- method_uuid: {
280
+ method: {
111
281
  type: 'string',
112
282
  description: 'UUID of the method to add code to',
113
283
  },
@@ -116,7 +286,56 @@ const tools = [
116
286
  description: 'PHP code for the method body (just the statements, no function declaration). Example: "return $a + $b;"',
117
287
  },
118
288
  },
119
- required: ['file_uuid', 'method_uuid', 'code'],
289
+ required: ['file', 'method', 'code'],
290
+ },
291
+ },
292
+ {
293
+ name: 'save_method',
294
+ description: `Update an existing method's properties (name, visibility, returnType, nullable, parameters).
295
+
296
+ Use this to modify a method after creation. For updating the method body, use add_method_body instead.
297
+
298
+ Example:
299
+ {
300
+ "uuid": "method-uuid",
301
+ "returnType": "object",
302
+ "nullable": true
303
+ }`,
304
+ inputSchema: {
305
+ type: 'object',
306
+ properties: {
307
+ uuid: {
308
+ type: 'string',
309
+ description: 'UUID of the method to update',
310
+ },
311
+ name: {
312
+ type: 'string',
313
+ description: 'Method name',
314
+ },
315
+ visibility: {
316
+ type: 'string',
317
+ enum: ['public', 'protected', 'private'],
318
+ description: 'Method visibility (PHP only)',
319
+ },
320
+ is_static: {
321
+ type: 'boolean',
322
+ description: 'Whether the method is static (PHP only)',
323
+ },
324
+ returnType: {
325
+ type: 'string',
326
+ description: 'Return type (e.g., "int", "string", "void", "object")',
327
+ },
328
+ nullable: {
329
+ type: 'boolean',
330
+ description: 'Whether the return type is nullable',
331
+ },
332
+ parameters: {
333
+ type: 'array',
334
+ description: 'Array of parameter clause UUIDs',
335
+ items: { type: 'string' },
336
+ },
337
+ },
338
+ required: ['uuid'],
120
339
  },
121
340
  },
122
341
  {
@@ -153,96 +372,1256 @@ const tools = [
153
372
  },
154
373
  },
155
374
  },
156
- ];
157
- // Create MCP server
158
- const server = new Server({
159
- name: 'stellify-mcp',
160
- version: '0.1.0',
161
- }, {
162
- capabilities: {
163
- tools: {},
375
+ {
376
+ name: 'create_route',
377
+ description: 'Create a new route/page in a Stellify project',
378
+ inputSchema: {
379
+ type: 'object',
380
+ properties: {
381
+ project_id: {
382
+ type: 'string',
383
+ description: 'The UUID of the Stellify project',
384
+ },
385
+ name: {
386
+ type: 'string',
387
+ description: 'Route/page name (e.g., "Home", "Counter", "About")',
388
+ },
389
+ path: {
390
+ type: 'string',
391
+ description: 'URL path (e.g., "/", "/counter", "/about")',
392
+ },
393
+ method: {
394
+ type: 'string',
395
+ enum: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH'],
396
+ description: 'HTTP method',
397
+ default: 'GET',
398
+ },
399
+ type: {
400
+ type: 'string',
401
+ enum: ['web', 'api'],
402
+ description: 'Route type: "web" for pages, "api" for API endpoints',
403
+ default: 'web',
404
+ },
405
+ data: {
406
+ type: 'object',
407
+ description: 'Additional route data (title, description, element UUIDs)',
408
+ },
409
+ },
410
+ required: ['project_id', 'name', 'path', 'method'],
411
+ },
164
412
  },
165
- });
166
- // Handle tool list requests
167
- server.setRequestHandler(ListToolsRequestSchema, async () => {
168
- return { tools };
169
- });
170
- // Handle tool execution
171
- server.setRequestHandler(CallToolRequestSchema, async (request) => {
172
- const { name, arguments: args } = request.params;
173
- if (!args) {
174
- throw new Error('Arguments are required');
175
- }
176
- try {
177
- switch (name) {
178
- case 'create_file': {
179
- const result = await stellify.createFile(args);
180
- return {
181
- content: [
182
- {
183
- type: 'text',
184
- text: JSON.stringify({
185
- success: true,
186
- message: `Created file "${args.name}" (${result.uuid})`,
187
- file: result,
188
- }, null, 2),
189
- },
190
- ],
191
- };
192
- }
193
- case 'create_method': {
194
- const result = await stellify.createMethod(args);
195
- return {
196
- content: [
197
- {
198
- type: 'text',
199
- text: JSON.stringify({
200
- success: true,
201
- message: `Created method "${args.name}" (${result.uuid})`,
202
- method: result,
203
- }, null, 2),
204
- },
205
- ],
206
- };
207
- }
208
- case 'add_method_body': {
209
- const result = await stellify.addMethodBody(args);
210
- return {
211
- content: [
212
- {
213
- type: 'text',
214
- text: JSON.stringify({
215
- success: true,
216
- message: 'Method body parsed and saved successfully',
217
- data: result,
218
- }, null, 2),
219
- },
220
- ],
221
- };
222
- }
223
- case 'search_methods': {
224
- const result = await stellify.searchMethods(args);
225
- return {
226
- content: [
227
- {
228
- type: 'text',
229
- text: JSON.stringify({
230
- success: true,
231
- results: result,
232
- }, null, 2),
233
- },
413
+ {
414
+ name: 'get_route',
415
+ description: `Get a route/page by UUID. Returns route details including name, path, and attached elements.
416
+
417
+ Use this to look up a route you created or to find existing routes in the project.`,
418
+ inputSchema: {
419
+ type: 'object',
420
+ properties: {
421
+ uuid: {
422
+ type: 'string',
423
+ description: 'The UUID of the route to retrieve',
424
+ },
425
+ },
426
+ required: ['uuid'],
427
+ },
428
+ },
429
+ {
430
+ name: 'search_routes',
431
+ description: `Search for routes/pages in the project by name. Use this to find existing routes before creating new ones.
432
+
433
+ Returns paginated results with route details including UUID, name, path, and type.
434
+ Use the returned UUID with html_to_elements (page parameter) or get_route for full details.`,
435
+ inputSchema: {
436
+ type: 'object',
437
+ properties: {
438
+ search: {
439
+ type: 'string',
440
+ description: 'Search term to match route names (e.g., "Counter", "Home")',
441
+ },
442
+ type: {
443
+ type: 'string',
444
+ enum: ['web', 'api'],
445
+ description: 'Filter by route type: "web" for pages, "api" for endpoints',
446
+ },
447
+ per_page: {
448
+ type: 'number',
449
+ description: 'Results per page (default: 10)',
450
+ },
451
+ },
452
+ },
453
+ },
454
+ {
455
+ name: 'create_element',
456
+ description: `Create a new UI element on a page (for Elements v2). Provide either page (route UUID) for root elements, or parent (element UUID) for child elements.
457
+
458
+ Valid element types:
459
+ - HTML5: s-wrapper, s-input, s-form, s-svg, s-shape, s-media, s-iframe
460
+ - Components: s-loop, s-transition, s-freestyle, s-motion
461
+ - Blade: s-directive
462
+ - Shadcn/ui: s-chart, s-table, s-combobox, s-accordion, s-calendar, s-contiguous`,
463
+ inputSchema: {
464
+ type: 'object',
465
+ properties: {
466
+ type: {
467
+ type: 'string',
468
+ enum: [
469
+ 's-wrapper', 's-input', 's-form', 's-svg', 's-shape', 's-media', 's-iframe',
470
+ 's-loop', 's-transition', 's-freestyle', 's-motion',
471
+ 's-directive',
472
+ 's-chart', 's-table', 's-combobox', 's-accordion', 's-calendar', 's-contiguous'
234
473
  ],
235
- };
236
- }
237
- case 'search_files': {
238
- const result = await stellify.searchFiles(args);
239
- return {
240
- content: [
241
- {
242
- type: 'text',
243
- text: JSON.stringify({
244
- success: true,
245
- results: result,
474
+ description: 'Element type - must be one of the valid Stellify element types',
475
+ },
476
+ page: {
477
+ type: 'string',
478
+ description: 'UUID of the page/route to add the element to (for root elements)',
479
+ },
480
+ parent: {
481
+ type: 'string',
482
+ description: 'UUID of the parent element (for child elements)',
483
+ },
484
+ },
485
+ required: ['type'],
486
+ },
487
+ },
488
+ {
489
+ name: 'update_element',
490
+ description: `Update an existing UI element (for Elements v2).
491
+
492
+ Use standard HTML attributes directly (placeholder, href, src, type, etc.).
493
+
494
+ Special Stellify fields:
495
+ - name: Element name in editor
496
+ - type: Element type (s-wrapper, s-input, etc.)
497
+ - locked: Prevent editing (boolean)
498
+ - tag: HTML tag (div, input, button, etc.)
499
+ - classes: CSS classes array ["class1", "class2"]
500
+ - text: Element text content
501
+
502
+ EVENT HANDLERS (set value to method UUID):
503
+ - click: @click - buttons, links, any clickable element
504
+ - submit: @submit - form submission
505
+ - change: @change - input/select value changed (on blur)
506
+ - input: @input - input value changing (real-time, as user types)
507
+ - focus: @focus - element receives focus
508
+ - blur: @blur - element loses focus
509
+ - keydown: @keydown - key pressed down
510
+ - keyup: @keyup - key released
511
+ - mouseenter: @mouseenter - mouse enters element
512
+ - mouseleave: @mouseleave - mouse leaves element
513
+
514
+ Example wiring a button click to a method:
515
+ {
516
+ "uuid": "button-element-uuid",
517
+ "data": {
518
+ "click": "increment-method-uuid"
519
+ }
520
+ }`,
521
+ inputSchema: {
522
+ type: 'object',
523
+ properties: {
524
+ uuid: {
525
+ type: 'string',
526
+ description: 'UUID of the element to update',
527
+ },
528
+ data: {
529
+ type: 'object',
530
+ description: 'Flat object with HTML attributes and Stellify fields (name, type, locked, tag, classes, text)',
531
+ },
532
+ },
533
+ required: ['uuid', 'data'],
534
+ },
535
+ },
536
+ {
537
+ name: 'get_element',
538
+ description: 'Get a single element by UUID. Returns the element data with all its attributes.',
539
+ inputSchema: {
540
+ type: 'object',
541
+ properties: {
542
+ uuid: {
543
+ type: 'string',
544
+ description: 'UUID of the element to retrieve',
545
+ },
546
+ },
547
+ required: ['uuid'],
548
+ },
549
+ },
550
+ {
551
+ name: 'get_element_tree',
552
+ description: 'Get an element with all its descendants (children, grandchildren, etc.) as a hierarchical tree structure.',
553
+ inputSchema: {
554
+ type: 'object',
555
+ properties: {
556
+ uuid: {
557
+ type: 'string',
558
+ description: 'UUID of the root element',
559
+ },
560
+ },
561
+ required: ['uuid'],
562
+ },
563
+ },
564
+ {
565
+ name: 'delete_element',
566
+ description: 'Delete an element and all its children (CASCADE). Returns the count of deleted elements.',
567
+ inputSchema: {
568
+ type: 'object',
569
+ properties: {
570
+ uuid: {
571
+ type: 'string',
572
+ description: 'UUID of the element to delete',
573
+ },
574
+ },
575
+ required: ['uuid'],
576
+ },
577
+ },
578
+ {
579
+ name: 'search_elements',
580
+ description: `Search for elements in the project. Useful for finding elements by name, type, or content.
581
+
582
+ Note: To reorder elements, use update_element to modify the parent element's 'data' array with the new order of child UUIDs.`,
583
+ inputSchema: {
584
+ type: 'object',
585
+ properties: {
586
+ search: {
587
+ type: 'string',
588
+ description: 'Search query to match against element name, type, or content',
589
+ },
590
+ type: {
591
+ type: 'string',
592
+ description: 'Filter by element type (e.g., s-wrapper, s-input)',
593
+ },
594
+ include_metadata: {
595
+ type: 'boolean',
596
+ description: 'Include additional metadata',
597
+ default: false,
598
+ },
599
+ per_page: {
600
+ type: 'number',
601
+ description: 'Results per page (1-100)',
602
+ default: 20,
603
+ },
604
+ },
605
+ },
606
+ },
607
+ {
608
+ name: 'html_to_elements',
609
+ description: `Convert HTML to Stellify elements in ONE operation. This is the FASTEST way to build interfaces!
610
+
611
+ This will:
612
+ 1. Parse the HTML structure
613
+ 2. Create all elements with proper nesting and types
614
+ 3. Preserve all attributes, classes, text content
615
+ 4. Auto-detect Vue bindings ({{ variable }}) and create linked statements
616
+ 5. Return element UUIDs to use in save_file template array
617
+
618
+ Element type mapping:
619
+ - button, input, textarea, select → s-input
620
+ - div, span, p, section, etc. → s-wrapper
621
+ - form → s-form
622
+ - img, video, audio → s-media
623
+
624
+ VUE BINDING AUTO-DETECTION:
625
+ Text like {{ count }} is automatically detected and:
626
+ - A statement is created with the binding code
627
+ - The statement UUID is added to the element's 'statements' array
628
+ - You still need to create the reactive data source separately (const count = ref(0))
629
+
630
+ For Vue components: Omit 'page' - elements are created standalone for the component template.
631
+ For page content: Provide 'page' (route UUID) to attach elements directly.
632
+
633
+ IMPORTANT: Use the returned root element UUID in save_file's template array.`,
634
+ inputSchema: {
635
+ type: 'object',
636
+ properties: {
637
+ elements: {
638
+ type: 'string',
639
+ description: 'HTML string to convert',
640
+ },
641
+ page: {
642
+ type: 'string',
643
+ description: 'Route UUID to attach elements to. Optional for Vue components.',
644
+ },
645
+ selection: {
646
+ type: 'string',
647
+ description: 'Parent element UUID to attach to (alternative to page)',
648
+ },
649
+ test: {
650
+ type: 'boolean',
651
+ description: 'If true, returns structure without creating elements',
652
+ },
653
+ },
654
+ required: ['elements'],
655
+ },
656
+ },
657
+ {
658
+ name: 'list_globals',
659
+ description: 'List all global files in the Application database. Globals are reusable, curated code (controllers, models, services) that can be installed into tenant projects.',
660
+ inputSchema: {
661
+ type: 'object',
662
+ properties: {},
663
+ },
664
+ },
665
+ {
666
+ name: 'get_global',
667
+ description: 'Get a global file with all its methods, statements, and clauses. Returns the full structure of a reusable code file.',
668
+ inputSchema: {
669
+ type: 'object',
670
+ properties: {
671
+ uuid: {
672
+ type: 'string',
673
+ description: 'UUID of the global file to retrieve',
674
+ },
675
+ },
676
+ required: ['uuid'],
677
+ },
678
+ },
679
+ {
680
+ name: 'install_global',
681
+ description: 'Install a global file from the Application database into a tenant project. Copies the file, methods, and statements to the tenant database with the same UUIDs (for deduplication). Clauses remain shared in the Application DB.',
682
+ inputSchema: {
683
+ type: 'object',
684
+ properties: {
685
+ file_uuid: {
686
+ type: 'string',
687
+ description: 'UUID of the global file to install',
688
+ },
689
+ directory_uuid: {
690
+ type: 'string',
691
+ description: 'UUID of the directory in the tenant project to install the file into',
692
+ },
693
+ },
694
+ required: ['file_uuid', 'directory_uuid'],
695
+ },
696
+ },
697
+ {
698
+ name: 'search_global_methods',
699
+ description: 'Search for methods across the Application database (global/framework methods). Use this to find reusable Laravel framework methods, facades, and shared code.',
700
+ inputSchema: {
701
+ type: 'object',
702
+ properties: {
703
+ query: {
704
+ type: 'string',
705
+ description: 'Search query to find methods by name',
706
+ },
707
+ },
708
+ required: ['query'],
709
+ },
710
+ },
711
+ // Module tools (groups of globals)
712
+ {
713
+ name: 'list_modules',
714
+ description: 'List all available modules. A module is a named collection of related global files that can be installed together as a package.',
715
+ inputSchema: {
716
+ type: 'object',
717
+ properties: {},
718
+ },
719
+ },
720
+ {
721
+ name: 'get_module',
722
+ description: 'Get a module with all its files. Returns the module metadata and list of global files it contains, in installation order.',
723
+ inputSchema: {
724
+ type: 'object',
725
+ properties: {
726
+ uuid: {
727
+ type: 'string',
728
+ description: 'UUID of the module to retrieve',
729
+ },
730
+ },
731
+ required: ['uuid'],
732
+ },
733
+ },
734
+ {
735
+ name: 'create_module',
736
+ description: 'Create a new module to group related global files together.',
737
+ inputSchema: {
738
+ type: 'object',
739
+ properties: {
740
+ name: {
741
+ type: 'string',
742
+ description: 'Unique name for the module (e.g., "laravel-sanctum-auth")',
743
+ },
744
+ description: {
745
+ type: 'string',
746
+ description: 'Description of what the module provides',
747
+ },
748
+ version: {
749
+ type: 'string',
750
+ description: 'Version string (default: "1.0.0")',
751
+ },
752
+ tags: {
753
+ type: 'array',
754
+ items: { type: 'string' },
755
+ description: 'Tags for categorization (e.g., ["auth", "api", "sanctum"])',
756
+ },
757
+ },
758
+ required: ['name'],
759
+ },
760
+ },
761
+ {
762
+ name: 'add_file_to_module',
763
+ description: 'Add a global file to a module. Files are installed in order when the module is installed.',
764
+ inputSchema: {
765
+ type: 'object',
766
+ properties: {
767
+ module_uuid: {
768
+ type: 'string',
769
+ description: 'UUID of the module',
770
+ },
771
+ file_uuid: {
772
+ type: 'string',
773
+ description: 'UUID of the global file to add',
774
+ },
775
+ order: {
776
+ type: 'number',
777
+ description: 'Installation order (optional, auto-increments if not specified)',
778
+ },
779
+ },
780
+ required: ['module_uuid', 'file_uuid'],
781
+ },
782
+ },
783
+ {
784
+ name: 'install_module',
785
+ description: 'Install all files from a module into a tenant project. Copies files, methods, and statements in the defined order. Clauses remain shared in the Application DB.',
786
+ inputSchema: {
787
+ type: 'object',
788
+ properties: {
789
+ module_uuid: {
790
+ type: 'string',
791
+ description: 'UUID of the module to install',
792
+ },
793
+ directory_uuid: {
794
+ type: 'string',
795
+ description: 'UUID of the directory in the tenant project to install files into',
796
+ },
797
+ },
798
+ required: ['module_uuid', 'directory_uuid'],
799
+ },
800
+ },
801
+ // =============================================================================
802
+ // STATEMENT & FILE MANAGEMENT TOOLS
803
+ // =============================================================================
804
+ {
805
+ name: 'get_statement',
806
+ description: `Get a statement by UUID. Returns the statement data including its clauses (code tokens).`,
807
+ inputSchema: {
808
+ type: 'object',
809
+ properties: {
810
+ uuid: {
811
+ type: 'string',
812
+ description: 'The UUID of the statement to retrieve',
813
+ },
814
+ },
815
+ required: ['uuid'],
816
+ },
817
+ },
818
+ {
819
+ name: 'create_statement',
820
+ description: `Create an empty statement in a file. This is step 1 of 2 - you MUST call add_statement_code next to add the actual code.
821
+
822
+ IMPORTANT: This is a TWO-STEP process:
823
+ 1. create_statement → returns statement UUID
824
+ 2. add_statement_code → adds the actual code to that statement
825
+
826
+ Use cases:
827
+ - PHP: Class properties, use statements, constants
828
+ - JS/Vue: Variable declarations, imports, reactive refs
829
+
830
+ For Vue components, include the returned statement UUID in save_file's 'data' array.`,
831
+ inputSchema: {
832
+ type: 'object',
833
+ properties: {
834
+ file: {
835
+ type: 'string',
836
+ description: 'UUID of the file to add the statement to',
837
+ },
838
+ method: {
839
+ type: 'string',
840
+ description: 'UUID of the method to add the statement to (for method body statements)',
841
+ },
842
+ },
843
+ },
844
+ },
845
+ {
846
+ name: 'add_statement_code',
847
+ description: `Add code to an existing statement. This is step 2 of 2 - call this AFTER create_statement.
848
+
849
+ The statement must already exist (created via create_statement). This parses and stores the code.
850
+
851
+ Examples:
852
+ - PHP: "use Illuminate\\Http\\Request;" or "private $items = [];"
853
+ - JS/Vue: "const count = ref(0);" or "import { ref } from 'vue';"`,
854
+ inputSchema: {
855
+ type: 'object',
856
+ properties: {
857
+ file: {
858
+ type: 'string',
859
+ description: 'UUID of the file containing the statement',
860
+ },
861
+ statement: {
862
+ type: 'string',
863
+ description: 'UUID of the statement to add code to',
864
+ },
865
+ code: {
866
+ type: 'string',
867
+ description: 'The code to add (e.g., "const count = ref(0);")',
868
+ },
869
+ },
870
+ required: ['file', 'statement', 'code'],
871
+ },
872
+ },
873
+ {
874
+ name: 'save_file',
875
+ description: `Save/update a file with its full configuration. This FINALIZES the file after create_file.
876
+
877
+ WORKFLOW: create_file creates an empty shell → add methods/statements → save_file wires everything together.
878
+
879
+ IMPORTANT: This is a full replacement, not a partial update. To update an existing file:
880
+ 1. Call get_file to fetch current state
881
+ 2. Modify the returned object
882
+ 3. Call save_file with the complete object
883
+
884
+ Required fields: uuid, name, type
885
+
886
+ IMPORTANT - data vs statements:
887
+ - 'data' array = METHOD UUIDs only (functions)
888
+ - 'statements' array = STATEMENT UUIDs (imports, variables, refs - code outside methods)
889
+
890
+ Vue SFC example:
891
+ save_file({
892
+ uuid: fileUuid,
893
+ name: "Counter",
894
+ type: "js",
895
+ extension: "vue",
896
+ template: [rootElementUuid], // From html_to_elements
897
+ data: [methodUuid], // Method UUIDs only
898
+ statements: [importStmtUuid, refStmtUuid] // Statement UUIDs (imports, refs)
899
+ })
900
+
901
+ For <script setup> content, the order in statements array determines output order.`,
902
+ inputSchema: {
903
+ type: 'object',
904
+ properties: {
905
+ uuid: {
906
+ type: 'string',
907
+ description: 'UUID of the file to save',
908
+ },
909
+ name: {
910
+ type: 'string',
911
+ description: 'File name (without extension)',
912
+ },
913
+ type: {
914
+ type: 'string',
915
+ enum: ['js', 'class', 'controller', 'model', 'middleware'],
916
+ description: 'File type: "js" for JavaScript/Vue, others for PHP',
917
+ },
918
+ extension: {
919
+ type: 'string',
920
+ description: 'File extension: "vue" for Vue SFCs, "js" for JavaScript',
921
+ },
922
+ template: {
923
+ type: 'array',
924
+ items: { type: 'string' },
925
+ description: 'Array of root element UUIDs for Vue <template> section (from html_to_elements)',
926
+ },
927
+ data: {
928
+ type: 'array',
929
+ items: { type: 'string' },
930
+ description: 'Array of METHOD UUIDs only (functions created via create_method)',
931
+ },
932
+ statements: {
933
+ type: 'array',
934
+ items: { type: 'string' },
935
+ description: 'Array of STATEMENT UUIDs (imports, variables, refs - created via create_statement)',
936
+ },
937
+ includes: {
938
+ type: 'array',
939
+ items: { type: 'string' },
940
+ description: 'Array of file UUIDs to import',
941
+ },
942
+ },
943
+ required: ['uuid', 'name', 'type'],
944
+ },
945
+ },
946
+ {
947
+ name: 'get_file',
948
+ description: 'Get a file by UUID with all its metadata, methods, and statements.',
949
+ inputSchema: {
950
+ type: 'object',
951
+ properties: {
952
+ uuid: {
953
+ type: 'string',
954
+ description: 'UUID of the file to retrieve',
955
+ },
956
+ },
957
+ required: ['uuid'],
958
+ },
959
+ },
960
+ {
961
+ name: 'get_directory',
962
+ description: `Get a directory by UUID to see its contents.
963
+
964
+ Use this to inspect directories returned by get_project. The project's data array contains directory UUIDs.
965
+ Returns the directory name and list of files/subdirectories inside it.`,
966
+ inputSchema: {
967
+ type: 'object',
968
+ properties: {
969
+ uuid: {
970
+ type: 'string',
971
+ description: 'The UUID of the directory to retrieve',
972
+ },
973
+ },
974
+ required: ['uuid'],
975
+ },
976
+ },
977
+ {
978
+ name: 'create_directory',
979
+ description: `Create a new directory for organizing files.
980
+
981
+ Common directories:
982
+ - 'js' for JavaScript/Vue files
983
+ - 'css' for stylesheets
984
+ - 'components' for reusable components
985
+
986
+ IMPORTANT: Check existing directories first using get_project and get_directory before creating new ones.`,
987
+ inputSchema: {
988
+ type: 'object',
989
+ properties: {
990
+ name: {
991
+ type: 'string',
992
+ description: 'Directory name (e.g., "js", "css", "components")',
993
+ },
994
+ },
995
+ required: ['name'],
996
+ },
997
+ },
998
+ {
999
+ name: 'broadcast_element_command',
1000
+ description: `Broadcast a real-time command to update UI elements via WebSocket.
1001
+
1002
+ IMPORTANT: USE THIS TOOL FIRST when the user asks you to:
1003
+ - Show, display, or demonstrate something visually
1004
+ - Update, change, or modify what's on screen
1005
+ - Build or create UI elements for demonstration
1006
+ - Send messages or content to the browser
1007
+ - Do anything "live" or "in real-time"
1008
+
1009
+ This is the PRIMARY tool for real-time AI-to-browser communication. It pushes changes instantly to all connected browsers. Changes are EPHEMERAL (not saved to database) - perfect for demonstrations, live content, and interactive sessions.
1010
+
1011
+ ACTIONS:
1012
+ - update: Modify an existing element's attributes (text, classes, styles, etc.)
1013
+ - create: Create a new ephemeral element (provide any UUID string you want)
1014
+ - batch: Modify multiple elements at once
1015
+ - delete: Remove an element from the UI state
1016
+
1017
+ TO CREATE EPHEMERAL ELEMENTS (not stored in database):
1018
+ 1. First, use action="create" with any UUID (e.g., "msg-001") and full element structure in changes
1019
+ 2. Then, use action="update" on the PARENT element to add your new UUID to its "data" array
1020
+
1021
+ Example - Update existing element text:
1022
+ { action: "update", element: "existing-uuid", changes: { text: "Hello world!", classes: ["p-4", "bg-blue-500"] } }
1023
+
1024
+ Example - Create ephemeral child element:
1025
+ Step 1: { action: "create", element: "my-new-element", changes: { type: "s-wrapper", tag: "div", text: "I exist!", classes: ["p-2", "bg-green-500"] } }
1026
+ Step 2: { action: "update", element: "parent-uuid", changes: { data: ["my-new-element"] } }
1027
+
1028
+ For PERSISTENT changes (saved to database), use update_element or html_to_elements instead.`,
1029
+ inputSchema: {
1030
+ type: 'object',
1031
+ properties: {
1032
+ action: {
1033
+ type: 'string',
1034
+ enum: ['update', 'batch', 'delete', 'create'],
1035
+ description: 'The type of command to broadcast',
1036
+ },
1037
+ element: {
1038
+ type: 'string',
1039
+ description: 'UUID of the element to modify (required for update, delete, create)',
1040
+ },
1041
+ changes: {
1042
+ type: 'object',
1043
+ description: 'Object containing attribute changes (e.g., { classes: ["bg-blue-500"], text: "Hello" })',
1044
+ },
1045
+ updates: {
1046
+ type: 'array',
1047
+ description: 'Array of updates for batch action: [{ element: "uuid", changes: {...} }]',
1048
+ items: {
1049
+ type: 'object',
1050
+ properties: {
1051
+ element: { type: 'string' },
1052
+ changes: { type: 'object' },
1053
+ },
1054
+ required: ['element', 'changes'],
1055
+ },
1056
+ },
1057
+ },
1058
+ required: ['action'],
1059
+ },
1060
+ },
1061
+ ];
1062
+ // Server instructions for tool discovery (used by MCP Tool Search)
1063
+ const SERVER_INSTRUCTIONS = `Stellify is a coding platform where you code alongside AI on a codebase maintained and curated by AI. Build Laravel/PHP and Vue.js applications.
1064
+
1065
+ Use Stellify tools when:
1066
+ - Building PHP controllers, models, middleware, or classes
1067
+ - Creating Vue.js components with reactive state and UI
1068
+ - Managing UI elements (HTML stored as structured JSON)
1069
+ - Working with a Stellify project (user will mention "Stellify" or provide project UUID)
1070
+
1071
+ Key concepts:
1072
+ - Code is stored as structured JSON, enabling surgical AI edits at the statement level
1073
+ - Files contain methods and statements (code outside methods)
1074
+ - Vue components link to UI elements via the 'template' field
1075
+ - Event handlers (click, submit) wire UI elements to methods by UUID`;
1076
+ // Create MCP server
1077
+ const server = new Server({
1078
+ name: 'stellify-mcp',
1079
+ version: '0.1.0',
1080
+ }, {
1081
+ capabilities: {
1082
+ tools: {},
1083
+ },
1084
+ instructions: SERVER_INSTRUCTIONS,
1085
+ });
1086
+ // Handle tool list requests
1087
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
1088
+ return { tools };
1089
+ });
1090
+ // Handle tool execution
1091
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
1092
+ const { name, arguments: args } = request.params;
1093
+ if (!args) {
1094
+ throw new Error('Arguments are required');
1095
+ }
1096
+ try {
1097
+ switch (name) {
1098
+ case 'get_project': {
1099
+ const result = await stellify.getProject();
1100
+ return {
1101
+ content: [
1102
+ {
1103
+ type: 'text',
1104
+ text: JSON.stringify({
1105
+ success: true,
1106
+ message: `Active project: "${result.data?.name || result.name}" (${result.data?.uuid || result.uuid})`,
1107
+ project: result.data || result,
1108
+ }, null, 2),
1109
+ },
1110
+ ],
1111
+ };
1112
+ }
1113
+ case 'create_file': {
1114
+ const result = await stellify.createFile(args);
1115
+ const fileData = result.data || result;
1116
+ return {
1117
+ content: [
1118
+ {
1119
+ type: 'text',
1120
+ text: JSON.stringify({
1121
+ success: true,
1122
+ message: `Created file "${args.name}" (UUID: ${fileData.uuid})`,
1123
+ file: fileData,
1124
+ }, null, 2),
1125
+ },
1126
+ ],
1127
+ };
1128
+ }
1129
+ case 'create_method': {
1130
+ const result = await stellify.createMethod(args);
1131
+ const methodData = result.data || result;
1132
+ return {
1133
+ content: [
1134
+ {
1135
+ type: 'text',
1136
+ text: JSON.stringify({
1137
+ success: true,
1138
+ message: `Created method "${args.name}" (UUID: ${methodData.uuid})`,
1139
+ method: methodData,
1140
+ }, null, 2),
1141
+ },
1142
+ ],
1143
+ };
1144
+ }
1145
+ case 'save_method': {
1146
+ const { uuid, ...data } = args;
1147
+ const result = await stellify.saveMethod(uuid, { uuid, ...data });
1148
+ return {
1149
+ content: [
1150
+ {
1151
+ type: 'text',
1152
+ text: JSON.stringify({
1153
+ success: true,
1154
+ message: `Updated method "${uuid}"`,
1155
+ method: result,
1156
+ }, null, 2),
1157
+ },
1158
+ ],
1159
+ };
1160
+ }
1161
+ case 'add_method_body': {
1162
+ const result = await stellify.addMethodBody(args);
1163
+ return {
1164
+ content: [
1165
+ {
1166
+ type: 'text',
1167
+ text: JSON.stringify({
1168
+ success: true,
1169
+ message: 'Method body parsed and saved successfully',
1170
+ data: result,
1171
+ }, null, 2),
1172
+ },
1173
+ ],
1174
+ };
1175
+ }
1176
+ case 'search_methods': {
1177
+ const result = await stellify.searchMethods(args);
1178
+ return {
1179
+ content: [
1180
+ {
1181
+ type: 'text',
1182
+ text: JSON.stringify({
1183
+ success: true,
1184
+ results: result,
1185
+ }, null, 2),
1186
+ },
1187
+ ],
1188
+ };
1189
+ }
1190
+ case 'search_files': {
1191
+ const result = await stellify.searchFiles(args);
1192
+ return {
1193
+ content: [
1194
+ {
1195
+ type: 'text',
1196
+ text: JSON.stringify({
1197
+ success: true,
1198
+ results: result,
1199
+ }, null, 2),
1200
+ },
1201
+ ],
1202
+ };
1203
+ }
1204
+ case 'create_route': {
1205
+ const result = await stellify.createRoute(args);
1206
+ const routeData = result.data || result;
1207
+ return {
1208
+ content: [
1209
+ {
1210
+ type: 'text',
1211
+ text: JSON.stringify({
1212
+ success: true,
1213
+ message: `Created route "${args.name}" at ${args.path} (UUID: ${routeData.uuid}). Use this UUID for html_to_elements page parameter.`,
1214
+ route: routeData,
1215
+ }, null, 2),
1216
+ },
1217
+ ],
1218
+ };
1219
+ }
1220
+ case 'get_route': {
1221
+ const result = await stellify.getRoute(args.uuid);
1222
+ const routeData = result.data || result;
1223
+ return {
1224
+ content: [
1225
+ {
1226
+ type: 'text',
1227
+ text: JSON.stringify({
1228
+ success: true,
1229
+ message: `Route: "${routeData.name}" at ${routeData.path}`,
1230
+ route: routeData,
1231
+ }, null, 2),
1232
+ },
1233
+ ],
1234
+ };
1235
+ }
1236
+ case 'search_routes': {
1237
+ const result = await stellify.searchRoutes(args);
1238
+ const routes = result.data || result;
1239
+ // Handle paginated response - data.data contains the actual routes array
1240
+ const routeData = routes.data || routes;
1241
+ const routeCount = Array.isArray(routeData) ? routeData.length : routes.total || 0;
1242
+ return {
1243
+ content: [
1244
+ {
1245
+ type: 'text',
1246
+ text: JSON.stringify({
1247
+ success: true,
1248
+ message: `Found ${routeCount} routes`,
1249
+ routes: routes,
1250
+ }, null, 2),
1251
+ },
1252
+ ],
1253
+ };
1254
+ }
1255
+ case 'create_element': {
1256
+ const result = await stellify.createElement(args);
1257
+ return {
1258
+ content: [
1259
+ {
1260
+ type: 'text',
1261
+ text: JSON.stringify({
1262
+ success: true,
1263
+ message: `Created element of type "${args.type}"`,
1264
+ element: result,
1265
+ }, null, 2),
1266
+ },
1267
+ ],
1268
+ };
1269
+ }
1270
+ case 'update_element': {
1271
+ const { uuid, data } = args;
1272
+ const result = await stellify.updateElement(uuid, data);
1273
+ return {
1274
+ content: [
1275
+ {
1276
+ type: 'text',
1277
+ text: JSON.stringify({
1278
+ success: true,
1279
+ message: `Updated element ${uuid}`,
1280
+ element: result,
1281
+ }, null, 2),
1282
+ },
1283
+ ],
1284
+ };
1285
+ }
1286
+ case 'get_element': {
1287
+ const { uuid } = args;
1288
+ const result = await stellify.getElement(uuid);
1289
+ return {
1290
+ content: [
1291
+ {
1292
+ type: 'text',
1293
+ text: JSON.stringify({
1294
+ success: true,
1295
+ element: result,
1296
+ }, null, 2),
1297
+ },
1298
+ ],
1299
+ };
1300
+ }
1301
+ case 'get_element_tree': {
1302
+ const { uuid } = args;
1303
+ const result = await stellify.getElementTree(uuid);
1304
+ return {
1305
+ content: [
1306
+ {
1307
+ type: 'text',
1308
+ text: JSON.stringify({
1309
+ success: true,
1310
+ message: `Retrieved element tree for ${uuid}`,
1311
+ tree: result,
1312
+ }, null, 2),
1313
+ },
1314
+ ],
1315
+ };
1316
+ }
1317
+ case 'delete_element': {
1318
+ const { uuid } = args;
1319
+ const result = await stellify.deleteElement(uuid);
1320
+ return {
1321
+ content: [
1322
+ {
1323
+ type: 'text',
1324
+ text: JSON.stringify({
1325
+ success: true,
1326
+ message: `Deleted element ${uuid} and ${result.deleted_count} total elements`,
1327
+ deleted_count: result.deleted_count,
1328
+ }, null, 2),
1329
+ },
1330
+ ],
1331
+ };
1332
+ }
1333
+ case 'search_elements': {
1334
+ const result = await stellify.searchElements(args);
1335
+ return {
1336
+ content: [
1337
+ {
1338
+ type: 'text',
1339
+ text: JSON.stringify({
1340
+ success: true,
1341
+ message: `Found ${result.data.length} elements`,
1342
+ elements: result.data,
1343
+ pagination: result.pagination,
1344
+ }, null, 2),
1345
+ },
1346
+ ],
1347
+ };
1348
+ }
1349
+ case 'html_to_elements': {
1350
+ const result = await stellify.htmlToElements(args);
1351
+ const elementCount = Object.keys(result.data || {}).length;
1352
+ const testMode = args.test ? ' (TEST MODE - not created)' : '';
1353
+ return {
1354
+ content: [
1355
+ {
1356
+ type: 'text',
1357
+ text: JSON.stringify({
1358
+ success: true,
1359
+ message: `Converted HTML to ${elementCount} elements${testMode}`,
1360
+ elements: result.data,
1361
+ }, null, 2),
1362
+ },
1363
+ ],
1364
+ };
1365
+ }
1366
+ case 'list_globals': {
1367
+ const result = await stellify.listGlobals();
1368
+ return {
1369
+ content: [
1370
+ {
1371
+ type: 'text',
1372
+ text: JSON.stringify({
1373
+ success: true,
1374
+ message: `Found ${result.data?.length || 0} globals`,
1375
+ globals: result.data,
1376
+ }, null, 2),
1377
+ },
1378
+ ],
1379
+ };
1380
+ }
1381
+ case 'get_global': {
1382
+ const { uuid } = args;
1383
+ const result = await stellify.getGlobal(uuid);
1384
+ return {
1385
+ content: [
1386
+ {
1387
+ type: 'text',
1388
+ text: JSON.stringify({
1389
+ success: true,
1390
+ global: result,
1391
+ }, null, 2),
1392
+ },
1393
+ ],
1394
+ };
1395
+ }
1396
+ case 'install_global': {
1397
+ const result = await stellify.installGlobal(args);
1398
+ return {
1399
+ content: [
1400
+ {
1401
+ type: 'text',
1402
+ text: JSON.stringify({
1403
+ success: true,
1404
+ message: `Installed global "${result.data?.file_name}" (${result.data?.methods_copied} methods, ${result.data?.statements_copied} statements)`,
1405
+ data: result.data,
1406
+ }, null, 2),
1407
+ },
1408
+ ],
1409
+ };
1410
+ }
1411
+ case 'search_global_methods': {
1412
+ const result = await stellify.searchGlobalMethods(args);
1413
+ return {
1414
+ content: [
1415
+ {
1416
+ type: 'text',
1417
+ text: JSON.stringify({
1418
+ success: true,
1419
+ message: `Found ${result.data?.length || 0} global methods`,
1420
+ methods: result.data,
1421
+ }, null, 2),
1422
+ },
1423
+ ],
1424
+ };
1425
+ }
1426
+ // Module handlers
1427
+ case 'list_modules': {
1428
+ const result = await stellify.listModules();
1429
+ return {
1430
+ content: [
1431
+ {
1432
+ type: 'text',
1433
+ text: JSON.stringify({
1434
+ success: true,
1435
+ message: `Found ${result.data?.length || 0} modules`,
1436
+ modules: result.data,
1437
+ }, null, 2),
1438
+ },
1439
+ ],
1440
+ };
1441
+ }
1442
+ case 'get_module': {
1443
+ const { uuid } = args;
1444
+ const result = await stellify.getModule(uuid);
1445
+ return {
1446
+ content: [
1447
+ {
1448
+ type: 'text',
1449
+ text: JSON.stringify({
1450
+ success: true,
1451
+ module: result.module,
1452
+ files: result.files,
1453
+ }, null, 2),
1454
+ },
1455
+ ],
1456
+ };
1457
+ }
1458
+ case 'create_module': {
1459
+ const result = await stellify.createModule(args);
1460
+ return {
1461
+ content: [
1462
+ {
1463
+ type: 'text',
1464
+ text: JSON.stringify({
1465
+ success: true,
1466
+ message: `Created module "${result.data?.name}"`,
1467
+ data: result.data,
1468
+ }, null, 2),
1469
+ },
1470
+ ],
1471
+ };
1472
+ }
1473
+ case 'add_file_to_module': {
1474
+ const result = await stellify.addFileToModule(args);
1475
+ return {
1476
+ content: [
1477
+ {
1478
+ type: 'text',
1479
+ text: JSON.stringify({
1480
+ success: true,
1481
+ message: `Added "${result.data?.file_name}" to module (order: ${result.data?.order})`,
1482
+ data: result.data,
1483
+ }, null, 2),
1484
+ },
1485
+ ],
1486
+ };
1487
+ }
1488
+ case 'install_module': {
1489
+ const result = await stellify.installModule(args);
1490
+ return {
1491
+ content: [
1492
+ {
1493
+ type: 'text',
1494
+ text: JSON.stringify({
1495
+ success: true,
1496
+ message: `Installed module "${result.data?.module_name}" (${result.data?.files_installed} files, ${result.data?.methods_copied} methods, ${result.data?.statements_copied} statements)`,
1497
+ data: result.data,
1498
+ }, null, 2),
1499
+ },
1500
+ ],
1501
+ };
1502
+ }
1503
+ // Statement & File Management handlers
1504
+ case 'get_statement': {
1505
+ const result = await stellify.getStatement(args.uuid);
1506
+ return {
1507
+ content: [
1508
+ {
1509
+ type: 'text',
1510
+ text: JSON.stringify({
1511
+ success: true,
1512
+ message: `Statement retrieved`,
1513
+ statement: result.statement || result,
1514
+ clauses: result.clauses || null,
1515
+ }, null, 2),
1516
+ },
1517
+ ],
1518
+ };
1519
+ }
1520
+ case 'create_statement': {
1521
+ const result = await stellify.createStatement(args);
1522
+ return {
1523
+ content: [
1524
+ {
1525
+ type: 'text',
1526
+ text: JSON.stringify({
1527
+ success: true,
1528
+ message: `Created statement (${result.data?.uuid || result.uuid})`,
1529
+ statement: result.data || result,
1530
+ }, null, 2),
1531
+ },
1532
+ ],
1533
+ };
1534
+ }
1535
+ case 'add_statement_code': {
1536
+ const result = await stellify.addStatementCode(args);
1537
+ return {
1538
+ content: [
1539
+ {
1540
+ type: 'text',
1541
+ text: JSON.stringify({
1542
+ success: true,
1543
+ message: 'Statement code added successfully',
1544
+ data: result,
1545
+ }, null, 2),
1546
+ },
1547
+ ],
1548
+ };
1549
+ }
1550
+ case 'save_file': {
1551
+ const { uuid, ...data } = args;
1552
+ const result = await stellify.saveFile(uuid, { uuid, ...data });
1553
+ return {
1554
+ content: [
1555
+ {
1556
+ type: 'text',
1557
+ text: JSON.stringify({
1558
+ success: true,
1559
+ message: `Saved file "${data.name || uuid}"`,
1560
+ file: result,
1561
+ }, null, 2),
1562
+ },
1563
+ ],
1564
+ };
1565
+ }
1566
+ case 'get_file': {
1567
+ const { uuid } = args;
1568
+ const result = await stellify.getFile(uuid);
1569
+ return {
1570
+ content: [
1571
+ {
1572
+ type: 'text',
1573
+ text: JSON.stringify({
1574
+ success: true,
1575
+ file: result,
1576
+ }, null, 2),
1577
+ },
1578
+ ],
1579
+ };
1580
+ }
1581
+ case 'get_directory': {
1582
+ const result = await stellify.getDirectory(args.uuid);
1583
+ const dirData = result.data || result;
1584
+ return {
1585
+ content: [
1586
+ {
1587
+ type: 'text',
1588
+ text: JSON.stringify({
1589
+ success: true,
1590
+ message: `Directory: "${dirData.name}" (${dirData.uuid})`,
1591
+ directory: dirData,
1592
+ }, null, 2),
1593
+ },
1594
+ ],
1595
+ };
1596
+ }
1597
+ case 'create_directory': {
1598
+ const result = await stellify.createDirectory(args);
1599
+ return {
1600
+ content: [
1601
+ {
1602
+ type: 'text',
1603
+ text: JSON.stringify({
1604
+ success: true,
1605
+ message: result.existing
1606
+ ? `Using existing directory "${args.name}" (${result.data?.uuid || result.uuid})`
1607
+ : `Created directory "${args.name}" (${result.data?.uuid || result.uuid})`,
1608
+ directory: result.data || result,
1609
+ existing: result.existing || false,
1610
+ }, null, 2),
1611
+ },
1612
+ ],
1613
+ };
1614
+ }
1615
+ case 'broadcast_element_command': {
1616
+ const result = await stellify.broadcastElementCommand(args);
1617
+ return {
1618
+ content: [
1619
+ {
1620
+ type: 'text',
1621
+ text: JSON.stringify({
1622
+ success: true,
1623
+ message: `Broadcast ${args.action} command${args.element ? ` for element ${args.element}` : ''}`,
1624
+ data: result,
246
1625
  }, null, 2),
247
1626
  },
248
1627
  ],