|
| 1 | +# Eloquent Schema |
| 2 | + |
| 3 | +Adds new MCP tools to [Laravel Boost](https://github.com/bootstrapguru/laravel-boost) for Eloquent model introspection. Designed for AI assistants and development tools that need to understand your application's data structure. |
| 4 | + |
| 5 | +Provides complete model schemas, relationships and accessors so AI assistants can generate more accurate Eloquent queries and code without needing to read through multiple model files. This reduces token usage, speeds up responses, and eliminates guesswork about your database structure. |
| 6 | + |
| 7 | +## Features |
| 8 | + |
| 9 | +- **MCP Tools** - Expose model schemas to AI assistants via Laravel MCP |
| 10 | +- **Model Discovery** - Automatically discover models in your app and configured vendor packages |
| 11 | +- **Schema Introspection** - Extract columns, relationships, and accessors from models |
| 12 | +- **Caching** - Built-in caching for performance |
| 13 | +- **Vendor Support** - Include models from packages like Spatie Permission, Media Library, etc. |
| 14 | + |
| 15 | +## Requirements |
| 16 | + |
| 17 | +- PHP 8.2+ |
| 18 | +- Laravel 11 or 12 |
| 19 | +- Laravel MCP package (optional, for MCP tools) |
| 20 | + |
| 21 | +## Installation |
| 22 | + |
| 23 | +```bash |
| 24 | +composer require visualbuilder/eloquent-schema |
| 25 | +``` |
| 26 | + |
| 27 | +Publish the configuration file: |
| 28 | + |
| 29 | +```bash |
| 30 | +php artisan vendor:publish --tag=eloquent-schema-config |
| 31 | +``` |
| 32 | + |
| 33 | +## Configuration |
| 34 | + |
| 35 | +```php |
| 36 | +// config/eloquent-schema.php |
| 37 | + |
| 38 | +return [ |
| 39 | + // Cache TTL in seconds (0 to disable) |
| 40 | + 'cache_ttl' => env('ELOQUENT_SCHEMA_CACHE_TTL', 3600), |
| 41 | + |
| 42 | + // Additional model paths to scan |
| 43 | + 'model_paths' => [ |
| 44 | + // app_path('Domain/Models'), |
| 45 | + ], |
| 46 | + |
| 47 | + // Explicitly include specific models |
| 48 | + 'additional_models' => [ |
| 49 | + // \App\Models\SomeModel::class, |
| 50 | + ], |
| 51 | + |
| 52 | + // Exclude specific models from discovery |
| 53 | + 'excluded_models' => [ |
| 54 | + // \App\Models\ExcludedModel::class, |
| 55 | + ], |
| 56 | + |
| 57 | + // Vendor packages to include (use composer package names) |
| 58 | + 'included_packages' => [ |
| 59 | + // 'spatie/laravel-permission', |
| 60 | + // 'spatie/laravel-medialibrary', |
| 61 | + ], |
| 62 | + |
| 63 | + // MCP tools configuration |
| 64 | + 'mcp' => [ |
| 65 | + 'enabled' => true, |
| 66 | + ], |
| 67 | +]; |
| 68 | +``` |
| 69 | + |
| 70 | +## MCP Tools |
| 71 | + |
| 72 | +This package provides three MCP tools for AI assistants: |
| 73 | + |
| 74 | +### list-models |
| 75 | + |
| 76 | +List all discoverable Eloquent models in the application. |
| 77 | + |
| 78 | +**Parameters:** |
| 79 | +- `filter` (string, optional) - Filter models by name (case-insensitive partial match) |
| 80 | +- `include_vendor` (boolean, default: false) - Include models from vendor packages |
| 81 | + |
| 82 | +**Example Response:** |
| 83 | +```json |
| 84 | +{ |
| 85 | + "count": 5, |
| 86 | + "namespace": "App\\Models", |
| 87 | + "models": ["User", "Order", "Product"], |
| 88 | + "vendor_models": ["Spatie\\Permission\\Models\\Role", "Spatie\\Permission\\Models\\Permission"] |
| 89 | +} |
| 90 | +``` |
| 91 | + |
| 92 | +Note: Combine `namespace` + model name for the full class (e.g., `App\Models\User`). Vendor models include their full namespace. The `vendor_models` key is only present when vendor models exist. |
| 93 | + |
| 94 | +### model-schema |
| 95 | + |
| 96 | +Get the complete schema for an Eloquent model including columns, relationships, and accessors. |
| 97 | + |
| 98 | +**Parameters:** |
| 99 | +- `model` (string, required) - Fully qualified model class name |
| 100 | +- `max_depth` (integer, default: 2, max: 3) - Depth for relationship exploration |
| 101 | + |
| 102 | +**Example Response:** |
| 103 | +```json |
| 104 | +{ |
| 105 | + "model": "App\\Models\\Order", |
| 106 | + "table": "orders", |
| 107 | + "columns": { |
| 108 | + "id": "bigint", |
| 109 | + "user_id": "bigint", |
| 110 | + "status": "string", |
| 111 | + "total": "decimal", |
| 112 | + "created_at": "datetime", |
| 113 | + "updated_at": "datetime" |
| 114 | + }, |
| 115 | + "accessors": { |
| 116 | + "formatted_total": "string" |
| 117 | + }, |
| 118 | + "relationships": { |
| 119 | + "user": { |
| 120 | + "type": "BelongsTo", |
| 121 | + "model": "User" |
| 122 | + }, |
| 123 | + "lineItems": { |
| 124 | + "type": "HasMany", |
| 125 | + "model": "OrderLineItem" |
| 126 | + } |
| 127 | + } |
| 128 | +} |
| 129 | +``` |
| 130 | + |
| 131 | +### model-fields |
| 132 | + |
| 133 | +Get a compact list of model columns and relationship names. Useful for building queries. |
| 134 | + |
| 135 | +**Parameters:** |
| 136 | +- `model` (string, required) - Fully qualified model class name |
| 137 | + |
| 138 | +**Example Response:** |
| 139 | +```json |
| 140 | +{ |
| 141 | + "model": "App\\Models\\Order", |
| 142 | + "table": "orders", |
| 143 | + "columns": ["id", "user_id", "status", "total", "created_at", "updated_at"], |
| 144 | + "accessors": ["formatted_total"], |
| 145 | + "relationships": ["user", "lineItems", "payments"] |
| 146 | +} |
| 147 | +``` |
| 148 | + |
| 149 | +## Artisan Commands |
| 150 | + |
| 151 | +### List Models |
| 152 | + |
| 153 | +```bash |
| 154 | +# List all app models |
| 155 | +php artisan eloquent-schema:list |
| 156 | + |
| 157 | +# Include vendor models |
| 158 | +php artisan eloquent-schema:list --vendor |
| 159 | + |
| 160 | +# Filter by name |
| 161 | +php artisan eloquent-schema:list --filter=User |
| 162 | + |
| 163 | +# Show count only |
| 164 | +php artisan eloquent-schema:list --count |
| 165 | +``` |
| 166 | + |
| 167 | +### Discover Vendor Packages |
| 168 | + |
| 169 | +Interactively discover and select vendor packages with Eloquent models: |
| 170 | + |
| 171 | +```bash |
| 172 | +# Interactive selection |
| 173 | +php artisan eloquent-schema:discover |
| 174 | + |
| 175 | +# List available packages without selection |
| 176 | +php artisan eloquent-schema:discover --list |
| 177 | +``` |
| 178 | + |
| 179 | +### Cache Management |
| 180 | + |
| 181 | +```bash |
| 182 | +# Warm the cache (discovers models and preloads schemas) |
| 183 | +php artisan eloquent-schema:cache |
| 184 | + |
| 185 | +# Skip schema preloading |
| 186 | +php artisan eloquent-schema:cache --no-schema |
| 187 | + |
| 188 | +# Set relationship depth for schema caching (warning: depth 2+ uses significant memory) |
| 189 | +php artisan eloquent-schema:cache --max-depth=2 |
| 190 | + |
| 191 | +# Clear the cache |
| 192 | +php artisan eloquent-schema:clear |
| 193 | + |
| 194 | +# Clear including individual schema caches |
| 195 | +php artisan eloquent-schema:clear --schema |
| 196 | +``` |
| 197 | + |
| 198 | +### Testing MCP Tools from CLI |
| 199 | + |
| 200 | +Test the eloquent-schema MCP tools directly from the command line: |
| 201 | + |
| 202 | +```bash |
| 203 | +# Test list-models |
| 204 | +php artisan eloquent-schema:mcp list-models |
| 205 | +php artisan eloquent-schema:mcp list-models --vendor --filter=User |
| 206 | + |
| 207 | +# Test model-schema |
| 208 | +php artisan eloquent-schema:mcp model-schema --model='App\Models\Order' |
| 209 | +php artisan eloquent-schema:mcp model-schema --model='App\Models\Order' --max-depth=2 |
| 210 | + |
| 211 | +# Test model-fields |
| 212 | +php artisan eloquent-schema:mcp model-fields --model='App\Models\Order' |
| 213 | +``` |
| 214 | + |
| 215 | +### Generic MCP Tools Command |
| 216 | + |
| 217 | +List and call any registered MCP tool (works with Laravel Boost and custom tools): |
| 218 | + |
| 219 | +```bash |
| 220 | +# List all available MCP tools |
| 221 | +php artisan mcp:tools --list |
| 222 | + |
| 223 | +# Describe a tool's parameters |
| 224 | +php artisan mcp:tools ModelSchema --describe |
| 225 | + |
| 226 | +# Call any MCP tool with arguments |
| 227 | +php artisan mcp:tools GetConfig --args='{"key":"app.name"}' |
| 228 | +php artisan mcp:tools ListModels |
| 229 | +php artisan mcp:tools DatabaseSchema --args='{"filter":"users"}' |
| 230 | +php artisan mcp:tools ModelSchema --args='{"model":"App\\Models\\Order","max_depth":1}' |
| 231 | +``` |
| 232 | + |
| 233 | +## Vendor Model Discovery |
| 234 | + |
| 235 | +To include models from vendor packages: |
| 236 | + |
| 237 | +1. Run the discovery command to find packages with models: |
| 238 | + ```bash |
| 239 | + php artisan eloquent-schema:discover |
| 240 | + ``` |
| 241 | + |
| 242 | +2. Select the packages you want to include |
| 243 | + |
| 244 | +3. Add the suggested configuration to `config/eloquent-schema.php`: |
| 245 | + ```php |
| 246 | + 'included_packages' => [ |
| 247 | + 'spatie/laravel-permission', |
| 248 | + 'spatie/laravel-medialibrary', |
| 249 | + ], |
| 250 | + ``` |
| 251 | + |
| 252 | +4. Warm the cache: |
| 253 | + ```bash |
| 254 | + php artisan eloquent-schema:cache |
| 255 | + ``` |
| 256 | + |
| 257 | +### Deduplication |
| 258 | + |
| 259 | +When your app extends a vendor model, the package intelligently prefers your app model: |
| 260 | + |
| 261 | +- `App\Models\User` extends `Spatie\Permission\Models\User` → Only `App\Models\User` is included |
| 262 | +- Models with the same basename prefer the App version |
| 263 | + |
| 264 | +## Using with Laravel Boost |
| 265 | + |
| 266 | +Add the tools to your `config/boost.php`: |
| 267 | + |
| 268 | +```php |
| 269 | +'mcp' => [ |
| 270 | + 'tools' => [ |
| 271 | + 'include' => [ |
| 272 | + \Visualbuilder\EloquentSchema\Mcp\Tools\ListModels::class, |
| 273 | + \Visualbuilder\EloquentSchema\Mcp\Tools\ModelSchema::class, |
| 274 | + \Visualbuilder\EloquentSchema\Mcp\Tools\ModelFields::class, |
| 275 | + ], |
| 276 | + 'exclude' => [], |
| 277 | + ], |
| 278 | +], |
| 279 | +``` |
| 280 | + |
| 281 | +## Using with Custom MCP Server |
| 282 | + |
| 283 | +If using a custom MCP server, register the tools in your server class: |
| 284 | + |
| 285 | +```php |
| 286 | +use Visualbuilder\EloquentSchema\Mcp\Tools\ListModels; |
| 287 | +use Visualbuilder\EloquentSchema\Mcp\Tools\ModelSchema; |
| 288 | +use Visualbuilder\EloquentSchema\Mcp\Tools\ModelFields; |
| 289 | + |
| 290 | +class YourServer extends Server |
| 291 | +{ |
| 292 | + protected array $tools = [ |
| 293 | + ListModels::class, |
| 294 | + ModelSchema::class, |
| 295 | + ModelFields::class, |
| 296 | + ]; |
| 297 | +} |
| 298 | +``` |
| 299 | + |
| 300 | +## Programmatic Usage |
| 301 | + |
| 302 | +You can also use the services directly: |
| 303 | + |
| 304 | +```php |
| 305 | +use Visualbuilder\EloquentSchema\Services\ModelDiscoveryService; |
| 306 | +use Visualbuilder\EloquentSchema\Services\ModelSchemaService; |
| 307 | + |
| 308 | +// Discover models |
| 309 | +$discovery = app(ModelDiscoveryService::class); |
| 310 | +$models = $discovery->getModels(includeVendor: true); |
| 311 | + |
| 312 | +// Get schema for a model |
| 313 | +$schema = app(ModelSchemaService::class); |
| 314 | +$orderSchema = $schema->getSchema(Order::class, maxDepth: 2); |
| 315 | + |
| 316 | +// Get flat field list |
| 317 | +$fields = $schema->getFlatFieldList(Order::class); |
| 318 | +``` |
| 319 | + |
| 320 | +## Caching |
| 321 | + |
| 322 | +Caching improves performance when frequently querying model schemas: |
| 323 | + |
| 324 | +```bash |
| 325 | +# Warm the cache (recommended after model changes) |
| 326 | +php artisan eloquent-schema:cache |
| 327 | + |
| 328 | +# Clear the cache when models change |
| 329 | +php artisan eloquent-schema:clear --schema |
| 330 | +``` |
| 331 | + |
| 332 | +Set cache TTL via environment variable: |
| 333 | +``` |
| 334 | +ELOQUENT_SCHEMA_CACHE_TTL=3600 |
| 335 | +``` |
| 336 | + |
| 337 | +Set to `0` to disable caching during active development. |
| 338 | + |
| 339 | +## License |
| 340 | + |
| 341 | +MIT License. See [LICENSE](LICENSE) for details. |
0 commit comments