はじめにIntroduction
Laravel MCPは、Model Context Protocolを介してAIクライアントがLaravelアプリケーションと対話するための、シンプルでエレガントな方法を提供します。アプリケーションとのAIによる対話を可能にするサーバ、ツール、リソース、プロンプトを定義するための、表現力豊かで流れるようなインターフェイスを提供します。Laravel MCP[https://github.com/laravel/mcp] provides a simple and elegant way for AI clients to interact with your Laravel application through the Model Context Protocol[https://modelcontextprotocol.io/docs/getting-started/intro]. It offers an expressive, fluent interface for defining servers, tools, resources, and prompts that enable AI-powered interactions with your application.
インストールInstallation
始めるには、Composerパッケージマネージャを使い、プロジェクトにLaravel MCPをインストールしてください:To get started, install Laravel MCP into your project using the Composer package manager:
composer require laravel/mcp
ルートの公開Publishing Routes
Laravel MCPをインストールした後、vendor:publish
Artisanコマンドを実行して、MCPサーバを定義するroutes/ai.php
ファイルを公開してください:After installing Laravel MCP, execute the vendor:publish
Artisan command to publish the routes/ai.php
file where you will define your MCP servers:
php artisan vendor:publish --tag=ai-routes
このコマンドは、アプリケーションのroutes
ディレクトリにroutes/ai.php
ファイルを作成します。このファイルはMCPサーバを登録するために使用します。This command creates the routes/ai.php
file in your application's routes
directory, which you will use to register your MCP servers.
サーバの作成Creating Servers
make:mcp-server
Artisanコマンドを使用してMCPサーバを作成できます。サーバは、ツール、リソース、プロンプトのようなMCP機能をAIクライアントに公開する中心的な通信ポイントとして機能します:You can create an MCP server using the make:mcp-server
Artisan command. Servers act as the central communication point that exposes MCP capabilities like tools, resources, and prompts to AI clients:
php artisan make:mcp-server WeatherServer
このコマンドはapp/Mcp/Servers
ディレクトリに新しいサーバクラスを作成します。生成されたサービスクラスは、Laravel MCPのベースであるLaravel\Mcp\Server
クラスを拡張し、ツール、リソース、プロンプトを登録するためのプロパティを提供します:This command will create a new server class in the app/Mcp/Servers
directory. The generated server class extends Laravel MCP's base Laravel\Mcp\Server
class and provides properties for registering tools, resources, and prompts:
<?php
namespace App\Mcp\Servers;
use Laravel\Mcp\Server;
class WeatherServer extends Server
{
/**
* MCPサーバ名
*/
protected string $name = 'Weather Server';
/**
* MCPサーバのバージョン
*/
protected string $version = '1.0.0';
/**
* LLMへのMCPサーバの指示
*/
protected string $instructions = 'This server provides weather information and forecasts.';
/**
* このMCPサーバで登録するツール
*
* @var array<int, class-string<\Laravel\Mcp\Server\Tool>>
*/
protected array $tools = [
// GetCurrentWeatherTool::class,
];
/**
* このMCPサーバで登録するリソース
*
* @var array<int, class-string<\Laravel\Mcp\Server\Resource>>
*/
protected array $resources = [
// WeatherGuidelinesResource::class,
];
/**
* このMCPサーバで登録するプロンプト
*
* @var array<int, class-string<\Laravel\Mcp\Server\Prompt>>
*/
protected array $prompts = [
// DescribeWeatherPrompt::class,
];
}
サーバの登録Server Registration
サーバを作成したら、アクセス可能にするためにroutes/ai.php
ファイルに登録する必要があります。Laravel MCPはサーバを登録するために2つのメソッドを提供します。HTTPでアクセス可能なサーバ用のweb
と、コマンドラインサーバ用のlocal
です。Once you've created a server, you must register it in your routes/ai.php
file to make it accessible. Laravel MCP provides two methods for registering servers: web
for HTTP-accessible servers and local
for command-line servers.
WebサーバWeb Servers
Webサーバは最も一般的なタイプのサーバであり、HTTP POSTリクエストを介してアクセスできるため、リモートAIクライアントやWebベースの統合に最適です。Webサーバを登録するにはweb
メソッドを使用します:Web servers are the most common types of servers and are accessible via HTTP POST requests, making them ideal for remote AI clients or web-based integrations. Register a web server using the web
method:
use App\Mcp\Servers\WeatherServer;
use Laravel\Mcp\Facades\Mcp;
Mcp::web('/mcp/weather', WeatherServer::class);
通常のルートと同様に、ミドルウェアを適用してWebサーバを保護できます:Just like normal routes, you may apply middleware to protect your web servers:
Mcp::web('/mcp/weather', WeatherServer::class)
->middleware(['throttle:mcp']);
ローカルサーバLocal Servers
ローカルサーバはArtisanコマンドとして実行され、Laravel BoostのようなローカルAIアシスタントの統合を構築するのに最適です。ローカルサーバを登録するにはlocal
メソッドを使用します:Local servers run as Artisan commands, perfect for building local AI assistant integrations like Laravel Boost[/docs/{{version}}/installation#installing-laravel-boost]. Register a local server using the local
method:
use App\Mcp\Servers\WeatherServer;
use Laravel\Mcp\Facades\Mcp;
Mcp::local('weather', WeatherServer::class);
登録後は、通常、mcp:start
Artisanコマンドを手作業で実行する必要はありません。代わりに、MCPクライアント(AIエージェント)を設定してサーバを起動するか、MCP Inspectorを使用してください。Once registered, you should not typically need to manually run the mcp:start
Artisan command yourself. Instead, configure your MCP client (AI agent) to start the server or use the MCP Inspector[#mcp-inspector].
ツールTools
ツールを使用すると、サーバはAIクライアントが呼び出せる機能を公開できます。これにより、言語モデルはアクションの実行、コードの実行、または外部システムとの対話が可能になります:Tools enable your server to expose functionality that AI clients can call. They allow language models to perform actions, run code, or interact with external systems:
<?php
namespace App\Mcp\Tools;
use Illuminate\JsonSchema\JsonSchema;
use Laravel\Mcp\Request;
use Laravel\Mcp\Response;
use Laravel\Mcp\Server\Tool;
class CurrentWeatherTool extends Tool
{
/**
* ツールの説明
*/
protected string $description = 'Fetches the current weather forecast for a specified location.';
/**
* ツールリクエストの処理
*/
public function handle(Request $request): Response
{
$location = $request->get('location');
// 天気を取得...
return Response::text('The weather is...');
}
/**
* ツールの入力スキーマの取得
*
* @return array<string, \Illuminate\JsonSchema\JsonSchema>
*/
public function schema(JsonSchema $schema): array
{
return [
'location' => $schema->string()
->description('The location to get the weather for.')
->required(),
];
}
}
ツールの作成Creating Tools
ツールを作成するには、make:mcp-tool
Artisanコマンドを実行します:To create a tool, run the make:mcp-tool
Artisan command:
php artisan make:mcp-tool CurrentWeatherTool
ツールを作成した後、サーバの$tools
プロパティに登録してください:After creating a tool, register it in your server's $tools
property:
<?php
namespace App\Mcp\Servers;
use App\Mcp\Tools\CurrentWeatherTool;
use Laravel\Mcp\Server;
class WeatherServer extends Server
{
/**
* このMCPサーバで登録するツール
*
* @var array<int, class-string<\Laravel\Mcp\Server\Tool>>
*/
protected array $tools = [
CurrentWeatherTool::class,
];
}
ツール名、タイトル、説明Tool Name, Title, and Description
デフォルトでは、ツール名とタイトルはクラス名から派生します。たとえば、CurrentWeatherTool
の名前はcurrent-weather
、タイトルはCurrent Weather Tool
になります。ツールの$name
および$title
プロパティを定義することで、これらの値をカスタマイズできます:By default, the tool's name and title are derived from the class name. For example, CurrentWeatherTool
will have a name of current-weather
and a title of Current Weather Tool
. You may customize these values by defining the tool's $name
and $title
properties:
class CurrentWeatherTool extends Tool
{
/**
* ツール名
*/
protected string $name = 'get-optimistic-weather';
/**
* ツールのタイトル
*/
protected string $title = 'Get Optimistic Weather Forecast';
// ...
}
ツールの説明は自動的に生成されません。ツールに$description
プロパティを定義して、常に意味のある説明を提供すべきです:Tool descriptions are not automatically generated. You should always provide a meaningful description by defining a $description
property on your tool:
class CurrentWeatherTool extends Tool
{
/**
* ツールの説明
*/
protected string $description = 'Fetches the current weather forecast for a specified location.';
//
}
[!NOTE] The description is a critical part of the tool's metadata, as it helps AI models understand when and how to use the tool effectively.
Note: 説明はツールのメタデータの重要な部分であり、AIモデルがツールをいつ、どのように効果的に使用するかを理解するのに役立ちます。
ツールの入力スキーマTool Input Schemas
ツールは入力スキーマを定義して、AIクライアントから受け入れる引数を指定できます。LaravelのIlluminate\JsonSchema\JsonSchema
ビルダを使用して、ツールの入力要件を定義してください:Tools can define input schemas to specify what arguments they accept from AI clients. Use Laravel's Illuminate\JsonSchema\JsonSchema
builder to define your tool's input requirements:
<?php
namespace App\Mcp\Tools;
use Illuminate\JsonSchema\JsonSchema;
use Laravel\Mcp\Server\Tool;
class CurrentWeatherTool extends Tool
{
/**
* ツールの入力スキーマの取得
*
* @return array<string, JsonSchema>
*/
public function schema(JsonSchema $schema): array
{
return [
'location' => $schema->string()
->description('The location to get the weather for.')
->required(),
'units' => $schema->enum(['celsius', 'fahrenheit'])
->description('The temperature units to use.')
->default('celsius'),
];
}
}
ツール引数のバリデーションValidating Tool Arguments
JSON Schema定義はツール引数の基本的な構造を提供しますが、より複雑なバリデーションルールを適用したい場合もあるでしょう。JSON Schema definitions provide a basic structure for tool arguments, but you may also want to enforce more complex validation rules.
Laravel MCPは、Laravelのバリデーション機能とシームレスに連携します。ツールのhandle
メソッド内で、受信したツール引数をバリデーションできます。Laravel MCP integrates seamlessly with Laravel's validation features[/docs/{{version}}/validation]. You may validate incoming tool arguments within your tool's handle
method:
<?php
namespace App\Mcp\Tools;
use Laravel\Mcp\Request;
use Laravel\Mcp\Response;
use Laravel\Mcp\Server\Tool;
class CurrentWeatherTool extends Tool
{
/**
* ツールリクエストの処理
*/
public function handle(Request $request): Response
{
$validated = $request->validate([
'location' => 'required|string|max:100',
'units' => 'in:celsius,fahrenheit',
]);
// バリデーションされた引数を使用して天気データを取得...
}
}
バリデーションが失敗した場合、AIクライアントはあなたが提供するエラーメッセージに基づいて動作します。そのため、明確で実行可能なエラーメッセージを提供することが重要です。On validation failure, AI clients will act based on the error messages you provide. As such, is critical to provide clear and actionable error messages:
$validated = $request->validate([
'location' => ['required','string','max:100'],
'units' => 'in:celsius,fahrenheit',
],[
'location.required' => 'You must specify a location to get the weather for. For example, "New York City" or "Tokyo".',
'units.in' => 'You must specify either "celsius" or "fahrenheit" for the units.',
]);
ツールの依存注入Tool Dependency Injection
Laravelのサービスコンテナは、すべてのツールを解決するために使用されます。その結果、コンストラクタでツールが必要とするあらゆる依存関係をタイプヒントで指定できます。宣言された依存関係は自動的に解決され、ツールインスタンスに注入されます。The Laravel service container[/docs/{{version}}/container] is used to resolve all tools. As a result, you are able to type-hint any dependencies your tool may need in its constructor. The declared dependencies will automatically be resolved and injected into the tool instance:
<?php
namespace App\Mcp\Tools;
use App\Repositories\WeatherRepository;
use Laravel\Mcp\Server\Tool;
class CurrentWeatherTool extends Tool
{
/**
* 新しいツールインスタンスの生成
*/
public function __construct(
protected WeatherRepository $weather,
) {}
// ...
}
コンストラクタインジェクションに加えて、ツールのhandle()
メソッドで依存関係をタイプヒントで指定することもできます。メソッドが呼び出されると、サービスコンテナが自動的に依存関係を解決し、注入します。In addition to constructor injection, you may also type-hint dependencies in your tool's handle()
method. The service container will automatically resolve and inject the dependencies when the method is called:
<?php
namespace App\Mcp\Tools;
use App\Repositories\WeatherRepository;
use Laravel\Mcp\Request;
use Laravel\Mcp\Response;
use Laravel\Mcp\Server\Tool;
class CurrentWeatherTool extends Tool
{
/**
* ツールリクエストの処理
*/
public function handle(Request $request, WeatherRepository $weather): Response
{
$location = $request->get('location');
$forecast = $weather->getForecastFor($location);
// ...
}
}
ツールアノテーションTool Annotations
アノテーションを使用してツールを拡張し、AIクライアントに追加のメタデータを提供できます。これらのアノテーションは、AIモデルがツールの動作と能力を理解するのに役立ちます。アノテーションはアトリビュートを介してツールに追加されます。You may enhance your tools with annotations[https://modelcontextprotocol.io/specification/2025-06-18/schema#toolannotations] to provide additional metadata to AI clients. These annotations help AI models understand the tool's behavior and capabilities. Annotations are added to tools via attributes:
<?php
namespace App\Mcp\Tools;
use Laravel\Mcp\Server\Tools\Annotations\IsIdempotent;
use Laravel\Mcp\Server\Tools\Annotations\IsReadOnly;
use Laravel\Mcp\Server\Tool;
#[IsIdempotent]
#[IsReadOnly]
class CurrentWeatherTool extends Tool
{
//
}
利用可能なアノテーションは次のとおりです。Available annotations include:
アノテーションAnnotation | タイプType | 説明Description |
---|---|---|
#[IsReadOnly] #[IsReadOnly] |
booleanboolean | ツールがその環境を変更しないことを示します。Indicates the tool does not modify its environment. |
#[IsDestructive] #[IsDestructive] |
booleanboolean | ツールが破壊的な更新を実行する可能性があることを示します(読み取り専用でない場合にのみ意味があります)。Indicates the tool may perform destructive updates (only meaningful when not read-only). |
#[IsIdempotent] #[IsIdempotent] |
booleanboolean | 同じ引数で繰り返し呼び出しても追加の効果がないことを示します(読み取り専用でない場合)。Indicates repeated calls with same arguments have no additional effect (when not read-only). |
#[IsOpenWorld] #[IsOpenWorld] |
booleanboolean | ツールが外部エンティティと対話する可能性があることを示します。Indicates the tool may interact with external entities. |
条件付きツール登録Conditional Tool Registration
ツールクラスにshouldRegister
メソッドを実装することで、実行時にツールを条件付きで登録できます。このメソッドを使用すると、アプリケーションの状態、設定、またはリクエストパラメータに基づいてツールが利用可能であるべきかどうかを決定できます。You may conditionally register tools at runtime by implementing the shouldRegister
method in your tool class. This method allows you to determine whether a tool should be available based on application state, configuration, or request parameters:
<?php
namespace App\Mcp\Tools;
use Laravel\Mcp\Request;
use Laravel\Mcp\Server\Tool;
class CurrentWeatherTool extends Tool
{
/**
* ツールを登録すべきか判定
*/
public function shouldRegister(Request $request): bool
{
return $request?->user()?->subscribed() ?? false;
}
}
ツールのshouldRegister
メソッドがfalse
を返すと、そのツールは利用可能なツールの一覧に表示されず、AIクライアントから呼び出すことはできません。When a tool's shouldRegister
method returns false
, it will not appear in the list of available tools and cannot be invoked by AI clients.
ツールのレスポンスTool Responses
ツールはLaravel\Mcp\Response
のインスタンスを返す必要があります。Responseクラスは、さまざまなタイプのレスポンスを作成するための便利なメソッドをいくつか提供しています。Tools must return an instance of Laravel\Mcp\Response
. The Response class provides several convenient methods for creating different types of responses:
単純なテキストレスポンスには、text
メソッドを使用します。For simple text responses, use the text
method:
use Laravel\Mcp\Request;
use Laravel\Mcp\Response;
/**
* ツールリクエストの処理
*/
public function handle(Request $request): Response
{
// ...
return Response::text('Weather Summary: Sunny, 72°F');
}
ツールの実行中にエラーが発生したことを示すには、error
メソッドを使用します。To indicate an error occurred during tool execution, use the error
method:
return Response::error('Unable to fetch weather data. Please try again.');
複数コンテンツのレスポンスMultiple Content Responses
ツールはResponse
インスタンスの配列を返すことで、複数のコンテンツを返すことができます。Tools can return multiple pieces of content by returning an array of Response
instances:
use Laravel\Mcp\Request;
use Laravel\Mcp\Response;
/**
* ツールリクエストの処理
*
* @return array<int, \Laravel\Mcp\Response>
*/
public function handle(Request $request): array
{
// ...
return [
Response::text('Weather Summary: Sunny, 72°F'),
Response::text('**Detailed Forecast**\n- Morning: 65°F\n- Afternoon: 78°F\n- Evening: 70°F')
];
}
ストリーミングレスポンスStreaming Responses
長時間の操作やリアルタイムのデータストリーミングの場合、ツールはhandle
メソッドからジェネレータを返すことができます。これにより、最終的なレスポンスの前に中間的な更新をクライアントに送信できます。For long-running operations or real-time data streaming, tools can return a generator[https://www.php.net/manual/en/language.generators.overview.php] from their handle
method. This enables sending intermediate updates to the client before the final response:
<?php
namespace App\Mcp\Tools;
use Generator;
use Laravel\Mcp\Request;
use Laravel\Mcp\Response;
use Laravel\Mcp\Server\Tool;
class CurrentWeatherTool extends Tool
{
/**
* ツールリクエストの処理
*
* @return \Generator<int, \Laravel\Mcp\Response>
*/
public function handle(Request $request): Generator
{
$locations = $request->array('locations');
foreach ($locations as $index => $location) {
yield Response::notification('processing/progress', [
'current' => $index + 1,
'total' => count($locations),
'location' => $location,
]);
yield Response::text($this->forecastFor($location));
}
}
}
Webベースのサーバを使用する場合、ストリーミングレスポンスは自動的にSSE(Server-Sent Events)ストリームを開き、yieldされた各メッセージをイベントとしてクライアントに送信します。When using web-based servers, streaming responses automatically open an SSE (Server-Sent Events) stream, sending each yielded message as an event to the client.
プロンプトPrompts
プロンプトを使用すると、AIクライアントが言語モデルと対話するために使用できる、再利用可能なプロンプトテンプレートをサーバで共有できます。これらは、一般的なクエリやインタラクションを構造化するための標準化された方法を提供します。Prompts[https://modelcontextprotocol.io/specification/2025-06-18/server/prompts] enable your server to share reusable prompt templates that AI clients can use to interact with language models. They provide a standardized way to structure common queries and interactions.
プロンプトの作成Creating Prompts
プロンプトを作成するには、make:mcp-prompt
Artisanコマンドを実行します。To create a prompt, run the make:mcp-prompt
Artisan command:
php artisan make:mcp-prompt DescribeWeatherPrompt
プロンプトを作成した後、サーバの$prompts
プロパティに登録します。After creating a prompt, register it in your server's $prompts
property:
<?php
namespace App\Mcp\Servers;
use App\Mcp\Prompts\DescribeWeatherPrompt;
use Laravel\Mcp\Server;
class WeatherServer extends Server
{
/**
* このMCPサーバに登録されているプロンプト
*
* @var array<int, class-string<\Laravel\Mcp\Server\Prompt>>
*/
protected array $prompts = [
DescribeWeatherPrompt::class,
];
}
プロンプトの名前、タイトル、説明Prompt Name, Title, and Description
デフォルトでは、プロンプトの名前とタイトルはクラス名から派生します。例えば、DescribeWeatherPrompt
の名前はdescribe-weather
、タイトルはDescribe Weather Prompt
になります。プロンプトに$name
と$title
プロパティを定義することで、これらの値をカスタマイズできます。By default, the prompt's name and title are derived from the class name. For example, DescribeWeatherPrompt
will have a name of describe-weather
and a title of Describe Weather Prompt
. You may customize these values by defining $name
and $title
properties on your prompt:
class DescribeWeatherPrompt extends Prompt
{
/**
* プロンプトの名前
*/
protected string $name = 'weather-assistant';
/**
* プロンプトのタイトル
*/
protected string $title = 'Weather Assistant Prompt';
// ...
}
プロンプトの説明は自動生成されません。プロンプトに$description
プロパティを定義して、必ず意味のある説明を提供してください。Prompt descriptions are not automatically generated. You should always provide a meaningful description by defining a $description
property on your prompts:
class DescribeWeatherPrompt extends Prompt
{
/**
* プロンプトの説明。
*/
protected string $description = 'Generates a natural-language explanation of the weather for a given location.';
//
}
[!NOTE] The description is a critical part of the prompt's metadata, as it helps AI models understand when and how to get the best use out of the prompt.
Note: 説明はプロンプトのメタデータの重要な部分であり、AIモデルがプロンプトをいつ、どのように最大限に活用するかを理解するのに役立ちます。
プロンプト引数Prompt Arguments
プロンプトは、AIクライアントがプロンプトテンプレートを特定の値でカスタマイズできるようにする引数を定義できます。プロンプトが受け入れる引数を定義するには、arguments
メソッドを使用します。Prompts can define arguments that allow AI clients to customize the prompt template with specific values. Use the arguments
method to define what arguments your prompt accepts:
<?php
namespace App\Mcp\Prompts;
use Laravel\Mcp\Server\Prompt;
use Laravel\Mcp\Server\Prompts\Argument;
class DescribeWeatherPrompt extends Prompt
{
/**
* プロンプトの引数を取得します。
*
* @return array<int, \Laravel\Mcp\Server\Prompts\Argument>
*/
public function arguments(): array
{
return [
new Argument(
name: 'tone',
description: 'The tone to use in the weather description (e.g., formal, casual, humorous).',
required: true,
),
];
}
}
プロンプト引数のバリデーションValidating Prompt Arguments
プロンプト引数は定義に基づいて自動的にバリデーションされますが、より複雑なバリデーションルールを適用したい場合もあるでしょう。Prompt arguments are automatically validated based on their definition, but you may also want to enforce more complex validation rules.
Laravel MCPは、Laravelのバリデーション機能とシームレスに統合されています。プロンプトのhandle
メソッド内で、受信したプロンプト引数をバリデーションできます。Laravel MCP integrates seamlessly with Laravel's validation features[/docs/{{version}}/validation]. You may validate incoming prompt arguments within your prompt's handle
method:
<?php
namespace App\Mcp\Prompts;
use Laravel\Mcp\Request;
use Laravel\Mcp\Response;
use Laravel\Mcp\Server\Prompt;
class DescribeWeatherPrompt extends Prompt
{
/**
* プロンプトのリクエストを処理します。
*/
public function handle(Request $request): Response
{
$validated = $request->validate([
'tone' => 'required|string|max:50',
]);
$tone = $validated['tone'];
// 指定されたトーンを使用してプロンプトのレスポンスを生成...
}
}
バリデーションが失敗した場合、AIクライアントは提供されたエラーメッセージに基づいて動作します。そのため、明確で実行可能なエラーメッセージを提供することが重要です。On validation failure, AI clients will act based on the error messages you provide. As such, is critical to provide clear and actionable error messages:
$validated = $request->validate([
'tone' => ['required','string','max:50'],
],[
'tone.*' => 'You must specify a tone for the weather description. Examples include "formal", "casual", or "humorous".',
]);
プロンプトの依存注入Prompt Dependency Injection
すべてのプロンプトを解決するために、Laravelのサービスコンテナが使用されます。その結果、プロンプトが必要とする依存関係をコンストラクタでタイプヒントできます。宣言された依存関係は自動的に解決され、プロンプトインスタンスに注入されます。The Laravel service container[/docs/{{version}}/container] is used to resolve all prompts. As a result, you are able to type-hint any dependencies your prompt may need in its constructor. The declared dependencies will automatically be resolved and injected into the prompt instance:
<?php
namespace App\Mcp\Prompts;
use App\Repositories\WeatherRepository;
use Laravel\Mcp\Server\Prompt;
class DescribeWeatherPrompt extends Prompt
{
/**
* 新しいプロンプトインスタンスを作成します。
*/
public function __construct(
protected WeatherRepository $weather,
) {}
//
}
コンストラクタインジェクションに加えて、プロンプトのhandle
メソッドで依存関係をタイプヒントすることもできます。メソッドが呼び出されると、サービスコンテナは自動的に依存関係を解決して注入します。In addition to constructor injection, you may also type-hint dependencies in your prompt's handle
method. The service container will automatically resolve and inject the dependencies when the method is called:
<?php
namespace App\Mcp\Prompts;
use App\Repositories\WeatherRepository;
use Laravel\Mcp\Request;
use Laravel\Mcp\Response;
use Laravel\Mcp\Server\Prompt;
class DescribeWeatherPrompt extends Prompt
{
/**
* プロンプトのリクエストを処理します。
*/
public function handle(Request $request, WeatherRepository $weather): Response
{
$isAvailable = $weather->isServiceAvailable();
// ...
}
}
条件付きプロンプト登録Conditional Prompt Registration
プロンプトクラスにshouldRegister
メソッドを実装することで、実行時にプロンプトを条件付きで登録できます。このメソッドを使用すると、アプリケーションの状態、設定、またはリクエストパラメータに基づいてプロンプトが利用可能であるべきかどうかを判断できます。You may conditionally register prompts at runtime by implementing the shouldRegister
method in your prompt class. This method allows you to determine whether a prompt should be available based on application state, configuration, or request parameters:
<?php
namespace App\Mcp\Prompts;
use Laravel\Mcp\Request;
use Laravel\Mcp\Server\Prompt;
class CurrentWeatherPrompt extends Prompt
{
/**
* プロンプトを登録すべきか判断します。
*/
public function shouldRegister(Request $request): bool
{
return $request?->user()?->subscribed() ?? false;
}
}
プロンプトのshouldRegister
メソッドがfalse
を返すと、そのプロンプトは利用可能なプロンプトのリストに表示されず、AIクライアントから呼び出すことはできません。When a prompt's shouldRegister
method returns false
, it will not appear in the list of available prompts and cannot be invoked by AI clients.
プロンプトのレスポンスPrompt Responses
プロンプトは、単一のLaravel\Mcp\Response
インスタンス、またはLaravel\Mcp\Response
インスタンスのiterableを返すことができます。これらのレスポンスは、AIクライアントに送信されるコンテンツをカプセル化します。Prompts may return a single Laravel\Mcp\Response
or an iterable of Laravel\Mcp\Response
instances. These responses encapsulate the content that will be sent to the AI client:
<?php
namespace App\Mcp\Prompts;
use Laravel\Mcp\Request;
use Laravel\Mcp\Response;
use Laravel\Mcp\Server\Prompt;
class DescribeWeatherPrompt extends Prompt
{
/**
* プロンプトのリクエストを処理します。
*
* @return array<int, \Laravel\Mcp\Response>
*/
public function handle(Request $request): array
{
$tone = $request->string('tone');
$systemMessage = "You are a helpful weather assistant. Please provide a weather description in a {$tone} tone.";
$userMessage = "What is the current weather like in New York City?";
return [
Response::text($systemMessage)->asAssistant(),
Response::text($userMessage),
];
}
}
asAssistant()
メソッドを使用すると、レスポンスメッセージがAIアシスタントからのものであることを示すことができます。一方、通常のメッセージはユーザー入力として扱われます。You can use the asAssistant()
method to indicate that a response message should be treated as coming from the AI assistant, while regular messages are treated as user input.
リソースResources
リソースを使用すると、AIクライアントが読み取り、言語モデルと対話する際のコンテキストとして使用できるデータやコンテンツをサーバが公開できます。リソースは、ドキュメント、設定、またはAIの応答を形成するのに役立つデータなどの静的または動的な情報を共有する方法を提供します。Resources[https://modelcontextprotocol.io/specification/2025-06-18/server/resources] enable your server to expose data and content that AI clients can read and use as context when interacting with language models. They provide a way to share static or dynamic information like documentation, configuration, or any data that helps inform AI responses.
リソースの作成Creating Resources
リソースを作成するには、make:mcp-resource
Artisanコマンドを実行します。To create a resource, run the make:mcp-resource
Artisan command:
php artisan make:mcp-resource WeatherGuidelinesResource
リソースを作成した後、サーバの$resources
プロパティに登録します。After creating a resource, register it in your server's $resources
property:
<?php
namespace App\Mcp\Servers;
use App\Mcp\Resources\WeatherGuidelinesResource;
use Laravel\Mcp\Server;
class WeatherServer extends Server
{
/**
* このMCPサーバに登録されているリソース。
*
* @var array<int, class-string<\Laravel\Mcp\Server\Resource>>
*/
protected array $resources = [
WeatherGuidelinesResource::class,
];
}
リソース名、タイトル、説明Resource Name, Title, and Description
デフォルトでは、リソースの名前とタイトルはクラス名から派生します。例えば、WeatherGuidelinesResource
はweather-guidelines
という名前とWeather Guidelines Resource
というタイトルになります。これらの値は、リソースに$name
プロパティと$title
プロパティを定義することでカスタマイズできます。By default, the resource's name and title are derived from the class name. For example, WeatherGuidelinesResource
will have a name of weather-guidelines
and a title of Weather Guidelines Resource
. You may customize these values by defining the $name
and $title
properties on your resource:
class WeatherGuidelinesResource extends Resource
{
/**
* リソースの名前。
*/
protected string $name = 'weather-api-docs';
/**
* リソースのタイトル。
*/
protected string $title = 'Weather API Documentation';
// ...
}
リソースの説明は自動生成されません。リソースに$description
プロパティを定義して、必ず意味のある説明を提供してください。Resource descriptions are not automatically generated. You should always provide a meaningful description by defining the $description
property on your resource:
class WeatherGuidelinesResource extends Resource
{
/**
* リソースの説明。
*/
protected string $description = 'Comprehensive guidelines for using the Weather API.';
//
}
[!NOTE] The description is a critical part of the resource's metadata, as it helps AI models understand when and how to use the resource effectively.
Note: 説明はリソースのメタデータの重要な部分であり、AIモデルがリソースをいつ、どのように効果的に使用するかを理解するのに役立ちます。
リソースURIとMIMEタイプResource URI and MIME Type
各リソースは一意のURIで識別され、AIクライアントがリソースの形式を理解するのに役立つMIMEタイプが関連付けられています。Each resource is identified by a unique URI and has an associated MIME type that helps AI clients understand the resource's format.
デフォルトでは、リソースのURIはリソース名に基づいて生成されるため、WeatherGuidelinesResource
のURIはweather://resources/weather-guidelines
になります。デフォルトのMIMEタイプはtext/plain
です。By default, the resource's URI is generated based on the resource's name, so WeatherGuidelinesResource
will have a URI of weather://resources/weather-guidelines
. The default MIME type is text/plain
.
これらの値は、リソースに$uri
プロパティと$mimeType
プロパティを定義することでカスタマイズできます。You may customize these values by defining the $uri
and $mimeType
properties on your resource:
<?php
namespace App\Mcp\Resources;
use Laravel\Mcp\Server\Resource;
class WeatherGuidelinesResource extends Resource
{
/**
* リソースのURI。
*/
protected string $uri = 'weather://resources/guidelines';
/**
* リソースのMIMEタイプ。
*/
protected string $mimeType = 'application/pdf';
}
URIとMIMEタイプは、AIクライアントがリソースコンテンツを適切に処理・解釈する方法を決定するのに役立ちます。The URI and MIME type help AI clients determine how to process and interpret the resource content appropriately.
リソースリクエストResource Request
ツールやプロンプトとは異なり、リソースは入力スキーマや引数を定義できません。しかし、リソースのhandle
メソッド内でリクエストオブジェクトを操作することは可能です:Unlike tools and prompts, resources can not define input schemas or arguments. However, you can still interact with request object within your resource's handle
method:
<?php
namespace App\Mcp\Resources;
use Laravel\Mcp\Request;
use Laravel\Mcp\Response;
use Laravel\Mcp\Server\Resource;
class WeatherGuidelinesResource extends Resource
{
/**
* リソースリクエストを処理
*/
public function handle(Request $request): Response
{
// ...
}
}
リソースの依存注入Resource Dependency Injection
Laravelのサービスコンテナは、すべてのリソースを解決するために使用されます。その結果、リソースが必要とする依存関係をコンストラクタでタイプヒントできます。宣言された依存関係は、自動的に解決され、リソースインスタンスに注入されます:The Laravel service container[/docs/{{version}}/container] is used to resolve all resources. As a result, you are able to type-hint any dependencies your resource may need in its constructor. The declared dependencies will automatically be resolved and injected into the resource instance:
<?php
namespace App\Mcp\Resources;
use App\Repositories\WeatherRepository;
use Laravel\Mcp\Server\Resource;
class WeatherGuidelinesResource extends Resource
{
/**
* 新しいリソースインスタンスを作成
*/
public function __construct(
protected WeatherRepository $weather,
) {}
// ...
}
コンストラクタインジェクションに加え、リソースのhandle
メソッドで依存関係をタイプヒントすることもできます。メソッドが呼び出されると、サービスコンテナが自動的に依存関係を解決し、注入します:In addition to constructor injection, you may also type-hint dependencies in your resource's handle
method. The service container will automatically resolve and inject the dependencies when the method is called:
<?php
namespace App\Mcp\Resources;
use App\Repositories\WeatherRepository;
use Laravel\Mcp\Request;
use Laravel\Mcp\Response;
use Laravel\Mcp\Server\Resource;
class WeatherGuidelinesResource extends Resource
{
/**
* リソースリクエストを処理
*/
public function handle(WeatherRepository $weather): Response
{
$guidelines = $weather->guidelines();
return Response::text($guidelines);
}
}
条件付きリソース登録Conditional Resource Registration
リソースクラスにshouldRegister
メソッドを実装することで、実行時にリソースを条件付きで登録できます。このメソッドにより、アプリケーションの状態、設定、またはリクエストパラメータに基づいてリソースを利用可能にすべきかどうかを判断できます:You may conditionally register resources at runtime by implementing the shouldRegister
method in your resource class. This method allows you to determine whether a resource should be available based on application state, configuration, or request parameters:
<?php
namespace App\Mcp\Resources;
use Laravel\Mcp\Request;
use Laravel\Mcp\Server\Resource;
class WeatherGuidelinesResource extends Resource
{
/**
* リソースを登録すべきか判定
*/
public function shouldRegister(Request $request): bool
{
return $request?->user()?->subscribed() ?? false;
}
}
リソースのshouldRegister
メソッドがfalse
を返すと、そのリソースは利用可能なリソースのリストに表示されず、AIクライアントからアクセスできなくなります。When a resource's shouldRegister
method returns false
, it will not appear in the list of available resources and cannot be accessed by AI clients.
リソースレスポンスResource Responses
リソースはLaravel\Mcp\Response
のインスタンスを返す必要があります。Responseクラスは、さまざまなタイプのレスポンスを作成するための便利なメソッドをいくつか提供しています:Resources must return an instance of Laravel\Mcp\Response
. The Response class provides several convenient methods for creating different types of responses:
単純なテキストコンテンツには、text
メソッドを使用します:For simple text content, use the text
method:
use Laravel\Mcp\Request;
use Laravel\Mcp\Response;
/**
* リソースリクエストを処理
*/
public function handle(Request $request): Response
{
// ...
return Response::text($weatherData);
}
BlobレスポンスBlob Responses
blobコンテンツを返すには、blobコンテンツを指定してblob
メソッドを使用します:To return blob content, use the blob
method, providing the blob content:
return Response::blob(file_get_contents(storage_path('weather/radar.png')));
blobコンテンツを返す場合、MIMEタイプはリソースクラスの$mimeType
プロパティの値によって決定されます:When returning blob content, the MIME type will be determined by the value of the $mimeType
property on the resource class:
<?php
namespace App\Mcp\Resources;
use Laravel\Mcp\Server\Resource;
class WeatherGuidelinesResource extends Resource
{
/**
* リソースのMIMEタイプ
*/
protected string $mimeType = 'image/png';
//
}
エラーレスポンスError Responses
リソースの取得中にエラーが発生したことを示すには、error()
メソッドを使用します:To indicate an error occurred during resource retrieval, use the error()
method:
return Response::error('Unable to fetch weather data for the specified location.');
認証Authentication
ルートの場合と同様に、ミドルウェアを使用してWeb MCPサーバを認証できます。これにより、ユーザーはサーバの機能を使用する前に認証が必要になります。You can authenticate web MCP servers with middleware just like you would for routes. This will require a user to authenticate before using any capability of the server.
MCPサーバへのアクセスを認証するには2つの方法があります。1つはLaravel Sanctumによるシンプルなトークンベースの認証、またはAuthorization
HTTPヘッダを介して渡されるその他の任意のAPIトークンによる認証です。もう1つは、Laravel Passportを使用したOAuthによる認証です。There are two ways to authenticate access to your MCP server: simple, token based authentication via Laravel Sanctum[/docs/{{version}}/sanctum], or any other arbitrary API tokens which are passed via the Authorization
HTTP header. Or, you may authenticate via OAuth using Laravel Passport[/docs/{{version}}/passport].
OAuth 2.1OAuth 2.1
WebベースのMCPサーバを保護する最も堅牢な方法は、Laravel Passportを介したOAuthを使用することです。The most robust way to protect your web-based MCP servers is with OAuth through Laravel Passport[/docs/{{version}}/passport].
MCPサーバをOAuth経由で認証する場合、routes/ai.php
ファイルでMcp::oauthRoutes
メソッドを呼び出し、必要なOAuth2ディスカバリおよびクライアント登録ルートを登録します。次に、routes/ai.php
ファイル内のMcp::web
ルートにPassportのauth:api
ミドルウェアを適用します:When authenticating your MCP server via OAuth, you will invoke the Mcp::oauthRoutes
method in your routes/ai.php
file to register the required OAuth2 discovery and client registration routes. Then, apply Passport's auth:api
middleware to your Mcp::web
route in your routes/ai.php
file:
use App\Mcp\Servers\WeatherExample;
use Laravel\Mcp\Facades\Mcp;
Mcp::oauthRoutes();
Mcp::web('/mcp/weather', WeatherExample::class)
->middleware('auth:api');
新規PassportインストールNew Passport Installation
アプリケーションでまだLaravel Passportを使用していない場合は、まずPassportのインストールとデプロイの手順に従ってください。次に進む前に、OAuthenticatable
モデル、新しい認証ガード、およびPassportキーが必要です。If your application is not already using Laravel Passport, start by following Passport's installation and deployment steps[/docs/{{version}}/passport#installation]. You should have an OAuthenticatable
model, new authentication guard, and passport keys before moving on.
次に、Laravel MCPが提供するPassport認可ビューを公開する必要があります:Next, you should publish Laravel MCP's provided Passport authorization view:
php artisan vendor:publish --tag=mcp-views
次に、Passport::authorizationView
メソッドを使用して、このビューを使用するようにPassportに指示します。通常、このメソッドはアプリケーションのAppServiceProvider
のboot
メソッドで呼び出す必要があります:Then, instruct Passport to use this view using the Passport::authorizationView
method. Typically, this method should be invoked in the boot
method of your application's AppServiceProvider
:
use Laravel\Passport\Passport;
/**
* アプリケーションサービスを初期起動
*/
public function boot(): void
{
Passport::authorizationView(function ($parameters) {
return view('mcp.authorize', $parameters);
});
}
このビューは、AIエージェントの認証試行を拒否または承認するために、認証中にエンドユーザーに表示されます。This view will be displayed to the end-user during authentication to reject or approve the AI agent's authentication attempt.
[!NOTE] In this scenario, we're simply using OAuth as a translation layer to the underlying authenticatable model. We are ignoring many aspects of OAuth, such as scopes.
Note: このシナリオでは、OAuth を単純に基盤となる認証可能なモデルへの変換レイヤーとして使用しています。スコープなど、OAuth の多くの側面は無視しています。
既存の Passport インストールの使用Using an Existing Passport Installation
アプリケーションがすでに Laravel Passport を使用している場合、Laravel MCP は既存の Passport インストール内でシームレスに動作するはずですが、OAuth は主に基盤となる認証可能なモデルへの変換レイヤーとして使用されるため、カスタムスコープは現在サポートされていません。If your application is already using Laravel Passport, Laravel MCP should work seamlessly within your existing Passport installation, but custom scopes aren't currently supported as OAuth is primarily used as a translation layer to the underlying authenticatable model.
Laravel MCP は、上記で説明した Mcp::oauthRoutes()
メソッドを介して、単一の mcp:use
スコープを追加、アドバタイズ、および使用します。Laravel MCP, via the Mcp::oauthRoutes()
method discussed above, adds, advertises, and uses a single mcp:use
scope.
Passport vs. SanctumPassport vs. Sanctum
OAuth2.1 は Model Context Protocol 仕様で文書化された認証メカニズムであり、MCP クライアントの間で最も広くサポートされています。そのため、可能な場合は Passport の使用を推奨します。OAuth2.1 is the documented authentication mechanism in the Model Context Protocol specification, and is the most widely supported among MCP clients. For that reason, we recommend using Passport when possible.
アプリケーションがすでに Sanctum を使用している場合、Passport を追加することは面倒かもしれません。この場合、OAuth のみをサポートする MCP クライアントを使用する明確で必要な要件が出るまで、Passport なしで Sanctum を使用することを推奨します。If your application is already using Sanctum[/docs/{{version}}/sanctum] then adding Passport may be cumbersome. In this instance, we recommend using Sanctum without Passport until you have a clear, necessary requirement to use an MCP client that only supports OAuth.
SanctumSanctum
Sanctum を使用して MCP サーバを保護したい場合は、routes/ai.php
ファイル内のサーバに Sanctum の認証ミドルウェアを追加するだけです。そして、MCP クライアントが認証を成功させるために Authorization: Bearer <token>
ヘッダを提供することを確認してください:If you would like to protect your MCP server using Sanctum[/docs/{{version}}/sanctum], simply add Sanctum's authentication middleware to your server in your routes/ai.php
file. Then, ensure your MCP clients provide a Authorization: Bearer <token>
header to ensure successful authentication:
use App\Mcp\Servers\WeatherExample;
use Laravel\Mcp\Facades\Mcp;
Mcp::web('/mcp/demo', WeatherExample::class)
->middleware('auth:sanctum');
カスタムMCP認証Custom MCP Authentication
アプリケーションが独自のカスタム API トークンを発行している場合、Mcp::web
ルートに任意のミドルウェアを割り当てることで MCP サーバを認証できます。カスタムミドルウェアは、Authorization
ヘッダを手作業で検査して、受信する MCP リクエストを認証できます。If your application issues its own custom API tokens, you may authenticate your MCP server by assigning any middleware you wish to your Mcp::web
routes. Your custom middleware can inspect the Authorization
header manually to authenticate the incoming MCP request.
認可Authorization
$request->user()
メソッドを介して現在認証されているユーザーにアクセスでき、MCP ツールとリソース内で認可チェックを実行できます。You may access the currently authenticated user via the $request->user()
method, allowing you to perform authorization checks[/docs/{{version}}/authorization] within your MCP tools and resources:
use Laravel\Mcp\Request;
use Laravel\Mcp\Response;
/**
* Handle the tool request.
*/
public function handle(Request $request): Response
{
if (! $request->user()->can('read-weather')) {
return Response::error('Permission denied.');
}
// ...
}
サーバのテストTesting Servers
組み込みの MCP Inspector を使用するか、ユニットテストを書くことで MCP サーバをテストできます。You may test your MCP servers using the built-in MCP Inspector or by writing unit tests.
MCP InspectorMCP Inspector
MCP Inspector は、MCP サーバをテストおよびデバッグするためのインタラクティブなツールです。これを使用してサーバに接続し、認証を確認し、ツール、リソース、プロンプトを試すことができます。The MCP Inspector[https://modelcontextprotocol.io/docs/tools/inspector] is an interactive tool for testing and debugging your MCP servers. Use it to connect to your server, verify authentication, and try out tools, resources, and prompts.
登録されたサーバに対してインスペクターを実行できます。You may run the inspector for any registered server:
# Web server...
php artisan mcp:inspector mcp/weather
# Local server named "weather"...
php artisan mcp:inspector weather
このコマンドは MCP Inspector を起動し、MCP クライアントにコピーして全てが正しく設定されていることを確認するために使用できるクライアント設定を提供します。Web サーバが認証ミドルウェアによって保護されている場合は、接続時に Authorization
ベアラートークンなどの必要なヘッダを含めることを忘れないでください。This command launches the MCP Inspector and provides the client settings that you may copy into your MCP client to ensure everything is configured correctly. If your web server is protected by an authentication middleware, make sure to include the required headers, such as an Authorization
bearer token, when connecting.
Unit TestsUnit Tests
MCPサーバ、ツール、リソース、プロンプトのユニットテストを作成できます。You may write unit tests for your MCP servers, tools, resources, and prompts.
まず、新しいテストケースを作成し、それを登録しているサーバで目的のプリミティブを呼び出します。例えば、WeatherServer
上のツールをテストするには、次のようにします:To get started, create a new test case and invoke the desired primitive on the server that registers it. For example, to test a tool on the WeatherServer
:
test('tool', function () {
$response = WeatherServer::tool(CurrentWeatherTool::class, [
'location' => 'New York City',
'units' => 'fahrenheit',
]);
$response
->assertOk()
->assertSee('The current weather in New York City is 72°F and sunny.');
});
/**
* ツールをテストします。
*/
public function test_tool(): void
{
$response = WeatherServer::tool(CurrentWeatherTool::class, [
'location' => 'New York City',
'units' => 'fahrenheit',
]);
$response
->assertOk()
->assertSee('The current weather in New York City is 72°F and sunny.');
}
同様に、プロンプトやリソースもテストできます:Similarly, you may test prompts and resources:
$response = WeatherServer::prompt(...);
$response = WeatherServer::resource(...);
プリミティブを呼び出す前にactingAs
メソッドをチェーンすることで、認証済みユーザーとして振る舞うことも可能です:You may also act as an authenticated user by chaining the actingAs
method before invoking the primitive:
$response = WeatherServer::actingAs($user)->tool(...);
レスポンスを受け取ったら、さまざまなアサーションメソッドを使用して、レスポンスの内容とステータスを検証できます。Once you receive the response, you may use various assertion methods to verify the content and status of the response.
assertOk
メソッドを使用すると、レスポンスが成功したことをアサートできます。これはレスポンスにエラーがないことをチェックします:You may assert that a response is successful using the assertOk
method. This checks that the response does not have any errors:
$response->assertOk();
assertSee
メソッドを使用すると、レスポンスに特定のテキストが含まれていることをアサートできます:You may assert that a response contains specific text using the assertSee
method:
$response->assertSee('The current weather in New York City is 72°F and sunny.');
assertHasErrors
メソッドを使用すると、レスポンスにエラーが含まれていることをアサートできます:You may assert that a response contains an error using the assertHasErrors
method:
$response->assertHasErrors();
$response->assertHasErrors([
'Something went wrong.',
]);
assertHasNoErrors
メソッドを使用すると、レスポンスにエラーが含まれていないことをアサートできます:You may assert that a response does not contain an error using the assertHasNoErrors
method:
$response->assertHasNoErrors();
assertName()
、assertTitle()
、assertDescription()
メソッドを使用すると、レスポンスに特定のメタデータが含まれていることをアサートできます:You may assert that a response contains specific metadata using the assertName()
, assertTitle()
, and assertDescription()
methods:
$response->assertName('current-weather');
$response->assertTitle('Current Weather Tool');
$response->assertDescription('Fetches the current weather forecast for a specified location.');
assertSentNotification
およびassertNotificationCount
メソッドを使用すると、通知が送信されたことをアサートできます:You may assert that notifications were sent using the assertSentNotification
and assertNotificationCount
methods:
$response->assertSentNotification('processing/progress', [
'step' => 1,
'total' => 5,
]);
$response->assertSentNotification('processing/progress', [
'step' => 2,
'total' => 5,
]);
$response->assertNotificationCount(5);
最後に、生のレスポンス内容を調査したい場合は、dd
またはdump
メソッドを使用して、デバッグ目的でレスポンスを出力できます:Finally, if you wish to inspect the raw response content, you may use the dd
or dump
methods to output the response for debugging purposes:
$response->dd();
$response->dump();