Core tools
The reuse-first core, always listed by the server: search the shared library, reference a proven unit into your project, scaffold what the library did not have, then run migrations and tests. A scaffold-or-reuse build needs nothing else.
These tools are always listed by the server — your MCP client sees them immediately after connecting and calls them directly by name.
Get Project
get_project
read-only
Get active project. Returns uuid, name, branches, and directories array.
This tool takes no parameters.
Search Code
search_code
read-only
Search the reusable-code library for an existing, proven unit that matches a requirement, ranked by fit. This is the RETRIEVE-don't-regenerate path: before scaffolding a feature from scratch with create_resources/create_file, search here first — a matching unit can be cloned in one call with reuse_code.
Returns COMPACT candidates only (uuid, capability summary, facets, similarity, fit score + reason, and 'variants' — how many curated fork alternatives descend from it) — never code. Inspect the winner with get_file/get_method before cloning. When a candidate has variants > 0, call list_forks(uuid) to see the alternatives (each with the submitter's note + adoption count) and let the user pick which to reuse.
CRITICAL — pin down requirements BEFORE searching. A vague query returns vague matches. If the user says "a login form", first establish the specifics that change which unit fits: SSO or password? which OAuth providers (Google/GitHub/…)? password reset, remember-me, MFA? Then encode the hard, non-negotiable constraints as 'required_facets' (a candidate is dropped unless it has ALL of them) and put the full natural-language requirement in 'query' (the semantic + rerank layers use it for nuance).
Facet keys you can require: providers (oauth provider tokens e.g. google, github, azure), packages (e.g. laravel/socialite, laravel/cashier, laravel/sanctum), framework_features (authentication, password, mfa, validation, mail, authorization, …), tables, methods, routes.
Typical flow: elicit specifics → search_code(query, required_facets) → reuse_code(files:[top uuid]) → adapt with the editing tools if needed (edits fork automatically; the canonical stays untouched).
Parameters
-
- Name
query- Type
- string
- Required
- required
- Description
-
The full natural-language requirement, as specific as possible (e.g. "user login page with Google and GitHub SSO, password reset, redirects to dashboard"). Drives semantic recall and fit reranking.
-
- Name
required_facets- Type
- object
- Description
-
Hard constraints — a candidate is excluded unless it has ALL listed values for each key. Each value is an array of strings. Example: { "providers": ["google", "github"], "packages": ["laravel/socialite"] }. Keys: providers, packages, framework_features, tables, methods, routes. Omit or leave empty for soft/exploratory searches.
-
- Name
limit- Type
- number
- Description
-
Max candidates to return (default 10, max 25).
-
- Name
project_id- Type
- string
- Description
-
Optional: restrict the search to units from a specific source project/library.
-
- Name
rerank- Type
- boolean
- Description
-
Apply the LLM fit-rerank pass (default true). Set false for a pure semantic+facet result.
Reuse Code
reuse_code
REFERENCE a reusable unit into your ACTIVE project — the canonical code is linked in place, never copied. Each reused file becomes a thin local shell whose methods resolve to the canonical originals at assembly time, so the code you get is byte-identical to the proven source and costs nothing to carry. This is how you RETRIEVE proven code instead of regenerating it — pair it with search_code.
Pass the uuids returned by search_code. EFFICIENCY: trust a high-fit search result — do NOT get_file/get_method to "double-check" before referencing, and do NOT get_assembled_code to verify after; the reference IS the proven code. References are VERBATIM by design: there is no rename step. To adapt the reused code (different names, fields, behaviour), just edit it afterwards with the normal editing tools — each edit forks only the touched code into your project automatically (copy-on-write), leaving the canonical unit and every other project referencing it untouched. ROUTES ARE AUTOMATIC: referencing a controller auto-carries the routes that point at it (rewired to your project) — you do NOT need to pass them in 'routes' or rebuild them with create_route afterwards. The source project is never modified. Returns the new file/route uuids + reference counts; then just run_migration for any carried migrations. So the whole reuse is ONE call: search_code → reuse_code(files) → run_migration.
Parameters
-
- Name
files- Type
- array
- Description
-
UUIDs of files to reuse (controller/model/migration/service/…). Their methods are referenced in place.
-
- Name
routes- Type
- array
- Description
-
Usually unnecessary — a controller's routes are auto-carried. Pass explicit route/page UUIDs only to reuse a standalone page that isn't reached via a referenced controller.
List Forks
list_forks
read-only
List the curated FORK VARIANTS of a canonical unit — approved forks that descend from it, ranked by adoption. When a search_code candidate reports variants > 0, call this with its uuid to see the alternatives: each carries a summary, the submitter's NOTE (their case for why this take is useful), and an adoption count (how many projects reference it). Present the options and let the user choose; reuse a chosen variant with reuse_code exactly like the canonical. A variant is byte-identical proven code just like any other referenced unit.
Parameters
-
- Name
uuid- Type
- string
- Required
- required
- Description
-
UUID of the canonical unit (a file or method) whose fork variants to list. Use the uuid of a search_code candidate that reported variants > 0.
Variant Counts
variant_counts
read-only
BULK check which of a set of units have curated fork alternatives — the cheap "badge" query. Pass the uuids you're working with (file/method) and get back a compact { uuid: count } map with only the non-zero entries. This is uuid→int, NO fork data — use it to decide which units are worth a list_forks call. References and local forks resolve to their canonical; a unit is excluded from its own count (a fork reports its siblings). Prefer this over calling list_forks blindly across many units.
Parameters
-
- Name
uuids- Type
- array
- Required
- required
- Description
-
file/method uuids to check for available fork alternatives (max 500).
Create Resources
create_resources
Scaffold a CRUD resource in ONE call: Model + Migration (+ Controller, + optional Service, + optional route files) from fields + relationships. MANDATORY: you MUST call search_code BEFORE this tool, every time — even for a small, fully-specified feature on an empty project ("it's quick to just build it" is the wrong instinct; cloning is far cheaper than regenerating). If any similar proven resource exists, reuse_code it (referenced in place) and adapt with the editing tools instead of scaffolding. Use create_resources ONLY after search_code has returned nothing usable; when you do, it's preferred over hand-building with create_file/create_method/create_migration. After it returns: call run_migration with the migration UUID to actually create the tables, then create_route/save_route to wire controller methods to executable routes (resource methods are not auto-wired).
Parameters
-
- Name
name- Type
- string
- Required
- required
- Description
-
Resource name in PascalCase (e.g., "User", "BlogPost", "OrderItem")
-
- Name
fields- Type
- array
- Description
-
Array of field definitions for the model and migration
-
- Name
relationships- Type
- array
- Description
-
Array of relationship definitions
-
- Name
controller- Type
- boolean
- Description
-
Create controller with CRUD actions (default: true)
-
- Name
service- Type
- boolean
- Description
-
Create service class for business logic (default: false)
-
- Name
migration- Type
- boolean
- Description
-
Create database migration (default: true)
-
- Name
routes- Type
- boolean
- Description
-
Create API routes (default: true)
-
- Name
soft_deletes- Type
- boolean
- Description
-
Add soft delete support to model and migration (default: false)
-
- Name
api- Type
- boolean
- Description
-
Generate API-style responses (default: true). Set to FALSE for SSR/Blade pages (controllers return views). Set to TRUE for API endpoints (controllers return JSON).
Create File
create_file
Create an empty file shell in a Stellify project. Returns file UUID.
For PHP: type='class', 'model', 'controller', or 'middleware'. CONSTRAINT: API controllers must return response()->json(...) — a bare array/string leaves the response null and the API route 404s.
For Vue: type='js', extension='vue'. Auto-creates app.js and template route. CONSTRAINT: Vue components must use native fetch with an X-XSRF-TOKEN header — the framework Http helper is not resolvable in the published bundle.
Pass 'includes' array for framework class dependencies (auto-resolved to UUIDs). Use 'models' array in save_file for project models.
IMPORTANT - Check appJs response for Vue components:
- If
appJs.action_required === "create_or_select_mount_file": No mount file exists. You MUST ask the user if they want to create a new app.js mount file before proceeding. - If
appJs.action_required === "register_component": Mount file exists but component isn't registered. Call save_file on the mount file to add the component UUID to its includes array.
Parameters
-
- Name
directory- Type
- string
- Required
- required
- Description
-
The UUID of the directory to create the file in (get from get_project directories array)
-
- Name
name- Type
- string
- Required
- required
- Description
-
File name without extension (e.g., "Counter", "UserController")
-
- Name
type- Type
- string
- Required
- required
- Description
-
Type of file: "js" for JavaScript/Vue, others for PHP. Use "test" for studio test files (run with run_tests) and "migration" for hand-authored migrations (run with run_migration).
-
- Name
extension- Type
- string
- Description
-
File extension. Use "vue" for Vue components, omit for PHP files.
-
- Name
namespace- Type
- string
- Description
-
PHP namespace (e.g., "App\Services\"). Only for PHP files.
-
- Name
includes- Type
- array
- Description
-
Array of namespace strings to include as dependencies (e.g., ["App\Models\User", "Illuminate\Support\Facades\Hash"]). These are resolved to UUIDs automatically.
-
- Name
module- Type
- string
- Description
-
Optional module name to group this file with related code (e.g., "blog-posts", "user-auth"). Module is auto-created if it doesn't exist.
-
- Name
attributes- Type
- array
- Description
-
PHP 8 class-level attributes (e.g., ["Fillable(['name', 'email'])"], ["ObservedBy(UserObserver::class)"]). Use search_attributes tool to find available attributes.
Search Files
search_files
read-only
Search for files in the project by name or type
Parameters
-
- Name
query- Type
- string
- Description
-
File name pattern to search for
-
- Name
type- Type
- string
- Description
-
File type to filter by (class, model, controller, middleware)
Search Methods
search_methods
read-only
Search for methods in the project by name or within a specific file
Parameters
-
- Name
name- Type
- string
- Description
-
Method name to search for (supports wildcards)
-
- Name
file_uuid- Type
- string
- Description
-
Optional: filter results to a specific file
Search Routes
search_routes
read-only
Search for routes/pages in the project by name. Use this to find existing routes before creating new ones.
Returns paginated results with route details including UUID, name, path, and type. Use the returned UUID with html_to_elements (page parameter) or get_route for full details.
Parameters
-
- Name
search- Type
- string
- Description
-
Search term to match route names (e.g., "Counter", "Home")
-
- Name
type- Type
- string
- Description
-
Filter by route type: "web" for pages, "api" for endpoints, "channels" for WebSocket channels, "view" for Blade views
-
- Name
per_page- Type
- number
- Description
-
Results per page (default: 10)
Create Route
create_route
Create a route/page. For API routes, you MUST pass BOTH controller AND controller_method UUIDs to wire execution.
IMPORTANT: Both 'controller' (file UUID) and 'controller_method' (method UUID) are required together for API routes to execute code. Without both, the route won't run any code.
Route params like {id} auto-inject into controller method parameters when names match.
Parameters
-
- Name
project_id- Type
- string
- Required
- required
- Description
-
The UUID of the Stellify project
-
- Name
name- Type
- string
- Required
- required
- Description
-
Route/page name (e.g., "Home", "Counter", "notes.index")
-
- Name
path- Type
- string
- Required
- required
- Description
-
URL path (e.g., "/", "/counter", "/api/notes")
-
- Name
method- Type
- string
- Required
- required
- Description
-
HTTP method. Use ANY for all methods, MATCH for custom combinations, FALLBACK for 404, REDIRECT/PERMANENT_REDIRECT for redirects.
-
- Name
type- Type
- string
- Description
-
Route type: "web" for pages, "api" for API endpoints, "channels" for WebSocket channels, "view" for Blade views
-
- Name
controller- Type
- string
- Description
-
UUID of the controller file. MUST be provided together with controller_method for API routes to execute code.
-
- Name
controller_method- Type
- string
- Description
-
UUID of the method to execute. MUST be provided together with controller for API routes to execute code.
-
- Name
data- Type
- object
- Description
-
Additional route data (title, description, element UUIDs)
-
- Name
module- Type
- string
- Description
-
Optional module name to group this route with related code (e.g., "blog-posts", "user-auth"). Module is auto-created if it doesn't exist.
-
- Name
file- Type
- string
- Description
-
UUID of the routes file (e.g., web.php) to register this route in. The route will be added to the file's data array.
Save Route
save_route
Update a route/page. Wire to controller with both controller and controller_method UUIDs. For significant routes, include context fields. Set meta_title/meta_description (and optional og_* / meta_keywords) to give a public/shared page its own <title> and link-preview text instead of the generic site defaults.
Parameters
-
- Name
uuid- Type
- string
- Required
- required
- Description
-
UUID of the route to update
-
- Name
meta_title- Type
- string
- Description
-
Page <title> and default og/twitter title. Use for shared/public pages so links preview as this page, not the generic site.
-
- Name
meta_description- Type
- string
- Description
-
Meta description and default og/twitter description shown in link previews.
-
- Name
meta_keywords- Type
- string
- Description
-
Optional meta keywords.
-
- Name
og_title- Type
- string
- Description
-
Open Graph / Twitter title override (defaults to meta_title).
-
- Name
og_description- Type
- string
- Description
-
Open Graph / Twitter description override (defaults to meta_description).
-
- Name
og_image- Type
- string
- Description
-
Absolute URL of the Open Graph / Twitter preview image.
-
- Name
controller- Type
- string
- Description
-
Controller file UUID. Requires controller_method.
-
- Name
controller_method- Type
- string
- Description
-
Method UUID. Requires controller.
-
- Name
path- Type
- string
- Description
-
URL path (e.g., "/api/notes")
-
- Name
name- Type
- string
- Description
-
Route name
-
- Name
type- Type
- string
- Description
-
Route type: "web" for pages, "api" for API endpoints, "channels" for WebSocket channels, "view" for Blade views.
-
- Name
method- Type
- string
- Description
-
HTTP method. Use ANY for all methods, MATCH for custom combinations, FALLBACK for 404, REDIRECT/PERMANENT_REDIRECT for redirects.
-
- Name
middleware- Type
- array
- Description
-
Array of middleware names to apply to the route.
-
- Name
public- Type
- boolean
- Description
-
Public route (no auth)
-
- Name
summary- Type
- string
- Description
-
Context: What this endpoint does
-
- Name
rationale- Type
- string
- Description
-
Context: Why built this way
-
- Name
references- Type
- array
- Description
-
Context: Related entities [{uuid, type, relationship, note}]
-
- Name
decisions- Type
- array
- Description
-
Context: Design decisions
Run Code
run_code
Execute a method in sandboxed environment. Requires file and method UUIDs. Returns output, success, error, and optional benchmark data. CONSTRAINT: the sandbox blocks literal http://|https:// strings (exfiltration guard) — build any URL (success_url, redirects, webhooks) with the url('/path') helper, never a literal scheme string.
Parameters
-
- Name
file- Type
- string
- Required
- required
- Description
-
UUID of the file containing the method to run (required)
-
- Name
method- Type
- string
- Required
- required
- Description
-
UUID of the method to execute (required)
-
- Name
args- Type
- array
- Description
-
Arguments to pass to the method
-
- Name
timeout- Type
- number
- Description
-
Execution timeout in seconds (default: 30, max: 60)
-
- Name
benchmark- Type
- boolean
- Description
-
Enable benchmarking to measure execution time and memory usage
Run Migration
run_migration
Apply a migration against the project's tenant database (creates/updates tables). Migrations need elevated Schema/DDL privileges that run_code forbids, so they have a dedicated runner. Pass the migration file UUID (returned by create_resources). Run this after create_resources to actually create the tables.
Parameters
-
- Name
file- Type
- string
- Required
- required
- Description
-
UUID of the migration file to apply (its up() method runs against the tenant DB)
Run Tests
run_tests
read-only
Run every test in a studio test file (type 'test') and return per-test results: pass/fail, failure message, location, duration. Use this to prove code you've built or reused actually works. Runs are wrapped in a database transaction and rolled back — tests never permanently mutate project data. AUTHORING CONSTRAINT: studio tests are named methods on the test file (e.g. "creates a plan"), asserting with expect() chains or $this->assert*() — Pest's top-level test()/it()/describe()/beforeEach() declarations do NOT work in the studio runtime and are rejected at validation.
Parameters
-
- Name
file- Type
- string
- Required
- required
- Description
-
UUID of the test file to run (required)
Get Assembled Code
get_assembled_code
read-only
Get the assembled source code for a file — the full PHP class or Vue SFC as it would render. Returns the WHOLE file, so it is the single biggest source of wasted tokens when overused.
HARD RULE: do NOT call this during a build. Call it AT MOST ONCE, at the very end, as a final sanity check. Every create_/save_ operation is validated server-side — a successful call means your edit is correct by construction, so you do NOT need to assemble the file to confirm it "took". The urge to "just check the result" after each edit is exactly the wrong instinct: it re-reads the entire file every time and throws away the token advantage of surgical editing. Trust your edits, keep moving, assemble once at the end. (Only exception: diagnosing a SPECIFIC failure the app actually reported.)
Parameters
-
- Name
uuid- Type
- string
- Required
- required
- Description
-
UUID of the file to get assembled code for