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での利用例 |
|---|---|---|
| Tools | LLMが能動的に呼び出す関数 | DB検索、API呼び出し、ファイル操作 |
| Resources | URIで特定される読み取り専用データ | 設定値、ドキュメント、ログ |
| Prompts | 再利用可能なプロンプトテンプレート | コードレビュー指示、翻訳指示 |
通信方式(トランスポート)は3種類あり、プロトコルバージョン2025-03-26でStreamable HTTPが導入されました。最新のプロトコルバージョンは2025-11-25で、実験的なTasksプリミティブやOAuth 2.1のRFC 9728準拠などが追加されています(出典: MCP Changelog)。
| トランスポート | 通信方式 | 特徴 |
|---|---|---|
| stdio | 標準入出力 | ローカル接続向け。Claude Desktop等が直接プロセスを起動 |
| HTTP+SSE | HTTP + Server-Sent Events | ネットワーク越し通信対応。現在は後方互換のため残存 |
| Streamable HTTP | HTTP ストリーミング | 再接続可能で新規プロジェクト推奨。ステートレス運用が可能 |
PHPで選べる3つのMCPパッケージ
PHP向けのMCPサーバー実装は複数存在します。主要な3パッケージの違いを整理します。
| 項目 | mcp/sdk(公式SDK) | laravel/mcp(Laravel公式) | Vanilla PHP(SDKなし) |
|---|---|---|---|
| 開発元 | Symfony / PHP Foundation / Anthropic | Laravel(Taylor Otwell) | 自前実装 |
| PHPバージョン | 8.1以上 | 8.2以上 | 制限なし(推奨8.1+) |
| フレームワーク依存 | なし | Laravel 11以上 | なし |
| インストール | composer require mcp/sdk | composer require laravel/mcp | Composer不要 |
| ツール定義方式 | PHP 8 Attributes | Artisanスキャフォールド | 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サーバーをどのトランスポートで提供するかは、利用シーンに応じて判断します。
| 判断基準 | stdio | Streamable HTTP |
|---|---|---|
| 接続元 | ローカルマシン上のクライアント | ネットワーク越しのクライアント |
| セッション管理 | プロセス単位で自動分離 | サーバー側で明示的に管理 |
| デプロイ先 | 開発マシン、CI環境 | Webサーバー、クラウド |
| 認証 | 不要(ローカル前提) | OAuth 2.1等が必要 |
| 対応クライアント例 | Claude Desktop, Claude Code, Cursor | Webアプリ、リモートエージェント |
| 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に準拠しているため、エラーレスポンスも仕様に沿って返す必要があります。標準エラーコードは以下のとおりです。
| コード | 意味 |
|---|---|
| -32700 | JSONパースエラー |
| -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 から参照できます。