PHP code example of php-mcp / laravel

1. Go to this page and download the library: Download php-mcp/laravel library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

php-mcp / laravel example snippets




use PhpMcp\Laravel\Facades\Mcp;
use App\Services\{CalculatorService, UserService, EmailService, PromptService};

// Register a simple tool
Mcp::tool([CalculatorService::class, 'add'])
    ->name('add_numbers')
    ->description('Add two numbers together');

// Register an invokable class as a tool
Mcp::tool(EmailService::class)
    ->description('Send emails to users');

// Register a resource with metadata
Mcp::resource('config://app/settings', [UserService::class, 'getAppSettings'])
    ->name('app_settings')
    ->description('Application configuration settings')
    ->mimeType('application/json')
    ->size(1024);

// Register a resource template for dynamic content
Mcp::resourceTemplate('user://{userId}/profile', [UserService::class, 'getUserProfile'])
    ->name('user_profile')
    ->description('Get user profile by ID')
    ->mimeType('application/json');

// Register a prompt generator
Mcp::prompt([PromptService::class, 'generateWelcome'])
    ->name('welcome_user')
    ->description('Generate a personalized welcome message');



namespace App\Services;

use PhpMcp\Server\Attributes\{McpTool, McpResource, McpResourceTemplate, McpPrompt};

class UserService
{
    /**
     * Create a new user account.
     */
    #[McpTool(name: 'create_user')]
    public function createUser(string $email, string $password, string $role = 'user'): array
    {
        // Create user logic
        return [
            'id' => 123,
            'email' => $email,
            'role' => $role,
            'created_at' => now()->toISOString(),
        ];
    }

    /**
     * Get application configuration.
     */
    #[McpResource(
        uri: 'config://app/settings',
        mimeType: 'application/json'
    )]
    public function getAppSettings(): array
    {
        return [
            'theme' => config('app.theme', 'light'),
            'timezone' => config('app.timezone'),
            'features' => config('app.features', []),
        ];
    }

    /**
     * Get user profile by ID.
     */
    #[McpResourceTemplate(
        uriTemplate: 'user://{userId}/profile',
        mimeType: 'application/json'
    )]
    public function getUserProfile(string $userId): array
    {
        return [
            'id' => $userId,
            'name' => 'John Doe',
            'email' => '[email protected]',
            'profile' => [
                'bio' => 'Software developer',
                'location' => 'New York',
            ],
        ];
    }

    /**
     * Generate a welcome message prompt.
     */
    #[McpPrompt(name: 'welcome_user')]
    public function generateWelcome(string $username, string $role = 'user'): array
    {
        return [
            [
                'role' => 'user',
                'content' => "Create a personalized welcome message for {$username} with role {$role}. Be warm and professional."
            ]
        ];
    }
}

// Routes are automatically registered at:
// GET  /mcp       - Streamable connection endpoint
// POST /mcp       - Message sending endpoint  
// DELETE /mcp     - Session termination endpoint

// Legacy mode (if enabled):
// GET  /mcp/sse   - Server-Sent Events endpoint
// POST /mcp/message - Message sending endpoint

// bootstrap/app.php
->withMiddleware(function (Middleware $middleware) {
    $middleware->validateCsrfTokens(except: [
        'mcp',           // For streamable transport (default)
        'mcp/*',   // For legacy transport (if enabled)
    ]);
})

// app/Http/Middleware/VerifyCsrfToken.php
protected $except = [
    'mcp',           // For streamable transport (default)
    'mcp/*',   // For legacy transport (if enabled)
];

'http_integrated' => [
    'enabled' => true,
    'route_prefix' => 'mcp',           // URL prefix
    'middleware' => ['api'],           // Applied middleware
    'domain' => 'api.example.com',     // Optional domain
    'legacy' => false,                 // Use legacy SSE transport instead
],

'http_dedicated' => [
    'enabled' => true,
    'host' => '127.0.0.1',              // Bind address
    'port' => 8090,                     // Port number
    'path_prefix' => 'mcp',             // URL path prefix
    'legacy' => false,                  // Use legacy transport
    'enable_json_response' => false,    // JSON mode vs SSE streaming
    'event_store' => null,              // Event store for resumability
    'ssl_context_options' => [],        // SSL configuration
],

'enable_json_response' => true,  // Returns immediate JSON responses
'enable_json_response' => false, // Uses SSE streaming (default)

use PhpMcp\Laravel\Events\{ToolsListChanged, ResourcesListChanged, PromptsListChanged};

// Notify clients that available tools have changed
ToolsListChanged::dispatch();

// Notify about resource list changes
ResourcesListChanged::dispatch();

// Notify about prompt list changes  
PromptsListChanged::dispatch();

use PhpMcp\Laravel\Events\ResourceUpdated;

// Update a file and notify subscribers
file_put_contents('/path/to/config.json', json_encode($newConfig));
ResourceUpdated::dispatch('file:///path/to/config.json');

// Update database content and notify
User::find(123)->update(['status' => 'active']);
ResourceUpdated::dispatch('user://123/profile');

use PhpMcp\Server\Attributes\Schema;

class PostService
{
    public function createPost(
        #[Schema(minLength: 5, maxLength: 200)]
        string $title,
        
        #[Schema(minLength: 10)]
        string $content,
        
        #[Schema(enum: ['draft', 'published', 'archived'])]
        string $status = 'draft',
        
        #[Schema(type: 'array', items: ['type' => 'string'])]
        array $tags = []
    ): array {
        return Post::create([
            'title' => $title,
            'content' => $content,
            'status' => $status,
            'tags' => $tags,
        ])->toArray();
    }
}

use PhpMcp\Server\Contracts\CompletionProviderInterface;
use PhpMcp\Server\Contracts\SessionInterface;
use PhpMcp\Server\Attributes\CompletionProvider;

class UserIdCompletionProvider implements CompletionProviderInterface
{
    public function getCompletions(string $currentValue, SessionInterface $session): array
    {
        return User::where('username', 'like', $currentValue . '%')
            ->limit(10)
            ->pluck('username')
            ->toArray();
    }
}

class UserService
{
    public function getUserData(
        #[CompletionProvider(UserIdCompletionProvider::class)]
        string $userId
    ): array {
        return User::where('username', $userId)->first()->toArray();
    }
}

class OrderService
{
    public function __construct(
        private PaymentGateway $gateway,
        private NotificationService $notifications,
        private LoggerInterface $logger
    ) {}

    #[McpTool(name: 'process_order')]
    public function processOrder(array $orderData): array
    {
        $this->logger->info('Processing order', $orderData);
        
        $payment = $this->gateway->charge($orderData['amount']);
        
        if ($payment->successful()) {
            $this->notifications->sendOrderConfirmation($orderData['email']);
            return ['status' => 'success', 'order_id' => $payment->id];
        }
        
        throw new \Exception('Payment failed: ' . $payment->error);
    }
}

#[McpTool(name: 'get_user')]
public function getUser(int $userId): array
{
    $user = User::find($userId);
    
    if (!$user) {
        throw new \InvalidArgumentException("User with ID {$userId} not found");
    }
    
    if (!$user->isActive()) {
        throw new \RuntimeException("User account is deactivated");
    }
    
    return $user->toArray();
}

// config/mcp.php
'logging' => [
    'channel' => 'mcp',  // Use dedicated log channel
    'level' => 'debug',  // Set appropriate log level
],

'channels' => [
    'mcp' => [
        'driver' => 'daily',
        'path' => storage_path('logs/mcp.log'),
        'level' => env('MCP_LOG_LEVEL', 'info'),
        'days' => 14,
    ],
],

// Old structure
'capabilities' => [
    'tools' => ['enabled' => true, 'listChanged' => true],
    'resources' => ['enabled' => true, 'subscribe' => true],
],

// New structure  
'capabilities' => [
    'tools' => true,
    'toolsListChanged' => true,
    'resources' => true,
    'resourcesSubscribe' => true,
],

// Old: Basic configuration
'session' => [
    'driver' => 'cache',
    'ttl' => 3600,
],

// New: Enhanced configuration
'session' => [
    'driver' => 'cache',
    'ttl' => 3600,
    'store' => config('cache.default'),
    'lottery' => [2, 100],
],

class EcommerceService
{
    #[McpTool(name: 'get_product_info')]
    public function getProductInfo(int $productId): array
    {
        return Product::with(['category', 'reviews'])
            ->findOrFail($productId)
            ->toArray();
    }

    #[McpTool(name: 'search_products')]
    public function searchProducts(
        string $query,
        ?string $category = null,
        int $limit = 10
    ): array {
        return Product::search($query)
            ->when($category, fn($q) => $q->where('category', $category))
            ->limit($limit)
            ->get()
            ->toArray();
    }

    #[McpResource(uri: 'config://store/settings', mimeType: 'application/json')]
    public function getStoreSettings(): array
    {
        return [
            'currency' => config('store.currency'),
            'tax_rate' => config('store.tax_rate'),
            'shipping_zones' => config('store.shipping_zones'),
        ];
    }
}

class ContentService
{
    #[McpResourceTemplate(uriTemplate: 'post://{slug}', mimeType: 'text/markdown')]
    public function getPostContent(string $slug): string
    {
        return Post::where('slug', $slug)
            ->firstOrFail()
            ->markdown_content;
    }

    #[McpPrompt(name: 'content_summary')]
    public function generateContentSummary(string $postSlug, int $maxWords = 50): array
    {
        $post = Post::where('slug', $postSlug)->firstOrFail();
        
        return [
            [
                'role' => 'user',
                'content' => "Summarize this blog post in {$maxWords} words or less:\n\n{$post->content}"
            ]
        ];
    }
}

class ApiService
{
    #[McpTool(name: 'send_notification')]
    public function sendNotification(
        #[Schema(format: 'email')]
        string $email,
        
        string $subject,
        string $message
    ): array {
        $response = Http::post('https://api.emailservice.com/send', [
            'to' => $email,
            'subject' => $subject,
            'body' => $message,
        ]);

        if ($response->failed()) {
            throw new \RuntimeException('Failed to send notification: ' . $response->body());
        }

        return $response->json();
    }
}
bash
composer 
bash
php artisan vendor:publish --provider="PhpMcp\Laravel\McpServiceProvider" --tag="mcp-config"
bash
php artisan vendor:publish --provider="PhpMcp\Laravel\McpServiceProvider" --tag="mcp-migrations"
php artisan migrate
bash
php artisan mcp:serve --transport=stdio
bash
# Start dedicated server
php artisan mcp:serve --transport=http

# With custom configuration
php artisan mcp:serve --transport=http \
    --host=0.0.0.0 \
    --port=8091 \
    --path-prefix=mcp_api
bash
# Interactive mode (prompts for transport selection)
php artisan mcp:serve

# STDIO transport
php artisan mcp:serve --transport=stdio

# HTTP transport with defaults
php artisan mcp:serve --transport=http

# HTTP transport with custom settings
php artisan mcp:serve --transport=http \
    --host=0.0.0.0 \
    --port=8091 \
    --path-prefix=api/mcp