Skip to content

Commit 313cfa5

Browse files
committed
feature #637 [MCP Bundle] Migrate from symfony/mcp-sdk to official mcp/sdk (camilleislasse)
This PR was merged into the main branch. Discussion ---------- [MCP Bundle] Migrate from `symfony/mcp-sdk` to official `mcp/sdk` | Q | A | ------------- | --- | Bug fix? | no | New feature? | yes | Docs? | yes | Issues | Fix #526 | License | MIT ## Summary This PR migrates the MCP Bundle from the internal `symfony/mcp-sdk` to the official `mcp/sdk` package and completely removes the internal MCP SDK component. ## Changes ### Remove Internal MCP SDK - **Deleted entire `src/mcp-sdk/` directory** - **Removed dependency** from `symfony/mcp-sdk` to `mcp/sdk` - **Updated all references** in documentation and configuration files ### MCP Bundle Migration - **Dependency change**: `symfony/mcp-sdk` → `mcp/sdk` in composer.json - **Server creation**: Refactored to use `Server::make()` builder pattern - **Service configuration**: Simplified using official SDK patterns ### New MCP Capabilities Support - **Attribute-based discovery**: Added support for `#[McpTool]`, `#[McpPrompt]`, `#[McpResource]`, `#[McpResourceTemplate]` - **Compiler passes**: Created `McpToolPass`, `McpPromptPass`, `McpResourcePass`, `McpResourceTemplatePass` - **Autoconfiguration**: Automatic service tagging and registration ### Bundle Enhancements - **EventDispatcher integration**: Added Symfony EventDispatcher for MCP SDK events - **Dedicated logger**: Added `monolog.logger.mcp` service - **Configuration options**: Added `pagination_limit` and `instructions` parameters - **Route loading**: Fixed RouteLoader registration for SSE transport ### Demo Application Updates - **Added new MCP examples**: - `CurrentTimePrompt.php` - Prompt capability - `CurrentTimeResource.php` - Resource capability - `CurrentTimeResourceTemplate.php` - Resource template capability - **Updated tool implementation**: Migrated `CurrentTimeTool.php` from interface to attribute - **Enhanced configuration**: Added pagination_limit, instructions ### Documentation - **rewrite** of `doc/index.rst` with examples for all capability types - **Event system documentation** with listener examples - **Logging configuration** guide - **Updated README and CHANGELOG** to reflect official SDK usage ### Testing - **Added tests** for all compiler passes - **Updated bundle tests** for new configuration options - **Added EventDispatcher test coverage** ## Breaking Changes - **Tool definition**: Use `#[McpTool]` attribute instead of implementing interfaces - **Dependency**: Replace `symfony/mcp-sdk` with `mcp/sdk` in composer.json ## Code Examples **Before (interface-based):** ```php class Tool implements MetadataInterface, ToolExecutorInterface { public function call(ToolCall $request): ToolCallResult { return new ToolCallResult($result); } public function getName(): string { return 'tool-name'; } } After (attribute-based): class Tool { #[McpTool(name: 'tool-name')] public function execute(string $param): string { return $result; } } New capabilities: #[McpPrompt(name: 'analysis')] public function getPrompt(): array { ... } #[McpResource(uri: 'data://current', name: 'current-data')] public function getResource(): array { ... } #[McpResourceTemplate(uriTemplate: 'data://{id}', name: 'data-by-id')] public function getTemplate(string $id): array { ... } Commits ------- 1382d4c Migrate MCP Bundle from symfony/mcp-sdk to official mcp/sdk
2 parents 30c655a + 1382d4c commit 313cfa5

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)