| name | mcp-development |
| description | Use this skill for Laravel MCP development only. Trigger when creating or editing MCP tools, resources, prompts, or servers in Laravel projects. Covers: artisan make:mcp-* generators, mcp:inspector, routes/ai.php, Tool/Resource/Prompt classes, schema validation, shouldRegister(), OAuth setup, URI templates, read-only attributes, and MCP debugging. Do not use for non-Laravel MCP projects or generic AI features without MCP. |
| license | MIT |
| metadata | {"author":"laravel"} |
MCP Development
Documentation First
CRITICAL: Always use search-docs BEFORE writing MCP code. The documentation is version-specific, comprehensive, and always up-to-date.
search-docs(['mcp tools', 'mcp resources', 'mcp validation'])
Quick Reference
Artisan Commands
Create MCP Primitives
php artisan make:mcp-tool ToolName
php artisan make:mcp-resource ResourceName
php artisan make:mcp-prompt PromptName
php artisan make:mcp-server ServerName
Basic Tool Implementation
use Illuminate\Contracts\JsonSchema\JsonSchema;
use Laravel\Mcp\Request;
use Laravel\Mcp\Response;
use Laravel\Mcp\Server\Tool;
class MyTool extends Tool
{
protected string $description = 'Tool description for LLM';
public function schema(JsonSchema $schema): array
{
return [
'param' => $schema->string()->required(),
];
}
public function handle(Request $request): Response
{
return Response::text($request->get('param'));
}
}
Basic Resource Implementation
use Laravel\Mcp\Response;
use Laravel\Mcp\Server\Resource;
class MyResource extends Resource
{
protected string $description = 'Resource description';
protected string $uri = 'file://path/to/resource';
protected string $mimeType = 'text/markdown';
public function handle(): Response
{
return Response::text($content);
}
}
Response Methods
Response::text('Text content');
Response::error('Error message');
Response::structured(['key' => 'value']);
Testing MCP Primitives
Test tools, resources, and prompts directly on their server:
$response = MyServer::tool(MyTool::class, ['param' => 'value']);
$response->assertOk()->assertSee('Expected text');
$response = MyServer::actingAs($user)->tool(MyTool::class, [...]);
$response->assertOk();
$response->assertSee('text');
$response->assertHasErrors();
$response->assertHasNoErrors();
$response->assertName('tool-name');
$response->assertSentNotification('event/type', ['data' => 'value']);
MCP Inspector
Test interactively using the inspector:
php artisan mcp:inspector mcp/my-server
php artisan mcp:inspector my-server
Available Features
The following features exist—use search-docs for implementation details:
- Tools:
schema(), validation, annotations (#[IsReadOnly], #[IsDestructive], etc.)
- Resources: URI templates (
HasUriTemplate), Dynamic resources
- Prompts: Arguments, multi-message responses
- All primitives: Dependency injection,
shouldRegister(), validation
- Responses: Text, error, structured, streaming, metadata
- Server registration: Web routes, local routes, OAuth
Critical Imports
use Laravel\Mcp\Request;
use Laravel\Mcp\Response;
use Laravel\Mcp\Server\Tool;
use Laravel\Mcp\Server\Resource;
use Laravel\Mcp\Server\Prompt;
use Illuminate\Contracts\JsonSchema\JsonSchema;
Common Pitfalls
- Not using
search-docs before implementation
- Wrong imports:
Laravel\Mcp\Server\Request (wrong) vs Laravel\Mcp\Request (correct)
- Forgetting
schema() method for tools with parameters
- Missing required properties:
$description, $uri, $mimeType
- Wrong response pattern:
new Response() instead of Response::text()
- Running
mcp:start command locally (hangs waiting for stdin)