Skip to content

Commit 1382d4c

Browse files
camilleislassechr-hertel
authored andcommitted
Migrate MCP Bundle from symfony/mcp-sdk to official mcp/sdk
- Replace symfony/mcp-sdk dependency with official mcp/sdk - Refactor Server creation to use Server::make() builder pattern - Convert tool definitions from interfaces to #[McpTool] attributes - Implement automatic tool discovery in src/ directory - Update STDIO transport command to mcp:server - Simplify service configuration using native SDK patterns - Remove redundant ServerFactory and routes.php files - Add custom LogicException for bundle-specific errors - Update all documentation (README, CHANGELOG, index.rst) - Fix composer.json description - Add .idea/ to .gitignore Resolves #526 Fabbot + php-cs-fixer DOCtor-RST Fix RouteLoader registration to always create when transports enabled Remove .idea - Add autoconfiguration for #[McpTool] attribute with mcp.tool tag - Create McpToolPass compiler pass using ServiceLocatorTagPass::register() - Inject Service Locator into ServerBuilder via setContainer() Fix PR review comments for MCP Bundle migration - Remove prefer-stable from root composer.json - Move CHANGELOG content to 0.1 section and remove BC BREAK labels - Use ServerBuilder::class and Server::class in services configuration - Fix "client vs server" comment in documentation - Use ServerBuilder::class in test instead of string Remove symfony/mcp-sdk Remove symfony/mcp-sdk ref in claude reamdde et phpstan Rewrite CHANGELOG.md Use [] === $taggedServices instead of empty($taggedServices) Use use Symfony\Component\Routing\Exception\LogicException; instead of custom Exception Add MCP capabilities support to Symfony bundle This commit implements Model Context Protocol (MCP) support by adding: - Prompts: System instructions for AI context using #[McpPrompt] - Resources: Static data access using #[McpResource] - Resource Templates: Dynamic resources with parameters using #[McpResourceTemplate] Implementation includes: - Auto-configuration for MCP attributes with proper tagging - Compiler passes extending AbstractMcpPass for service registration - Documentation updates with examples and usage patterns - Demo examples showcasing each capability type Technical details: - Refactored auto-configuration into registerMcpAttributes() method - Created AbstractMcpPass to eliminate code duplication - Added proper error handling for timezone validation - Resource Templates ready but await MCP SDK handler implementation Apply PHP CS Fixer to demo MCP examples - Add Symfony license headers to demo files - Fix code style and formatting - Add trailing commas where appropriate Add pagination_limit and instructions configuration options - Add pagination_limit option to control MCP list responses (default: 50) - Add instructions option for server description to help LLMs - Update services.php to pass both options to ServerBuilder - Add comprehensive tests for new configuration options - Update documentation with examples and usage - Update demo configuration with practical examples Both options map directly to ServerBuilder methods: - setPaginationLimit(int) - setInstructions(string) Add dedicated MCP logger with configurable Monolog integration - Create monolog.logger.mcp service with dedicated channel - Update ServerBuilder to use MCP-specific logger instead of generic logger - Add comprehensive logging documentation with configuration examples - Include examples for different environments (dev/prod) and handlers (file/Slack) - Add test coverage for MCP logger service creation and configuration The MCP logger uses Monolog's logger prototype pattern and can be customized by users through standard Monolog configuration in their applications. Add EventDispatcher support and event system documentation - Configure Symfony EventDispatcher for MCP SDK event handling - Add comprehensive event system documentation with examples - Add test coverage for EventDispatcher configuration - Fix PHPStan type assertion for ChildDefinition Migrate MCP Bundle from SSE to official StreamableHttpTransport - Replace custom SSE implementation with MCP SDK's StreamableHttpTransport - Change sse transport to http in configuration and code - Simplify DependencyInjection compiler passes - Add HTTP session management (file/memory store options) - Update documentation and tests for HTTP transport
1 parent dba7bb0 commit 1382d4c

File tree

114 files changed

+822
-4156
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

114 files changed

+822
-4156
lines changed

.phpstan/ForbidNativeExceptionRule.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ final class ForbidNativeExceptionRule implements Rule
5151
'Symfony\\AI\\Agent' => 'Symfony\\AI\\Agent\\Exception\\',
5252
'Symfony\\AI\\Platform' => 'Symfony\\AI\\Platform\\Exception\\',
5353
'Symfony\\AI\\Store' => 'Symfony\\AI\\Store\\Exception\\',
54-
'Symfony\\AI\\McpSdk' => 'Symfony\\AI\\McpSdk\\Exception\\',
5554
'Symfony\\AI\\AiBundle' => 'Symfony\\AI\\AiBundle\\Exception\\',
5655
'Symfony\\AI\\McpBundle' => 'Symfony\\AI\\McpBundle\\Exception\\',
5756
];

AGENTS.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,10 @@ Symfony AI monorepo with independent packages for AI integration in PHP applicat
1212
- **Platform** (`src/platform/`): Unified AI platform interface (OpenAI, Anthropic, Azure, Gemini, VertexAI)
1313
- **Agent** (`src/agent/`): AI agent framework for user interaction and task execution
1414
- **Store** (`src/store/`): Data storage abstraction with vector database support
15-
- **MCP SDK** (`src/mcp-sdk/`): Model Context Protocol SDK for agent-tool communication
1615

1716
### Integration Bundles
1817
- **AI Bundle** (`src/ai-bundle/`): Symfony integration for Platform, Store, and Agent
19-
- **MCP Bundle** (`src/mcp-bundle/`): Symfony integration for MCP SDK
18+
- **MCP Bundle** (`src/mcp-bundle/`): Symfony integration for official MCP SDK
2019

2120
### Supporting Directories
2221
- **Examples** (`examples/`): Standalone usage examples

CLAUDE.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,10 @@ This is the Symfony AI monorepo containing multiple components and bundles that
1212
- **Platform** (`src/platform/`): Unified interface to AI platforms (OpenAI, Anthropic, Azure, Gemini, VertexAI, etc.)
1313
- **Agent** (`src/agent/`): Framework for building AI agents that interact with users and perform tasks
1414
- **Store** (`src/store/`): Data storage abstraction with indexing and retrieval for vector databases
15-
- **MCP SDK** (`src/mcp-sdk/`): SDK for Model Context Protocol enabling agent-tool communication
1615

1716
### Integration Bundles
1817
- **AI Bundle** (`src/ai-bundle/`): Symfony integration for Platform, Store, and Agent components
19-
- **MCP Bundle** (`src/mcp-bundle/`): Symfony integration for MCP SDK
18+
- **MCP Bundle** (`src/mcp-bundle/`): Symfony integration for official MCP SDK
2019

2120
### Supporting Directories
2221
- **Examples** (`examples/`): Standalone examples demonstrating component usage across different AI platforms
@@ -92,7 +91,7 @@ symfony server:start
9291
Components are designed to work independently but have these relationships:
9392
- Agent depends on Platform for AI communication
9493
- AI Bundle integrates Platform, Agent, and Store
95-
- MCP Bundle provides MCP SDK integration
94+
- MCP Bundle provides official MCP SDK integration
9695
- Store is standalone but often used with Agent for RAG applications
9796

9897
## Testing Architecture

README.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,9 @@ Symfony AI consists of several lower and higher level **components** and the res
1616
* **[Platform](src/platform/README.md)**: A unified interface to various AI platforms like OpenAI, Anthropic, Azure, Gemini, VertexAI, and more.
1717
* **[Agent](src/agent/README.md)**: Framework for building AI agents that can interact with users and perform tasks.
1818
* **[Store](src/store/README.md)**: Data storage abstraction with indexing and retrieval for AI applications.
19-
* **[MCP SDK](src/mcp-sdk/README.md)**: SDK for [Model Context Protocol](https://modelcontextprotocol.io) enabling communication between AI agents and tools.
2019
* **Bundles**
2120
* **[AI Bundle](src/ai-bundle/README.md)**: Symfony integration for AI Platform, Store and Agent components.
22-
* **[MCP Bundle](src/mcp-bundle/README.md)**: Symfony integration for MCP SDK, allowing them to act as MCP servers or clients.
21+
* **[MCP Bundle](src/mcp-bundle/README.md)**: Symfony integration for official MCP SDK, allowing them to act as MCP servers or clients.
2322

2423
## Examples & Demo
2524

demo/composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
"symfony/flex": "^2.5",
2424
"symfony/framework-bundle": "~7.3.0",
2525
"symfony/http-client": "~7.3.0",
26+
"mcp/sdk": "@dev",
2627
"symfony/mcp-bundle": "@dev",
2728
"symfony/monolog-bundle": "^3.10",
2829
"symfony/runtime": "~7.3.0",

demo/config/packages/mcp.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
mcp:
22
app: demo-app
33
version: 0.0.1
4+
pagination_limit: 10
5+
instructions: |
6+
This demo MCP server provides time management capabilities for developers.
7+
8+
Use this server when you need to work with timestamps, time zones, or time-based calculations.
9+
410
client_transports:
511
stdio: true
12+
http: true
13+
http:
14+
session:
15+
store: file

demo/config/routes.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,8 @@ stream:
4949
stream_assistant_reply:
5050
path: '/stream/assistant-reply'
5151
controller: 'App\Stream\TwigComponent::streamContent'
52+
53+
# Load MCP routes conditionally based on configuration
54+
_mcp:
55+
resource: .
56+
type: mcp
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace App\MCP\Prompts;
13+
14+
use Mcp\Capability\Attribute\McpPrompt;
15+
16+
class CurrentTimePrompt
17+
{
18+
#[McpPrompt(name: 'time-analysis')]
19+
public function getTimeAnalysisPrompt(): array
20+
{
21+
return [
22+
[
23+
'role' => 'user',
24+
'content' => 'You are a time management expert. Analyze what time of day it is and suggest appropriate activities for this time.',
25+
],
26+
];
27+
}
28+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace App\MCP\ResourceTemplates;
13+
14+
use Mcp\Capability\Attribute\McpResourceTemplate;
15+
16+
class CurrentTimeResourceTemplate
17+
{
18+
#[McpResourceTemplate(uriTemplate: 'time://{timezone}', name: 'time-by-timezone')]
19+
public function getTimeByTimezone(string $timezone): array
20+
{
21+
try {
22+
$time = (new \DateTime('now', new \DateTimeZone($timezone)))->format('Y-m-d H:i:s T');
23+
} catch (\Exception $e) {
24+
$time = 'Invalid timezone: '.$timezone;
25+
}
26+
27+
return [
28+
'uri' => "time://$timezone",
29+
'mimeType' => 'text/plain',
30+
'text' => $time,
31+
];
32+
}
33+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace App\MCP\Resources;
13+
14+
use Mcp\Capability\Attribute\McpResource;
15+
16+
class CurrentTimeResource
17+
{
18+
#[McpResource(uri: 'time://current', name: 'current-time-resource')]
19+
public function getCurrentTimeResource(): array
20+
{
21+
return [
22+
'uri' => 'time://current',
23+
'mimeType' => 'text/plain',
24+
'text' => (new \DateTime('now'))->format('Y-m-d H:i:s T'),
25+
];
26+
}
27+
}

0 commit comments

Comments
 (0)