Picture a support engineer pasting a customer email into Claude and asking, "Why did this customer's last deployment fail?" Six months ago, the answer involved tab-switching between an admin panel, a log viewer, and a database client. Now the agent calls a tool named list-recent-deployments, reads the failed step's output through a second tool, and drafts a reply with the actual error attached. Nobody exported a CSV. Nobody ran a raw SQL query against production. The agent talked to the Laravel app directly, through a narrow, authenticated, audited interface that we designed for it.
That interface is an MCP server. The Model Context Protocol was introduced by Anthropic as an open standard in November 2024, and the interoperability story is the whole point: any MCP-compatible client, whether Claude, Cursor, or GitHub Copilot, can connect to any MCP server (Laravel MCP docs, Laravel's MCP guide). Laravel shipped first-party support through the official laravel/mcp package (Packagist), so you define tools the same way you define controllers, jobs, and policies: as small classes with validation and authorization built in.
Here's the tension, though. An MCP server is an API that a probabilistic system calls on behalf of a human. Agents in 2026 aren't autocomplete anymore; they run for minutes or hours and get delegated whole tasks (The New Stack). An agent with a badly scoped tool will eventually do something you didn't intend, not out of malice, but out of statistics. So this guide treats security as the backbone, not an afterthought. We'll build a working MCP server on Laravel 13 and PHP 8.5, then spend most of our time on the parts that keep it from becoming your most dangerous endpoint.
Key Takeaways -
laravel/mcpis the official first-party package; tools are classes with schemas, validation, and authorization (Packagist). - Any MCP client (Claude, Cursor, Copilot) can connect to any MCP server, per the open standard Anthropic released in November 2024. - Treat agents as untrusted callers: Sanctum auth, per-tool policies, rate limits, audit logs, and confirmation gates for anything destructive.
Why Would You Let AI Agents Talk to Your Laravel App at All?
The honest answer: because your team is already using agents, and the alternative is worse. When an agent can't reach your app through a sanctioned interface, people improvise. They paste production data into chat windows. They hand agents database credentials "just for this one query." They screenshot admin panels. An MCP server replaces that improvisation with an interface you control, validate, and log.
We see three use cases that justify the effort, and we've built for all three internally.
Support tooling is the easiest win. A support agent (human or AI) needs read access to a customer's recent activity: orders, deployments, invoices, error events. These are read-only queries with obvious tenant boundaries. An MCP tool that accepts a customer ID, checks authorization, and returns a structured summary saves hours per week and leaks nothing beyond what the caller was already allowed to see.
Internal ops is the second tier. Think "requeue this failed job," "resend this webhook," or "toggle this feature flag for one team." These are write operations, but they're small, reversible, and already exposed in your admin panel. Wrapping them in MCP tools means an on-call engineer can ask an agent to triage an incident at 2 a.m. instead of clicking through five screens half-asleep. In our experience, the audit trail actually improves here, because every tool call is logged with arguments, while admin-panel clicks often aren't.
Customer-facing agent features are the third tier and the highest stakes. If your product exposes an MCP server to customers, their agents can integrate your product into their workflows without you building a bespoke plugin for every client. This is where MCP's client-agnostic design pays off: you build one server, and Claude, Cursor, and Copilot users all get the integration for free. It's also where every security control in this article stops being optional.
What about the counterargument, that a REST API already covers this? [UNIQUE INSIGHT] A REST API is documentation-shaped: a human reads the docs, writes glue code, handles pagination, and ships an integration. An MCP server is decision-shaped: it hands the client a menu of typed, described actions that a model can choose between mid-conversation, with no glue code in between. You'll likely want both, and they'll share the same policies underneath. The difference is who the consumer is and how much ceremony sits between intent and execution.
What Are MCP Tools, Resources, and Prompts?
MCP defines three primitives a server can expose, and picking the right one for each capability matters more than it first appears. Getting this wrong usually means shipping a tool that should have been a resource, which inflates your writable surface for no benefit.
Primitive
Direction
What it's for
Laravel analogy
Tool
Agent calls it with arguments
Actions and parameterized queries: "create X," "list Y for Z"
A controller action with a Form Request
Resource
Agent reads it
Reference material: docs, config, schema descriptions, reports
A read-only route serving a document
Prompt
Agent requests a template
Reusable, server-authored instructions for common workflows
A Blade template for model instructions
Tools are the workhorses. Each tool has a name, a natural-language description, and a typed argument schema. The description is not decoration: it's how the model decides when to call the tool, so write it like you'd write for a sharp junior engineer who skims. Vague descriptions produce misfired calls.
Resources are content the agent can pull into context: your API changelog, a runbook, a schema reference. If a capability takes no arguments and changes nothing, make it a resource, not a tool. Fewer tools means fewer wrong choices for the model and a smaller surface for you to authorize.
Prompts are server-provided templates. If every "triage an incident" conversation should start with the same instructions and the same data-gathering sequence, ship that as a prompt so users don't reinvent it badly. We've found that prompts are the most underused primitive; teams put workflow instructions in a wiki that agents never read, when the server itself could serve them.
One design rule we'd push hard: model your tools around intents, not tables. resend-failed-webhook is a good tool. update-webhook-row is a bad one, because it forces the model to understand your schema and gives it write access far beyond the intent. Narrow tools are easier to authorize, easier to describe, and much harder to misuse.
How Do You Build One with laravel/mcp?
The official package makes this feel like normal Laravel work, which is exactly what you want. Install it and publish the routes file:
composer require laravel/mcp
php artisan vendor:publish --tag=ai-routes
That gives you routes/ai.php, a dedicated routes file for MCP servers, deliberately separate from web.php and api.php. Then generate a server and a first tool:
php artisan make:mcp-server OpsServer
php artisan make:mcp-tool ListRecentDeployments
Defining the server
A server class declares its identity, its instructions to connecting clients, and its capabilities. Instructions matter: they're the system-level guidance every client receives, so use them to state what the server is for and what it will refuse to do.
php
Top comments (0)