@stellisoft/stellify-mcp 0.1.24 → 0.1.26
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 +224 -56
- package/dist/stellify-client.d.ts +13 -3
- package/dist/stellify-client.js +9 -4
- package/package.json +1 -1
- package/server.json +2 -2
package/dist/index.js
CHANGED
|
@@ -127,11 +127,15 @@ This creates an EMPTY file shell - no methods, statements, or template yet. The
|
|
|
127
127
|
|
|
128
128
|
COMPLETE WORKFLOW:
|
|
129
129
|
1. create_file → creates empty shell, returns file UUID
|
|
130
|
-
2.
|
|
131
|
-
3. create_method
|
|
130
|
+
2. create_statement_with_code → add variables/imports in ONE call (returns statement UUIDs)
|
|
131
|
+
3. create_method with body param → add functions in ONE call (returns method UUIDs)
|
|
132
132
|
4. html_to_elements → create template elements (returns element UUIDs)
|
|
133
133
|
5. save_file → FINALIZE by wiring template/data arrays with all collected UUIDs
|
|
134
134
|
|
|
135
|
+
LEGACY (still supported but prefer combined tools above):
|
|
136
|
+
- create_statement + add_statement_code (2 calls instead of 1)
|
|
137
|
+
- create_method + add_method_body + save_method for is_async (3 calls instead of 1)
|
|
138
|
+
|
|
135
139
|
For PHP: Use type='class', 'model', 'controller', or 'middleware'.
|
|
136
140
|
For Vue: Use type='js' and extension='vue'. Place in the 'js' directory.
|
|
137
141
|
|
|
@@ -180,11 +184,13 @@ The system resolves these to UUIDs automatically, creating missing dependencies
|
|
|
180
184
|
},
|
|
181
185
|
{
|
|
182
186
|
name: 'create_method',
|
|
183
|
-
description: `Create a method
|
|
187
|
+
description: `Create a method in a file. Can optionally include the body and async flag in a single call.
|
|
188
|
+
|
|
189
|
+
**NEW: Combined creation** - You can now pass 'body' and 'is_async' to create the complete method in ONE call instead of three (create_method → add_method_body → save_method).
|
|
184
190
|
|
|
185
191
|
Parameters are automatically created as clauses. The response includes the clause UUIDs for each parameter.
|
|
186
192
|
|
|
187
|
-
Example request:
|
|
193
|
+
Example request (simple - signature only):
|
|
188
194
|
{
|
|
189
195
|
"file": "file-uuid",
|
|
190
196
|
"name": "verify",
|
|
@@ -196,14 +202,22 @@ Example request:
|
|
|
196
202
|
]
|
|
197
203
|
}
|
|
198
204
|
|
|
205
|
+
Example request (combined - with body and async):
|
|
206
|
+
{
|
|
207
|
+
"file": "file-uuid",
|
|
208
|
+
"name": "fetchData",
|
|
209
|
+
"body": "const response = await Http.get('/api/data');\\nreturn response.data;",
|
|
210
|
+
"is_async": true
|
|
211
|
+
}
|
|
212
|
+
|
|
199
213
|
Example response includes:
|
|
200
214
|
{
|
|
201
215
|
"uuid": "method-uuid",
|
|
202
|
-
"name": "
|
|
203
|
-
"
|
|
204
|
-
"nullable": true,
|
|
216
|
+
"name": "fetchData",
|
|
217
|
+
"is_async": true,
|
|
205
218
|
"parameters": ["clause-uuid-for-credentials"],
|
|
206
|
-
...
|
|
219
|
+
"statements": {...}, // Only if body was provided
|
|
220
|
+
"clauses": {...} // Only if body was provided
|
|
207
221
|
}`,
|
|
208
222
|
inputSchema: {
|
|
209
223
|
type: 'object',
|
|
@@ -225,6 +239,10 @@ Example response includes:
|
|
|
225
239
|
type: 'boolean',
|
|
226
240
|
description: 'Whether the method is static (PHP only)',
|
|
227
241
|
},
|
|
242
|
+
is_async: {
|
|
243
|
+
type: 'boolean',
|
|
244
|
+
description: 'Whether the method is async (JavaScript/Vue only). Set to true for methods that use await.',
|
|
245
|
+
},
|
|
228
246
|
returnType: {
|
|
229
247
|
type: 'string',
|
|
230
248
|
description: 'Return type (e.g., "int", "string", "void", "object")',
|
|
@@ -259,6 +277,10 @@ Example response includes:
|
|
|
259
277
|
required: ['name'],
|
|
260
278
|
},
|
|
261
279
|
},
|
|
280
|
+
body: {
|
|
281
|
+
type: 'string',
|
|
282
|
+
description: 'Method body code (optional). If provided, automatically parses and adds the code. Example: "const response = await Http.get(\\"/api/data\\");\\nreturn response.data;"',
|
|
283
|
+
},
|
|
262
284
|
},
|
|
263
285
|
required: ['file', 'name'],
|
|
264
286
|
},
|
|
@@ -294,12 +316,13 @@ IMPORTANT: This APPENDS to existing method statements. To REPLACE a method's cod
|
|
|
294
316
|
},
|
|
295
317
|
{
|
|
296
318
|
name: 'save_method',
|
|
297
|
-
description: `Update an existing method's properties (name, visibility, returnType, nullable, parameters, data).
|
|
319
|
+
description: `Update an existing method's properties (name, visibility, returnType, nullable, parameters, data, is_async).
|
|
298
320
|
|
|
299
321
|
Use this to modify a method after creation. For updating the method body, use add_method_body instead.
|
|
300
322
|
|
|
301
323
|
Parameters:
|
|
302
324
|
- data: Array of statement UUIDs that form the method body. Use this to reorder statements or remove unwanted statements from the method.
|
|
325
|
+
- is_async: Set to true for JavaScript/Vue methods that use await.
|
|
303
326
|
|
|
304
327
|
Example - Update return type:
|
|
305
328
|
{
|
|
@@ -308,6 +331,12 @@ Example - Update return type:
|
|
|
308
331
|
"nullable": true
|
|
309
332
|
}
|
|
310
333
|
|
|
334
|
+
Example - Mark method as async (for methods using await):
|
|
335
|
+
{
|
|
336
|
+
"uuid": "method-uuid",
|
|
337
|
+
"is_async": true
|
|
338
|
+
}
|
|
339
|
+
|
|
311
340
|
Example - Remove duplicate/unwanted statements:
|
|
312
341
|
{
|
|
313
342
|
"uuid": "method-uuid",
|
|
@@ -351,6 +380,10 @@ Example - Remove duplicate/unwanted statements:
|
|
|
351
380
|
description: 'Array of statement UUIDs that form the method body. Use to reorder or remove statements.',
|
|
352
381
|
items: { type: 'string' },
|
|
353
382
|
},
|
|
383
|
+
is_async: {
|
|
384
|
+
type: 'boolean',
|
|
385
|
+
description: 'Whether the method is async (JavaScript/Vue only). Set to true for methods that use await.',
|
|
386
|
+
},
|
|
354
387
|
},
|
|
355
388
|
required: ['uuid'],
|
|
356
389
|
},
|
|
@@ -374,16 +407,20 @@ Example - Remove duplicate/unwanted statements:
|
|
|
374
407
|
},
|
|
375
408
|
{
|
|
376
409
|
name: 'delete_method',
|
|
377
|
-
description: 'Delete a method from a file by UUID. This permanently removes the method and all its code.',
|
|
410
|
+
description: 'Delete a method from a file by UUID. This permanently removes the method and all its code. Requires both the file UUID and method UUID.',
|
|
378
411
|
inputSchema: {
|
|
379
412
|
type: 'object',
|
|
380
413
|
properties: {
|
|
414
|
+
file: {
|
|
415
|
+
type: 'string',
|
|
416
|
+
description: 'UUID of the file containing the method (required)',
|
|
417
|
+
},
|
|
381
418
|
uuid: {
|
|
382
419
|
type: 'string',
|
|
383
420
|
description: 'UUID of the method to delete',
|
|
384
421
|
},
|
|
385
422
|
},
|
|
386
|
-
required: ['uuid'],
|
|
423
|
+
required: ['file', 'uuid'],
|
|
387
424
|
},
|
|
388
425
|
},
|
|
389
426
|
{
|
|
@@ -784,6 +821,8 @@ Prefer SVG icons over emoji (encoding issues).`,
|
|
|
784
821
|
name: 'create_statement',
|
|
785
822
|
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.
|
|
786
823
|
|
|
824
|
+
**ALTERNATIVE:** Use create_statement_with_code for a single-call approach that combines both steps.
|
|
825
|
+
|
|
787
826
|
IMPORTANT: This is a TWO-STEP process:
|
|
788
827
|
1. create_statement → returns statement UUID
|
|
789
828
|
2. add_statement_code → adds the actual code to that statement
|
|
@@ -807,10 +846,42 @@ For Vue components, include the returned statement UUID in save_file's 'statemen
|
|
|
807
846
|
},
|
|
808
847
|
},
|
|
809
848
|
},
|
|
849
|
+
{
|
|
850
|
+
name: 'create_statement_with_code',
|
|
851
|
+
description: `Create a statement with code in a SINGLE call. This combines create_statement and add_statement_code.
|
|
852
|
+
|
|
853
|
+
**PREFERRED:** Use this instead of the two-step create_statement → add_statement_code process.
|
|
854
|
+
|
|
855
|
+
Examples:
|
|
856
|
+
- PHP: "use Illuminate\\Http\\Request;" or "private $items = [];"
|
|
857
|
+
- JS/Vue: "const count = ref(0);" or "import { ref } from 'vue';"
|
|
858
|
+
|
|
859
|
+
For Vue components, include the returned statement UUID in save_file's 'statements' array (NOT 'data' - that's for methods).`,
|
|
860
|
+
inputSchema: {
|
|
861
|
+
type: 'object',
|
|
862
|
+
properties: {
|
|
863
|
+
file: {
|
|
864
|
+
type: 'string',
|
|
865
|
+
description: 'UUID of the file to add the statement to',
|
|
866
|
+
},
|
|
867
|
+
code: {
|
|
868
|
+
type: 'string',
|
|
869
|
+
description: 'The code for the statement (e.g., "const count = ref(0);")',
|
|
870
|
+
},
|
|
871
|
+
method: {
|
|
872
|
+
type: 'string',
|
|
873
|
+
description: 'UUID of the method to add the statement to (optional, for method body statements)',
|
|
874
|
+
},
|
|
875
|
+
},
|
|
876
|
+
required: ['file', 'code'],
|
|
877
|
+
},
|
|
878
|
+
},
|
|
810
879
|
{
|
|
811
880
|
name: 'add_statement_code',
|
|
812
881
|
description: `Add code to an existing statement. This is step 2 of 2 - call this AFTER create_statement.
|
|
813
882
|
|
|
883
|
+
**ALTERNATIVE:** Use create_statement_with_code for a single-call approach.
|
|
884
|
+
|
|
814
885
|
The statement must already exist (created via create_statement). This parses and stores the code.
|
|
815
886
|
|
|
816
887
|
Examples:
|
|
@@ -903,7 +974,12 @@ Vue SFC example:
|
|
|
903
974
|
statements: [importStmtUuid, refStmtUuid] // Statement UUIDs (imports, refs)
|
|
904
975
|
})
|
|
905
976
|
|
|
906
|
-
For <script setup> content, the order in statements array determines output order
|
|
977
|
+
For <script setup> content, the order in statements array determines output order.
|
|
978
|
+
|
|
979
|
+
DEPENDENCY RESOLUTION (includes array):
|
|
980
|
+
The 'includes' array accepts BOTH UUIDs and namespace strings.
|
|
981
|
+
Namespace strings (e.g., "Illuminate\\Http\\JsonResponse") are automatically resolved to UUIDs.
|
|
982
|
+
This works the same as create_file's dependency resolution.`,
|
|
907
983
|
inputSchema: {
|
|
908
984
|
type: 'object',
|
|
909
985
|
properties: {
|
|
@@ -942,7 +1018,7 @@ For <script setup> content, the order in statements array determines output orde
|
|
|
942
1018
|
includes: {
|
|
943
1019
|
type: 'array',
|
|
944
1020
|
items: { type: 'string' },
|
|
945
|
-
description: 'Array of file UUIDs to import',
|
|
1021
|
+
description: 'Array of file UUIDs OR namespace strings to import. Namespace strings (e.g., "Illuminate\\\\Http\\\\JsonResponse") are auto-resolved to UUIDs.',
|
|
946
1022
|
},
|
|
947
1023
|
models: {
|
|
948
1024
|
type: 'array',
|
|
@@ -975,12 +1051,16 @@ WARNING: This is destructive and cannot be undone. Make sure the file is not ref
|
|
|
975
1051
|
inputSchema: {
|
|
976
1052
|
type: 'object',
|
|
977
1053
|
properties: {
|
|
1054
|
+
directory: {
|
|
1055
|
+
type: 'string',
|
|
1056
|
+
description: 'UUID of the directory containing the file (get from get_project directories array or get_file response)',
|
|
1057
|
+
},
|
|
978
1058
|
uuid: {
|
|
979
1059
|
type: 'string',
|
|
980
1060
|
description: 'UUID of the file to delete',
|
|
981
1061
|
},
|
|
982
1062
|
},
|
|
983
|
-
required: ['uuid'],
|
|
1063
|
+
required: ['directory', 'uuid'],
|
|
984
1064
|
},
|
|
985
1065
|
},
|
|
986
1066
|
{
|
|
@@ -1086,6 +1166,8 @@ Creates: Model ($fillable, $casts, relationships), Controller (CRUD actions), Se
|
|
|
1086
1166
|
|
|
1087
1167
|
IMPORTANT: Routes are NOT auto-wired. After creation, use create_route with the returned controller UUID and method UUIDs.
|
|
1088
1168
|
|
|
1169
|
+
IMPORTANT: After creation, check the controller methods for return types and parameter types. If methods use classes not already in includes (e.g., JsonResponse), add those class UUIDs to the controller's includes via save_file.
|
|
1170
|
+
|
|
1089
1171
|
Response includes controller.methods array with {uuid, name} for each action (index, store, update, destroy).`,
|
|
1090
1172
|
inputSchema: {
|
|
1091
1173
|
type: 'object',
|
|
@@ -1378,7 +1460,7 @@ The response includes actionable suggestions like:
|
|
|
1378
1460
|
},
|
|
1379
1461
|
];
|
|
1380
1462
|
// Server instructions for tool discovery (used by MCP Tool Search)
|
|
1381
|
-
const SERVER_INSTRUCTIONS = `Stellify is a coding platform where you code alongside AI on a codebase maintained and curated by AI. Build Laravel
|
|
1463
|
+
const SERVER_INSTRUCTIONS = `Stellify is a coding platform where you code alongside AI on a codebase maintained and curated by AI. Build Laravel, stellify-framework, and Vue.js applications.
|
|
1382
1464
|
|
|
1383
1465
|
Use Stellify tools when:
|
|
1384
1466
|
- Building PHP controllers, models, middleware, or classes
|
|
@@ -1404,18 +1486,33 @@ Key concepts:
|
|
|
1404
1486
|
|
|
1405
1487
|
1. get_project → find 'js' directory UUID (or create it)
|
|
1406
1488
|
2. create_file → type='js', extension='vue' for the component
|
|
1407
|
-
3. Create
|
|
1408
|
-
-
|
|
1409
|
-
-
|
|
1489
|
+
3. **Create a template route** for editor access:
|
|
1490
|
+
- create_route with name like "notes-template" or "component-name-template"
|
|
1491
|
+
- This route is NOT where the component displays - it's only for accessing the template in the Stellify visual editor
|
|
1492
|
+
- The actual display route (e.g., "/notes") will have just \`<div id="app"></div>\` where Vue mounts
|
|
1493
|
+
4. Create statements for imports using **create_statement_with_code** (ONE call each):
|
|
1494
|
+
- create_statement_with_code(file, "import { ref, onMounted } from 'vue';")
|
|
1495
|
+
- create_statement_with_code(file, "import { Http } from 'stellify-framework';")
|
|
1410
1496
|
NOTE: The npm package is "stellify-framework" (NOT @stellify/core)
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1497
|
+
5. Create statements for reactive data: create_statement_with_code(file, "const notes = ref([]);")
|
|
1498
|
+
6. **create_method with body and is_async** (ONE call instead of three). Example:
|
|
1499
|
+
\`\`\`
|
|
1500
|
+
create_method({
|
|
1501
|
+
file: fileUuid,
|
|
1502
|
+
name: "fetchNotes",
|
|
1503
|
+
body: "const response = await Http.get('/api/notes');\\nnotes.value = response.data || [];",
|
|
1504
|
+
is_async: true
|
|
1505
|
+
})
|
|
1506
|
+
\`\`\`
|
|
1507
|
+
7. Create statement for onMounted: create_statement_with_code(file, "onMounted(fetchNotes);")
|
|
1508
|
+
8. html_to_elements → template **with page=templateRouteUuid** (attach to the template route for editor access)
|
|
1509
|
+
9. update_element → wire click handlers to method UUIDs
|
|
1510
|
+
10. save_file with: extension='vue', template=[elementUuid], data=[methodUuids], statements=[importUuids, refUuids, onMountedUuid]
|
|
1511
|
+
- **data = method UUIDs only** (functions)
|
|
1512
|
+
- **statements = statement UUIDs** (imports, refs, onMounted)
|
|
1513
|
+
11. **MANDATORY: Create app.js entry file** (see "CRITICAL: JavaScript Entry File" section below)
|
|
1514
|
+
12. Create web route for the display page (e.g., "/notes")
|
|
1515
|
+
13. **MANDATORY: Add a div with id="app"** to the display page using html_to_elements:
|
|
1419
1516
|
- html_to_elements with page=routeUuid and elements='<div id="app"></div>'
|
|
1420
1517
|
- This is where Vue mounts the component. Without it, nothing renders!
|
|
1421
1518
|
|
|
@@ -1424,8 +1521,33 @@ Key concepts:
|
|
|
1424
1521
|
Use for SHOW/DISPLAY/DEMONSTRATE requests - sends instant WebSocket updates to browser.
|
|
1425
1522
|
Use html_to_elements/update_element for permanent/saved changes.
|
|
1426
1523
|
|
|
1524
|
+
## CRITICAL: Http Response Handling (Most Common Error)
|
|
1525
|
+
|
|
1526
|
+
**This is the #1 cause of "notes not displaying" bugs.**
|
|
1527
|
+
|
|
1528
|
+
When fetching data from API endpoints, stellify-framework's Http class returns the JSON body DIRECTLY - it does NOT wrap responses like axios does.
|
|
1529
|
+
|
|
1530
|
+
Laravel pagination returns: \`{ data: [...items], current_page: 1, per_page: 15, ... }\`
|
|
1531
|
+
|
|
1532
|
+
Since Http.get() returns this JSON directly (no axios wrapper), you access the array with ONE \`.data\`:
|
|
1533
|
+
|
|
1534
|
+
\`\`\`javascript
|
|
1535
|
+
// CORRECT - Http returns JSON directly, .data gets the paginated array
|
|
1536
|
+
const response = await Http.get('/api/notes');
|
|
1537
|
+
notes.value = response.data || [];
|
|
1538
|
+
|
|
1539
|
+
// WRONG - Double .data (axios habit) - returns undefined, notes stay empty!
|
|
1540
|
+
const response = await Http.get('/api/notes');
|
|
1541
|
+
notes.value = response.data.data || []; // BUG: response.data.data is undefined
|
|
1542
|
+
\`\`\`
|
|
1543
|
+
|
|
1544
|
+
**Why this mistake happens:** With axios, you write \`response.data.data\` because axios wraps the HTTP response (\`response.data\` unwraps axios, then \`.data\` gets the pagination array). Stellify's Http skips the wrapper, so you only need ONE \`.data\`.
|
|
1545
|
+
|
|
1546
|
+
**Symptom:** Notes exist in database, API returns them, but UI shows empty list or "No notes yet" message.
|
|
1547
|
+
|
|
1427
1548
|
## Common Pitfalls
|
|
1428
1549
|
|
|
1550
|
+
- **Vue template editor access:** Templates MUST be attached to a route for users to edit them in the visual editor. Create a separate "template route" (e.g., "notes-template") and pass its UUID to html_to_elements. This is different from the display route where the component renders.
|
|
1429
1551
|
- **Stellify imports:** Use "stellify-framework" package (NOT @stellify/core)
|
|
1430
1552
|
CORRECT: import { Http, List, Form } from 'stellify-framework';
|
|
1431
1553
|
WRONG: import { Http } from '@stellify/core';
|
|
@@ -1434,33 +1556,50 @@ Use html_to_elements/update_element for permanent/saved changes.
|
|
|
1434
1556
|
- add_method_body APPENDS, doesn't replace - create new method to replace
|
|
1435
1557
|
- 'data' array = method UUIDs, 'statements' array = import/variable UUIDs
|
|
1436
1558
|
- For buttons in forms, set inputType: "button" to prevent auto-submit
|
|
1559
|
+
- **Async methods:** Methods using await MUST be marked async. Use is_async: true in create_method (preferred) or save_method
|
|
1560
|
+
- **onMounted:** Use direct method reference: "onMounted(fetchNotes);"
|
|
1561
|
+
The assembler automatically outputs lifecycle hooks after method definitions.
|
|
1562
|
+
|
|
1563
|
+
## CRITICAL: Nullable Refs and v-if Guards
|
|
1437
1564
|
|
|
1438
|
-
|
|
1565
|
+
**This causes "Cannot read properties of null" errors.**
|
|
1439
1566
|
|
|
1440
|
-
|
|
1567
|
+
When using a nullable ref (e.g., \`const editingNote = ref(null)\`) with v-model or property access in templates, you MUST guard with an explicit v-if that checks the ref is not null.
|
|
1441
1568
|
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
-
|
|
1569
|
+
**WRONG - v-else does NOT protect against null evaluation:**
|
|
1570
|
+
\`\`\`html
|
|
1571
|
+
<template v-if="!editingItem">
|
|
1572
|
+
<!-- view mode -->
|
|
1573
|
+
</template>
|
|
1574
|
+
<template v-else>
|
|
1575
|
+
<input v-model="editingItem.title" /> <!-- ERROR: editingItem could be null -->
|
|
1576
|
+
</template>
|
|
1577
|
+
\`\`\`
|
|
1449
1578
|
|
|
1450
|
-
**
|
|
1579
|
+
**CORRECT - explicit v-if with null check:**
|
|
1580
|
+
\`\`\`html
|
|
1581
|
+
<template v-if="!editingItem || editingItem.id !== item.id">
|
|
1582
|
+
<!-- view mode -->
|
|
1583
|
+
</template>
|
|
1584
|
+
<template v-if="editingItem && editingItem.id === item.id">
|
|
1585
|
+
<input v-model="editingItem.title" /> <!-- Safe: editingItem is guaranteed non-null -->
|
|
1586
|
+
</template>
|
|
1587
|
+
\`\`\`
|
|
1451
1588
|
|
|
1452
|
-
|
|
1589
|
+
**Why v-else fails:** Vue evaluates v-model bindings during compilation/render setup, before the v-else condition is fully applied. The explicit v-if with \`editingItem &&\` ensures the binding is only evaluated when the ref exists.
|
|
1453
1590
|
|
|
1454
|
-
|
|
1591
|
+
**Inline editing pattern (CRUD apps):**
|
|
1592
|
+
1. Create ref: \`const editingItem = ref(null);\`
|
|
1593
|
+
2. View template: \`v-if="!editingItem || editingItem.id !== item.id"\`
|
|
1594
|
+
3. Edit template: \`v-if="editingItem && editingItem.id === item.id"\` (NOT v-else!)
|
|
1595
|
+
4. Start editing: \`editingItem.value = { ...item };\`
|
|
1596
|
+
5. Cancel/save: \`editingItem.value = null;\`
|
|
1455
1597
|
|
|
1456
|
-
|
|
1598
|
+
## Stack and Business Logic
|
|
1457
1599
|
|
|
1458
|
-
|
|
1459
|
-
- STOP IMMEDIATELY
|
|
1460
|
-
- Call request_capability() to log it
|
|
1461
|
-
- INFORM THE USER: "This feature requires the [X] package which isn't installed in Stellify yet. I've logged a request. This cannot be built until the package is added."
|
|
1600
|
+
**Default stack:** Laravel (PHP), stellify-framework (JS), and Vue.js. Available capabilities (optional packages/libraries) are returned by \`get_project\`. Use \`get_stellify_framework_api\` for the stellify-framework API reference.
|
|
1462
1601
|
|
|
1463
|
-
**
|
|
1602
|
+
**All business logic** (controllers, models, middleware, etc.) goes in the tenant DB via MCP tools. If a required capability is not available, use \`request_capability\` to log it.
|
|
1464
1603
|
|
|
1465
1604
|
## Project Modules (Code Organization)
|
|
1466
1605
|
|
|
@@ -1520,7 +1659,7 @@ Example app.js structure:
|
|
|
1520
1659
|
// Create MCP server
|
|
1521
1660
|
const server = new Server({
|
|
1522
1661
|
name: 'stellify-mcp',
|
|
1523
|
-
version: '0.1.
|
|
1662
|
+
version: '0.1.26',
|
|
1524
1663
|
}, {
|
|
1525
1664
|
capabilities: {
|
|
1526
1665
|
tools: {},
|
|
@@ -1599,15 +1738,26 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
1599
1738
|
case 'create_method': {
|
|
1600
1739
|
const result = await stellify.createMethod(args);
|
|
1601
1740
|
const methodData = result.data || result;
|
|
1741
|
+
const hasBody = !!args.body;
|
|
1742
|
+
const response = {
|
|
1743
|
+
success: true,
|
|
1744
|
+
message: hasBody
|
|
1745
|
+
? `Created method "${args.name}" with body (UUID: ${methodData.uuid})`
|
|
1746
|
+
: `Created method "${args.name}" (UUID: ${methodData.uuid})`,
|
|
1747
|
+
method: methodData,
|
|
1748
|
+
};
|
|
1749
|
+
// Include statements and clauses if body was provided
|
|
1750
|
+
if (result.statements) {
|
|
1751
|
+
response.statements = result.statements;
|
|
1752
|
+
}
|
|
1753
|
+
if (result.clauses) {
|
|
1754
|
+
response.clauses = result.clauses;
|
|
1755
|
+
}
|
|
1602
1756
|
return {
|
|
1603
1757
|
content: [
|
|
1604
1758
|
{
|
|
1605
1759
|
type: 'text',
|
|
1606
|
-
text: JSON.stringify(
|
|
1607
|
-
success: true,
|
|
1608
|
-
message: `Created method "${args.name}" (UUID: ${methodData.uuid})`,
|
|
1609
|
-
method: methodData,
|
|
1610
|
-
}, null, 2),
|
|
1760
|
+
text: JSON.stringify(response, null, 2),
|
|
1611
1761
|
},
|
|
1612
1762
|
],
|
|
1613
1763
|
};
|
|
@@ -1658,15 +1808,15 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
1658
1808
|
};
|
|
1659
1809
|
}
|
|
1660
1810
|
case 'delete_method': {
|
|
1661
|
-
const { uuid } = args;
|
|
1662
|
-
const result = await stellify.deleteMethod(uuid);
|
|
1811
|
+
const { file, uuid } = args;
|
|
1812
|
+
const result = await stellify.deleteMethod(file, uuid);
|
|
1663
1813
|
return {
|
|
1664
1814
|
content: [
|
|
1665
1815
|
{
|
|
1666
1816
|
type: 'text',
|
|
1667
1817
|
text: JSON.stringify({
|
|
1668
1818
|
success: true,
|
|
1669
|
-
message: `Deleted method ${uuid}`,
|
|
1819
|
+
message: `Deleted method ${uuid} from file ${file}`,
|
|
1670
1820
|
data: result,
|
|
1671
1821
|
}, null, 2),
|
|
1672
1822
|
},
|
|
@@ -1929,6 +2079,24 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
1929
2079
|
],
|
|
1930
2080
|
};
|
|
1931
2081
|
}
|
|
2082
|
+
case 'create_statement_with_code': {
|
|
2083
|
+
const result = await stellify.createStatementWithCode(args);
|
|
2084
|
+
const statementData = result.data || result;
|
|
2085
|
+
return {
|
|
2086
|
+
content: [
|
|
2087
|
+
{
|
|
2088
|
+
type: 'text',
|
|
2089
|
+
text: JSON.stringify({
|
|
2090
|
+
success: true,
|
|
2091
|
+
message: `Created statement with code (UUID: ${statementData.uuid})`,
|
|
2092
|
+
statement: statementData.statement || statementData,
|
|
2093
|
+
statements: statementData.statements,
|
|
2094
|
+
clauses: statementData.clauses,
|
|
2095
|
+
}, null, 2),
|
|
2096
|
+
},
|
|
2097
|
+
],
|
|
2098
|
+
};
|
|
2099
|
+
}
|
|
1932
2100
|
case 'add_statement_code': {
|
|
1933
2101
|
const result = await stellify.addStatementCode(args);
|
|
1934
2102
|
return {
|
|
@@ -2008,15 +2176,15 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
2008
2176
|
};
|
|
2009
2177
|
}
|
|
2010
2178
|
case 'delete_file': {
|
|
2011
|
-
const { uuid } = args;
|
|
2012
|
-
const result = await stellify.deleteFile(uuid);
|
|
2179
|
+
const { directory, uuid } = args;
|
|
2180
|
+
const result = await stellify.deleteFile(directory, uuid);
|
|
2013
2181
|
return {
|
|
2014
2182
|
content: [
|
|
2015
2183
|
{
|
|
2016
2184
|
type: 'text',
|
|
2017
2185
|
text: JSON.stringify({
|
|
2018
2186
|
success: true,
|
|
2019
|
-
message: `Deleted file ${uuid}`,
|
|
2187
|
+
message: `Deleted file ${uuid} from directory ${directory}`,
|
|
2020
2188
|
data: result,
|
|
2021
2189
|
}, null, 2),
|
|
2022
2190
|
},
|
|
@@ -17,11 +17,16 @@ export interface CreateMethodParams {
|
|
|
17
17
|
name: string;
|
|
18
18
|
visibility?: 'public' | 'protected' | 'private';
|
|
19
19
|
is_static?: boolean;
|
|
20
|
+
is_async?: boolean;
|
|
20
21
|
returnType?: string;
|
|
22
|
+
nullable?: boolean;
|
|
21
23
|
parameters?: Array<{
|
|
22
24
|
name: string;
|
|
23
|
-
type
|
|
25
|
+
type?: string;
|
|
26
|
+
datatype?: string;
|
|
27
|
+
value?: string;
|
|
24
28
|
}>;
|
|
29
|
+
body?: string;
|
|
25
30
|
}
|
|
26
31
|
export interface AddMethodBodyParams {
|
|
27
32
|
file: string;
|
|
@@ -76,14 +81,19 @@ export declare class StellifyClient {
|
|
|
76
81
|
searchFiles(params: SearchFilesParams): Promise<any>;
|
|
77
82
|
getFile(file: string): Promise<any>;
|
|
78
83
|
saveFile(file: string, data: any): Promise<any>;
|
|
79
|
-
deleteFile(file: string): Promise<any>;
|
|
84
|
+
deleteFile(directory: string, file: string): Promise<any>;
|
|
80
85
|
getMethod(method: string): Promise<any>;
|
|
81
86
|
saveMethod(method: string, data: any): Promise<any>;
|
|
82
|
-
deleteMethod(method: string): Promise<any>;
|
|
87
|
+
deleteMethod(file: string, method: string): Promise<any>;
|
|
83
88
|
createStatement(params: {
|
|
84
89
|
file?: string;
|
|
85
90
|
method?: string;
|
|
86
91
|
}): Promise<any>;
|
|
92
|
+
createStatementWithCode(params: {
|
|
93
|
+
file: string;
|
|
94
|
+
code: string;
|
|
95
|
+
method?: string;
|
|
96
|
+
}): Promise<any>;
|
|
87
97
|
getStatement(statement: string): Promise<any>;
|
|
88
98
|
deleteStatement(file: string, method: string, statement: string): Promise<any>;
|
|
89
99
|
saveStatement(statement: string, data: any): Promise<any>;
|
package/dist/stellify-client.js
CHANGED
|
@@ -43,8 +43,8 @@ export class StellifyClient {
|
|
|
43
43
|
const response = await this.client.put(`/file/${file}`, data);
|
|
44
44
|
return response.data;
|
|
45
45
|
}
|
|
46
|
-
async deleteFile(file) {
|
|
47
|
-
const response = await this.client.delete(`/file/${file}`);
|
|
46
|
+
async deleteFile(directory, file) {
|
|
47
|
+
const response = await this.client.delete(`/file/${directory}/${file}`);
|
|
48
48
|
return response.data;
|
|
49
49
|
}
|
|
50
50
|
async getMethod(method) {
|
|
@@ -55,14 +55,19 @@ export class StellifyClient {
|
|
|
55
55
|
const response = await this.client.put(`/method/${method}`, data);
|
|
56
56
|
return response.data;
|
|
57
57
|
}
|
|
58
|
-
async deleteMethod(method) {
|
|
59
|
-
const response = await this.client.delete(`/method/${method}`);
|
|
58
|
+
async deleteMethod(file, method) {
|
|
59
|
+
const response = await this.client.delete(`/method/${file}/${method}`);
|
|
60
60
|
return response.data;
|
|
61
61
|
}
|
|
62
62
|
async createStatement(params) {
|
|
63
63
|
const response = await this.client.post('/statement', params);
|
|
64
64
|
return response.data;
|
|
65
65
|
}
|
|
66
|
+
// NEW: Combined create statement with code in a single call
|
|
67
|
+
async createStatementWithCode(params) {
|
|
68
|
+
const response = await this.client.post('/statement/with-code', params);
|
|
69
|
+
return response.data;
|
|
70
|
+
}
|
|
66
71
|
async getStatement(statement) {
|
|
67
72
|
const response = await this.client.get(`/statement/${statement}`);
|
|
68
73
|
return response.data;
|
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.26",
|
|
10
10
|
"packages": [
|
|
11
11
|
{
|
|
12
12
|
"registryType": "npm",
|
|
13
13
|
"identifier": "@stellisoft/stellify-mcp",
|
|
14
|
-
"version": "0.1.
|
|
14
|
+
"version": "0.1.26",
|
|
15
15
|
"transport": {
|
|
16
16
|
"type": "stdio"
|
|
17
17
|
},
|