Створення MCP-серверів на PHP

Перекладено ШІ
Оригінал: Laravel News
Оновлено: 13 серпня, 2025
Модельний контекстний протокол (MCP) відкриває нові горизонти в інтеграції AI-додатків з PHP. Дізнайтеся, як легко створити сервер, що відповідає MCP, та які можливості відкриваються для вашого проєкту

Model Context Protocol (MCP) — це відкритий протокол, що стандартизує обмін структурованим контекстом і можливостями між клієнтами LLM та інструментами. PHP MCP Server SDK — це пакет, який спрощує створення серверів, що сумісні з MCP. Розроблений Кіріаном Обіквелу, він дозволяє без особливих зусиль перенести специфічні методи вашого додатка PHP в інструменти, ресурси або запити MCP.

# Основні можливості

# Практичний приклад: створення простого MCP-сервера файлової системи

Давайте розглянемо, як легко створити простий MCP-сервер. Ми розробимо браузер файлової системи, що дозволяє AI помічникам безпечно та ефективно взаємодіяти з вашими локальними файлами.

<?php
// src/FileSystemElements.php

declare(strict_types=1);

namespace App;

use PhpMcp\Server\Attributes\McpTool;
use PhpMcp\Server\Attributes\McpResource;
use PhpMcp\Server\Attributes\Schema;

/**
 * File System MCP Elements
 *
 * Simple file operations for educational purposes
 */
class FileSystemElements
{
    private string $basePath;

    public function __construct()
    {
        // Встановлює базовий шлях до поточної директорії для безпеки
        $this->basePath = getcwd();
    }

    /**
     * Список файлів у директорії
     */
    #[McpTool(name: 'ln_list_files')]
    public function listFiles(
        #[Schema(description: 'Шлях до директорії відносно бази', default: '.')]
        string $path = '.'
    ): array {
        $fullPath = $this->basePath . DIRECTORY_SEPARATOR . ltrim($path, '/\\');

        if (!is_dir($fullPath)) {
            throw new \InvalidArgumentException("'$path' не є директорією");
        }

        $files = [];
        foreach (scandir($fullPath) as $item) {
            if ($item === '.' || $item === '..') continue;

            $itemPath = $fullPath . DIRECTORY_SEPARATOR . $item;
            $files[] = [
                'name' => $item,
                'type' => is_dir($itemPath) ? 'директорія' : 'файл',
                'size' => is_file($itemPath) ? filesize($itemPath) : null
            ];
        }

        return ['path' => $path, 'items' => $files];
    }

    /**
     * Читання вмісту файлу
     */
    #[McpTool(name: 'ln_read_file')]
    public function readFile(
        #[Schema(description: 'Шлях до файлу для читання')]
        string $filePath
    ): string {
        $fullPath = $this->basePath . DIRECTORY_SEPARATOR . ltrim($filePath, '/\\');

        if (!file_exists($fullPath)) {
            throw new \InvalidArgumentException("Файл '$filePath' не існує");
        }

        if (!is_file($fullPath)) {
            throw new \InvalidArgumentException("'$filePath' не є файлом");
        }

        $content = file_get_contents($fullPath);
        if ($content === false) {
            throw new \RuntimeException("Не вдалося прочитати файл '$filePath'");
        }

        return $content;
    }

    /**
     * Пошук файлів за назвою
     */
    #[McpTool(name: 'ln_search_files')]
    public function searchFiles(
        #[Schema(description: 'Шаблон для пошуку (підтримує символи-замінники)')]
        string $pattern
    ): array {
        $results = [];
        $iterator = new \RecursiveIteratorIterator(
            new \RecursiveDirectoryIterator($this->basePath)
        );

        foreach ($iterator as $file) {
            if ($file->isFile() & fnmatch($pattern, $file->getFilename())) {
                $relativePath = str_replace($this->basePath . DIRECTORY_SEPARATOR, '', $file->getPathname());
                $results[] = [
                    'path' => $relativePath,
                    'name' => $file->getFilename(),
                    'size' => $file->getSize()
                ];
            }
        }

        return [
            'pattern' => $pattern,
            'results' => $results,
            'count' => count($results)
        ];
    }

    /**
     * Отримати інформацію про поточну робочу директорію
     */
    #[McpResource(
        uri: 'filesystem://info',
        mimeType: 'application/json'
    )]
    public function getFilesystemInfo(): array {
        return [
            'base_path' => $this->basePath,
            'working_directory' => getcwd(),
            'php_version' => PHP_VERSION,
            'os' => PHP_OS
        ];
    }
}

Налаштування сервера також є простим:

<?php
// server.php
declare(strict_types=1);

require_once __DIR__ . '/vendor/autoload.php';

use PhpMcp\Server\Server;
use PhpMcp\Server\Transports\StdioServerTransport;

try {
    // Створюємо сервер з виявленням атрибутів
    $server = Server::make()
        ->withServerInfo('Простий сервер файлової системи', '1.0.0')
        ->build();

    // Виявлення елементів MCP через атрибути
    $server->discover(
        basePath: __DIR__,
        scanDirs: ['src']
    );

    // Розпочинаємо прослуховування через stdio транспорт
    $transport = new StdioServerTransport();
    $server->listen($transport);

} catch (\Throwable $e) {
    fwrite(STDERR, "[ERROR] " . $e->getMessage() . "\n");
    exit(1);
}

Тепер, коли все готово, ви можете додати наш MCP сервер до обраного AI помічника. Припустимо, ми хочемо додати його до AI помічника в PHPStorm.

  1. Перейдіть до Settings > Tools > AI Assistant > Model Context Protocol (MCP).
  2. Натисніть "Додати" і налаштуйте свій сервер:
    • Назва: PHP File System Server
    • Команда: php
    • Аргументи: /absolute/path/to/your/server.php
    • Робоча директорія: корінь вашого проєкту

Тепер, відкривши AI Chat у PHP Storm, ми можемо почати використовувати наші MCP інструменти.

Наприклад, ми можемо виконати /ln_list_files ./data, і наш помічник використає наш MCP інструмент для списку файлів у директорії data.

Model Context Protocol означає фундаментальну зміну в способі створення AI-інтегрованих додатків. Замість того, щоб розробляти індивідуальні інтеграції для кожного AI помічника, ми можемо побудувати один раз і підключити у нас на всіх етапах завдяки стандарту MCP.

Бібліотека PHP-MCP робить цю концепцію доступною для PHP-розробників завдяки архітектурі та функціоналу, які легко використовувати. Чи розробляєте ви прості файлові інструменти, чи складну бізнес-логіку, бібліотека забезпечує базу, яка вам потрібна.

Готові розпочати розробку? Встановіть цей пакет за допомогою Composer:

composer require php-mcp/server

Відвідайте репозиторій PHP-MCP на GitHub, щоб переглянути повну документацію, додаткові приклади та ресурси для спільноти.

У наступній статті ми використаємо спеціальну версію SDK для Laravel для безшовної інтеграції з фреймворком, управління конфігураціями та команд Artisan.