@stellisoft/stellify-mcp 0.1.27 → 0.1.29

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
@@ -23,7 +23,7 @@ const STELLIFY_FRAMEWORK_API = {
23
23
  // Data & Forms
24
24
  Form: ['create', 'set', 'get', 'getData', 'validate', 'isValid', 'getErrors', 'getError', 'reset', 'store', 'update', 'delete'],
25
25
  Table: ['create', 'setData', 'addColumn', 'removeColumn', 'sort', 'filter', 'clearFilter', 'paginate', 'page', 'getData', 'getAllData', 'getColumns', 'getColumn', 'getTotalRows', 'getTotalPages', 'getCurrentPage', 'getPageSize', 'getSortKey', 'getSortDirection'],
26
- List: ['create', 'from', 'range', 'add', 'remove', 'removeWhere', 'set', 'get', 'first', 'last', 'sort', 'sortBy', 'reverse', 'filter', 'find', 'findIndex', 'map', 'reduce', 'forEach', 'includes', 'indexOf', 'every', 'some', 'slice', 'take', 'skip', 'chunk', 'unique', 'uniqueBy', 'groupBy', 'flatten', 'concat', 'isEmpty', 'isNotEmpty', 'count', 'clear', 'toArray', 'toJSON', 'clone', 'sum', 'avg', 'min', 'max'],
26
+ Collection: ['create', 'collect', 'from', 'range', 'add', 'remove', 'removeWhere', 'set', 'get', 'first', 'last', 'sort', 'sortBy', 'reverse', 'filter', 'find', 'findIndex', 'map', 'reduce', 'forEach', 'includes', 'indexOf', 'every', 'some', 'slice', 'take', 'skip', 'chunk', 'unique', 'uniqueBy', 'groupBy', 'flatten', 'concat', 'isEmpty', 'isNotEmpty', 'count', 'clear', 'toArray', 'toJSON', 'clone', 'sum', 'avg', 'min', 'max'],
27
27
  Tree: ['create', 'setRoot', 'addChild', 'removeNode', 'getNode', 'getRoot', 'getChildren', 'getParent', 'getSiblings', 'getAncestors', 'getDescendants', 'getDepth', 'getPath', 'traverse', 'find', 'findAll', 'move', 'toArray', 'size'],
28
28
  // Network
29
29
  Http: ['create', 'get', 'post', 'put', 'patch', 'delete', 'items', 'withHeaders', 'withToken', 'withTimeout'],
@@ -74,11 +74,11 @@ Use this tool when you need to:
74
74
 
75
75
  IMPORTANT - Stellify Framework Import:
76
76
  The npm package is "stellify-framework" (NOT @stellify/core).
77
- Import like: import { Http, List, Form } from 'stellify-framework';
77
+ Import like: import { Http, Collection, Form } from 'stellify-framework';
78
78
 
79
- IMPORTANT - List class and Vue reactivity:
80
- List is iterable and works directly with Vue's v-for directive.
81
- Use List.from() to wrap arrays for chainable operations (filter, map, sort, etc.).
79
+ IMPORTANT - Collection class and Vue reactivity:
80
+ Collection is iterable and works directly with Vue's v-for directive.
81
+ Use Collection.collect() to wrap arrays for chainable operations (filter, map, sort, etc.).
82
82
 
83
83
  Example response:
84
84
  {
@@ -128,9 +128,11 @@ COMPLETE WORKFLOW:
128
128
  4. html_to_elements → create template elements (returns element UUIDs)
129
129
  5. save_file → FINALIZE by wiring template/data arrays with all collected UUIDs
130
130
 
131
- LEGACY (still supported but prefer combined tools above):
131
+ TWO-STEP ALTERNATIVES (still supported but prefer combined tools above):
132
132
  - create_statement + add_statement_code (2 calls instead of 1)
133
- - create_method + add_method_body + save_method for is_async (3 calls instead of 1)
133
+ - create_method (without body) + add_method_body (2 calls instead of 1)
134
+
135
+ NOTE: add_method_body is also useful for APPENDING code to an existing method.
134
136
 
135
137
  For PHP: Use type='class', 'model', 'controller', or 'middleware'.
136
138
  For Vue: Use type='js' and extension='vue'. Place in the 'js' directory.
@@ -187,6 +189,8 @@ NOTE: For controllers that use PROJECT models (Feedback, Vote, etc.), add those
187
189
 
188
190
  **NEW: Combined creation** - Pass 'body' to create the complete method in ONE call. Async is auto-detected when body contains \`await\`.
189
191
 
192
+ **Nested code is handled correctly.** The parser tracks brace/bracket/paren depth and only splits statements on semicolons at the top level. This means computed properties, arrow functions with block bodies, and other nested constructs work correctly as single statements.
193
+
190
194
  Parameters are automatically created as clauses. The response includes the clause UUIDs for each parameter.
191
195
 
192
196
  Example request (simple - signature only):
@@ -285,14 +289,17 @@ Example response includes:
285
289
  },
286
290
  {
287
291
  name: 'add_method_body',
288
- description: `Parse and add PHP code to a method body. Provide the method implementation code (without the function declaration). Stellify will parse it into structured statements.
289
-
290
- IMPORTANT: This APPENDS to existing method statements. To REPLACE a method's code:
291
- 1. Create a NEW method with create_method
292
- 2. Add body with add_method_body
293
- 3. Update the file's 'data' array to include new method UUID (remove old one)
294
- 4. Update any element click handlers to reference the new method UUID
295
- 5. Optionally delete the old method with delete_method`,
292
+ description: `Append code to an existing method. Use this when you need to ADD MORE code to a method that already has statements.
293
+
294
+ **For new methods:** Use \`create_method\` with the \`body\` parameter instead - it creates the method with code in one call.
295
+
296
+ **Nested code is handled correctly.** The parser tracks brace/bracket/paren depth and only splits on semicolons at the top level. Arrow functions with block bodies, computed properties, and other nested constructs work as single statements.
297
+
298
+ IMPORTANT: This APPENDS to existing method statements. To REPLACE a method's code entirely:
299
+ 1. Create a NEW method with create_method (with body parameter)
300
+ 2. Update the file's 'data' array to include new method UUID (remove old one)
301
+ 3. Update any element click handlers to reference the new method UUID
302
+ 4. Delete the old method with delete_method`,
296
303
  inputSchema: {
297
304
  type: 'object',
298
305
  properties: {
@@ -692,6 +699,11 @@ Create methods for all handlers, including simple state changes like opening mod
692
699
 
693
700
  Event types: click, submit, change, input, focus, blur, keydown, keyup, mouseenter, mouseleave.
694
701
 
702
+ DYNAMIC CLASS BINDINGS - For classes that toggle based on expressions:
703
+ { "classBindings": { "rotate-180": "panel.open", "bg-red-500": "hasError" } }
704
+ Assembles to: :class="{ 'rotate-180': panel.open, 'bg-red-500': hasError }"
705
+ Use for state-dependent styling in v-for loops or reactive components.
706
+
695
707
  EFFICIENCY - Prefer updates over delete/recreate:
696
708
  - Move between routes: change \`routeParent\` attribute
697
709
  - Reparent elements: change \`parent\` attribute
@@ -705,7 +717,7 @@ EFFICIENCY - Prefer updates over delete/recreate:
705
717
  },
706
718
  data: {
707
719
  type: 'object',
708
- description: 'Flat object with HTML attributes and Stellify fields (name, type, locked, tag, classes, text)',
720
+ description: 'Flat object with HTML attributes and Stellify fields (name, type, locked, tag, classes, text, classBindings)',
709
721
  },
710
722
  },
711
723
  required: ['uuid', 'data'],
@@ -870,11 +882,13 @@ For Vue components, include the returned statement UUID in save_file's 'statemen
870
882
 
871
883
  **PREFERRED:** Use this instead of the two-step create_statement → add_statement_code process.
872
884
 
885
+ **Nested code is handled correctly.** The parser tracks brace/bracket/paren depth and only splits on top-level semicolons. Computed properties, arrow functions with block bodies, and other nested constructs are kept as single statements.
886
+
873
887
  Examples:
874
888
  - PHP: "use Illuminate\\Http\\Request;" or "private $items = [];"
875
889
  - JS/Vue: "const count = ref(0);" or "import { ref } from 'vue';"
876
890
 
877
- For Vue components, include the returned statement UUID in save_file's 'statements' array (NOT 'data' - that's for methods).`,
891
+ For Vue components, include the returned statement UUIDs in save_file's 'statements' array (NOT 'data' - that's for methods).`,
878
892
  inputSchema: {
879
893
  type: 'object',
880
894
  properties: {
@@ -898,7 +912,7 @@ For Vue components, include the returned statement UUID in save_file's 'statemen
898
912
  name: 'add_statement_code',
899
913
  description: `Add code to an existing statement. This is step 2 of 2 - call this AFTER create_statement.
900
914
 
901
- **ALTERNATIVE:** Use create_statement_with_code for a single-call approach.
915
+ **ALTERNATIVE:** Use create_statement_with_code for a single-call approach that combines both steps.
902
916
 
903
917
  The statement must already exist (created via create_statement). This parses and stores the code.
904
918
 
@@ -1476,6 +1490,204 @@ The response includes actionable suggestions like:
1476
1490
  },
1477
1491
  },
1478
1492
  },
1493
+ {
1494
+ name: 'get_setting',
1495
+ description: `Get a setting/config value from the tenant's settings table.
1496
+
1497
+ These settings are read by the config() function in sandbox code execution.
1498
+ Use this to check existing configuration values before modifying them.
1499
+
1500
+ EXAMPLE:
1501
+ { "name": "app" }
1502
+
1503
+ Returns the setting data as key-value pairs, e.g.:
1504
+ {
1505
+ "name": "My App",
1506
+ "timezone": "UTC",
1507
+ "locale": "en"
1508
+ }
1509
+
1510
+ Common setting profiles:
1511
+ - "app": Application settings (name, timezone, locale)
1512
+ - "database": Database connection settings
1513
+ - "mail": Mail configuration
1514
+ - "cache": Cache settings
1515
+ - Custom profiles for app-specific config`,
1516
+ inputSchema: {
1517
+ type: 'object',
1518
+ properties: {
1519
+ name: {
1520
+ type: 'string',
1521
+ description: 'Setting profile name (e.g., "app", "database", "mail", or custom names like "vote")',
1522
+ },
1523
+ },
1524
+ required: ['name'],
1525
+ },
1526
+ },
1527
+ {
1528
+ name: 'save_setting',
1529
+ description: `Create or update a setting in the tenant's settings table.
1530
+
1531
+ These settings are accessible via config() in sandbox code execution.
1532
+ Use this to configure application behavior, API keys, feature flags, etc.
1533
+
1534
+ IMPORTANT: This creates or updates the setting profile with the provided key-value data.
1535
+ The data is merged with any existing values for that profile.
1536
+
1537
+ EXAMPLE - Create app settings:
1538
+ {
1539
+ "name": "app",
1540
+ "data": {
1541
+ "name": "My Feedback App",
1542
+ "timezone": "America/New_York",
1543
+ "locale": "en"
1544
+ }
1545
+ }
1546
+
1547
+ EXAMPLE - Create custom settings for voting:
1548
+ {
1549
+ "name": "vote",
1550
+ "data": {
1551
+ "salt": "my-secret-salt-for-ip-hashing",
1552
+ "allow_anonymous": true,
1553
+ "max_votes_per_day": 10
1554
+ }
1555
+ }
1556
+
1557
+ In your controller code, access these with:
1558
+ - config('app.name') returns "My Feedback App"
1559
+ - config('vote.salt') returns "my-secret-salt-for-ip-hashing"
1560
+ - config('vote.allow_anonymous') returns true`,
1561
+ inputSchema: {
1562
+ type: 'object',
1563
+ properties: {
1564
+ name: {
1565
+ type: 'string',
1566
+ description: 'Setting profile name (e.g., "app", "vote", "features")',
1567
+ },
1568
+ data: {
1569
+ type: 'object',
1570
+ description: 'Key-value pairs for the setting (e.g., { "salt": "secret", "enabled": true })',
1571
+ },
1572
+ },
1573
+ required: ['name', 'data'],
1574
+ },
1575
+ },
1576
+ {
1577
+ name: 'delete_setting',
1578
+ description: `Delete a setting profile from the tenant's settings table.
1579
+
1580
+ WARNING: This permanently removes the entire setting profile and all its values.
1581
+ This cannot be undone.
1582
+
1583
+ EXAMPLE:
1584
+ { "name": "vote" }
1585
+
1586
+ This removes the "vote" setting profile entirely.`,
1587
+ inputSchema: {
1588
+ type: 'object',
1589
+ properties: {
1590
+ name: {
1591
+ type: 'string',
1592
+ description: 'Setting profile name to delete',
1593
+ },
1594
+ },
1595
+ required: ['name'],
1596
+ },
1597
+ },
1598
+ {
1599
+ name: 'get_pattern',
1600
+ description: `Get a UI pattern checklist for building common components correctly.
1601
+
1602
+ WHEN TO USE: Call this BEFORE building any of these UI patterns:
1603
+ - accordion: Collapsible content panels
1604
+ - modal: Overlay dialogs
1605
+ - tabs: Tabbed content navigation
1606
+ - dropdown: Toggleable menus
1607
+ - toast: Notification messages
1608
+
1609
+ The checklist contains best practices and common pitfalls to avoid.
1610
+ Following the checklist prevents bugs like hidden content still being visible,
1611
+ missing keyboard navigation, or incorrect ARIA attributes.
1612
+
1613
+ EXAMPLE:
1614
+ { "name": "accordion" }
1615
+
1616
+ Returns:
1617
+ {
1618
+ "name": "accordion",
1619
+ "description": "Collapsible content panels",
1620
+ "checklist": [
1621
+ "Use v-show for visibility toggle (not CSS height tricks)",
1622
+ "Store open state as boolean in each panel object",
1623
+ ...
1624
+ ],
1625
+ "example": "const panels = ref([...]);"
1626
+ }
1627
+
1628
+ If no pattern exists for the given name, returns null.`,
1629
+ inputSchema: {
1630
+ type: 'object',
1631
+ properties: {
1632
+ name: {
1633
+ type: 'string',
1634
+ description: 'Pattern name (e.g., "accordion", "modal", "tabs", "dropdown", "toast")',
1635
+ },
1636
+ },
1637
+ required: ['name'],
1638
+ },
1639
+ },
1640
+ {
1641
+ name: 'save_pattern',
1642
+ description: `Save or update a UI pattern checklist.
1643
+
1644
+ Use this to add new patterns or update existing ones based on lessons learned.
1645
+
1646
+ EXAMPLE:
1647
+ {
1648
+ "name": "accordion",
1649
+ "description": "Collapsible content panels",
1650
+ "checklist": [
1651
+ "Use v-show for visibility toggle",
1652
+ "Store open state as boolean"
1653
+ ],
1654
+ "example": "const panels = ref([...]);"
1655
+ }`,
1656
+ inputSchema: {
1657
+ type: 'object',
1658
+ properties: {
1659
+ name: {
1660
+ type: 'string',
1661
+ description: 'Pattern name (e.g., "accordion", "modal")',
1662
+ },
1663
+ description: {
1664
+ type: 'string',
1665
+ description: 'Brief description of the pattern',
1666
+ },
1667
+ checklist: {
1668
+ type: 'array',
1669
+ items: { type: 'string' },
1670
+ description: 'Array of checklist items - best practices and things to remember',
1671
+ },
1672
+ example: {
1673
+ type: 'string',
1674
+ description: 'Optional code example',
1675
+ },
1676
+ },
1677
+ required: ['name', 'description', 'checklist'],
1678
+ },
1679
+ },
1680
+ {
1681
+ name: 'list_patterns',
1682
+ description: `List all available UI pattern checklists.
1683
+
1684
+ Returns an array of pattern names and descriptions.
1685
+ Use this to discover what patterns are available before building UI components.`,
1686
+ inputSchema: {
1687
+ type: 'object',
1688
+ properties: {},
1689
+ },
1690
+ },
1479
1691
  ];
1480
1692
  // Server instructions for tool discovery (used by MCP Tool Search)
1481
1693
  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.
@@ -1548,14 +1760,18 @@ const response = await Http.get('/api/notes');
1548
1760
  notes.value = response.data || [];
1549
1761
  \`\`\`
1550
1762
 
1763
+ ## Editing Existing Code
1764
+
1765
+ - **Edit at the right level:** To change code, edit the statement or clause - never delete an entire method just to change a line.
1766
+
1551
1767
  ## Common Pitfalls
1552
1768
 
1553
1769
  - **@click auto-wiring:** Pass the file UUID to html_to_elements to auto-wire @click handlers. Methods must be created BEFORE calling html_to_elements.
1554
1770
  - **Stellify imports:** Use "stellify-framework" package (NOT @stellify/core)
1555
- CORRECT: import { Http, List, Form } from 'stellify-framework';
1771
+ CORRECT: import { Http, Collection, Form } from 'stellify-framework';
1556
1772
  WRONG: import { Http } from '@stellify/core';
1557
1773
  - v-model requires ref(), NOT Form class: const formData = ref({title: ''})
1558
- - List is iterable and works directly with v-for (no .toArray() needed)
1774
+ - Collection is iterable and works directly with v-for (no .toArray() needed)
1559
1775
  - add_method_body APPENDS, doesn't replace - create new method to replace
1560
1776
  - 'data' array = method UUIDs, 'statements' array = import/variable UUIDs
1561
1777
  - For buttons in forms, set inputType: "button" to prevent auto-submit
@@ -1577,6 +1793,8 @@ Vue evaluates v-model bindings before v-else is applied, causing "Cannot read pr
1577
1793
 
1578
1794
  **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.
1579
1795
 
1796
+ **Prefer Laravel methods:** When Laravel provides a helper (Str, Arr, Hash, Number, Collection), use it instead of native PHP functions.
1797
+
1580
1798
  ## JavaScript Entry File (app.js) - Auto-Generated
1581
1799
 
1582
1800
  When you create a Vue component, **app.js is automatically created/updated** with component registration. The create_file response will confirm this with an \`appJs\` field.
@@ -1586,7 +1804,7 @@ When you create a Vue component, **app.js is automatically created/updated** wit
1586
1804
  // Create MCP server
1587
1805
  const server = new Server({
1588
1806
  name: 'stellify-mcp',
1589
- version: '0.1.27',
1807
+ version: '0.1.29',
1590
1808
  }, {
1591
1809
  capabilities: {
1592
1810
  tools: {},
@@ -2364,6 +2582,95 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
2364
2582
  ],
2365
2583
  };
2366
2584
  }
2585
+ case 'get_setting': {
2586
+ const result = await stellify.getSetting(args.name);
2587
+ const data = result.data || result;
2588
+ return {
2589
+ content: [
2590
+ {
2591
+ type: 'text',
2592
+ text: JSON.stringify({
2593
+ success: true,
2594
+ message: `Retrieved setting "${args.name}"`,
2595
+ setting: data,
2596
+ }, null, 2),
2597
+ },
2598
+ ],
2599
+ };
2600
+ }
2601
+ case 'save_setting': {
2602
+ const { name, data } = args;
2603
+ await stellify.saveSetting(name, data);
2604
+ return {
2605
+ content: [
2606
+ {
2607
+ type: 'text',
2608
+ text: JSON.stringify({
2609
+ success: true,
2610
+ message: `Saved setting "${name}" with ${Object.keys(data).length} key(s)`,
2611
+ keys: Object.keys(data),
2612
+ }, null, 2),
2613
+ },
2614
+ ],
2615
+ };
2616
+ }
2617
+ case 'delete_setting': {
2618
+ await stellify.deleteSetting(args.name);
2619
+ return {
2620
+ content: [
2621
+ {
2622
+ type: 'text',
2623
+ text: JSON.stringify({
2624
+ success: true,
2625
+ message: `Deleted setting "${args.name}"`,
2626
+ }, null, 2),
2627
+ },
2628
+ ],
2629
+ };
2630
+ }
2631
+ case 'get_pattern': {
2632
+ const result = await stellify.getPattern(args.name);
2633
+ return {
2634
+ content: [
2635
+ {
2636
+ type: 'text',
2637
+ text: JSON.stringify({
2638
+ success: true,
2639
+ pattern: result.data || result,
2640
+ }, null, 2),
2641
+ },
2642
+ ],
2643
+ };
2644
+ }
2645
+ case 'save_pattern': {
2646
+ const { name, description, checklist, example } = args;
2647
+ await stellify.savePattern(name, { description, checklist, example });
2648
+ return {
2649
+ content: [
2650
+ {
2651
+ type: 'text',
2652
+ text: JSON.stringify({
2653
+ success: true,
2654
+ message: `Saved pattern "${name}" with ${checklist.length} checklist items`,
2655
+ }, null, 2),
2656
+ },
2657
+ ],
2658
+ };
2659
+ }
2660
+ case 'list_patterns': {
2661
+ const result = await stellify.listPatterns();
2662
+ return {
2663
+ content: [
2664
+ {
2665
+ type: 'text',
2666
+ text: JSON.stringify({
2667
+ success: true,
2668
+ patterns: result.data || result,
2669
+ }, null, 2),
2670
+ },
2671
+ ],
2672
+ };
2673
+ }
2367
2674
  default:
2368
2675
  throw new Error(`Unknown tool: ${name}`);
2369
2676
  }
@@ -184,4 +184,15 @@ export declare class StellifyClient {
184
184
  analyzeQuality(params: {
185
185
  type?: 'full' | 'relationships' | 'fillables' | 'casts' | 'routes';
186
186
  }): Promise<any>;
187
+ getSetting(name: string): Promise<any>;
188
+ saveSetting(name: string, data: Record<string, any>): Promise<any>;
189
+ createSetting(name: string): Promise<any>;
190
+ deleteSetting(name: string): Promise<any>;
191
+ getPattern(name: string): Promise<any>;
192
+ savePattern(name: string, data: {
193
+ description: string;
194
+ checklist: string[];
195
+ example?: string;
196
+ }): Promise<any>;
197
+ listPatterns(): Promise<any>;
187
198
  }
@@ -207,4 +207,35 @@ export class StellifyClient {
207
207
  const response = await this.client.get(endpoint);
208
208
  return response.data;
209
209
  }
210
+ // Settings/Config management - for tenant-specific configuration
211
+ // These settings are read by the config() override in sandbox code execution
212
+ async getSetting(name) {
213
+ const response = await this.client.get(`/config/${name}`);
214
+ return response.data;
215
+ }
216
+ async saveSetting(name, data) {
217
+ const response = await this.client.put(`/config/${name}`, { data });
218
+ return response.data;
219
+ }
220
+ async createSetting(name) {
221
+ const response = await this.client.post('/config', { name });
222
+ return response.data;
223
+ }
224
+ async deleteSetting(name) {
225
+ const response = await this.client.delete(`/config/${name}`);
226
+ return response.data;
227
+ }
228
+ // UI Pattern checklists - best practices for common UI patterns
229
+ async getPattern(name) {
230
+ const response = await this.client.get(`/pattern/${name}`);
231
+ return response.data;
232
+ }
233
+ async savePattern(name, data) {
234
+ const response = await this.client.put(`/pattern/${name}`, data);
235
+ return response.data;
236
+ }
237
+ async listPatterns() {
238
+ const response = await this.client.get('/pattern');
239
+ return response.data;
240
+ }
210
241
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stellisoft/stellify-mcp",
3
- "version": "0.1.27",
3
+ "version": "0.1.29",
4
4
  "mcpName": "io.github.MattStellisoft/stellify-mcp",
5
5
  "description": "MCP server for Stellify - AI-native code generation platform",
6
6
  "main": "dist/index.js",
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.27",
9
+ "version": "0.1.29",
10
10
  "packages": [
11
11
  {
12
12
  "registryType": "npm",
13
13
  "identifier": "@stellisoft/stellify-mcp",
14
- "version": "0.1.27",
14
+ "version": "0.1.29",
15
15
  "transport": {
16
16
  "type": "stdio"
17
17
  },