masitings / geni-api
Static-analysis OpenAPI documentation generator for Laravel
Requires
- php: ^8.2
- illuminate/contracts: ^10.0|^11.0|^12.0|^13.0
- nikic/php-parser: ^5.0
- phpstan/phpdoc-parser: ^2.0
- spatie/laravel-package-tools: ^1.16
Requires (Dev)
- laravel/pint: ^1.13
- lorisleiva/laravel-actions: ^2.0|^3.0
- opis/json-schema: ^2.3
- orchestra/testbench: ^10.0
- pestphp/pest: ^3.0
- pestphp/pest-plugin-arch: ^3.0
- pestphp/pest-plugin-laravel: ^3.0
- spatie/laravel-data: ^4.0
- spatie/laravel-query-builder: ^5.0|^6.0
Suggests
- lorisleiva/laravel-actions: Enables automatic OpenAPI documentation for routes defined as Laravel Actions (^2.0|^3.0).
- spatie/laravel-data: Required to automatically infer OpenAPI schemas from Data DTOs (^3.0|^4.0).
- spatie/laravel-query-builder: Enables automatic OpenAPI query parameter documentation from Spatie QueryBuilder calls (^5.0|^6.0).
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-09-16 19:20:50 UTC
README
Geni is a static-analysis OpenAPI 3.1.0 documentation generator for Laravel. It reads your source files (routes, controllers, Form Requests, Resources, migrations) and produces a specification without ever booting your application or connecting to a database.
It includes a built-in standalone interactive documentation portal (BladeRenderer) that runs out-of-the-box with zero JavaScript build step (no React, no Vite, no node_modules required).
Geni supports standard OpenAPI docblock conventions and PHP 8 attributes. If you are migrating from existing documentation tools like Scramble, Geni understands familiar PHPDoc tags and attribute conventions, making switching straightforward.
📖 Full Documentation: See geni.masiting.dev for complete architecture details, configuration reference, PHP attributes, and end-to-end examples.
Key Highlights
- Zero database connections. Column types are reconstructed offline from migration files.
- Zero application boot for inference. Route discovery is the only runtime touchpoint; everything else is static AST analysis.
- Standalone docs UI out of the box. Powered by Blade, Tailwind Play CDN, and Alpine.js with live search, Prism.js syntax highlighting, and an interactive Try It console.
- Form-based or HTTP Basic Auth gate. Protect documentation routes with isolated credentials independent of application user tables.
- Runs anywhere your code does (local checkouts, CI pipelines, pre-commit hooks).
Installation
composer require masitings/geni-api
Publish the configuration file:
php artisan vendor:publish --tag=geni-config
Quick Start
-
Configure migration paths and API routes in
config/geni.php(defaults todatabase_path('migrations')and/api/*). -
Export a specification file:
php artisan geni:export --path=openapi.json
-
Or browse the interactive documentation live in your browser at
/docs/api(gated to thelocalenvironment by default).
No annotations required: for endpoints using route-model binding, validated request bodies, and JsonResource responses, Geni infers schemas automatically.
Commands Overview
| Command | Description |
|---|---|
php artisan geni:export {--path=} {--api=} |
Export the OpenAPI specification to a file |
php artisan geni:mcp {--path=} {--format=} {--base-url=} |
Generate an MCP tool manifest or client configuration for AI agents |
php artisan geni:mcp:serve {--api=} {--base-url=} {--timeout=} |
Run live MCP stdio server responding to tools/list and executing tools/call |
php artisan geni:check {--path=} {--api=} |
Compare current routes against committed spec; exits non-zero on drift |
php artisan geni:analyze {--json} {--api=} |
Inspect all unresolved inference diagnostics |
php artisan geni:cache {--api=} / geni:clear |
Pre-generate and cache the document, or clear cache |
Model Context Protocol (MCP) Integration
Geni natively exports and executes your Laravel API as Model Context Protocol (MCP) tools, turning your application into an AI-ready toolkit. AI agents (Claude Code, Cursor, Windsurf, Claude Desktop) can discover, understand, and execute your endpoints directly without manual wrapper code or extra setup.
What AI Agents Can Do With Your API
- Autonomous Endpoint Discovery (
tools/list): AI assistants automatically read all your routes, complete with request body parameters, validation constraints (required, email, min, max, enum), and response models inferred from your source code. - Direct Action Execution (
tools/call): An AI agent can perform real tasks via your API. For example, ask your agent: "Find the user with email alex@example.com and set their role to editor", and the agent will callGET /api/usersandPATCH /api/users/{id}autonomously! - Safe Credential Injection: Configure your Bearer token or API key in your environment. Credentials are automatically attached during execution and never exposed to the LLM context or tool schemas.
1. Live Stdio Execution (php artisan geni:mcp:serve)
Configure Claude Desktop or Claude Code to run Geni's built-in MCP server:
Claude Desktop (claude_desktop_config.json):
{
"mcpServers": {
"my-laravel-api": {
"command": "php",
"args": ["artisan", "geni:mcp:serve"],
"cwd": "/path/to/laravel-app",
"env": {
"GENI_MCP_BEARER_TOKEN": "your-api-bearer-token",
"GENI_MCP_API_KEY": "your-api-key"
}
}
}
}
Claude Code (.mcp.json):
{
"mcpServers": {
"api": {
"command": "php",
"args": ["artisan", "geni:mcp:serve"]
}
}
}
2. Declarative Tools Manifest & Remote HTTP Discovery
- Export Manifest File:
php artisan geni:mcp --path=mcp-manifest.json
- Generate Client Bridge Configuration:
php artisan geni:mcp --format=client-config --base-url=https://api.example.com
- Live HTTP Discovery & Execution Endpoint:
GET /docs/api/mcpreturns the standard MCPtools/listJSON envelope.POST /docs/api/mcpaccepts JSON-RPC 2.0 requests (initialize,tools/list,tools/call).
Multi-Version API Documentation
Document multiple versions (e.g. v1, v2) or separate domains independently with automatic version-switching in the UI:
// config/geni.php 'apis' => [ 'v1' => [ 'title' => 'API v1 (Legacy)', 'version' => '1.4.0', 'api_path' => 'api/v1', ], 'v2' => [ 'title' => 'API v2 (Latest)', 'version' => '2.0.0', 'api_path' => 'api/v2', ], ],
When multiple versions are defined:
- Dedicated routes are registered:
/docs/api/v1,/docs/api/v2,/docs/api/v1.json,/docs/api/v2.json,/docs/api/v1/mcp,/docs/api/v2/mcp. - An interactive version switcher dropdown automatically appears in the sidebar header of the documentation portal.
- Single-API setups (empty
apis => []) retain standard zero-overhead behavior without dropdowns.
Spatie Laravel Data Support
Geni provides first-class, opt-in support for Spatie Laravel Data (spatie/laravel-data):
- Request parameters: Controller action parameters type-hinting a class extending
Spatie\LaravelData\Dataautomatically generate the OpenAPI request body schema. - Responses: Controller return statements returning
new DataClass(...),DataClass::from(...),DataClass::collect(...), or declaring aDataClassreturn type hint generate accurate OpenAPI response schemas. - Validation attributes: Spatie validation attributes (
#[Required],#[Min],#[Max],#[Email],#[Url],#[Regex]) are statically mapped to JSON Schema constraints. - Nested Data & Collections: Nested Data classes and
DataCollectionreturns are recursively resolved and referenced. - Zero runtime overhead: Fully static AST analysis. The package never requires
spatie/laravel-dataat runtime.
Laravel Actions Support
Geni provides first-class, opt-in support for Laravel Actions (lorisleiva/laravel-actions):
- Single-action routes: Routes registered as
Route::get('/users', CreateUserAction::class)are automatically detected. Geni resolvesasController()(preferred) orhandle()as the execution method. - Rules extraction: When an action defines a
rules()method (or usesActionRequest), request validation rules are statically inferred into the OpenAPI request body schema. - Authorization: When an action defines an
authorize()method with non-trivial logic, a 403 Forbidden response is automatically documented. - Summary derivation: Operation summaries are cleanly derived from action class names (e.g.
CreateUserAction-> "Create user") when no explicit summary annotation is provided.
Spatie Laravel Query Builder Support
Geni statically inspects Spatie Laravel Query Builder (spatie/laravel-query-builder) calls on GET operations:
allowedFilters(...): Generatesfilter[field]query parameters with database column types automatically resolved from your migrations. SupportsAllowedFilter::exact,partial,scope, andtrashed.allowedSorts(...)anddefaultSort(...): Generates a unifiedsortquery parameter with expanded ascending and descending enums and default values.allowedIncludes(...): Generates anincludequery parameter listing available relation names.allowedFields(...): Generatesfields[resource]query parameters for sparse fieldsets.allowedAppends(...): Generates anappendquery parameter listing dynamic model accessors.
Design Decisions & Static Analysis Nuances
Geni parses code statically rather than evaluating runtime values:
Rule::in($variable): Non-literal variables cannot be expanded into an enum. Geni documents the base type and records a diagnostic. (Workaround: inline literal values, or add@var).- Column types from migrations: Relies on migration history. Pruned migrations via
schema:dumprequireschema_overrides. exists:table,column: Resolved offline from migration schemas rather than live database queries.
For in-depth guides on all features, custom renderers, security schemes, and PHP attributes, please read the full documentation at geni.masiting.dev.
Disclaimer
Scramble is a trademark of dedoc.co and Roman Lytvynenko. Geni is an independent open-source project and is not affiliated with, endorsed by, or sponsored by dedoc.co.
License
The MIT License (MIT). Please see LICENSE for more information.

