Skip to main content

What is MCP?

Model Context Protocol (MCP) is a standardised protocol for communication between AI clients (Claude, Cursor, GitHub Copilot, etc.) and your application. By implementing an MCP server you let AI agents read your application’s data and execute actions on your behalf.
Laravel MCP is an official package added in Laravel 13, available as laravel/mcp. It provides everything you need to build MCP servers.
An MCP server can expose three types of capabilities:

Installation

After installation, publish the routes/ai.php file:
This creates routes/ai.php where you register your MCP servers.

Creating a server

Generate a server class with Artisan:
The class is placed in app/Mcp/Servers:

Registering a server

Register servers in routes/ai.php. You can register a server as a web server or a local server.

Web server

A web server listens for HTTP POST requests. Use it for remote AI clients or web-based integrations.
Apply middleware just like any other route:

Local server

A local server runs as an Artisan command. Use it with local AI clients such as Claude Desktop.
The MCP client normally starts local servers automatically — you do not need to run mcp:start manually.

Tools

Tools are functions an AI client can call. They can fetch data, update records, or integrate with external services.

Creating a tool

Register the tool in the server’s $tools array:
A basic tool implementation:

Tool name and description

The tool’s name and title are automatically derived from the class name. CurrentWeatherTool becomes name current-weather and title Current Weather Tool. Override with Name and Title attributes:
The Description attribute is not generated automatically. Always provide a meaningful description — it is how the AI model understands what the tool does and when to use it.

Input schema

Define input parameters in the schema method using Laravel’s JSON schema builder:

Output schema

Define the shape of the response in outputSchema so AI clients can parse it reliably:

Validation

Use Laravel’s standard validation inside handle:
When validation fails the AI client receives the error message and can retry. Write clear, actionable error messages to help the agent self-correct.

Dependency injection

Tools are resolved through the service container, so you can type-hint dependencies in the constructor or handle method:

Annotations

Add annotations to give AI clients additional hints about a tool’s behaviour:

Conditional registration

Implement shouldRegister to expose a tool only when certain conditions are met:
When this returns false, the tool is invisible to the AI client.

Responses

Tools must return a Laravel\Mcp\Response instance.
Stream progress updates for long-running operations:

Prompts

Prompts are reusable, parameterised prompt templates that standardise common queries an AI client sends to a language model.

Creating a prompt

Register it in the server’s $prompts array:

Prompt arguments

Define prompt parameters in the arguments method:

Prompt validation

Prompt arguments are automatically validated based on their definition, but you may enforce more complex validation rules by calling validate inside the handle method:
On validation failure, AI clients will act based on the error messages you provide. Provide clear and actionable messages:

Prompt dependency injection

The Laravel service container resolves all prompts, so you may type-hint dependencies in the constructor or handle method:
You may also type-hint dependencies in the handle method:

Conditional prompt registration

Implement shouldRegister to conditionally register a prompt at runtime:
When shouldRegister returns false, the prompt will not appear in the list of available prompts and cannot be invoked by AI clients.

Prompt responses

Return user and assistant messages from the handle method. Use asAssistant() to mark a message as coming from the assistant:

Resources

Resources are data or information an AI client can load as context — documentation, configuration, or dynamic application data that improves the quality of AI responses.

Creating a resource

Register it in the server’s $resources array:

URI and MIME type

The URI is derived automatically from the class name (e.g. weather://resources/weather-guidelines). Customise with Uri and MimeType attributes:

Resource templates

Implement HasUriTemplate to define dynamic resources with URI variables:
URI variables are automatically injected into the request and accessible via get().

Resource request

Unlike tools and prompts, resources cannot define input schemas or arguments. However, you can still interact with the request object within your resource’s handle method:

Resource dependency injection

The Laravel service container resolves all resources, so you may type-hint dependencies in the constructor or handle method:
You may also type-hint dependencies in the handle method:

Resource annotations

Annotate resources with audience, priority, and last-modified date:

Conditional resource registration

Implement shouldRegister to conditionally register a resource at runtime:
When shouldRegister returns false, the resource will not appear in the available list and cannot be accessed by AI clients.

Resource responses

Resources must return an instance of Laravel\Mcp\Response. For text content, use the text method:
Use resourceLink to return a URI pointer that the AI client fetches independently, rather than embedded content:
You may also pass a registered resource class or instance to automatically inherit its URI, name, title, description, and MIME type:

Blob responses

Return binary content using the blob method. The MIME type is determined by the resource’s #[MimeType] attribute:

Error responses

Indicate an error using the error method:

Apps

Laravel MCP supports MCP Apps, an extension of the Model Context Protocol that allows tools to render interactive HTML applications within sandboxed iframes in supported hosts. This allows you to build dashboards, forms, visualizations, and other rich experiences that go beyond plain text responses. An MCP app consists of two parts working together:
  • An app resource that returns the self-contained HTML for your application.
  • A tool that is linked to the app resource using the #[RendersApp] attribute. When the tool is called, the host fetches and renders the linked resource.

Creating app resources

Create an app resource using the make:mcp-app-resource Artisan command:
This command creates two files: a PHP class in app/Mcp/Resources and a Blade view in resources/views/mcp. The view name is automatically inferred from the class name. For example, WeatherDashboardApp maps to mcp.weather-dashboard-app:
AppResource extends the base Resource class and automatically configures the ui:// URI scheme and the text/html;profile=mcp-app MIME type required by the MCP Apps specification. Like any other resource, you must register it in your server’s $resources array. The generated Blade view uses the <x-mcp::app> component, which renders a complete HTML document with the client-side MCP SDK bundled and ready to use:
The createMcpApp global is provided by the bundled SDK and handles connecting the iframe to the server, applying host theming, and exposing helpers such as callServerTool, sendMessage, openLink, and event callbacks. For the full client-side API, refer to the MCP Apps specification.

Rendering apps from tools

To display an app resource, link a tool to it using the #[RendersApp] attribute. When the tool is called, Laravel MCP includes the resource’s URI in the tool metadata so the host can render the app in a sandboxed iframe:
Laravel MCP automatically advertises the io.modelcontextprotocol/ui capability whenever any AppResource is registered, so no additional server configuration is required.

App tool visibility

Each #[RendersApp] tool can limit who may invoke it via the visibility argument. This is useful for exposing private, app-only tools that the UI calls to load or refresh data without making those tools visible to the model:
The Visibility enum has two cases, Model and App, and defaults to both. Use [Visibility::App] for backend actions the UI calls directly, or [Visibility::Model] to make a tool unavailable to the UI.

App configuration

The #[AppMeta] attribute on your app resource configures the iframe’s Content Security Policy, browser permissions, and any library scripts that should be included in the view’s <head>:
The Library enum includes pre-configured CDN scripts for common front-end libraries such as Library::Tailwind and Library::Alpine, and their CDN origins are automatically merged into the CSP. The Permission enum covers browser permissions such as Camera, Microphone, Geolocation, and ClipboardWrite.
For computed or dynamic configuration, override the appMeta method on your resource using the fluent AppMeta, Csp, and Permissions builders from the Laravel\Mcp\Server\Ui namespace.

Building apps with Boost

Laravel MCP includes a dedicated Boost skill reference for building MCP Apps. If you have Laravel Boost installed, your AI coding agent can invoke the mcp-development skill and ask it to scaffold an app resource, Blade view, and linked tool for you. For the complete protocol reference, including the full client-side API and schema details, see the official MCP Apps documentation.

Metadata

Attach MCP spec _meta fields to tool, resource, and prompt responses:
To attach metadata to the response envelope, use Response::make:
To attach metadata to the tool, resource, or prompt class itself, define a $meta property:

Icons

MCP clients can display icons for your server and its primitives. Declare icons on a server, tool, resource, or prompt using the Icon attribute:
The Icon attribute is repeatable, so you may declare multiple icons to provide different sizes or light and dark theme variants. Alternatively, define icons programmatically by overriding the icons method. This is useful when an icon depends on runtime conditions:
Icons defined via the attribute and the icons method are combined automatically. Icon paths are resolved as follows:
  • Paths with a URI scheme such as https: or data: are used as-is.
  • Relative paths are resolved to a URL using Laravel’s asset helper.

Authentication

Web servers support Laravel’s standard middleware for authentication.

Sanctum

Use token-based authentication with Laravel Sanctum. The MCP client sends an Authorization: Bearer <token> header.

OAuth 2.1

Use Laravel Passport for robust OAuth-based authentication:
When using OAuth, publish the MCP authorization views and register them with Passport:

Authorization

Access the authenticated user inside a tool or resource via $request->user():

MCP Client

In addition to building servers, Laravel MCP includes a client for connecting to other MCP servers, whether first-party or third-party. The client lets your application discover and call the tools exposed by an MCP server, which is especially useful for giving your AI agents access to capabilities provided by external MCP servers.

Connecting to Servers

Connect to an HTTP-accessible MCP server using the Client::web method, passing the server’s URL:
To connect to a local MCP server that runs as a command, use the Client::local method, providing the command and any arguments needed to start the server:
The client connects lazily, automatically establishing the connection the first time you list or call tools. If you need to manage the connection manually, you may use the connect, connected, ping, and disconnect methods:
Customize the request timeout using the withTimeout method:

Named Clients

Instead of constructing a client each time, register reusable named clients in the boot method of a service provider using the Mcp facade:
Resolve the client anywhere in your application by name:
Named clients are resolved once per request and automatically disconnected at the end of the request lifecycle.

Client Authentication

To connect to a web MCP server protected by a bearer token, use the withToken method. You may pass a token string or a closure that lazily resolves the token:
For servers protected by OAuth 2.1, configure the client using the withOAuth method:
The clientId and clientSecret arguments may be omitted when the MCP server supports dynamic client registration, in which case the client registers itself automatically.
Register the OAuth routes for the named client in routes/ai.php using the oAuthRoutesFor method:
This registers two named routes: a connect route (mcp.oauth.{client}.connect) that redirects the user to the authorization server, and a callback route (mcp.oauth.{client}.callback) that exchanges the authorization code and invokes your handler. To begin the authorization flow, redirect the user to the connect route:

Tools

Retrieve the tools exposed by an MCP server using the tools method, which returns a collection keyed by tool name:
The client automatically paginates through all available tools. Limit the number returned using the limit argument:
Invoke a tool with the callTool method, passing the tool name and an array of arguments:
You may also call a tool directly from a listed tool instance:
If you are building agents with the Laravel AI SDK, you may provide tools from an MCP client directly to an agent. See the MCP Tools section of the AI SDK documentation for more information.

Prompts

Retrieve the prompts exposed by an MCP server using the prompts method, which returns a collection keyed by prompt name:
The client automatically paginates through all available prompts. Limit the number returned using the limit argument:
To retrieve a prompt, use the getPrompt method, passing the prompt name and an array of arguments. The returned PromptResult instance exposes the generated messages:

Resources

Retrieve the resources exposed by an MCP server using the resources method, which returns a collection keyed by URI:
The client automatically paginates through all available resources. Limit the number returned using the limit argument:
To read a resource, use the readResource method, passing the resource URI. The returned ResourceReadResult instance exposes the resource content:

Testing

MCP Inspector

Use the interactive mcp:inspector command to debug your server:
The command launches the MCP Inspector and displays a client configuration you can copy. If your server uses authentication middleware, include the Authorization header when connecting.

Unit tests

Write unit tests directly against your tools, resources, and prompts:
Prompts and resources follow the same pattern:
Authenticate as a specific user with actingAs:
Key assertion methods:
Assert that an error is present:
Assert that no errors are present:
Assert the name, title, or description of the tool, resource, or prompt:
Assert streaming notifications using assertSentNotification and assertNotificationCount:
Inspect the raw response for debugging:
Last modified on July 20, 2026