Skip to content

Commit 20ef42c

Browse files
Added Compiler Pass to build ToolChain
Address comments lint Update src/mcp-bundle/CHANGELOG.md Co-authored-by: Oskar Stark <[email protected]> Update src/mcp-bundle/CHANGELOG.md Co-authored-by: Oskar Stark <[email protected]> Update src/mcp-bundle/doc/index.rst Co-authored-by: Oskar Stark <[email protected]> Update src/mcp-bundle/doc/index.rst Co-authored-by: Oskar Stark <[email protected]> Remove strict types
1 parent f0a63bd commit 20ef42c

File tree

6 files changed

+66
-9
lines changed

6 files changed

+66
-9
lines changed

demo/config/services.yaml

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,3 @@ services:
1818
- '../src/DependencyInjection/'
1919
- '../src/Entity/'
2020
- '../src/Kernel.php'
21-
22-
mcp.tool_executor:
23-
class: Symfony\AI\McpSdk\Capability\ToolChain
24-
arguments:
25-
- ['@App\MCP\Tools\CurrentTimeTool']
26-
27-
mcp.tool_collection:
28-
alias: mcp.tool_executor

demo/src/MCP/Tools/CurrentTimeTool.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,12 @@
1515
use Symfony\AI\McpSdk\Capability\Tool\ToolCall;
1616
use Symfony\AI\McpSdk\Capability\Tool\ToolCallResult;
1717
use Symfony\AI\McpSdk\Capability\Tool\ToolExecutorInterface;
18+
use Symfony\Component\DependencyInjection\Attribute\AutoconfigureTag;
1819

1920
/**
2021
* @author Tom Hart <[email protected]>
2122
*/
23+
#[AutoconfigureTag('mcp.tool')]
2224
class CurrentTimeTool implements MetadataInterface, ToolExecutorInterface
2325
{
2426
public function call(ToolCall $input): ToolCallResult

src/mcp-bundle/CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,6 @@ CHANGELOG
1717
* Add `McpCommand` providing STDIO interface
1818
* Add bundle configuration for enabling/disabling transports
1919
* Add cache-based SSE message storage
20-
* Add service configuration for MCP server setup
20+
* Add service configuration for MCP server setup
21+
* Add `Symfony\AI\McpBundle\DependencyInjection\ContainerBuilder\McpToolChainCompilerPass`
22+
to find services tagged `mcp.tool` and register them in the MCP tool chain.

src/mcp-bundle/doc/index.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,11 @@ Configuration
6363
sse:
6464
url: 'http://localhost:8000/sse' # URL to SSE endpoint of MCP server
6565
66+
To add your tools to the MCP server, add the following tag::
67+
68+
#[AutoconfigureTag('mcp.tool')]
69+
class CurrentTimeTool implements MetadataInterface, ToolExecutorInterface
70+
6671
.. _`Model Context Protocol`: https://modelcontextprotocol.io/
6772
.. _`symfony/mcp-sdk`: https://github.com/symfony/mcp-sdk
6873
.. _`Claude Desktop`: https://claude.ai/download
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
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 Symfony\AI\McpBundle\DependencyInjection\ContainerBuilder;
13+
14+
use Symfony\AI\McpSdk\Capability\Tool\CollectionInterface;
15+
use Symfony\AI\McpSdk\Capability\Tool\ToolExecutorInterface;
16+
use Symfony\AI\McpSdk\Capability\ToolChain;
17+
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
18+
use Symfony\Component\DependencyInjection\Compiler\PriorityTaggedServiceTrait;
19+
use Symfony\Component\DependencyInjection\ContainerBuilder;
20+
use Symfony\Component\DependencyInjection\Definition;
21+
22+
/**
23+
* @author Tom Hart <[email protected]>
24+
*/
25+
final class McpToolChainCompilerPass implements CompilerPassInterface
26+
{
27+
use PriorityTaggedServiceTrait;
28+
29+
public function process(ContainerBuilder $container): void
30+
{
31+
// If the user has already defined this service, don't override it.
32+
if ($container->hasDefinition(ToolExecutorInterface::class)) {
33+
return;
34+
}
35+
36+
$definition = new Definition(ToolChain::class);
37+
38+
$taggedServices = $this->findAndSortTaggedServices('mcp.tool', $container);
39+
40+
$definition->setArgument(0, $taggedServices);
41+
42+
$container->setDefinition(ToolExecutorInterface::class, $definition);
43+
44+
if (!$container->hasDefinition(CollectionInterface::class)) {
45+
$container->setAlias(CollectionInterface::class, ToolExecutorInterface::class);
46+
}
47+
}
48+
}

src/mcp-bundle/src/McpBundle.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use Symfony\AI\McpBundle\Command\McpCommand;
1515
use Symfony\AI\McpBundle\Controller\McpController;
16+
use Symfony\AI\McpBundle\DependencyInjection\ContainerBuilder\McpToolChainCompilerPass;
1617
use Symfony\AI\McpBundle\Routing\RouteLoader;
1718
use Symfony\Component\Config\Definition\Configurator\DefinitionConfigurator;
1819
use Symfony\Component\DependencyInjection\ContainerBuilder;
@@ -22,6 +23,13 @@
2223

2324
final class McpBundle extends AbstractBundle
2425
{
26+
public function build(ContainerBuilder $container): void
27+
{
28+
parent::build($container);
29+
30+
$container->addCompilerPass(new McpToolChainCompilerPass());
31+
}
32+
2533
public function configure(DefinitionConfigurator $definition): void
2634
{
2735
$definition->import('../config/options.php');

0 commit comments

Comments
 (0)