Stellify MCP Server

MCP serverDev tools

Build Laravel apps through conversation. Code stored as structured JSON for surgical AI edits.

Use Stellify MCP Server in Claude, ChatGPT or Ahel Desktop

Free. Sign in, add Stellify MCP Server and connect your AI. About a minute.

Also: Claude Code · Cursor · Codex

Then ask your AI: use Stellify MCP Server

Details

Available today. Use it from your connected AI after setup.

Add Ahel to your AI once: Claude, ChatGPT, Cursor, Claude Code or Codex. Then ask it to use this.

Stellify MCP ServerStart free

Install Stellify MCP Server

The server’s own address, for the clients that take one directly. Or connect Ahel once and every client you use reads it from one address, with the account kept on Ahel rather than in each client’s config.

  • Claude Code

    claude mcp add --transport http --scope user stellify-mcp-server 'https://api.stellisoft.com/mcp'

    Run it once in your project, then open /mcp to approve any sign-in the server asks for.

  • Claude Desktop

    https://api.stellisoft.com/mcp

    Add a custom connector in Settings, paste this address, and approve the sign-in.

  • Cursor

    cursor://anysphere.cursor-deeplink/mcp/install?name=stellify-mcp-server&config=eyJ1cmwiOiJodHRwczovL2FwaS5zdGVsbGlzb2Z0LmNvbS9tY3AifQ==

    Open the link and Cursor adds the server at that address.

  • ChatGPT

    https://api.stellisoft.com/mcp

    In Settings, enable Developer mode, create an MCP app, and paste this address. Your plan and workspace must allow custom apps.

  • Codex

    codex mcp add stellify-mcp-server --url 'https://api.stellisoft.com/mcp'

    Run it once, then sign in with codex mcp login stellify-mcp-server if the server asks for an account.

From the project's README

As published by stellify-software-ltd/stellify-mcp in README.md.

Model Context Protocol (MCP) server for Stellify - the AI-native code generation platform.

What is This?

This MCP server lets AI assistants (like Claude Desktop) interact with your Stellify projects to build Laravel and Vue.js applications incrementally. Instead of generating full code files at once, AI can:

  • Create file structures (classes, controllers, models, middleware, Vue components)
  • Add method signatures with type hints
  • Parse PHP/JavaScript code into structured JSON (statement-by-statement)
  • Convert HTML to Stellify elements in a single operation
  • Search existing code in your projects
  • Install reusable code from the global library
  • Build applications through natural conversation

Quick Start — Hosted Server (recommended)

The easiest way to connect is the hosted server at https://api.stellisoft.com/mcp. No install, no Node.js, no API token — your MCP client opens a browser window where you sign in with your Stellify account and approve access (OAuth).

Claude (web or desktop): Stellify is listed in the Claude connectors directory — go to Settings → Connectors, find Stellify, and click Connect. Or choose Add custom connector and paste https://api.stellisoft.com/mcp.

Claude Code:

claude mcp add --transport http stellify https://api.stellisoft.com/mcp

Cursor (.cursor/mcp.json):

{
  "mcpServers": {
    "stellify": { "url": "https://api.stellisoft.com/mcp" }
  }
}

VS Code (.vscode/mcp.json):

{
  "servers": {
    "stellify": { "type": "http", "url": "https://api.stellisoft.com/mcp" }
  }
}

Windsurf (~/.codeium/windsurf/mcp_config.json):

{
  "mcpServers": {
    "stellify": { "serverUrl": "https://api.stellisoft.com/mcp" }
  }
}

Local Install (npm alternative)

Prefer to run the server locally? The npm package speaks the same protocol against the same platform API, authenticated with an API token instead of OAuth.

Prerequisites

  • Node.js 18 or higher
  • A Stellify account - Sign up at stellisoft.com
  • Claude Desktop (or another MCP-compatible AI client)

Installation

Install globally via npm:

npm install -g @stellisoft/stellify-mcp

Configuration

  1. Get your Stellify API token:

    • Log into Stellify
    • Navigate to Settings → API Tokens
    • Click "Create New Token"
    • Copy your token
  2. Configure Claude Desktop:

    Edit your Claude Desktop configuration file:

    • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
    • Windows: %APPDATA%\Claude\claude_desktop_config.json
    • Linux: ~/.config/claude/claude_desktop_config.json

    Add the Stellify MCP server:

    {
      "mcpServers": {
        "stellify": {
          "command": "stellify-mcp",
          "env": {
            "STELLIFY_API_URL": "https://stellisoft.com/api/v1",
            "STELLIFY_API_TOKEN": "your-token-here"
          }
        }
      }
    }
    
  3. Restart Claude Desktop

That's it! The Stellify tools should now be available in Claude Desktop.

Usage

Once configured, you can talk to Claude naturally to build applications:

Example Conversations

Create a new controller:

"Create a UserController in my Stellify project"

Add methods:

"Add a method called 'store' that takes a Request parameter and returns a JsonResponse"

Implement method logic:

"Add this implementation to the store method:
$user = User::create($request->validated());
return response()->json($user, 201);"

Build a Vue component:

"Create a Counter component with an increment button"

Convert HTML to elements:

"Convert this HTML to Stellify elements:
<div class='container'><h1>Hello</h1><button>Click me</button></div>"

Search your codebase:

"Search for all controller files in my project"
"Find methods related to authentication"

Available Tools

Project & Directory Tools

get_project

Get the active Stellify project for the authenticated user. Call this first before any other operations.

Parameters: None

Returns:

  • uuid: Project UUID (needed for most operations)
  • name: Project name
  • directories: Array of {uuid, name} for existing directories

get_directory

Get a directory by UUID to see its contents.

Parameters:

  • uuid (required): The UUID of the directory

create_directory

Create a new directory for organizing files.

Parameters:

  • name (required): Directory name (e.g., "js", "css", "components")

File Tools

create_file

Create a new file in a Stellify project. This creates an empty file shell - no methods, statements, or template yet.

Parameters:

  • directory (required): UUID of the directory (get from get_project directories array)
  • name (required): File name without extension (e.g., "Counter", "UserController")
  • type (required): File type - "class", "model", "controller", "middleware", or "js"
  • extension (optional): File extension. Use "vue" for Vue components.
  • namespace (optional): PHP namespace (e.g., "App\Services\"). Only for PHP files.
  • includes (optional): Array of fully-qualified class names to import (e.g., ["App\\Models\\User", "Illuminate\\Http\\Request"]). Stellify will resolve these to file UUIDs, fetching from Laravel API or vendor directory if needed.

Directory selection: Match the directory to your file's purpose. If the directory doesn't exist, create it first with create_directory.

File TypeDirectoryNamespace
ControllerscontrollersApp\Http\Controllers\
ModelsmodelsApp\Models\
ServicesservicesApp\Services\
MiddlewaremiddlewareApp\Http\Middleware\
Vue/JSjsN/A

Example workflow:

  1. create_file → creates empty shell, returns file UUID
  2. create_statement + add_statement_code → add variables/imports
  3. create_method + add_method_body → add functions
  4. html_to_elements → create template elements (for Vue)
  5. save_file → finalize with all UUIDs wired together

Auto-dependency creation (when auto_create_dependencies: true):

When you create a file with code like:

<?php
namespace App\Http\Controllers;

use App\Models\User;
use Illuminate\Http\Request;

class UserController extends Controller
{
    public function store(Request $request)
    {
        $user = User::create($request->validated());
        return response()->json($user);
    }
}

Stellify will:

  1. Parse use statements to find dependencies (User, Request, Socialite)
  2. Check Application DB for framework classes → find cached classes
  3. For core Laravel classes → fetch from api.laravel.com
  4. For vendor packages (Socialite, Spatie, etc.) → read from vendor/ directory
  5. Create missing App classes → create User model file
  6. Wire up the file's includes array with all dependency UUIDs

Supported sources:

  • Laravel API - Core Illuminate\* classes fetched from api.laravel.com
  • Vendor packages - Laravel\Socialite\*, Laravel\Cashier\*, Spatie\*, Livewire\*, etc. read directly from your vendor/ directory using PHP-Parser

The response includes a dependencies report showing what was created/resolved and from which source.


get_file

Get a file by UUID with all its metadata, methods, and statements.

Parameters:

  • uuid (required): UUID of the file

save_file

Save/update a file with its full configuration. This finalizes the file after create_file.

Parameters:

  • uuid (required): UUID of the file
  • name (required): File name (without extension)
  • type (required): File type ("js", "class", "controller", "model", "middleware")
  • extension (optional): File extension ("vue" for Vue SFCs)
  • template (optional): Array of root element UUIDs for Vue <template> section
  • data (optional): Array of METHOD UUIDs only (functions)
  • statements (optional): Array of STATEMENT UUIDs (imports, variables, refs)
  • includes (optional): Array of file UUIDs to import

Important: data = method UUIDs only, statements = statement UUIDs (code outside methods)


search_files

Search for files in the project by name or type.

Parameters:

  • name (optional): File name pattern to search for
  • type (optional): File type filter

Method Tools

create_method

Create a method signature in a file (without implementation).

Parameters:

  • file (required): UUID of the file to add the method to
  • name (required): Method name (e.g., "increment", "store", "handleClick")
  • visibility (optional): "public", "protected", or "private" (PHP only, default: "public")
  • is_static (optional): Whether the method is static (PHP only, default: false)
  • returnType (optional): Return type (e.g., "int", "string", "void")
  • parameters (optional): Array of {name, type} objects

add_method_body

Parse and add code to a method body. Stellify parses the code into structured JSON statements.

Parameters:

  • file_uuid (required): UUID of the file containing the method
  • method_uuid (required): UUID of the method to add code to
  • code (required): Code for the method body (just the statements, no function declaration)

Example:

code: "return $a + $b;"

search_methods

Search for methods in the project by name or within a specific file.

Parameters:

  • name (optional): Method name to search for (supports wildcards)
  • file_uuid (optional): Filter results to a specific file

Statement Tools

create_statement

Create an empty statement in a file. This is step 1 of 2 - you must call add_statement_code next.

Parameters:

  • file (optional): UUID of the file to add the statement to
  • method (optional): UUID of the method to add the statement to (for method body statements)

Use cases:

  • PHP: Class properties, use statements, constants
  • JS/Vue: Variable declarations, imports, reactive refs

add_statement_code

Add code to an existing statement. This is step 2 of 2 - call after create_statement.

Parameters:

  • file_uuid (required): UUID of the file containing the statement
  • statement_uuid (required): UUID of the statement to add code to
  • code (required): The code to add

Examples:

code: "use Illuminate\\Http\\Request;"
code: "const count = ref(0);"
code: "import { ref } from 'vue';"

get_statement

Get a statement by UUID with its clauses (code tokens).

Parameters:

  • uuid (required): The UUID of the statement

Route Tools

create_route

Create a new route/page in a Stellify project.

Parameters:

  • project_id (required): The UUID of the Stellify project
  • name (required): Route/page name (e.g., "Home", "Counter", "About")
  • path (required): URL path (e.g., "/", "/counter", "/about")
  • method (required): HTTP method ("GET", "POST", "PUT", "DELETE", "PATCH")
  • type (optional): Route type - "web" for pages, "api" for API endpoints (default: "web")
  • data (optional): Additional route data

get_route

Get a route/page by UUID.

Parameters:

  • uuid (required): The UUID of the route

search_routes

Search for routes/pages in the project by name.

Parameters:

  • search (optional): Search term to match route names
  • type (optional): Filter by route type ("web" or "api")
  • per_page (optional): Results per page (default: 10)

Views & Blade Templates

Stellify stores Blade views as elements instead of files. The root element's name field maps to the view name:

  • Element with name="notes.index" → view('notes.index', $data)
  • Element with name="layouts.app" → @extends('layouts.app')
  • Element with name="components.card" → <x-card>

Use update_element to set the name on a root element after creating it with html_to_elements.

Convention for reusable templates: Attach layouts, components, and partials to a template route (e.g., /template/app-layout, /template/card) to keep them organized and editable.


Element Tools (UI Components)

create_element

Create a new UI element. Provide either page (route UUID) for root elements, or parent (element UUID) for child elements.

Parameters:

  • type (required): Element type - one of:
    • HTML5: s-wrapper, s-input, s-form, s-svg, s-shape, s-media, s-iframe
    • Components: s-transition, s-freestyle, s-motion
    • Blade: s-directive
    • Shadcn/ui: s-chart, s-table, s-combobox, s-accordion, s-calendar, s-contiguous
  • page (optional): UUID of the page/route (for root elements)
  • parent (optional): UUID of the parent element (for child elements)

Using s-directive for Blade Conditionals:

s-directive elements output Blade directives (like @if, @foreach, @endif). They are sibling elements — they don't wrap children. To conditionally render content:

  1. Create an s-directive element with a statement for the opening directive (e.g., @if(...))
  2. Create the content element(s) as the next sibling(s)
  3. Create another s-directive element with a statement for the closing directive (e.g., @endif)

Example — conditionally showing an image:

// 1. Create statement for @if
create_statement_with_code({
  file: "<file-uuid>",
  code: "@if($item->featured_image)"
})

// 2. Create opening directive element and set its statement
create_element({ type: "s-directive", page: "<route-uuid>" })
update_element({ uuid: "<if-directive-uuid>", data: { "statement": "<if-statement-uuid>" } })

// 3. Create the image as the next sibling
html_to_elements({ page: "<route-uuid>", elements: "<img class=\"w-full\" />" })
// Then update with dynamic src:
update_element({ uuid: "<img-uuid>", data: { "srcField": "featured_image" } })

// 4. Create statement for @endif
create_statement_with_code({ file: "<file-uuid>", code: "@endif" })

// 5. Create closing directive element
create_element({ type: "s-directive", page: "<route-uuid>" })
update_element({ uuid: "<endif-directive-uuid>", data: { "statement": "<endif-statement-uuid>" } })

The three elements render in order as siblings:

@if($item->featured_image)
<img class="w-full" src="{{ $item->featured_image }}" />
@endif

Using s-directive for Loops:

// 1. Create @foreach directive
create_statement_with_code({ file: "<file-uuid>", code: "@foreach($posts as $item)" })
create_element({ type: "s-directive", page: "<route-uuid>" })
update_element({ uuid: "<foreach-uuid>", data: { "statement": "<foreach-statement-uuid>" } })

// 2. Create loop content (article with dynamic fields)
html_to_elements({ page: "<route-uuid>", elements: "<article><h2></h2><p></p></article>" })
// Update elements to use loop item fields:
update_element({ uuid: "<h2-uuid>", data: { "textField": "title" } })  // → {{ $item->title }}
update_element({ uuid: "<p-uuid>", data: { "textField": "excerpt" } }) // → {{ $item->excerpt }}

// 3. Create @endforeach directive
create_statement_with_code({ file: "<file-uuid>", code: "@endforeach" })
create_element({ type: "s-directive", page: "<route-uuid>" })
update_element({ uuid: "<endforeach-uuid>", data: { "statement": "<endforeach-statement-uuid>" } })

Loop Item Attributes: Inside @foreach loops, use these attributes on elements to reference $item:

  • textField: "fieldName" → outputs {{ $item->fieldName }}
  • hrefField: "fieldName" → outputs href="{{ $item->fieldName }}"
  • srcField: "fieldName" → outputs src="{{ $item->fieldName }}"
  • hrefExpression: "{{ route('posts.show', $item->slug) }}" → for complex expressions
  • srcExpression, altExpression → same pattern for other attributes

update_element

Update an existing UI element.

Parameters:

  • uuid (required): UUID of the element to update
  • data (required): Object with HTML attributes and Stellify fields

Standard HTML attributes: placeholder, href, src, type, etc.

Stellify fields:

  • name: Element name in editor
  • type: Element type
  • locked: Prevent editing (boolean)
  • tag: HTML tag (div, input, button, etc.)
  • classes: CSS classes array ["class1", "class2"]
  • text: Static text content
  • statements: Array of statement UUIDs for dynamic Blade content

Loop item fields (for elements inside @foreach loops, references $item):

  • textField: Field name → outputs {{ $item->fieldName }}
  • hrefField: Field name → outputs href="{{ $item->fieldName }}"
  • srcField: Field name → outputs src="{{ $item->fieldName }}"

Expression attributes (for complex Blade expressions):

  • hrefExpression: Full Blade expression for href (e.g., "{{ route('posts.show', $item->slug) }}")
  • srcExpression: Full Blade expression for src
  • altExpression: Full Blade expression for alt

Event handlers (set value to method UUID):

  • click: @click
  • submit: @submit
  • change: @change
  • input: @input
  • focus: @focus
  • blur: @blur
  • keydown: @keydown
  • keyup: @keyup
  • mouseenter: @mouseenter
  • mouseleave: @mouseleave

get_element

Get a single element by UUID.

Parameters:

  • uuid (required): UUID of the element

get_element_tree

Get an element with all its descendants as a hierarchical tree structure.

Parameters:

  • uuid (required): UUID of the root element

delete_element

Delete an element and all its children (CASCADE).

Parameters:

  • uuid (required): UUID of the element to delete

search_elements

Search for elements in the project.

Parameters:

  • search (optional): Search query to match element name, type, or content
  • type (optional): Filter by element type
  • include_metadata (optional): Include additional metadata (default: false)
  • per_page (optional): Results per page, 1-100 (default: 20)

html_to_elements

Convert HTML to Stellify elements in ONE operation. This is the fastest way to build interfaces!

Parameters:

  • elements (required): HTML string to convert
  • page (optional): Route UUID to attach elements to. Omit for Vue components.
  • selection (optional): Parent element UUID to attach to (alternative to page)
  • file (optional): Vue component file UUID. Pass this to auto-wire @click handlers to method UUIDs.
  • test (optional): If true, returns structure without creating elements

⚠️ CRITICAL: Multiple Root Elements

When passing HTML with multiple root-level elements (e.g., <header>, <main>, <footer>), only the FIRST root element gets attached to the route via routeParent. Other elements are created but become orphaned (not attached to the route).

Wrong approach (causes orphaned elements):

html_to_elements(page: routeUUID, elements: "<header>...</header><main>...</main><footer>...</footer>")
// Result: Only <header> is attached to the route. <main> and <footer> are orphaned!

Correct approach (make separate calls for each root element):

// Call 1: Header
html_to_elements(page: routeUUID, elements: "<header>...</header>")

// Call 2: Main content
html_to_elements(page: routeUUID, elements: "<main>...</main>")

// Call 3: Footer
html_to_elements(page: routeUUID, elements: "<footer>...</footer>")

Features:

  • Parses HTML structure
  • Creates all elements with proper nesting
  • Preserves attributes, classes, text content
  • Auto-detects Vue bindings ({{ variable }}) and creates linked statements
  • Returns element UUIDs for use in save_file template array

Element type mapping:

  • button, input, textarea, select → s-input
  • div, span, p, section, etc. → s-wrapper
  • form → s-form
  • img, video, audio → s-media

Global Library Tools

list_globals

List all global files in the Application database. Globals are reusable, curated code that can be installed into tenant projects.

Parameters: None


get_global

Get a global file with all its methods, statements, and clauses.

Parameters:

  • uuid (required): UUID of the global file

install_global

Install a global file from the Application database into a tenant project.

Parameters:

  • file_uuid (required): UUID of the global file to install
  • directory_uuid (required): UUID of the directory to install into

search_global_methods

Search for methods across the Application database (global/framework methods).

Parameters:

  • query (required): Search query to find methods by name

Module Tools

Modules are named collections of related global files that can be installed together.

list_modules

List all available modules.

Parameters: None


get_module

Get a module with all its files.

Parameters:

  • uuid (required): UUID of the module

create_module

Create a new module to group related global files.

Parameters:

  • name (required): Unique name for the module (e.g., "laravel-sanctum-auth")
  • description (optional): Description of what the module provides
  • version (optional): Version string (default: "1.0.0")
  • tags (optional): Tags for categorization (e.g., ["auth", "api", "sanctum"])

add_file_to_module

Add a global file to a module.

Parameters:

  • module_uuid (required): UUID of the module
  • file_uuid (required): UUID of the global file to add
  • order (optional): Installation order (auto-increments if not specified)

install_module

Install all files from a module into a tenant project.

Parameters:

  • module_uuid (required): UUID of the module to install
  • directory_uuid (required): UUID of the directory to install files into

How Stellify Works

Stellify stores your application code as structured JSON in a database, not text files. This architecture enables:

  • Surgical precision: AI modifies specific methods without touching other code
  • Query your codebase like data: Find all methods that use a specific class
  • Instant refactoring: Rename a method across your entire application instantly
  • Version control at the statement level: Track changes to individual code statements
  • AI-native development: Give AI granular access without worrying about breaking existing code
  • Auto-dependency resolution: Framework classes are automatically fetched from Laravel API docs

When you build with Stellify through this MCP server, code is parsed into structured data and can be assembled back into executable code when you deploy.

Dependency Resolution

When you use auto_create_dependencies, Stellify resolves dependencies in this order:

  1. Tenant Database - Check if the class exists in your project
  2. Application Database - Check the global library of pre-defined classes
  3. Laravel API Docs - For core Illuminate\* classes, fetch from api.laravel.com
  4. Vendor Directory - For installed packages, read directly from vendor/

Supported Package Sources

Shortened here. Read the whole README on GitHub.

Signals

GitHub stars
1
Last commit
Oct 2026

Ahel review

  • S4low
    published under mattstellisoft's namespace; repository belongs to stellify-software-ltd

Automated review, not a security audit. Ruleset v1.

Advanced
Delivery
stellify-mcp MCP server → your Ahel connector (mcp.ahel.ai) → your AI.
Item type
mcp-server
Key
io-github-mattstellisoft-stellify-mcp
Source
github.com/stellify-software-ltd/stellify-mcp
Hosted endpoint
https://api.stellisoft.com/mcp