|
1 | | -# Model Context Protocol PHP SDK [WIP] |
| 1 | +# Model Context Protocol PHP SDK |
2 | 2 |
|
3 | 3 | Model Context Protocol SDK for Client and Server applications in PHP. |
4 | | -**Currently only support Tool Calls as Server via Server-Sent Events (SSE) and STDIO.** |
5 | | - |
6 | | -See [Demo App](https://github.com/php-llm/mcp-demo) for a working example and [MCP Bundle](https://github.com/php-llm/mcp-bundle) for Symfony integration. |
7 | 4 |
|
8 | 5 | ## Installation |
9 | 6 |
|
10 | 7 | ```bash |
11 | | -composer require php-llm/mcp-sdk |
12 | | -``` |
13 | | - |
14 | | -## Usage with Symfony |
15 | | - |
16 | | -Server integration points for are tailored to Symfony Console and HttpFoundation (Laravel compatible). |
17 | | - |
18 | | -### Console Command for STDIO Server |
19 | | - |
20 | | -```php |
21 | | -namespace App\Command; |
22 | | - |
23 | | -use PhpLlm\McpSdk\Server; |
24 | | -use PhpLlm\McpSdk\Server\Transport\Stdio\SymfonyConsoleTransport; |
25 | | -use Symfony\Component\Console\Attribute\AsCommand; |
26 | | -use Symfony\Component\Console\Command\Command; |
27 | | -use Symfony\Component\Console\Input\InputInterface; |
28 | | -use Symfony\Component\Console\Output\OutputInterface; |
29 | | - |
30 | | -#[AsCommand('mcp', 'Starts an MCP server')] |
31 | | -final class McpCommand extends Command |
32 | | -{ |
33 | | - public function __construct( |
34 | | - private readonly Server $server, |
35 | | - ) { |
36 | | - parent::__construct(); |
37 | | - } |
38 | | - |
39 | | - protected function execute(InputInterface $input, OutputInterface $output): int |
40 | | - { |
41 | | - $this->server->connect( |
42 | | - new SymfonyConsoleTransport($input, $output) |
43 | | - ); |
44 | | - |
45 | | - return Command::SUCCESS; |
46 | | - } |
47 | | -} |
| 8 | +composer require symfony/mcp-sdk |
48 | 9 | ``` |
49 | 10 |
|
50 | | -### Controller for Server-Sent Events Server |
| 11 | +This is a low level SDK that implements the [Model Context Protocol](https://modelcontextprotocol.io/) |
| 12 | +(MCP). The protocol is used by LLM model to build "plugins" and give them extra |
| 13 | +context. Example the logged in users' latest order. |
51 | 14 |
|
52 | | -```php |
53 | | -namespace App\Controller; |
| 15 | +**This repository is a READ-ONLY sub-tree split**. See |
| 16 | +https://github.com/symfony/ai to create issues or submit pull requests. |
54 | 17 |
|
55 | | -use PhpLlm\McpSdk\Server; |
56 | | -use PhpLlm\McpSdk\Server\Transport\Sse\Store\CachePoolStore; |
57 | | -use PhpLlm\McpSdk\Server\Transport\Sse\StreamTransport; |
58 | | -use Symfony\Component\HttpFoundation\Request; |
59 | | -use Symfony\Component\HttpFoundation\Response; |
60 | | -use Symfony\Component\HttpFoundation\StreamedResponse; |
61 | | -use Symfony\Component\HttpKernel\Attribute\AsController; |
62 | | -use Symfony\Component\Routing\Attribute\Route; |
63 | | -use Symfony\Component\Routing\Generator\UrlGeneratorInterface; |
64 | | -use Symfony\Component\Uid\Uuid; |
| 18 | +## Resources |
65 | 19 |
|
66 | | -#[AsController] |
67 | | -#[Route('/mcp', name: 'mcp_')] |
68 | | -final readonly class McpController |
69 | | -{ |
70 | | - public function __construct( |
71 | | - private Server $server, |
72 | | - private CachePoolStore $store, |
73 | | - private UrlGeneratorInterface $urlGenerator, |
74 | | - ) { |
75 | | - } |
| 20 | +- [Documentation](doc/index.rst) |
| 21 | +- [Report issues](https://github.com/symfony/ai/issues) and |
| 22 | + [send Pull Requests](https://github.com/symfony/ai/pulls) |
| 23 | + in the [main Symfony AI repository](https://github.com/symfony/ai) |
76 | 24 |
|
77 | | - #[Route('/sse', name: 'sse', methods: ['GET'])] |
78 | | - public function sse(): StreamedResponse |
79 | | - { |
80 | | - $id = Uuid::v4(); |
81 | | - $endpoint = $this->urlGenerator->generate('mcp_messages', ['id' => $id], UrlGeneratorInterface::ABSOLUTE_URL); |
82 | | - $transport = new StreamTransport($endpoint, $this->store, $id); |
83 | | - |
84 | | - return new StreamedResponse(fn() => $this->server->connect($transport), headers: [ |
85 | | - 'Content-Type' => 'text/event-stream', |
86 | | - 'Cache-Control' => 'no-cache', |
87 | | - 'X-Accel-Buffering' => 'no', |
88 | | - ]); |
89 | | - } |
90 | | - |
91 | | - #[Route('/messages/{id}', name: 'messages', methods: ['POST'])] |
92 | | - public function messages(Request $request, Uuid $id): Response |
93 | | - { |
94 | | - $this->store->push($id, $request->getContent()); |
95 | | - |
96 | | - return new Response(); |
97 | | - } |
98 | | -} |
99 | | -``` |
100 | | - |
101 | | -### Exposing Tools |
102 | | - |
103 | | -Under the hood the SDK uses [LLM Chain](https://github.com/php-llm/llm-chain)'s `ToolBox` to register, analyze and |
104 | | -execute tools. In combination with its [Symfony Bundle](https://github.com/php-llm/llm-chain-bundle) you can expose |
105 | | -tools with `#[AsTool]` attribute. |
106 | | - |
107 | | -```php |
108 | | -use PhpLlm\LlmChain\ToolBox\Attribute\AsTool; |
109 | | - |
110 | | -#[AsTool('company_name', 'Provides the name of your company')] |
111 | | -final class CompanyName |
112 | | -{ |
113 | | - public function __invoke(): string |
114 | | - { |
115 | | - return 'ACME Corp.' |
116 | | - } |
117 | | -} |
118 | | -``` |
119 | | -See [LLM Chain Documentation](https://github.com/php-llm/llm-chain?tab=readme-ov-file#tools) for more information. |
| 25 | +[1]: https://symfony.com/backers |
| 26 | +[3]: https://symfony.com/sponsor |
0 commit comments