feat: add McpRoutesRegistering lifecycle event
All checks were successful
CI / PHP 8.4 (push) Successful in 2m0s
CI / PHP 8.3 (push) Successful in 2m11s

Wire MCP protocol routes through the event-driven module system.
Front\Mcp\Boot now fires McpRoutesRegistering, wrapping routes
with the 'mcp' middleware group (stateless, rate limiting, no prefix).

Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
Snider 2026-03-03 21:52:55 +00:00
parent 97ca407cdd
commit 0323243c9a
3 changed files with 83 additions and 1 deletions

View file

@ -0,0 +1,54 @@
<?php
/*
* Core PHP Framework
*
* Licensed under the European Union Public Licence (EUPL) v1.2.
* See LICENSE file for details.
*/
declare(strict_types=1);
namespace Core\Events;
/**
* Fired when MCP protocol routes are being registered.
*
* Modules listen to this event to register their MCP HTTP endpoints
* for AI agent access via the mcp.* domain.
*
* ## When This Event Fires
*
* Fired by `LifecycleEventProvider::fireMcpRoutes()` when the MCP frontage
* initialises, typically for requests to the MCP domain.
*
* ## Middleware
*
* Routes registered through this event are automatically wrapped with
* the 'mcp' middleware group (stateless, rate limiting).
*
* ## Usage Example
*
* ```php
* public static array $listens = [
* McpRoutesRegistering::class => 'onMcpRoutes',
* ];
*
* public function onMcpRoutes(McpRoutesRegistering $event): void
* {
* $event->routes(fn () => Route::domain(config('mcp.domain'))
* ->middleware(McpApiKeyAuth::class)
* ->group(function () {
* Route::post('tools/call', [McpApiController::class, 'callTool']);
* })
* );
* }
* ```
*
* @see ApiRoutesRegistering For REST API routes
* @see McpToolsRegistering For registering MCP tool handlers
*/
class McpRoutesRegistering extends LifecycleEvent
{
//
}

View file

@ -11,6 +11,7 @@ declare(strict_types=1);
namespace Core\Front\Mcp;
use Core\LifecycleEventProvider;
use Illuminate\Foundation\Configuration\Middleware;
use Illuminate\Support\ServiceProvider;
@ -40,6 +41,7 @@ class Boot extends ServiceProvider
public function boot(): void
{
//
// Fire McpRoutesRegistering event for lazy-loaded modules
LifecycleEventProvider::fireMcpRoutes();
}
}

View file

@ -16,6 +16,7 @@ use Core\Events\ApiRoutesRegistering;
use Core\Events\ClientRoutesRegistering;
use Core\Events\ConsoleBooting;
use Core\Events\FrameworkBooted;
use Core\Events\McpRoutesRegistering;
use Core\Events\McpToolsRegistering;
use Core\Events\QueueWorkerBooting;
use Core\Events\WebRoutesRegistering;
@ -88,6 +89,10 @@ use Livewire\Livewire;
* Processes: command classes
*
* └─── Front/Mcp/Boot ──────────────────────────────────────────────────
* ├── LifecycleEventProvider::fireMcpRoutes()
* Fires: McpRoutesRegistering
* Processes: routes ('mcp' middleware)
*
* └── LifecycleEventProvider::fireMcpTools()
* Fires: McpToolsRegistering
* Returns: MCP tool handler classes
@ -395,6 +400,27 @@ class LifecycleEventProvider extends ServiceProvider
}
}
/**
* Fire McpRoutesRegistering and process collected requests.
*
* Called by Front/Mcp/Boot when MCP protocol routes are being set up.
* Routes registered through this event are automatically wrapped with
* the 'mcp' middleware group (stateless, rate limiting).
*
* No prefix is applied MCP routes live at the domain root
* (e.g., mcp.host.uk.com/tools/call).
*/
public static function fireMcpRoutes(): void
{
$event = new McpRoutesRegistering;
event($event);
// Process route requests with mcp middleware
foreach ($event->routeRequests() as $callback) {
Route::middleware('mcp')->group($callback);
}
}
/**
* Fire McpToolsRegistering and return collected handler classes.
*