PHPプロジェクトが持つデータやロジックをAIに公開し、エージェントが自律的に活用できる仕組みを構築したい——そんなニーズに応えるのがMCP(Model Context Protocol)サーバーです。2025年9月にPHP公式SDKがリリースされ、さらにLaravel 12.xでも公式サポートが追加されたことで、PHPエンジニアがMCPサーバーを構築するハードルは大幅に下がりました。

PHPでMCPサーバーを実装するには、大きく3つの選択肢があります。フレームワーク非依存の公式SDK(mcp/sdk)、Laravelエコシステムに統合されたlaravel/mcp、そしてComposerすら使わない**素のPHP(Vanilla PHP)**による最小実装です。プロジェクトの規模や技術スタックに合わせて最適な手段を選べます。

MCPの基本構造をPHP視点で整理する

MCPはAnthropicが策定したオープンプロトコルで、AIアプリケーション(クライアント)と外部システム(サーバー)を標準的なインターフェースで接続します。公式サイトでは「AIアプリケーション向けのUSB-Cポート」と表現されています(出典: modelcontextprotocol.io)。

MCPサーバーが提供できる機能は、3つのプリミティブに分類されます。

プリミティブ役割PHPでの利用例
ToolsLLMが能動的に呼び出す関数DB検索、API呼び出し、ファイル操作
ResourcesURIで特定される読み取り専用データ設定値、ドキュメント、ログ
Prompts再利用可能なプロンプトテンプレートコードレビュー指示、翻訳指示

通信方式(トランスポート)は3種類あり、プロトコルバージョン2025-03-26でStreamable HTTPが導入されました。最新のプロトコルバージョンは2025-11-25で、実験的なTasksプリミティブやOAuth 2.1のRFC 9728準拠などが追加されています(出典: MCP Changelog)。

トランスポート通信方式特徴
stdio標準入出力ローカル接続向け。Claude Desktop等が直接プロセスを起動
HTTP+SSEHTTP + Server-Sent Eventsネットワーク越し通信対応。現在は後方互換のため残存
Streamable HTTPHTTP ストリーミング再接続可能で新規プロジェクト推奨。ステートレス運用が可能

PHPで選べる3つのMCPパッケージ

PHP向けのMCPサーバー実装は複数存在します。主要な3パッケージの違いを整理します。

項目mcp/sdk(公式SDK)laravel/mcp(Laravel公式)Vanilla PHP(SDKなし)
開発元Symfony / PHP Foundation / AnthropicLaravel(Taylor Otwell)自前実装
PHPバージョン8.1以上8.2以上制限なし(推奨8.1+)
フレームワーク依存なしLaravel 11以上なし
インストールcomposer require mcp/sdkcomposer require laravel/mcpComposer不要
ツール定義方式PHP 8 AttributesArtisanスキャフォールドJSON-RPCハンドラ直書き
stdio対応ありあり(Artisanコマンド経由)あり
Streamable HTTPありあり(Webトランスポート)自前実装が必要
認証機能なし(自前実装)OAuth 2.1 / Sanctum内蔵なし
向いているケースフレームワーク非依存で汎用的に使いたいLaravelプロジェクトへの統合MCPプロトコルの学習、最小構成

コミュニティ発のphp-mcp/serverおよびphp-mcp/laravelも存在しますが、公式SDKのリリース後はメンテナンス体制の観点から上記3パッケージのいずれかを推奨します。

公式SDK(mcp/sdk)で実装する手順

公式PHP SDKはSymfony・PHP Foundation・Anthropicの3者が共同開発しており、フレームワークに依存しない汎用的なMCPサーバー構築が可能です(出典: PHP Foundation)。最新バージョンはv0.3.0(2026年1月11日リリース)です。

インストールと初期設定

composer require mcp/sdk

ツールの定義

PHP 8のAttributes構文を使い、メソッドに#[McpTool]を付与するだけでMCPツールとして登録できます。引数の型情報とdocblockからJSON Schemaが自動生成されるため、スキーマ定義を手書きする必要はありません。

<?php

use PhpMcp\Server\Attributes\McpTool;

class WeatherTools
{
    /**
     * 指定都市の天気情報を取得する
     *
     * @param string $city 都市名(例: Tokyo)
     */
    #[McpTool(name: 'get_weather', description: '指定都市の天気を取得')]
    public function getWeather(string $city): array
    {
        // 天気APIを呼び出す処理
        return [
            'city' => $city,
            'temperature' => 22,
            'condition' => 'sunny',
        ];
    }
}

リソースの定義

読み取り専用データの公開には#[McpResource]を使用します。

<?php

use PhpMcp\Server\Attributes\McpResource;

class AppResources
{
    #[McpResource(uri: 'config://app/version', name: 'app_version')]
    public function getVersion(): string
    {
        return '2.1.0';
    }
}

サーバーの起動(stdio)

stdioトランスポートで起動する場合のエントリポイントは次のとおりです。

<?php
// server.php

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

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

$server = Server::make()
    ->withTool(new WeatherTools())
    ->withResource(new AppResources())
    ->build();

$transport = new StdioServerTransport();
$server->listen($transport);

Claude Desktopやカーソルから利用する場合、MCP設定ファイルに以下のように登録します。

{
  "mcpServers": {
    "my-php-server": {
      "command": "php",
      "args": ["/path/to/server.php"]
    }
  }
}

Laravel公式パッケージで実装する手順

Laravel 12.xではlaravel/mcpが公式サポートされ、Artisanコマンドによるスキャフォールドやミドルウェア統合が利用できます(出典: Laravel公式ドキュメント)。最新バージョンはv0.5.5(2026年2月5日リリース)です。

インストール

composer require laravel/mcp
php artisan vendor:publish --tag=ai-routes

routes/ai.php にMCPサーバーのルーティングが生成されます。

ツールの作成

php artisan make:mcp-tool WeatherTool

生成されたクラスにロジックを追加します。

<?php

namespace App\Mcp\Tools;

use Laravel\Mcp\Tool;

class WeatherTool extends Tool
{
    public string $name = 'get_weather';
    public string $description = '都市名から天気情報を取得';

    public function parameters(): array
    {
        return [
            'city' => [
                'type' => 'string',
                'description' => '都市名',
                'required' => true,
            ],
        ];
    }

    public function handle(array $arguments): mixed
    {
        $city = $arguments['city'];
        // 天気API呼び出し
        return [
            'city' => $city,
            'temperature' => 22,
            'condition' => 'sunny',
        ];
    }
}

サーバーの登録

routes/ai.php でサーバーを登録します。

<?php

use Laravel\Mcp\Facades\Mcp;
use App\Mcp\Servers\WeatherServer;

// HTTPベース(リモートクライアント向け)
Mcp::web('/mcp/weather', WeatherServer::class)
    ->middleware(['throttle:mcp']);

// stdio(ローカルクライアント向け)
Mcp::local('weather', WeatherServer::class);

stdioで起動する場合は以下のコマンドを実行します。

php artisan mcp:start weather

認証の設定

Laravel MCPはOAuth 2.1(Laravel Passport経由)およびSanctumによる認証に対応しています。公式ドキュメントではOAuth(Passport)の利用が推奨されていますが、既にSanctumを導入済みのプロジェクトではSanctumのみでも運用可能です。リモートクライアントからの接続時にトークン認証を有効化できるため、本番環境でも安全にMCPサーバーを公開できます。

素のPHP(Vanilla PHP)で最小実装する

Composerもフレームワークも使わず、PHPファイル1枚でMCPサーバーを実装する方法もあります。MCPの内部プロトコル(JSON-RPC 2.0)を理解するのに最適なアプローチです。PHP Conference Japan 2025でもこの手法が紹介されました。

Streamable HTTPトランスポートによる最小実装

プロトコルバージョン2025-03-26で導入されたStreamable HTTPを使えば、通常のHTTPサーバー上でステートレスに動作するMCPサーバーを構築できます。

<?php
// mcp_server.php

header('Content-Type: application/json');

$input = json_decode(file_get_contents('php://input'), true);

if (!$input || !isset($input['method'])) {
    http_response_code(400);
    echo json_encode(['error' => 'Invalid request']);
    exit;
}

$method = $input['method'];
$id = $input['id'] ?? null;

match ($method) {
    'initialize' => respond($id, [
        'protocolVersion' => '2025-03-26',
        'capabilities' => ['tools' => ['listChanged' => false]],
        'serverInfo' => ['name' => 'php-minimal', 'version' => '1.0.0'],
    ]),
    'tools/list' => respond($id, [
        'tools' => [
            [
                'name' => 'current_time',
                'description' => '現在の日時を返す',
                'inputSchema' => [
                    'type' => 'object',
                    'properties' => [
                        'timezone' => [
                            'type' => 'string',
                            'description' => 'タイムゾーン(例: Asia/Tokyo)',
                        ],
                    ],
                ],
            ],
        ],
    ]),
    'tools/call' => handleToolCall($id, $input['params'] ?? []),
    'notifications/initialized' => null, // 通知は応答不要
    default => respondError($id, -32601, "Method not found: {$method}"),
};

function handleToolCall(mixed $id, array $params): void
{
    $toolName = $params['name'] ?? '';
    $args = $params['arguments'] ?? [];

    if ($toolName === 'current_time') {
        $tz = $args['timezone'] ?? 'Asia/Tokyo';
        $dt = new DateTimeImmutable('now', new DateTimeZone($tz));
        respond($id, [
            'content' => [
                ['type' => 'text', 'text' => $dt->format('Y-m-d H:i:s T')],
            ],
        ]);
        return;
    }

    respondError($id, -32602, "Unknown tool: {$toolName}");
}

function respond(mixed $id, array $result): void
{
    echo json_encode([
        'jsonrpc' => '2.0',
        'id' => $id,
        'result' => $result,
    ]);
    exit;
}

function respondError(mixed $id, int $code, string $message): void
{
    echo json_encode([
        'jsonrpc' => '2.0',
        'id' => $id,
        'error' => ['code' => $code, 'message' => $message],
    ]);
    exit;
}

PHPビルトインサーバーで起動できます。

php -S localhost:8080 mcp_server.php

この方式はMCPの仕組みを学ぶ目的に適していますが、セッション管理やエラーハンドリングを自前で実装する必要があるため、本番運用には公式SDKまたはLaravelパッケージの利用を推奨します。

トランスポート方式の選定基準

MCPサーバーをどのトランスポートで提供するかは、利用シーンに応じて判断します。

判断基準stdioStreamable HTTP
接続元ローカルマシン上のクライアントネットワーク越しのクライアント
セッション管理プロセス単位で自動分離サーバー側で明示的に管理
デプロイ先開発マシン、CI環境Webサーバー、クラウド
認証不要(ローカル前提)OAuth 2.1等が必要
対応クライアント例Claude Desktop, Claude Code, CursorWebアプリ、リモートエージェント
PHP実行環境CLIのみCLI + Webサーバー

stdioはローカル開発やCI連携で手軽に使え、Streamable HTTPは本番環境やチーム共有のサーバーに向いています。HTTP+SSEは後方互換のために残されていますが、新規実装ではStreamable HTTPを選択してください。

IDE連携の設定方法

MCPサーバーを構築したら、各種AIクライアントから接続して利用します。主要なIDEおよびツールでの設定方法を整理します。

Claude Desktop / Claude Code

claude_desktop_config.json(Claude Desktop)または.claude/settings.json(Claude Code)に設定を追加します。

{
  "mcpServers": {
    "my-php-tools": {
      "command": "php",
      "args": ["/path/to/server.php"]
    }
  }
}

Cursor

Cursorの設定画面から「MCP Servers」を開き、同様のJSON設定を追加します。Streamable HTTP接続の場合はURLを直接指定します。

{
  "mcpServers": {
    "my-php-tools": {
      "url": "http://localhost:8080/mcp"
    }
  }
}

VS Code(GitHub Copilot)

VS Codeでは.vscode/mcp.jsonまたはSettings UIから設定します。GitHub Copilotのエージェントモードで自動的にMCPツールが利用可能になります。

{
  "servers": {
    "my-php-tools": {
      "command": "php",
      "args": ["/path/to/server.php"]
    }
  }
}

PhpStorm(JetBrains)

PhpStorm 2025.2以降ではIDE自体がMCPサーバーとして動作し、外部のAIクライアントにIDE機能を提供します。設定は Settings → Tools → AI Assistant → MCP Server から有効化できます。PhpStormが提供するMCPツールには、ファイル検索・コード分析・実行構成の起動などが含まれます。

逆にPhpStormからPHP製MCPサーバーを利用する場合は、JetBrains AI Assistantの設定からMCPサーバーを追加します。

実装時に押さえておきたいポイント

エラーハンドリング

MCPプロトコルはJSON-RPC 2.0に準拠しているため、エラーレスポンスも仕様に沿って返す必要があります。標準エラーコードは以下のとおりです。

コード意味
-32700JSONパースエラー
-32600不正なリクエスト
-32601メソッド未実装
-32602不正なパラメータ
-32603内部エラー

公式SDKを利用すれば、これらのエラーハンドリングは内部で自動処理されます。

セキュリティの考慮点

MCPサーバーはLLMに対して強力な操作権限を与えるため、以下の対策が重要です。

  • 入力バリデーション: ツールに渡される引数は必ず検証する
  • 権限の最小化: ツールが操作できる範囲を必要最小限に制限する
  • 認証の導入: リモート公開時はOAuth 2.1やトークン認証を必ず設定する
  • ログ記録: ツール実行のリクエスト・レスポンスをログに残す

パフォーマンスの最適化

PHP SDKはReactPHPを採用して非同期処理を実現しています。stdio接続ではプロセスが常駐するため、メモリリークに注意が必要です。Streamable HTTP接続はリクエストごとにプロセスが起動するPHP-FPMとの相性が良く、従来のPHPホスティング環境でもデプロイしやすい構成です。

まとめ

PHPでMCPサーバーを構築する手段は、プロジェクトの規模と技術スタックに応じて選択できます。

  • 公式SDK(mcp/sdk): フレームワーク非依存で汎用性が高い。Symfony / PHP Foundation / Anthropicの3者共同開発で信頼性も十分。PHP 8.1以上の環境であればどのプロジェクトでも導入可能です
  • Laravel公式(laravel/mcp): Laravelプロジェクトなら最も効率的。ArtisanコマンドによるスキャフォールドやOAuth認証、ミドルウェア統合などLaravelの強みをそのまま活かせます
  • Vanilla PHP: 依存ゼロでMCPプロトコルの仕組みを深く理解できる手段。学習目的やPoCには有効ですが、本番運用にはSDKの利用を推奨します

公式SDKのGitHubリポジトリは modelcontextprotocol/php-sdk で公開されており、Laravel公式パッケージのドキュメントは laravel.com/docs/12.x/mcp から参照できます。