The Model Context Protocol (MCP) lets AI assistants like Claude Desktop discover and call tools exposed by your application. In this guide you will install the MCP Bundle, create a tool, a prompt, and a resource, then test them with a client.
Prerequisites
- A Symfony application
- Symfony AI MCP Bundle
Step 1: Install the MCP Bundle
The MCP Bundle integrates the official mcp/sdk PHP package into your Symfony application:
1 |
composer require symfony/mcp-bundle
|
Step 2: Configure Routing
Add the MCP route to your routing configuration. This exposes the HTTP endpoint that MCP clients connect to:
1 2 3 4 |
# config/routes.yaml
mcp:
resource: .
type: mcp
|
Step 3: Create a Tool
Use the #[McpTool] attribute on a method to expose it as a callable tool. MCP clients see the
tool name and can invoke it with parameters:
1 2 3 4 5 6 7 8 9 10 11 12 |
namespace App\Mcp;
use Mcp\Capability\Attribute\McpTool;
class CurrentTimeTool
{
#[McpTool(name: 'current-time')]
public function getCurrentTime(string $format = 'Y-m-d H:i:s'): string
{
return (new \DateTime('now', new \DateTimeZone('UTC')))->format($format);
}
}
|
Tip
You can place multiple #[McpTool] methods in the same class to group related tools
together.
Step 4: Configure Transport
Enable STDIO and/or HTTP transport in the bundle configuration. The STDIO transport is used by command-line clients; HTTP is used by web-based clients and the MCP Inspector:
1 2 3 4 5 6 7 8 9 10 11 12 |
# config/packages/mcp.yaml
mcp:
app: 'my-app'
version: '1.0.0'
description: 'My Symfony MCP server'
client_transports:
stdio: true
http: true
http:
path: /_mcp
|
Step 5: Create a Prompt
Prompts provide system instructions that AI clients can request. Use the #[McpPrompt]
attribute and return an array of messages:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
namespace App\Mcp;
use Mcp\Capability\Attribute\McpPrompt;
class TimePrompts
{
#[McpPrompt(name: 'time-analysis')]
public function getTimeAnalysisPrompt(): array
{
return [
['role' => 'user', 'content' => 'You are a time management expert.'],
];
}
}
|
Step 6: Create a Resource
Resources expose static data that AI clients can read. Use the #[McpResource] attribute with
a URI and a name:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
namespace App\Mcp;
use Mcp\Capability\Attribute\McpResource;
class TimeResource
{
#[McpResource(uri: 'time://current', name: 'current-time')]
public function getCurrentTimeResource(): array
{
return [
'uri' => 'time://current',
'mimeType' => 'text/plain',
'text' => (new \DateTime('now'))->format('Y-m-d H:i:s'),
];
}
}
|
Step 7: Test with an MCP Client
To connect Claude Desktop (or any MCP-compatible client) to your server, add an entry to the client's configuration file pointing at your Symfony console command for STDIO transport:
1 2 3 4 5 6 7 |
{
"mcpServers": {
"my-app": {
"command": "php /path/to/project/bin/console mcp:server"
}
}
}
|
For the HTTP transport, point the client at your application's MCP endpoint instead:
1 2 3 4 5 6 7 |
{
"mcpServers": {
"my-app": {
"url": "http://localhost:8000/_mcp"
}
}
}
|
Tip
Run symfony console mcp:server to start the STDIO server manually. This is useful for
debugging before connecting a client.
Learn More
- MCP Bundle - Full configuration, session storage, and event system
- Model Context Protocol Specification - The official MCP standard
- MCP PHP SDK - Documentation for the official MCP SDK for PHP