Skip to content

Commit d7907b6

Browse files
committed
first commit
0 parents  commit d7907b6

28 files changed

+3037
-0
lines changed

.github/workflows/run-tests.yml

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
name: run-tests
2+
3+
on: [push, pull_request]
4+
5+
jobs:
6+
tests:
7+
runs-on: ${{ matrix.os }}
8+
strategy:
9+
fail-fast: false
10+
matrix:
11+
os: [ubuntu-latest]
12+
php: [8.2, 8.3, 8.4]
13+
laravel: [11.*, 12.*]
14+
stability: [prefer-stable]
15+
include:
16+
- laravel: 11.*
17+
testbench: 9.*
18+
- laravel: 12.*
19+
testbench: 10.*
20+
21+
name: P${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.stability }}
22+
23+
steps:
24+
- name: Checkout code
25+
uses: actions/checkout@v4
26+
27+
- name: Install SQLite 3
28+
run: |
29+
sudo apt-get update
30+
sudo apt-get install sqlite3
31+
32+
- name: Setup PHP
33+
uses: shivammathur/setup-php@v2
34+
with:
35+
php-version: ${{ matrix.php }}
36+
extensions: curl, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, iconv
37+
coverage: none
38+
39+
- name: Install dependencies
40+
run: |
41+
composer require "laravel/framework:${{ matrix.laravel }}" "orchestra/testbench:${{ matrix.testbench }}" --no-interaction --no-update
42+
composer update --${{ matrix.stability }} --prefer-dist --no-interaction
43+
44+
- name: Setup Problem Matches
45+
run: |
46+
echo "::add-matcher::${{ runner.tool_cache }}/php.json"
47+
echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json"
48+
49+
- name: Execute tests
50+
run: vendor/bin/pest

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
/vendor/
2+
/.idea/
3+
/.phpunit.cache/
4+
.phpunit.result.cache
5+
composer.lock

README.md

Lines changed: 341 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,341 @@
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

Comments
 (0)