@stellisoft/stellify-mcp 0.1.21 → 0.1.23
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 +121 -432
- package/package.json +1 -1
- package/server.json +2 -2
package/dist/index.js
CHANGED
|
@@ -17,223 +17,6 @@ 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
|
-
// VUE COMPONENT + ROUTE PATTERN (for visual editing)
|
|
95
|
-
// -----------------------------------------------------------------------------
|
|
96
|
-
// When building Vue components, use TWO routes to enable visual editing:
|
|
97
|
-
//
|
|
98
|
-
// 1. TEMPLATE ROUTE - Holds the component's UI elements for editing
|
|
99
|
-
// - create_route: name='NotesTemplate', path='/notes-template', type='web'
|
|
100
|
-
// - html_to_elements: page=templateRouteUuid, elements='<div>...</div>'
|
|
101
|
-
// - Users can visually edit these elements in the route editor
|
|
102
|
-
//
|
|
103
|
-
// 2. DISPLAY ROUTE - The actual page that renders the component
|
|
104
|
-
// - create_route: name='Notes', path='/notes', type='web'
|
|
105
|
-
// - html_to_elements: page=displayRouteUuid, elements='<NotesApp />'
|
|
106
|
-
// - This embeds the Vue component on the page
|
|
107
|
-
//
|
|
108
|
-
// 3. VUE COMPONENT FILE - Links to template route elements
|
|
109
|
-
// - create_file: type='js', extension='vue', name='NotesApp'
|
|
110
|
-
// - save_file: template=[elementUuidsFromTemplateRoute]
|
|
111
|
-
//
|
|
112
|
-
// WHY THIS PATTERN?
|
|
113
|
-
// - Template elements need a route to be viewable/editable in the UI
|
|
114
|
-
// - The display route keeps the clean component embedding pattern
|
|
115
|
-
// - Component logic (methods, state) stays in the .vue file
|
|
116
|
-
//
|
|
117
|
-
// EXAMPLE WORKFLOW:
|
|
118
|
-
// 1. Create template route: '/notes-template' (for editing)
|
|
119
|
-
// 2. Create display route: '/notes' (for viewing)
|
|
120
|
-
// 3. html_to_elements on template route (creates editable elements)
|
|
121
|
-
// 4. html_to_elements on display route with '<NotesApp />'
|
|
122
|
-
// 5. create_file for NotesApp.vue
|
|
123
|
-
// 6. Add methods, statements, wire events
|
|
124
|
-
// 7. save_file with template pointing to template route's root element
|
|
125
|
-
//
|
|
126
|
-
// -----------------------------------------------------------------------------
|
|
127
|
-
// ELEMENT EVENT HANDLERS (for frontend files)
|
|
128
|
-
// -----------------------------------------------------------------------------
|
|
129
|
-
// Elements can have these event properties (value is method UUID):
|
|
130
|
-
// - click: Fires on click (@click)
|
|
131
|
-
// - submit: Fires on form submit (@submit)
|
|
132
|
-
// - change: Fires on input change (@change)
|
|
133
|
-
// - input: Fires on input in real-time (@input)
|
|
134
|
-
// - focus: Fires when element receives focus (@focus)
|
|
135
|
-
// - blur: Fires when element loses focus (@blur)
|
|
136
|
-
// - keydown: Fires on key press (@keydown)
|
|
137
|
-
// - keyup: Fires on key release (@keyup)
|
|
138
|
-
// - mouseenter: Fires on mouse enter (@mouseenter)
|
|
139
|
-
// - mouseleave: Fires on mouse leave (@mouseleave)
|
|
140
|
-
//
|
|
141
|
-
// -----------------------------------------------------------------------------
|
|
142
|
-
// STELLIFY FRAMEWORK (frontend library for Vue/JS files)
|
|
143
|
-
// -----------------------------------------------------------------------------
|
|
144
|
-
// Stellify Framework is an AI-friendly frontend library with constrained APIs.
|
|
145
|
-
// Use these modules in Vue components for common frontend tasks.
|
|
146
|
-
//
|
|
147
|
-
// IMPORT PATTERN:
|
|
148
|
-
// import { Form, Http, Table } from 'stellify-framework'
|
|
149
|
-
//
|
|
150
|
-
// DATA & FORMS:
|
|
151
|
-
// Form.create({name:'',email:''}).validate({...}).store('/api/users')
|
|
152
|
-
// Table.create(data).addColumn('name').sort('name').paginate(10)
|
|
153
|
-
// List.create(items).add(item).remove(id).filter(fn).map(fn)
|
|
154
|
-
// Tree.create().setRoot(data).addChild(parentId,child).traverse(fn)
|
|
155
|
-
//
|
|
156
|
-
// NETWORK:
|
|
157
|
-
// Http.create('/api').withToken(t).get('/users').post('/users',data)
|
|
158
|
-
// Socket.create('wss://...').on('message',fn).connect().send(data)
|
|
159
|
-
// Auth.create('/api').login(creds).logout().getUser().isAuthenticated()
|
|
160
|
-
// Stream.create('/api/chat').onChunk(fn).onComplete(fn).post(data)
|
|
161
|
-
//
|
|
162
|
-
// GRAPHICS:
|
|
163
|
-
// Svg.create(800,600).rect(0,0,100,50).circle(50,50,20).text('Hi',10,10)
|
|
164
|
-
// Canvas.create(800,600).rect(0,0,100,50).circle(50,50,20).toDataURL()
|
|
165
|
-
// Graph.create().addNode('a').addNode('b').addEdge('a','b').layout('force')
|
|
166
|
-
// Scale.linear().domain([0,100]).range([0,500]).value(50) // returns 250
|
|
167
|
-
// Motion.tween(0,100,{duration:500}).onUpdate(fn).start()
|
|
168
|
-
//
|
|
169
|
-
// PLATFORM:
|
|
170
|
-
// Router.create().register('/users',component).navigate('/users')
|
|
171
|
-
// Storage.local().set('key',val).get('key').remove('key')
|
|
172
|
-
// Events.create().on('event',fn).emit('event',data)
|
|
173
|
-
// Clipboard.copy('text').paste()
|
|
174
|
-
// Notify.request().send('Title',{body:'Message'})
|
|
175
|
-
// Geo.getPosition().then(pos=>...).watchPosition(fn)
|
|
176
|
-
// Media.selectFile({accept:'image/*'}).resize(800,600).toBase64()
|
|
177
|
-
// DB.create('mydb').store({name:'items'}).open().put('items',obj)
|
|
178
|
-
// Worker.fromFunction(fn).run(data).terminate()
|
|
179
|
-
//
|
|
180
|
-
// AI & LANGUAGE:
|
|
181
|
-
// Speech.create().onResult(fn).listen({continuous:true})
|
|
182
|
-
// Speech.create().speak('Hello',{voice:'...'})
|
|
183
|
-
// Chat.create().addUser('Hi').addAssistant('Hello').getMessages()
|
|
184
|
-
// Embed.create().store('id',vector,meta).nearest(queryVec,5)
|
|
185
|
-
// Diff.lines(old,new) // [{type:'equal'|'insert'|'delete',value:'...'}]
|
|
186
|
-
//
|
|
187
|
-
// UTILITIES:
|
|
188
|
-
// Time.now().format('YYYY-MM-DD').add(7,'days').relative()
|
|
189
|
-
//
|
|
190
|
-
// KEY METHODS PER MODULE (max 7 each - AI-friendly constraint):
|
|
191
|
-
// Form: create,set,get,validate,store,update,delete
|
|
192
|
-
// Table: create,setData,addColumn,sort,filter,paginate
|
|
193
|
-
// Http: create,get,post,put,delete,withToken
|
|
194
|
-
// Stream: create,post,onChunk,onComplete,abort,getBuffer
|
|
195
|
-
// Speech: create,listen,speak,stopListening,getVoices,onResult
|
|
196
|
-
// Chat: create,addMessage,getHistory,clear,fork,truncate
|
|
197
|
-
// Embed: create,store,compare,nearest,search,toJSON
|
|
198
|
-
// Diff: chars,words,lines,apply,createPatch,similarity
|
|
199
|
-
//
|
|
200
|
-
// -----------------------------------------------------------------------------
|
|
201
|
-
// COMMON PITFALLS - AVOID THESE MISTAKES
|
|
202
|
-
// -----------------------------------------------------------------------------
|
|
203
|
-
// 1. v-model requires ref(), NOT Form class
|
|
204
|
-
// WRONG: const form = Form.create({title: ''}) with v-model="form.title"
|
|
205
|
-
// RIGHT: const formData = ref({title: ''}) with v-model="formData.title"
|
|
206
|
-
//
|
|
207
|
-
// 2. List.from() returns List instance, not array - use .toArray() for v-for
|
|
208
|
-
// WRONG: notes.value = List.from(response.data)
|
|
209
|
-
// RIGHT: notes.value = List.from(response.data).toArray()
|
|
210
|
-
//
|
|
211
|
-
// 3. add_method_body APPENDS, doesn't replace - create new method to replace
|
|
212
|
-
//
|
|
213
|
-
// 4. Use 'inputType' not 'type' for HTML type attribute on elements
|
|
214
|
-
//
|
|
215
|
-
// 5. Statements go in 'statements' array, methods go in 'data' array in save_file
|
|
216
|
-
//
|
|
217
|
-
// 6. Always wire click handlers to METHOD UUIDs, not file UUIDs
|
|
218
|
-
//
|
|
219
|
-
// 7. For buttons in forms, set inputType: "button" to prevent auto-submit
|
|
220
|
-
//
|
|
221
|
-
// -----------------------------------------------------------------------------
|
|
222
|
-
// ERROR HANDLING
|
|
223
|
-
// -----------------------------------------------------------------------------
|
|
224
|
-
// If a tool call fails, check:
|
|
225
|
-
// - UUID validity: Is the file/method/element UUID correct and exists?
|
|
226
|
-
// - Required fields: Did you provide all required parameters?
|
|
227
|
-
// - Order of operations: Did you create the parent before the child?
|
|
228
|
-
// - Array contents: Are you passing statement UUIDs to 'statements' (not 'data')?
|
|
229
|
-
//
|
|
230
|
-
// Common error scenarios:
|
|
231
|
-
// - "File not found" → The file UUID is invalid or was deleted
|
|
232
|
-
// - "Method not found" → The method UUID doesn't exist in that file
|
|
233
|
-
// - "Invalid element type" → Use valid types like s-wrapper, s-input, s-form
|
|
234
|
-
// - Empty response → Operation succeeded but returned no data (normal for deletes)
|
|
235
|
-
//
|
|
236
|
-
// =============================================================================
|
|
237
20
|
// Define MCP tools
|
|
238
21
|
// Stellify Framework API - full method reference for AI code generation
|
|
239
22
|
const STELLIFY_FRAMEWORK_API = {
|
|
@@ -289,6 +72,10 @@ Use this tool when you need to:
|
|
|
289
72
|
- Verify method names before generating code
|
|
290
73
|
- Understand the full API surface
|
|
291
74
|
|
|
75
|
+
IMPORTANT - Stellify Framework Import:
|
|
76
|
+
The npm package is "stellify-framework" (NOT @stellify/core).
|
|
77
|
+
Import like: import { Http, List, Form } from 'stellify-framework';
|
|
78
|
+
|
|
292
79
|
IMPORTANT - List class and Vue reactivity:
|
|
293
80
|
The List class methods return List instances, NOT plain arrays.
|
|
294
81
|
Vue's v-for directive cannot iterate over List instances directly.
|
|
@@ -632,39 +419,9 @@ Example - Remove duplicate/unwanted statements:
|
|
|
632
419
|
},
|
|
633
420
|
{
|
|
634
421
|
name: 'create_route',
|
|
635
|
-
description: `Create a
|
|
636
|
-
|
|
637
|
-
IMPORTANT - WIRING ROUTES TO CONTROLLERS:
|
|
638
|
-
For API routes to execute code, you MUST connect them to a controller and method:
|
|
639
|
-
- controller: UUID of the controller file (e.g., NoteController)
|
|
640
|
-
- controller_method: UUID of the method to execute (e.g., index, store, update, destroy)
|
|
641
|
-
|
|
642
|
-
Without these fields, the route exists but won't execute any code!
|
|
643
|
-
|
|
644
|
-
EXAMPLE - Create an API route wired to a controller:
|
|
645
|
-
{
|
|
646
|
-
"project_id": "project-uuid",
|
|
647
|
-
"name": "notes.index",
|
|
648
|
-
"path": "/api/notes",
|
|
649
|
-
"method": "GET",
|
|
650
|
-
"type": "api",
|
|
651
|
-
"controller": "controller-file-uuid",
|
|
652
|
-
"controller_method": "index-method-uuid"
|
|
653
|
-
}
|
|
654
|
-
|
|
655
|
-
WORKFLOW for API endpoints:
|
|
656
|
-
1. Create controller with create_file (type: "controller") or create_resources
|
|
657
|
-
2. Create methods with create_method + add_method_body
|
|
658
|
-
3. Create route with create_route, passing controller and controller_method UUIDs
|
|
422
|
+
description: `Create a route/page. For API routes, pass controller and controller_method UUIDs to wire execution.
|
|
659
423
|
|
|
660
|
-
|
|
661
|
-
Route parameters like {id} in "/api/notes/{id}" are automatically injected into controller method parameters when the parameter name matches.
|
|
662
|
-
|
|
663
|
-
Example: Route "/api/notes/{id}" (DELETE) with controller method destroy($id)
|
|
664
|
-
The $id parameter receives the value from the URL automatically.
|
|
665
|
-
|
|
666
|
-
When creating methods with create_method, include the parameter:
|
|
667
|
-
{ "name": "destroy", "parameters": [{ "name": "id", "datatype": "int" }] }`,
|
|
424
|
+
Route params like {id} auto-inject into controller method parameters when names match.`,
|
|
668
425
|
inputSchema: {
|
|
669
426
|
type: 'object',
|
|
670
427
|
properties: {
|
|
@@ -883,55 +640,13 @@ Generates: <div class="card p-4" v-for="note in notes" :key="note.id">`,
|
|
|
883
640
|
},
|
|
884
641
|
{
|
|
885
642
|
name: 'update_element',
|
|
886
|
-
description: `Update
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
- locked: Prevent editing (boolean)
|
|
894
|
-
- tag: HTML tag (div, input, button, etc.)
|
|
895
|
-
- classes: CSS classes array ["class1", "class2"]
|
|
896
|
-
- text: Element text content
|
|
897
|
-
|
|
898
|
-
V-MODEL BINDING (for s-input elements):
|
|
899
|
-
- variable: Set this to bind v-model to a reactive variable
|
|
900
|
-
- Example: { "variable": "formData.title" } renders as <input v-model="formData.title" />
|
|
901
|
-
- IMPORTANT: The variable must reference a Vue ref() object, NOT a Form class instance
|
|
902
|
-
- CORRECT: const formData = ref({ title: '', content: '' }) → v-model="formData.title"
|
|
903
|
-
- WRONG: const form = Form.create({ title: '' }) → Form class is not reactive for v-model
|
|
904
|
-
|
|
905
|
-
INPUT TYPE ATTRIBUTE:
|
|
906
|
-
- Use 'inputType' (not 'type') to set the HTML type attribute on buttons/inputs
|
|
907
|
-
- Example: { "inputType": "button" } renders as type="button"
|
|
908
|
-
- Example: { "inputType": "textarea" } renders as <textarea> instead of <input>
|
|
909
|
-
- For buttons inside <form> elements, always set inputType: "button" to prevent form submission on click
|
|
910
|
-
|
|
911
|
-
EVENT HANDLERS (set value to method UUID):
|
|
912
|
-
- click: @click - buttons, links, any clickable element
|
|
913
|
-
- submit: @submit - form submission
|
|
914
|
-
- change: @change - input/select value changed (on blur)
|
|
915
|
-
- input: @input - input value changing (real-time, as user types)
|
|
916
|
-
- focus: @focus - element receives focus
|
|
917
|
-
- blur: @blur - element loses focus
|
|
918
|
-
- keydown: @keydown - key pressed down
|
|
919
|
-
- keyup: @keyup - key released
|
|
920
|
-
- mouseenter: @mouseenter - mouse enters element
|
|
921
|
-
- mouseleave: @mouseleave - mouse leaves element
|
|
922
|
-
|
|
923
|
-
EVENT HANDLER ARGUMENTS:
|
|
924
|
-
When wiring click handlers that need arguments (e.g., from v-for loops), use clickArgs:
|
|
925
|
-
- { "click": "delete-method-uuid", "clickArgs": "item.id" } → @click="deleteItem(item.id)"
|
|
926
|
-
- { "click": "edit-method-uuid", "clickArgs": "item" } → @click="editItem(item)"
|
|
927
|
-
|
|
928
|
-
Example wiring a button click to a method:
|
|
929
|
-
{
|
|
930
|
-
"uuid": "button-element-uuid",
|
|
931
|
-
"data": {
|
|
932
|
-
"click": "increment-method-uuid"
|
|
933
|
-
}
|
|
934
|
-
}`,
|
|
643
|
+
description: `Update a UI element's attributes.
|
|
644
|
+
|
|
645
|
+
Pass data object with: tag, classes (array), text, variable (for v-model), and event handlers (click, submit, etc. = method UUID).
|
|
646
|
+
|
|
647
|
+
Key fields: inputType (not 'type') for button/input HTML type. clickArgs for handler arguments in v-for loops.
|
|
648
|
+
|
|
649
|
+
Event handlers: click, submit, change, input, focus, blur, keydown, keyup, mouseenter, mouseleave.`,
|
|
935
650
|
inputSchema: {
|
|
936
651
|
type: 'object',
|
|
937
652
|
properties: {
|
|
@@ -1020,37 +735,11 @@ Note: To reorder elements, use update_element to modify the parent element's 'da
|
|
|
1020
735
|
},
|
|
1021
736
|
{
|
|
1022
737
|
name: 'html_to_elements',
|
|
1023
|
-
description: `Convert HTML to Stellify elements
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
3. Preserve all attributes, classes, text content
|
|
1029
|
-
4. Auto-detect Vue bindings ({{ variable }}) and create linked statements
|
|
1030
|
-
5. Return element UUIDs to use in save_file template array
|
|
1031
|
-
|
|
1032
|
-
Element type mapping:
|
|
1033
|
-
- button, input, textarea, select → s-input
|
|
1034
|
-
- div, span, p, section, etc. → s-wrapper
|
|
1035
|
-
- form → s-form
|
|
1036
|
-
- img, video, audio → s-media
|
|
1037
|
-
|
|
1038
|
-
VUE BINDING AUTO-DETECTION:
|
|
1039
|
-
Text like {{ count }} is automatically detected and:
|
|
1040
|
-
- A statement is created with the binding code
|
|
1041
|
-
- The statement UUID is added to the element's 'statements' array
|
|
1042
|
-
- You still need to create the reactive data source separately (const count = ref(0))
|
|
1043
|
-
|
|
1044
|
-
For Vue components: Omit 'page' - elements are created standalone for the component template.
|
|
1045
|
-
For page content: Provide 'page' (route UUID) to attach elements directly.
|
|
1046
|
-
|
|
1047
|
-
ICONS - Best practices:
|
|
1048
|
-
- Prefer SVG icons or icon fonts (Heroicons, Font Awesome) over emoji
|
|
1049
|
-
- Use HTML entities where available (e.g., × for ×)
|
|
1050
|
-
- Avoid raw emoji characters as they may have encoding issues
|
|
1051
|
-
- Example: <button><svg>...</svg></button> instead of <button>🗑️</button>
|
|
1052
|
-
|
|
1053
|
-
IMPORTANT: Use the returned root element UUID in save_file's template array.`,
|
|
738
|
+
description: `Convert HTML to Stellify elements. Returns element UUIDs to use in save_file template array.
|
|
739
|
+
|
|
740
|
+
Auto-detects Vue bindings ({{ var }}). For Vue components, omit 'page'. For pages, provide route UUID.
|
|
741
|
+
|
|
742
|
+
Prefer SVG icons over emoji (encoding issues).`,
|
|
1054
743
|
inputSchema: {
|
|
1055
744
|
type: 'object',
|
|
1056
745
|
properties: {
|
|
@@ -1344,35 +1033,11 @@ IMPORTANT: Check existing directories first using get_project and get_directory
|
|
|
1344
1033
|
},
|
|
1345
1034
|
{
|
|
1346
1035
|
name: 'broadcast_element_command',
|
|
1347
|
-
description: `
|
|
1348
|
-
|
|
1349
|
-
IMPORTANT: USE THIS TOOL FIRST when the user asks you to:
|
|
1350
|
-
- Show, display, or demonstrate something visually
|
|
1351
|
-
- Update, change, or modify what's on screen
|
|
1352
|
-
- Build or create UI elements for demonstration
|
|
1353
|
-
- Send messages or content to the browser
|
|
1354
|
-
- Do anything "live" or "in real-time"
|
|
1355
|
-
|
|
1356
|
-
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.
|
|
1357
|
-
|
|
1358
|
-
ACTIONS:
|
|
1359
|
-
- update: Modify an existing element's attributes (text, classes, styles, etc.)
|
|
1360
|
-
- create: Create a new ephemeral element (provide any UUID string you want)
|
|
1361
|
-
- batch: Modify multiple elements at once
|
|
1362
|
-
- delete: Remove an element from the UI state
|
|
1036
|
+
description: `Push real-time UI updates via WebSocket. Use for SHOW/DISPLAY/DEMONSTRATE requests.
|
|
1363
1037
|
|
|
1364
|
-
|
|
1365
|
-
1. First, use action="create" with any UUID (e.g., "msg-001") and full element structure in changes
|
|
1366
|
-
2. Then, use action="update" on the PARENT element to add your new UUID to its "data" array
|
|
1038
|
+
Actions: update (modify element), create (ephemeral element), batch (multiple updates), delete.
|
|
1367
1039
|
|
|
1368
|
-
|
|
1369
|
-
{ action: "update", element: "existing-uuid", changes: { text: "Hello world!", classes: ["p-4", "bg-blue-500"] } }
|
|
1370
|
-
|
|
1371
|
-
Example - Create ephemeral child element:
|
|
1372
|
-
Step 1: { action: "create", element: "my-new-element", changes: { type: "s-wrapper", tag: "div", text: "I exist!", classes: ["p-2", "bg-green-500"] } }
|
|
1373
|
-
Step 2: { action: "update", element: "parent-uuid", changes: { data: ["my-new-element"] } }
|
|
1374
|
-
|
|
1375
|
-
For PERSISTENT changes (saved to database), use update_element or html_to_elements instead.`,
|
|
1040
|
+
Changes are EPHEMERAL (not saved). For persistent changes, use update_element or html_to_elements.`,
|
|
1376
1041
|
inputSchema: {
|
|
1377
1042
|
type: 'object',
|
|
1378
1043
|
properties: {
|
|
@@ -1407,80 +1072,13 @@ For PERSISTENT changes (saved to database), use update_element or html_to_elemen
|
|
|
1407
1072
|
},
|
|
1408
1073
|
{
|
|
1409
1074
|
name: 'create_resources',
|
|
1410
|
-
description: `Scaffold
|
|
1075
|
+
description: `Scaffold Model, Controller, Service, and Migration in ONE operation.
|
|
1411
1076
|
|
|
1412
|
-
|
|
1077
|
+
Creates: Model ($fillable, $casts, relationships), Controller (CRUD actions), Service (optional), Migration.
|
|
1413
1078
|
|
|
1414
|
-
|
|
1415
|
-
- Model: With $fillable, $casts, and relationship methods
|
|
1416
|
-
- Controller: With index, store, show, update, destroy actions
|
|
1417
|
-
- Service (optional): Business logic layer with list, find, create, update, delete methods
|
|
1418
|
-
- Migration: With proper column types based on field definitions
|
|
1079
|
+
IMPORTANT: Routes are NOT auto-wired. After creation, use create_route with the returned controller UUID and method UUIDs.
|
|
1419
1080
|
|
|
1420
|
-
|
|
1421
|
-
{
|
|
1422
|
-
"name": "User",
|
|
1423
|
-
"fields": [
|
|
1424
|
-
{ "name": "name", "type": "string" },
|
|
1425
|
-
{ "name": "email", "type": "string", "unique": true },
|
|
1426
|
-
{ "name": "password", "type": "string" },
|
|
1427
|
-
{ "name": "is_active", "type": "boolean", "default": true }
|
|
1428
|
-
],
|
|
1429
|
-
"relationships": [
|
|
1430
|
-
{ "type": "hasMany", "model": "Post" }
|
|
1431
|
-
],
|
|
1432
|
-
"controller": true,
|
|
1433
|
-
"service": true,
|
|
1434
|
-
"migration": true
|
|
1435
|
-
}
|
|
1436
|
-
|
|
1437
|
-
FIELD TYPES:
|
|
1438
|
-
- string, text, longtext (text fields)
|
|
1439
|
-
- integer, int, bigint (numbers)
|
|
1440
|
-
- boolean, bool (true/false)
|
|
1441
|
-
- float, double, decimal (decimals)
|
|
1442
|
-
- date, datetime, timestamp (dates)
|
|
1443
|
-
- json (JSON/array data)
|
|
1444
|
-
- email (string with email validation)
|
|
1445
|
-
|
|
1446
|
-
FIELD OPTIONS:
|
|
1447
|
-
- nullable: Allow NULL values
|
|
1448
|
-
- unique: Add unique constraint
|
|
1449
|
-
- required: Require in validation (default: true for store)
|
|
1450
|
-
- default: Default value
|
|
1451
|
-
- max: Maximum length/value
|
|
1452
|
-
|
|
1453
|
-
RELATIONSHIP TYPES:
|
|
1454
|
-
- hasOne: One-to-one (User hasOne Profile)
|
|
1455
|
-
- hasMany: One-to-many (User hasMany Posts)
|
|
1456
|
-
- belongsTo: Inverse of hasOne/hasMany (Post belongsTo User)
|
|
1457
|
-
- belongsToMany: Many-to-many (User belongsToMany Roles)
|
|
1458
|
-
|
|
1459
|
-
IMPORTANT - WIRING ROUTES TO CONTROLLERS:
|
|
1460
|
-
This tool creates controller methods but does NOT automatically wire routes to them.
|
|
1461
|
-
After calling create_resources, you must MANUALLY wire routes using create_route:
|
|
1462
|
-
|
|
1463
|
-
1. Note the returned controller UUID and method UUIDs from the response
|
|
1464
|
-
2. For each API route, call create_route with:
|
|
1465
|
-
- controller: the controller file UUID
|
|
1466
|
-
- controller_method: the specific method UUID (index, store, update, destroy)
|
|
1467
|
-
|
|
1468
|
-
Example response structure:
|
|
1469
|
-
{
|
|
1470
|
-
"controller": {
|
|
1471
|
-
"uuid": "controller-uuid",
|
|
1472
|
-
"methods": [
|
|
1473
|
-
{ "uuid": "index-method-uuid", "name": "index" },
|
|
1474
|
-
{ "uuid": "store-method-uuid", "name": "store" },
|
|
1475
|
-
...
|
|
1476
|
-
]
|
|
1477
|
-
}
|
|
1478
|
-
}
|
|
1479
|
-
|
|
1480
|
-
Then create routes:
|
|
1481
|
-
create_route({ path: "/api/notes", method: "GET", controller: "controller-uuid", controller_method: "index-method-uuid" })
|
|
1482
|
-
|
|
1483
|
-
Returns UUIDs for all created files so you can customize them further if needed.`,
|
|
1081
|
+
Response includes controller.methods array with {uuid, name} for each action (index, store, update, destroy).`,
|
|
1484
1082
|
inputSchema: {
|
|
1485
1083
|
type: 'object',
|
|
1486
1084
|
properties: {
|
|
@@ -1786,6 +1384,49 @@ Key concepts:
|
|
|
1786
1384
|
- Vue components link to UI elements via the 'template' field
|
|
1787
1385
|
- Event handlers (click, submit) wire UI elements to methods by UUID
|
|
1788
1386
|
|
|
1387
|
+
## General Workflow (all file types)
|
|
1388
|
+
|
|
1389
|
+
1. create_file → empty shell, returns file UUID
|
|
1390
|
+
2. create_method → signature only, returns method UUID
|
|
1391
|
+
3. add_method_body → implementation code
|
|
1392
|
+
4. create_statement + add_statement_code → for imports, variables, refs
|
|
1393
|
+
5. save_file → finalize with template/data/statements arrays
|
|
1394
|
+
|
|
1395
|
+
## Vue Component Workflow
|
|
1396
|
+
|
|
1397
|
+
1. get_project → find 'js' directory UUID (or create it)
|
|
1398
|
+
2. create_file → type='js', extension='vue' for the component
|
|
1399
|
+
3. Create statements for imports:
|
|
1400
|
+
- "import { ref } from 'vue';" (REQUIRED for ref())
|
|
1401
|
+
- "import { Http, List } from 'stellify-framework';" (for Stellify classes)
|
|
1402
|
+
NOTE: The npm package is "stellify-framework" (NOT @stellify/core)
|
|
1403
|
+
4. Create statements for data: "const count = ref(0);"
|
|
1404
|
+
5. create_method + add_method_body → functions
|
|
1405
|
+
6. html_to_elements → template (no 'page' param for components)
|
|
1406
|
+
7. update_element → wire click handlers to method UUIDs
|
|
1407
|
+
8. save_file with: extension='vue', template=[elementUuid], data=[methodUuids], statements=[importUuids, refUuids]
|
|
1408
|
+
9. **MANDATORY: Create app.js entry file** (see "CRITICAL: JavaScript Entry File" section below)
|
|
1409
|
+
10. Create web route for the page
|
|
1410
|
+
11. **MANDATORY: Add a div with id="app"** to the page using html_to_elements:
|
|
1411
|
+
- html_to_elements with page=routeUuid and elements='<div id="app"></div>'
|
|
1412
|
+
- This is where Vue mounts the component. Without it, nothing renders!
|
|
1413
|
+
|
|
1414
|
+
## Real-Time UI (broadcast_element_command)
|
|
1415
|
+
|
|
1416
|
+
Use for SHOW/DISPLAY/DEMONSTRATE requests - sends instant WebSocket updates to browser.
|
|
1417
|
+
Use html_to_elements/update_element for permanent/saved changes.
|
|
1418
|
+
|
|
1419
|
+
## Common Pitfalls
|
|
1420
|
+
|
|
1421
|
+
- **Stellify imports:** Use "stellify-framework" package (NOT @stellify/core)
|
|
1422
|
+
CORRECT: import { Http, List, Form } from 'stellify-framework';
|
|
1423
|
+
WRONG: import { Http } from '@stellify/core';
|
|
1424
|
+
- v-model requires ref(), NOT Form class: const formData = ref({title: ''})
|
|
1425
|
+
- List.from() returns List, not array - use .toArray() for v-for
|
|
1426
|
+
- add_method_body APPENDS, doesn't replace - create new method to replace
|
|
1427
|
+
- 'data' array = method UUIDs, 'statements' array = import/variable UUIDs
|
|
1428
|
+
- For buttons in forms, set inputType: "button" to prevent auto-submit
|
|
1429
|
+
|
|
1789
1430
|
## Framework Capabilities (Libraries/Packages)
|
|
1790
1431
|
|
|
1791
1432
|
**CRITICAL: You write BUSINESS LOGIC only. Capabilities are installed packages/libraries (Sanctum, Stripe, AWS SDK, etc.) that Stellify provides. You CANNOT create these by writing code.**
|
|
@@ -1817,18 +1458,66 @@ Examples of capabilities (packages you cannot write):
|
|
|
1817
1458
|
|
|
1818
1459
|
When building features, group related files by passing a "module" parameter.
|
|
1819
1460
|
|
|
1820
|
-
**WORKFLOW:** Simply include the 'module' parameter when creating files or routes:
|
|
1821
|
-
|
|
1822
1461
|
- create_file(..., module: "blog-posts") - auto-groups file
|
|
1823
1462
|
- create_route(..., module: "blog-posts") - auto-groups route
|
|
1824
1463
|
|
|
1825
1464
|
Modules are auto-created if they don't exist. This helps users see all code related to a feature grouped together.
|
|
1826
1465
|
|
|
1827
|
-
|
|
1466
|
+
## CRITICAL: JavaScript Entry File (app.js)
|
|
1467
|
+
|
|
1468
|
+
**You MUST have a JS entry file to register Vue components for use on pages.**
|
|
1469
|
+
|
|
1470
|
+
### First component in a project:
|
|
1471
|
+
1. Create app.js in the 'js' directory:
|
|
1472
|
+
- create_file with type='js', extension='js', name='app'
|
|
1473
|
+
2. Add statements:
|
|
1474
|
+
- "import { createApp } from 'vue';"
|
|
1475
|
+
- "import NotesApp from './NotesApp.vue';"
|
|
1476
|
+
- "createApp(NotesApp).mount('#app');"
|
|
1477
|
+
3. save_file with all statement UUIDs
|
|
1478
|
+
|
|
1479
|
+
### Adding more components (app.js already exists):
|
|
1480
|
+
1. **search_files** for "app" to find existing app.js
|
|
1481
|
+
2. **get_file** to retrieve current statements
|
|
1482
|
+
3. Add ONLY the new import statement:
|
|
1483
|
+
- "import Counter from './Counter.vue';"
|
|
1484
|
+
4. Update the mount code to register the new component:
|
|
1485
|
+
- Create new statement: "app.component('Counter', Counter);"
|
|
1486
|
+
- Or recreate the initialization to include all components
|
|
1487
|
+
5. save_file with updated statements array
|
|
1488
|
+
|
|
1489
|
+
**DO NOT create duplicate app.js files or duplicate createApp imports!**
|
|
1490
|
+
|
|
1491
|
+
### Page mount point (div#app):
|
|
1492
|
+
Each page that uses Vue components needs a \`<div id="app"></div>\`.
|
|
1493
|
+
|
|
1494
|
+
- **First time on a page:** html_to_elements(page=routeUuid, elements='<div id="app"></div>')
|
|
1495
|
+
- **Page already has it:** Do NOT add another one. Check with get_route first if unsure.
|
|
1496
|
+
|
|
1497
|
+
**Without app.js AND div#app, Vue components will NOT render!**
|
|
1498
|
+
|
|
1499
|
+
Example app.js with multiple components:
|
|
1500
|
+
\`\`\`javascript
|
|
1501
|
+
import { createApp } from 'vue';
|
|
1502
|
+
import NotesApp from './NotesApp.vue';
|
|
1503
|
+
import Counter from './Counter.vue';
|
|
1504
|
+
|
|
1505
|
+
const app = createApp({});
|
|
1506
|
+
app.component('NotesApp', NotesApp);
|
|
1507
|
+
app.component('Counter', Counter);
|
|
1508
|
+
app.mount('#app');
|
|
1509
|
+
\`\`\`
|
|
1510
|
+
|
|
1511
|
+
## Efficiency Tips
|
|
1512
|
+
|
|
1513
|
+
- **Move elements between routes:** Use \`update_element\` to change \`routeParent\` - don't delete/recreate
|
|
1514
|
+
- **Reparent elements:** Update \`parent\` attribute instead of recreating
|
|
1515
|
+
- **Reorder children:** Update parent's \`data\` array with new UUID order
|
|
1516
|
+
- Always prefer updating over deleting and recreating`;
|
|
1828
1517
|
// Create MCP server
|
|
1829
1518
|
const server = new Server({
|
|
1830
1519
|
name: 'stellify-mcp',
|
|
1831
|
-
version: '0.1.
|
|
1520
|
+
version: '0.1.23',
|
|
1832
1521
|
}, {
|
|
1833
1522
|
capabilities: {
|
|
1834
1523
|
tools: {},
|
|
@@ -2270,7 +1959,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
2270
1959
|
}
|
|
2271
1960
|
case 'save_statement': {
|
|
2272
1961
|
const { uuid, ...data } = args;
|
|
2273
|
-
const result = await stellify.saveStatement(uuid, data);
|
|
1962
|
+
const result = await stellify.saveStatement(uuid, { uuid, ...data });
|
|
2274
1963
|
return {
|
|
2275
1964
|
content: [
|
|
2276
1965
|
{
|
package/package.json
CHANGED
package/server.json
CHANGED
|
@@ -6,12 +6,12 @@
|
|
|
6
6
|
"url": "https://github.com/Stellify-Software-Ltd/stellify-mcp",
|
|
7
7
|
"source": "github"
|
|
8
8
|
},
|
|
9
|
-
"version": "0.1.
|
|
9
|
+
"version": "0.1.23",
|
|
10
10
|
"packages": [
|
|
11
11
|
{
|
|
12
12
|
"registryType": "npm",
|
|
13
13
|
"identifier": "@stellisoft/stellify-mcp",
|
|
14
|
-
"version": "0.1.
|
|
14
|
+
"version": "0.1.23",
|
|
15
15
|
"transport": {
|
|
16
16
|
"type": "stdio"
|
|
17
17
|
},
|