@@ -95,23 +95,69 @@ Mcp::tool([CalculatorService::class, 'add'])
9595Mcp::tool(EmailService::class)
9696 ->description('Send emails to users');
9797
98+ // Register a closure as a tool with custom input schema
99+ Mcp::tool(function(float $x, float $y): float {
100+ return $x * $y;
101+ })
102+ ->name('multiply')
103+ ->description('Multiply two numbers')
104+ ->inputSchema([
105+ 'type' => 'object',
106+ 'properties' => [
107+ 'x' => ['type' => 'number', 'description' => 'First number'],
108+ 'y' => ['type' => 'number', 'description' => 'Second number'],
109+ ],
110+ 'required' => ['x', 'y'],
111+ ]);
112+
98113// Register a resource with metadata
99114Mcp::resource('config://app/settings', [UserService::class, 'getAppSettings'])
100115 ->name('app_settings')
101116 ->description('Application configuration settings')
102117 ->mimeType('application/json')
103118 ->size(1024);
104119
120+ // Register a closure as a resource
121+ Mcp::resource('system://time', function(): string {
122+ return now()->toISOString();
123+ })
124+ ->name('current_time')
125+ ->description('Get current server time')
126+ ->mimeType('text/plain');
127+
105128// Register a resource template for dynamic content
106129Mcp::resourceTemplate('user://{userId}/profile', [UserService::class, 'getUserProfile'])
107130 ->name('user_profile')
108131 ->description('Get user profile by ID')
109132 ->mimeType('application/json');
110133
134+ // Register a closure as a resource template
135+ Mcp::resourceTemplate('file://{path}', function(string $path): string {
136+ if (!file_exists($path) || !is_readable($path)) {
137+ throw new \InvalidArgumentException("File not found or not readable: {$path}");
138+ }
139+ return file_get_contents($path);
140+ })
141+ ->name('file_reader')
142+ ->description('Read file contents by path')
143+ ->mimeType('text/plain');
144+
111145// Register a prompt generator
112146Mcp::prompt([PromptService::class, 'generateWelcome'])
113147 ->name('welcome_user')
114148 ->description('Generate a personalized welcome message');
149+
150+ // Register a closure as a prompt
151+ Mcp::prompt(function(string $topic, string $tone = 'professional'): array {
152+ return [
153+ [
154+ 'role' => 'user',
155+ 'content' => "Write a {$tone} summary about {$topic}. Make it informative and engaging."
156+ ]
157+ ];
158+ })
159+ ->name('topic_summary')
160+ ->description('Generate topic summary prompts');
115161```
116162
117163** Available Fluent Methods:**
@@ -120,14 +166,23 @@ Mcp::prompt([PromptService::class, 'generateWelcome'])
120166- ` name(string $name) ` : Override the inferred name
121167- ` description(string $description) ` : Set a custom description
122168
169+ ** For Tools:**
170+ - ` annotations(ToolAnnotations $annotations) ` : Add MCP tool annotations
171+ - ` inputSchema(array $schema) ` : Define custom JSON schema for parameters
172+
123173** For Resources:**
124174- ` mimeType(string $mimeType) ` : Specify content type
125175- ` size(int $size) ` : Set content size in bytes
126- - ` annotations(array|Annotations $annotations) ` : Add MCP annotations
176+ - ` annotations(Annotations $annotations) ` : Add MCP annotations
177+
178+ ** For Resource Templates:**
179+ - ` mimeType(string $mimeType) ` : Specify content type
180+ - ` annotations(Annotations $annotations) ` : Add MCP annotations
127181
128182** Handler Formats:**
129183- ` [ClassName::class, 'methodName'] ` - Class method
130184- ` InvokableClass::class ` - Invokable class with ` __invoke() ` method
185+ - ` function(...) { ... } ` - Callables (v3.2+)
131186
132187### 2. Attribute-Based Discovery
133188
@@ -717,6 +772,69 @@ Create a dedicated log channel in `config/logging.php`:
717772
718773## Migration Guide
719774
775+ ### From v3.0 to v3.1
776+
777+ ** New Handler Types:**
778+
779+ Laravel MCP v3.1 introduces support for closure handlers, expanding beyond just class methods and invokable classes:
780+
781+ ``` php
782+ // v3.0 and earlier - Class-based handlers only
783+ Mcp::tool([CalculatorService::class, 'add'])
784+ ->name('add_numbers');
785+
786+ Mcp::tool(EmailService::class) // Invokable class
787+ ->name('send_email');
788+
789+ // v3.1+ - Now supports closures
790+ Mcp::tool(function(float $x, float $y): float {
791+ return $x * $y;
792+ })
793+ ->name('multiply')
794+ ->description('Multiply two numbers');
795+
796+ Mcp::resource('system://time', function(): string {
797+ return now()->toISOString();
798+ })
799+ ->name('current_time');
800+ ```
801+
802+ ** Input Schema Support:**
803+
804+ Tools can now define custom JSON schemas for parameter validation:
805+
806+ ``` php
807+ // v3.1+ - Custom input schema
808+ Mcp::tool([CalculatorService::class, 'calculate'])
809+ ->inputSchema([
810+ 'type' => 'object',
811+ 'properties' => [
812+ 'operation' => [
813+ 'type' => 'string',
814+ 'enum' => ['add', 'subtract', 'multiply', 'divide']
815+ ],
816+ 'numbers' => [
817+ 'type' => 'array',
818+ 'items' => ['type' => 'number'],
819+ 'minItems' => 2
820+ ]
821+ ],
822+ 'required' => ['operation', 'numbers']
823+ ]);
824+ ```
825+
826+ ** Enhanced Blueprint Methods:**
827+
828+ New fluent methods available on blueprints:
829+
830+ ``` php
831+ ->inputSchema(array $schema) // Define custom parameter schema
832+ ```
833+
834+ ** No Breaking Changes:**
835+
836+ All existing v3.0 code continues to work without modification. The new features are additive enhancements.
837+
720838### From v2.x to v3.x
721839
722840** Configuration Changes:**
0 commit comments