イントロダクション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インスペクタを使用してください。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: 説明はツールのメタデータの重要な部分であり、AIモデルがツールをいつ、どのように効果的に使用するかを理解するのに役立ちます。[!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.
ツールの入力スキーマ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->string()
->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, it 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: 説明はプロンプトのメタデータの重要な部分であり、AIモデルがプロンプトをいつ、どのように最大限に活用するかを理解するのに役立ちます。[!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.
プロンプト引数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, it 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: 説明はリソースのメタデータの重要な部分であり、AIモデルがリソースをいつ、どのように効果的に使用するかを理解するのに役立ちます。[!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.
リソース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サーバを認証できます。MCPサーバに認証を追加すると、ユーザーはサーバの機能を利用する前に認証を行う必要があります。Just like routes, you can authenticate web MCP servers with middleware. Adding authentication to your MCP server will require a user to authenticate before using any capability of the server.
MCPサーバへのアクセス認証には2つの方法があります:Laravel Sanctumによるシンプルなトークンベース認証、またはAuthorization HTTPヘッダ経由で渡す任意のトークンによる認証です。あるいは、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 token which is 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 using Laravel Passport[/docs/{{version}}/passport].
OAuth経由でMCPサーバを認証する場合、routes/ai.phpファイルでMcp::oauthRoutesメソッドを呼び出し、必要なOAuth2ディスカバリおよびクライアント登録ルートを登録します。次に、routes/ai.phpファイル内のMcp::webルートにPassportのauth:apiミドルウェアを適用します。When authenticating your MCP server via OAuth, 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のインストールとデプロイガイドに従ってPassportを追加してください。次に進む前に、OAuthenticatableモデル、新しい認証ガード、およびPassportキーを用意しておく必要があります。If your application is not already using Laravel Passport, follow Passport's installation and deployment guide[/docs/{{version}}/passport#installation] to add Passport to your application. 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: このシナリオでは、OAuth を単純に基盤となる認証可能なモデルへの変換レイヤーとして使用しています。スコープなど、OAuth の多くの側面は無視しています。[!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.
既存の 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インスペクタ を使用するか、ユニットテストを書くことで MCP サーバをテストできます。You may test your MCP servers using the built-in MCP Inspector or by writing unit tests.
MCPインスペクタMCP Inspector
MCPインスペクタ は、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();